[gthumb] selections: show an emblem when a file is added to a selection
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] selections: show an emblem when a file is added to a selection
- Date: Mon, 9 Apr 2012 20:00:19 +0000 (UTC)
commit bdc81841beef5ea609987259eb93d8947b6df364
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Apr 9 21:20:08 2012 +0200
selections: show an emblem when a file is added to a selection
extensions/selections/Makefile.am | 20 ++--
.../selections/gth-metadata-provider-selections.c | 108 ++++++++++++++++++++
.../selections/gth-metadata-provider-selections.h | 51 +++++++++
extensions/selections/gth-selections-manager.c | 54 ++++++++--
extensions/selections/gth-selections-manager.h | 4 +
extensions/selections/main.c | 2 +
gthumb/glib-utils.h | 1 +
gthumb/gth-browser.c | 73 +++++++++++++
gthumb/gth-file-list.c | 44 ++++++++
gthumb/gth-file-list.h | 2 +
gthumb/gth-file-store.c | 16 +++-
gthumb/gth-file-store.h | 1 +
gthumb/gth-grid-view.c | 53 ++++++++++
gthumb/gth-main-default-metadata.c | 1 +
gthumb/gth-monitor.c | 41 ++++++++
gthumb/gth-monitor.h | 6 +-
16 files changed, 453 insertions(+), 24 deletions(-)
---
diff --git a/extensions/selections/Makefile.am b/extensions/selections/Makefile.am
index 1d1156e..95889b8 100644
--- a/extensions/selections/Makefile.am
+++ b/extensions/selections/Makefile.am
@@ -1,15 +1,17 @@
extensiondir = $(pkglibdir)/extensions
extension_LTLIBRARIES = libselections.la
-libselections_la_SOURCES = \
- actions.c \
- actions.h \
- callbacks.c \
- callbacks.h \
- gth-file-source-selections.c \
- gth-file-source-selections.h \
- gth-selections-manager.c \
- gth-selections-manager.h \
+libselections_la_SOURCES = \
+ actions.c \
+ actions.h \
+ callbacks.c \
+ callbacks.h \
+ gth-file-source-selections.c \
+ gth-file-source-selections.h \
+ gth-metadata-provider-selections.c \
+ gth-metadata-provider-selections.h \
+ gth-selections-manager.c \
+ gth-selections-manager.h \
main.c
libselections_la_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
diff --git a/extensions/selections/gth-metadata-provider-selections.c b/extensions/selections/gth-metadata-provider-selections.c
new file mode 100644
index 0000000..14c0615
--- /dev/null
+++ b/extensions/selections/gth-metadata-provider-selections.c
@@ -0,0 +1,108 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <gthumb.h>
+#include "gth-metadata-provider-selections.h"
+#include "gth-selections-manager.h"
+
+
+G_DEFINE_TYPE (GthMetadataProviderSelections, gth_metadata_provider_selections, GTH_TYPE_METADATA_PROVIDER)
+
+
+static gboolean
+gth_metadata_provider_selections_can_read (GthMetadataProvider *self,
+ const char *mime_type,
+ char **attribute_v)
+{
+ return _g_file_attributes_matches_any_v (GTH_FILE_ATTRIBUTE_EMBLEMS,
+ attribute_v);
+}
+
+
+static gboolean
+gth_metadata_provider_selections_can_write (GthMetadataProvider *self,
+ const char *mime_type,
+ char **attribute_v)
+{
+ return FALSE;
+}
+
+
+static void
+gth_metadata_provider_selections_read (GthMetadataProvider *self,
+ GthFileData *file_data,
+ const char *attributes,
+ GCancellable *cancellable)
+{
+ GList *emblem_list;
+ GthStringList *emblems;
+ GthStringList *other_emblems;
+ int i;
+
+ emblem_list = NULL;
+ for (i = GTH_SELECTIONS_MANAGER_N_SELECTIONS; i >= 0; i--) {
+ if (gth_selections_manager_file_exists (i, file_data->file))
+ emblem_list = g_list_prepend (emblem_list, g_strdup_printf ("selection%d", i));
+ }
+
+ emblems = gth_string_list_new (emblem_list);
+ other_emblems = (GthStringList *) g_file_info_get_attribute_object (file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS);
+ if (other_emblems != NULL)
+ gth_string_list_append (emblems, other_emblems);
+
+ g_file_info_set_attribute_object (file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS, G_OBJECT (emblems));
+
+ g_object_unref (emblems);
+ _g_string_list_free (emblem_list);
+}
+
+
+static void
+gth_metadata_provider_selections_write (GthMetadataProvider *self,
+ GthMetadataWriteFlags flags,
+ GthFileData *file_data,
+ const char *attributes,
+ GCancellable *cancellable)
+{
+ /* void: never called */
+}
+
+
+static void
+gth_metadata_provider_selections_class_init (GthMetadataProviderSelectionsClass *klass)
+{
+ GthMetadataProviderClass *mp_class;
+
+ mp_class = GTH_METADATA_PROVIDER_CLASS (klass);
+ mp_class->can_read = gth_metadata_provider_selections_can_read;
+ mp_class->can_write = gth_metadata_provider_selections_can_write;
+ mp_class->read = gth_metadata_provider_selections_read;
+ mp_class->write = gth_metadata_provider_selections_write;
+}
+
+
+static void
+gth_metadata_provider_selections_init (GthMetadataProviderSelections *self)
+{
+ /* void */
+}
diff --git a/extensions/selections/gth-metadata-provider-selections.h b/extensions/selections/gth-metadata-provider-selections.h
new file mode 100644
index 0000000..c370d62
--- /dev/null
+++ b/extensions/selections/gth-metadata-provider-selections.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_METADATA_PROVIDER_SELECTIONS_H
+#define GTH_METADATA_PROVIDER_SELECTIONS_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gthumb.h>
+
+#define GTH_TYPE_METADATA_PROVIDER_SELECTIONS (gth_metadata_provider_selections_get_type ())
+#define GTH_METADATA_PROVIDER_SELECTIONS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTH_TYPE_METADATA_PROVIDER_SELECTIONS, GthMetadataProviderSelections))
+#define GTH_METADATA_PROVIDER_SELECTIONS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTH_TYPE_METADATA_PROVIDER_SELECTIONS, GthMetadataProviderSelectionsClass))
+#define GTH_IS_METADATA_PROVIDER_SELECTIONS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTH_TYPE_METADATA_PROVIDER_SELECTIONS))
+#define GTH_IS_METADATA_PROVIDER_SELECTIONS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTH_TYPE_METADATA_PROVIDER_SELECTIONS))
+#define GTH_METADATA_PROVIDER_SELECTIONS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GTH_TYPE_METADATA_PROVIDER_SELECTIONS, GthMetadataProviderSelectionsClass))
+
+typedef struct _GthMetadataProviderSelections GthMetadataProviderSelections;
+typedef struct _GthMetadataProviderSelectionsClass GthMetadataProviderSelectionsClass;
+
+struct _GthMetadataProviderSelections
+{
+ GthMetadataProvider __parent;
+};
+
+struct _GthMetadataProviderSelectionsClass
+{
+ GthMetadataProviderClass __parent_class;
+};
+
+GType gth_metadata_provider_selections_get_type (void) G_GNUC_CONST;
+
+#endif /* GTH_METADATA_PROVIDER_SELECTIONS_H */
diff --git a/extensions/selections/gth-selections-manager.c b/extensions/selections/gth-selections-manager.c
index 5ba4c2b..93e5213 100644
--- a/extensions/selections/gth-selections-manager.c
+++ b/extensions/selections/gth-selections-manager.c
@@ -27,14 +27,12 @@
#include "gth-selections-manager.h"
-#define N_SELECTIONS 3
-
-
struct _GthSelectionsManagerPrivate {
- GList *files[N_SELECTIONS];
- char *order[N_SELECTIONS];
- gboolean order_inverse[N_SELECTIONS];
- GMutex *mutex;
+ GList *files[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
+ GHashTable *files_hash[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
+ char *order[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
+ gboolean order_inverse[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
+ GMutex *mutex;
};
@@ -72,8 +70,9 @@ gth_selections_manager_finalize (GObject *object)
self = GTH_SELECTIONS_MANAGER (object);
- for (i = 0; i < N_SELECTIONS; i++) {
+ for (i = 0; i < GTH_SELECTIONS_MANAGER_N_SELECTIONS; i++) {
_g_object_list_unref (self->priv->files[i]);
+ g_hash_table_unref (self->priv->files_hash[i]);
g_free (self->priv->order[i]);
}
g_mutex_free (self->priv->mutex);
@@ -101,8 +100,9 @@ gth_selections_manager_init (GthSelectionsManager *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SELECTIONS_MANAGER, GthSelectionsManagerPrivate);
self->priv->mutex = g_mutex_new ();
- for (i = 0; i < N_SELECTIONS; i++) {
+ for (i = 0; i < GTH_SELECTIONS_MANAGER_N_SELECTIONS; i++) {
self->priv->files[i] = NULL;
+ self->priv->files_hash[i] = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
self->priv->order[i] = NULL;
self->priv->order_inverse[i] = FALSE;
}
@@ -280,7 +280,7 @@ _gth_selections_manager_for_each_selection (gpointer user_data)
ForEachChildData *data = user_data;
int i;
- for (i = 0; i < N_SELECTIONS; i++) {
+ for (i = 0; i < GTH_SELECTIONS_MANAGER_N_SELECTIONS; i++) {
char *uri;
GFile *file;
GFileInfo *info;
@@ -356,6 +356,7 @@ gth_selections_manager_add_files (GFile *folder,
GthSelectionsManager *self;
int n_selection;
GList *new_list;
+ GList *scan;
GList *link;
if (! g_file_has_uri_scheme (folder, "selection"))
@@ -369,6 +370,10 @@ gth_selections_manager_add_files (GFile *folder,
g_mutex_lock (self->priv->mutex);
new_list = _g_file_list_dup (file_list);
+
+ for (scan = new_list; scan; scan = scan->next)
+ g_hash_table_insert (self->priv->files_hash[n_selection - 1], scan->data, GINT_TO_POINTER (1));
+
link = g_list_nth (self->priv->files[n_selection - 1], destination_position);
if (link != NULL) {
GList *last_new;
@@ -386,6 +391,7 @@ gth_selections_manager_add_files (GFile *folder,
else
self->priv->files[n_selection - 1] = g_list_concat (self->priv->files[n_selection - 1], new_list);
+ gth_monitor_emblems_changed (gth_main_get_default_monitor (), file_list);
gth_monitor_folder_changed (gth_main_get_default_monitor (),
folder,
file_list,
@@ -415,8 +421,10 @@ gth_selections_manager_remove_files (GFile *folder,
g_mutex_lock (self->priv->mutex);
files_to_remove = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
- for (scan = file_list; scan; scan = scan->next)
+ for (scan = file_list; scan; scan = scan->next) {
g_hash_table_insert (files_to_remove, scan->data, GINT_TO_POINTER (1));
+ g_hash_table_remove (self->priv->files_hash[n_selection - 1], scan->data);
+ }
new_list = NULL;
for (scan = self->priv->files[n_selection - 1]; scan; scan = scan->next) {
@@ -438,6 +446,7 @@ gth_selections_manager_remove_files (GFile *folder,
folder,
file_list,
GTH_MONITOR_EVENT_REMOVED);
+ gth_monitor_emblems_changed (gth_main_get_default_monitor (), file_list);
g_mutex_unlock (self->priv->mutex);
}
@@ -506,6 +515,27 @@ gth_selections_manager_set_sort_type (GFile *folder,
}
+gboolean
+gth_selections_manager_file_exists (int n_selection,
+ GFile *file)
+{
+ GthSelectionsManager *self;
+ gboolean result;
+
+ if ((n_selection <= 0) || (n_selection > GTH_SELECTIONS_MANAGER_N_SELECTIONS))
+ return FALSE;
+
+ self = gth_selections_manager_get_default ();
+ g_mutex_lock (self->priv->mutex);
+
+ result = (g_hash_table_lookup (self->priv->files_hash[n_selection - 1], file) != NULL);
+
+ g_mutex_unlock (self->priv->mutex);
+
+ return result;
+}
+
+
int
_g_file_get_n_selection (GFile *file)
{
@@ -522,7 +552,7 @@ _g_file_get_n_selection (GFile *file)
g_free (uri);
- if (n > N_SELECTIONS)
+ if (n > GTH_SELECTIONS_MANAGER_N_SELECTIONS)
n = -1;
return n;
diff --git a/extensions/selections/gth-selections-manager.h b/extensions/selections/gth-selections-manager.h
index f6294a1..92058b0 100644
--- a/extensions/selections/gth-selections-manager.h
+++ b/extensions/selections/gth-selections-manager.h
@@ -28,6 +28,8 @@
G_BEGIN_DECLS
+#define GTH_SELECTIONS_MANAGER_N_SELECTIONS 3
+
#define GTH_TYPE_SELECTIONS_MANAGER (gth_selections_manager_get_type ())
#define GTH_SELECTIONS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTH_TYPE_SELECTIONS_MANAGER, GthSelectionsManager))
#define GTH_SELECTIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTH_TYPE_SELECTIONS_MANAGER, GthSelectionsManagerClass))
@@ -70,6 +72,8 @@ void gth_selections_manager_set_sort_type (GFile *folder,
gboolean sort_inverse);
void gth_selections_manager_update_file_info (GFile *file,
GFileInfo *info);
+gboolean gth_selections_manager_file_exists (int n_selection,
+ GFile *file);
/* utilities */
diff --git a/extensions/selections/main.c b/extensions/selections/main.c
index 2dcfaeb..abd97ad 100644
--- a/extensions/selections/main.c
+++ b/extensions/selections/main.c
@@ -25,12 +25,14 @@
#include <gthumb.h>
#include "callbacks.h"
#include "gth-file-source-selections.h"
+#include "gth-metadata-provider-selections.h"
G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
gth_main_register_file_source (GTH_TYPE_FILE_SOURCE_SELECTIONS);
+ gth_main_register_metadata_provider (GTH_TYPE_METADATA_PROVIDER_SELECTIONS);
gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (selections__gth_browser_construct_cb), NULL);
gth_hook_add_callback ("gth-browser-file-list-key-press", 10, G_CALLBACK (selections__gth_browser_file_list_key_press_cb), NULL);
gth_hook_add_callback ("gth-browser-load-location-after", 10, G_CALLBACK (selections__gth_browser_load_location_after_cb), NULL);
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 28fd1d8..b15babc 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -55,6 +55,7 @@ G_BEGIN_DECLS
#define GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE (DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type"))
#define GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE (DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type,standard::content-type"))
#define GIO_ATTRIBUTES ("standard::*,etag::*,id::*,access::*,mountable::*,time::*,unix::*,dos::*,owner::*,thumbnail::*,filesystem::*,gvfs::*,xattr::*,xattr-sys::*,selinux::*")
+#define GTH_FILE_ATTRIBUTE_EMBLEMS "gth::file::emblems"
#define GNOME_COPIED_FILES (gdk_atom_intern_static_string ("x-special/gnome-copied-files"))
#define IROUND(x) ((int)floor(((double)x) + 0.5))
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 0ed580b..1b0c81b 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -129,6 +129,7 @@ struct _GthBrowserPrivate {
gulong folder_changed_id;
gulong file_renamed_id;
gulong metadata_changed_id;
+ gulong emblems_changed_id;
gulong entry_points_changed_id;
gulong order_changed_id;
GthFileData *location;
@@ -1339,6 +1340,13 @@ _gth_browser_get_list_attributes (GthBrowser *browser,
g_free (thumbnail_caption);
}
+ /* other attributes */
+
+ g_string_append (attributes, ",");
+ g_string_append (attributes, GTH_FILE_ATTRIBUTE_EMBLEMS);
+
+ /* save in a variable to avoid recalculation */
+
browser->priv->list_attributes = g_string_free (attributes, FALSE);
return browser->priv->list_attributes;
@@ -2234,6 +2242,8 @@ _gth_browser_real_close (GthBrowser *browser)
g_signal_handler_disconnect (gth_main_get_default_monitor (),
browser->priv->metadata_changed_id);
g_signal_handler_disconnect (gth_main_get_default_monitor (),
+ browser->priv->emblems_changed_id);
+ g_signal_handler_disconnect (gth_main_get_default_monitor (),
browser->priv->entry_points_changed_id);
g_signal_handler_disconnect (gth_main_get_default_monitor (),
browser->priv->order_changed_id);
@@ -3301,6 +3311,64 @@ metadata_changed_cb (GthMonitor *monitor,
}
+typedef struct {
+ GthBrowser *browser;
+ GthFileSource *file_source;
+ GList *files;
+} EmblemsData;
+
+
+static void
+emblems_data_free (EmblemsData *data)
+{
+ _g_object_list_unref (data->files);
+ g_object_unref (data->file_source);
+ g_free (data);
+}
+
+
+static void
+emblems_attributes_ready_cb (GthFileSource *file_source,
+ GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ EmblemsData *data = user_data;
+
+ if (error == NULL) {
+ GthBrowser *browser = data->browser;
+
+ gth_file_list_update_emblems (GTH_FILE_LIST (browser->priv->file_list), files);
+ gth_file_list_update_emblems (GTH_FILE_LIST (browser->priv->thumbnail_list), files);
+ }
+
+ emblems_data_free (data);
+}
+
+
+static void
+emblems_changed_cb (GthMonitor *monitor,
+ GList *files, /* GFile list */
+ GthBrowser *browser)
+{
+ EmblemsData *data;
+
+ if (browser->priv->location_source == NULL)
+ return;
+
+ data = g_new0 (EmblemsData, 1);
+ data->browser = browser;
+ data->file_source = g_object_ref (browser->priv->location_source);
+ data->files = _g_object_list_ref (files);
+
+ gth_file_source_read_attributes (browser->priv->location_source,
+ files,
+ GTH_FILE_ATTRIBUTE_EMBLEMS,
+ emblems_attributes_ready_cb,
+ data);
+}
+
+
static void
entry_points_changed_cb (GthMonitor *monitor,
GthBrowser *browser)
@@ -4495,6 +4563,11 @@ gth_browser_init (GthBrowser *browser)
"metadata-changed",
G_CALLBACK (metadata_changed_cb),
browser);
+ browser->priv->emblems_changed_id =
+ g_signal_connect (gth_main_get_default_monitor (),
+ "emblems-changed",
+ G_CALLBACK (emblems_changed_cb),
+ browser);
browser->priv->entry_points_changed_id =
g_signal_connect (gth_main_get_default_monitor (),
"entry-points-changed",
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index e416a6c..2eec4ee 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -49,6 +49,7 @@ typedef enum {
GTH_FILE_LIST_OP_TYPE_CLEAR_FILES,
GTH_FILE_LIST_OP_TYPE_ADD_FILES,
GTH_FILE_LIST_OP_TYPE_UPDATE_FILES,
+ GTH_FILE_LIST_OP_TYPE_UPDATE_EMBLEMS,
GTH_FILE_LIST_OP_TYPE_DELETE_FILES,
GTH_FILE_LIST_OP_TYPE_SET_FILTER,
GTH_FILE_LIST_OP_TYPE_SET_SORT_FUNC,
@@ -181,6 +182,7 @@ gth_file_list_op_free (GthFileListOp *op)
break;
case GTH_FILE_LIST_OP_TYPE_ADD_FILES:
case GTH_FILE_LIST_OP_TYPE_UPDATE_FILES:
+ case GTH_FILE_LIST_OP_TYPE_UPDATE_EMBLEMS:
_g_object_list_unref (op->file_list);
break;
case GTH_FILE_LIST_OP_TYPE_DELETE_FILES:
@@ -1002,6 +1004,45 @@ gth_file_list_update_files (GthFileList *file_list,
static void
+gfl_update_emblems (GthFileList *file_list,
+ GList *files)
+{
+ GthFileStore *file_store;
+ GList *scan;
+
+ file_store = (GthFileStore*) gth_file_view_get_model (GTH_FILE_VIEW (file_list->priv->view));
+ for (scan = files; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+ ThumbData *thumb_data;
+ GtkTreeIter iter;
+
+ thumb_data = g_hash_table_lookup (file_list->priv->thumb_data, file_data->file);
+ if (thumb_data == NULL)
+ continue;
+
+ if (gth_file_store_find (file_store, file_data->file, &iter))
+ gth_file_store_queue_set (file_store,
+ &iter,
+ GTH_FILE_STORE_EMBLEMS_COLUMN, g_file_info_get_attribute_object (file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS),
+ -1);
+ }
+ gth_file_store_exec_set (file_store);
+}
+
+
+void
+gth_file_list_update_emblems (GthFileList *file_list,
+ GList *files /* GthFileData */)
+{
+ GthFileListOp *op;
+
+ op = gth_file_list_op_new (GTH_FILE_LIST_OP_TYPE_UPDATE_EMBLEMS);
+ op->file_list = _g_object_list_ref (files);
+ _gth_file_list_queue_op (file_list, op);
+}
+
+
+static void
gfl_rename_file (GthFileList *file_list,
GFile *file,
GthFileData *file_data)
@@ -1858,6 +1899,9 @@ _gth_file_list_exec_next_op (GthFileList *file_list)
case GTH_FILE_LIST_OP_TYPE_UPDATE_FILES:
gfl_update_files (file_list, op->file_list);
break;
+ case GTH_FILE_LIST_OP_TYPE_UPDATE_EMBLEMS:
+ gfl_update_emblems (file_list, op->file_list);
+ break;
case GTH_FILE_LIST_OP_TYPE_ENABLE_THUMBS:
gfl_enable_thumbs (file_list, op->ival);
exec_next_op = FALSE;
diff --git a/gthumb/gth-file-list.h b/gthumb/gth-file-list.h
index 3caea6b..a1e2254 100644
--- a/gthumb/gth-file-list.h
+++ b/gthumb/gth-file-list.h
@@ -84,6 +84,8 @@ void gth_file_list_delete_files (GthFileList *file_li
GList *list /* GFile */);
void gth_file_list_update_files (GthFileList *file_list,
GList *list /* GthFileData */);
+void gth_file_list_update_emblems (GthFileList *file_list,
+ GList *list /* GthFileData */);
void gth_file_list_rename_file (GthFileList *file_list,
GFile *file,
GthFileData *file_data);
diff --git a/gthumb/gth-file-store.c b/gthumb/gth-file-store.c
index 41216b5..5a23416 100644
--- a/gthumb/gth-file-store.c
+++ b/gthumb/gth-file-store.c
@@ -24,6 +24,7 @@
#include "glib-utils.h"
#include "gth-file-store.h"
#include "gth-marshal.h"
+#include "gth-string-list.h"
#undef DEBUG_FILE_STORE
@@ -264,6 +265,7 @@ gth_file_store_init (GthFileStore *file_store)
column_type[GTH_FILE_STORE_FILE_DATA_COLUMN] = GTH_TYPE_FILE_DATA;
column_type[GTH_FILE_STORE_THUMBNAIL_COLUMN] = GDK_TYPE_PIXBUF;
column_type[GTH_FILE_STORE_IS_ICON_COLUMN] = G_TYPE_BOOLEAN;
+ column_type[GTH_FILE_STORE_EMBLEMS_COLUMN] = GTH_TYPE_STRING_LIST;
}
}
@@ -375,6 +377,10 @@ gth_file_store_get_value (GtkTreeModel *tree_model,
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, row->is_icon);
break;
+ case GTH_FILE_STORE_EMBLEMS_COLUMN:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_object (value, g_file_info_get_attribute_object (row->file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS));
+ break;
}
}
@@ -1397,8 +1403,9 @@ gth_file_store_queue_set_valist (GthFileStore *file_store,
column = va_arg (var_args, int);
while (column != -1) {
- GthFileData *file_data;
- GdkPixbuf *thumbnail;
+ GthFileData *file_data;
+ GdkPixbuf *thumbnail;
+ GthStringList *string_list;
switch (column) {
case GTH_FILE_STORE_FILE_DATA_COLUMN:
@@ -1418,6 +1425,11 @@ gth_file_store_queue_set_valist (GthFileStore *file_store,
row->is_icon = va_arg (var_args, gboolean);
row->changed = TRUE;
break;
+ case GTH_FILE_STORE_EMBLEMS_COLUMN:
+ string_list = va_arg (var_args, GthStringList *);
+ g_file_info_set_attribute_object (row->file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS, G_OBJECT (string_list));
+ row->changed = TRUE;
+ break;
default:
g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
break;
diff --git a/gthumb/gth-file-store.h b/gthumb/gth-file-store.h
index 6dd3fbf..b4db381 100644
--- a/gthumb/gth-file-store.h
+++ b/gthumb/gth-file-store.h
@@ -43,6 +43,7 @@ enum {
GTH_FILE_STORE_FILE_DATA_COLUMN,
GTH_FILE_STORE_THUMBNAIL_COLUMN,
GTH_FILE_STORE_IS_ICON_COLUMN,
+ GTH_FILE_STORE_EMBLEMS_COLUMN,
GTH_FILE_STORE_N_COLUMNS
};
diff --git a/gthumb/gth-grid-view.c b/gthumb/gth-grid-view.c
index 2b733c6..374fb0a 100644
--- a/gthumb/gth-grid-view.c
+++ b/gthumb/gth-grid-view.c
@@ -33,6 +33,7 @@
#include "gth-file-selection.h"
#include "gth-file-store.h"
#include "gth-file-view.h"
+#include "gth-icon-cache.h"
#include "gth-grid-view.h"
#include "gth-marshal.h"
#include "gth-enum-types.h"
@@ -205,6 +206,8 @@ struct _GthGridViewPrivate {
char *caption_attributes;
char **caption_attributes_v;
PangoLayout *caption_layout;
+
+ GthIconCache *icon_cache;
};
@@ -1030,6 +1033,9 @@ gth_grid_view_unrealize (GtkWidget *widget)
g_object_unref (self->priv->caption_layout);
self->priv->caption_layout = NULL;
+ gth_icon_cache_free (self->priv->icon_cache);
+ self->priv->icon_cache = NULL;
+
GTK_WIDGET_CLASS (gth_grid_view_parent_class)->unrealize (widget);
}
@@ -1483,6 +1489,51 @@ _gth_grid_view_item_draw_caption (GthGridViewItem *item,
}
+#define EMBLEM_SIZE 16
+
+
+static void
+_gth_grid_view_item_draw_emblems (GthGridViewItem *item,
+ cairo_t *cr,
+ GtkWidget *widget,
+ GtkStateFlags item_state,
+ GthGridView *grid_view)
+{
+ GthStringList *emblems;
+ GList *scan;
+ int emblem_offset;
+
+ cairo_save (cr);
+
+ emblem_offset = 0;
+ emblems = (GthStringList *) g_file_info_get_attribute_object (item->file_data->info, GTH_FILE_ATTRIBUTE_EMBLEMS);
+ for (scan = gth_string_list_get_list (emblems); scan; scan = scan->next) {
+ char *emblem = scan->data;
+ GIcon *icon;
+ GdkPixbuf *pixbuf;
+
+ if (grid_view->priv->icon_cache == NULL)
+ grid_view->priv->icon_cache = gth_icon_cache_new (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (grid_view))), EMBLEM_SIZE);
+
+ icon = g_themed_icon_new (emblem);
+ pixbuf = gth_icon_cache_get_pixbuf (grid_view->priv->icon_cache, icon);
+ if (pixbuf != NULL) {
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, item->thumbnail_area.x + emblem_offset + 1, item->thumbnail_area.y + 1);
+ cairo_rectangle (cr, item->thumbnail_area.x + emblem_offset + 1, item->thumbnail_area.y + 1, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
+ cairo_fill (cr);
+
+ g_object_unref (pixbuf);
+
+ emblem_offset += EMBLEM_SIZE + (EMBLEM_SIZE / 2);
+ }
+
+ g_object_unref (icon);
+ }
+
+ cairo_restore (cr);
+}
+
+
static void
_gth_grid_view_draw_item (GthGridView *self,
GthGridViewItem *item,
@@ -1518,6 +1569,7 @@ _gth_grid_view_draw_item (GthGridView *self,
_gth_grid_view_item_draw_thumbnail (item, cr, GTK_WIDGET (self), item_state, self);
_gth_grid_view_item_draw_caption (item, cr, GTK_WIDGET (self), item_state, self->priv->caption_layout, self);
+ _gth_grid_view_item_draw_emblems (item, cr, GTK_WIDGET (self), item_state, self);
}
@@ -3786,6 +3838,7 @@ gth_grid_view_init (GthGridView *self)
self->priv->caption_attributes = NULL;
self->priv->caption_attributes_v = NULL;
self->priv->caption_layout = NULL;
+ self->priv->icon_cache = NULL;
_gth_grid_view_set_hadjustment (self, gtk_adjustment_new (0.0, 1.0, 0.0, 0.1, 1.0, 1.0));
_gth_grid_view_set_vadjustment (self, gtk_adjustment_new (0.0, 1.0, 0.0, 0.1, 1.0, 1.0));
diff --git a/gthumb/gth-main-default-metadata.c b/gthumb/gth-main-default-metadata.c
index 02ec2a0..ba8d52a 100644
--- a/gthumb/gth-main-default-metadata.c
+++ b/gthumb/gth-main-default-metadata.c
@@ -53,6 +53,7 @@ GthMetadataInfo file_metadata_info[] = {
{ "general::tags", N_("Tags"), "general", 18, NULL, GTH_METADATA_ALLOW_EVERYWHERE },
{ "general::rating", N_("Rating"), "general", 19, NULL, GTH_METADATA_ALLOW_EVERYWHERE },
+ { "gth::file::emblems", "", "", 0, NULL, GTH_METADATA_ALLOW_NOWHERE },
{ "image::width", "", "", 0, NULL, GTH_METADATA_ALLOW_NOWHERE },
{ "image::height", "", "", 0, NULL, GTH_METADATA_ALLOW_NOWHERE },
{ "frame::width", "", "", 0, NULL, GTH_METADATA_ALLOW_NOWHERE },
diff --git a/gthumb/gth-monitor.c b/gthumb/gth-monitor.c
index cf9fd7e..6475003 100644
--- a/gthumb/gth-monitor.c
+++ b/gthumb/gth-monitor.c
@@ -38,6 +38,7 @@ enum {
FOLDER_CONTENT_CHANGED,
FILE_RENAMED,
METADATA_CHANGED,
+ EMBLEMS_CHANGED,
ENTRY_POINTS_CHANGED,
ORDER_CHANGED,
LAST_SIGNAL
@@ -156,6 +157,16 @@ gth_monitor_class_init (GthMonitorClass *class)
G_TYPE_NONE,
1,
G_TYPE_OBJECT);
+ monitor_signals[EMBLEMS_CHANGED] =
+ g_signal_new ("emblems-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthMonitorClass, emblems_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT_LIST);
monitor_signals[ENTRY_POINTS_CHANGED] =
g_signal_new ("entry-points-changed",
G_TYPE_FROM_CLASS (class),
@@ -340,6 +351,36 @@ gth_monitor_metadata_changed (GthMonitor *self,
void
+gth_monitor_emblems_changed (GthMonitor *self,
+ GList *list /* GFile list */)
+{
+ GList *changed_list = NULL;
+ GList *scan;
+
+ /* ignore paused files */
+ for (scan = list; scan; scan = scan->next) {
+ GFile *file = scan->data;
+
+ if (g_hash_table_lookup (self->priv->paused_files, file) != NULL)
+ continue;
+
+ changed_list = g_list_prepend (changed_list, g_object_ref (file));
+ }
+ changed_list = g_list_reverse (changed_list);
+
+ if (changed_list == NULL)
+ return;
+
+ g_signal_emit (G_OBJECT (self),
+ monitor_signals[EMBLEMS_CHANGED],
+ 0,
+ changed_list);
+
+ _g_object_list_unref (changed_list);
+}
+
+
+void
gth_monitor_entry_points_changed (GthMonitor *self)
{
g_return_if_fail (GTH_IS_MONITOR (self));
diff --git a/gthumb/gth-monitor.h b/gthumb/gth-monitor.h
index 42eb49e..c75acfa 100644
--- a/gthumb/gth-monitor.h
+++ b/gthumb/gth-monitor.h
@@ -65,7 +65,7 @@ struct _GthMonitorClass
void (*tags_changed) (GthMonitor *monitor);
void (*folder_changed) (GthMonitor *monitor,
GFile *parent,
- GList *list,
+ GList *list /* GFile list */,
int position,
GthMonitorEvent event);
void (*file_renamed) (GthMonitor *monitor,
@@ -73,6 +73,8 @@ struct _GthMonitorClass
GFile *new_file);
void (*metadata_changed) (GthMonitor *monitor,
GthFileData *file_data);
+ void (*emblems_changed) (GthMonitor *monitor,
+ GList *list /* GFile list */);
void (*entry_points_changed) (GthMonitor *monitor);
void (*order_changed) (GthMonitor *monitor,
GFile *file,
@@ -102,6 +104,8 @@ void gth_monitor_file_renamed (GthMonitor *monitor,
GFile *new_file);
void gth_monitor_metadata_changed (GthMonitor *monitor,
GthFileData *file_data);
+void gth_monitor_emblems_changed (GthMonitor *monitor,
+ GList *list /* GFile list */);
void gth_monitor_entry_points_changed (GthMonitor *monitor);
void gth_monitor_order_changed (GthMonitor *monitor,
GFile *file,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]