[gthumb] added ability to organize files by tag
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] added ability to organize files by tag
- Date: Thu, 12 Aug 2010 20:01:35 +0000 (UTC)
commit c3c44b091cc117558a688be0d598c9247f682dfc
Author: Paolo Bacchilega <paobac src gnome org>
Date: Wed Aug 11 19:40:25 2010 +0200
added ability to organize files by tag
the organize command can organize files by tag, creating a catalog for each tag.
extensions/catalogs/data/ui/organize-files.ui | 52 +++--
extensions/catalogs/dlg-organize-files.c | 13 +
extensions/catalogs/gth-catalog.c | 38 ++--
extensions/catalogs/gth-catalog.h | 7 +-
extensions/catalogs/gth-organize-task.c | 319 +++++++++++++++++++------
extensions/catalogs/gth-organize-task.h | 4 +-
extensions/importer/gth-import-task.c | 5 +-
gthumb/gth-info-bar.c | 7 +
gthumb/gth-info-bar.h | 1 +
gthumb/gth-test-category.c | 12 +
gthumb/gth-test-category.h | 4 +
gthumb/gth-test-simple.c | 112 +++++-----
gthumb/gth-test-simple.h | 10 +-
gthumb/gth-time-selector.c | 7 +-
gthumb/gth-time.c | 13 +-
gthumb/gth-time.h | 2 +-
16 files changed, 422 insertions(+), 184 deletions(-)
---
diff --git a/extensions/catalogs/data/ui/organize-files.ui b/extensions/catalogs/data/ui/organize-files.ui
index f038fc8..d9caf6f 100644
--- a/extensions/catalogs/data/ui/organize-files.ui
+++ b/extensions/catalogs/data/ui/organize-files.ui
@@ -1,32 +1,42 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="organize_files_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Organize Files</property>
+ <property name="resizable">False</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
+ <property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">5</property>
+ <property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="spacing">12</property>
<child>
- <object class="GtkImage" id="icon_image">
+ <object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
- <property name="yalign">0</property>
- <property name="stock">gtk-dialog-info</property>
- <property name="pixel_size">24</property>
- <property name="icon-size">6</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">12</property>
+ <child>
+ <object class="GtkImage" id="icon_image">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="pixel_size">48</property>
+ <property name="icon_name">file-catalog</property>
+ <property name="icon-size">6</property>
+ </object>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -36,22 +46,20 @@
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
+ <property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
+ <property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkAlignment" id="alignment2">
+ <object class="GtkAlignment" id="info_alignment">
<property name="visible">True</property>
- <property name="bottom_padding">6</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">12</property>
<child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Files will be organized in catalogs. No file will be moved on disk.</property>
- <property name="wrap">True</property>
- </object>
+ <placeholder/>
</child>
</object>
<packing>
@@ -156,7 +164,7 @@
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
- <property name="invisible_char">â??</property>
+ <property name="invisible_char">●</property>
<property name="text" translatable="yes">Singles</property>
</object>
<packing>
@@ -270,14 +278,24 @@
<data>
<row>
<col id="0">0</col>
- <col id="1" translatable="yes">date photo was taken</col>
+ <col id="1" translatable="yes">Date photo was taken</col>
<col id="2">camera-photo</col>
</row>
<row>
<col id="0">1</col>
- <col id="1" translatable="yes">file modified date</col>
+ <col id="1" translatable="yes">File modified date</col>
<col id="2">appointment-soon</col>
</row>
+ <row>
+ <col id="0">2</col>
+ <col id="1" translatable="yes">Tag</col>
+ <col id="2" translatable="yes">tag</col>
+ </row>
+ <row>
+ <col id="0">3</col>
+ <col id="1" translatable="yes">Tag (embedded)</col>
+ <col id="2" translatable="yes">tag</col>
+ </row>
</data>
</object>
</interface>
diff --git a/extensions/catalogs/dlg-organize-files.c b/extensions/catalogs/dlg-organize-files.c
index 173ffa6..6518e82 100644
--- a/extensions/catalogs/dlg-organize-files.c
+++ b/extensions/catalogs/dlg-organize-files.c
@@ -101,6 +101,8 @@ dlg_organize_files (GthBrowser *browser,
GFile *folder)
{
DialogData *data;
+ GtkWidget *info_bar;
+ GtkWidget *info_label;
g_return_if_fail (folder != NULL);
@@ -110,6 +112,17 @@ dlg_organize_files (GthBrowser *browser,
data->builder = _gtk_builder_new_from_file ("organize-files.ui", "catalogs");
data->dialog = GET_WIDGET ("organize_files_dialog");
+ info_bar = gth_info_bar_new (NULL, NULL, NULL);
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_INFO);
+ info_label = gth_info_bar_get_primary_label (GTH_INFO_BAR (info_bar));
+ gtk_label_set_ellipsize (GTK_LABEL (info_label), PANGO_ELLIPSIZE_NONE);
+ gtk_label_set_line_wrap (GTK_LABEL (info_label), TRUE);
+ gtk_label_set_single_line_mode (GTK_LABEL (info_label), FALSE);
+ gtk_label_set_text (GTK_LABEL (info_label), _("Files will be organized in catalogs. No file will be moved on disk."));
+ gtk_widget_show (info_label);
+ gtk_widget_show (info_bar);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("info_alignment")), info_bar);
+
/* Set the signals handlers. */
g_signal_connect (G_OBJECT (data->dialog),
diff --git a/extensions/catalogs/gth-catalog.c b/extensions/catalogs/gth-catalog.c
index 86fa0ce..4b2712c 100644
--- a/extensions/catalogs/gth-catalog.c
+++ b/extensions/catalogs/gth-catalog.c
@@ -376,20 +376,6 @@ gth_catalog_get_order (GthCatalog *catalog,
void
-gth_catalog_set_for_date (GthCatalog *catalog,
- GthDateTime *date_time)
-{
- GFile *catalog_file;
-
- gth_catalog_set_date (catalog, date_time);
- catalog_file = gth_catalog_get_file_for_date (date_time);
- gth_catalog_set_file (catalog, catalog_file);
-
- g_object_unref (catalog_file);
-}
-
-
-void
gth_catalog_load_from_data (GthCatalog *catalog,
const void *buffer,
gsize count,
@@ -1129,22 +1115,20 @@ gth_catalog_load_from_file_async (GFile *file,
GFile *
-gth_catalog_get_file_for_date (GthDateTime *date_time)
+gth_catalog_get_file_for_date (GthDateTime *date_time,
+ const char *extension)
{
char *year;
char *uri;
- GFile *base;
char *display_name;
GFile *catalog_file;
year = gth_datetime_strftime (date_time, "%Y");
uri = g_strconcat ("catalog:///", year, "/", NULL);
- base = g_file_new_for_uri (uri);
display_name = gth_datetime_strftime (date_time, "%Y-%m-%d");
- catalog_file = _g_file_new_for_display_name (uri, display_name, ".catalog");
+ catalog_file = _g_file_new_for_display_name (uri, display_name, extension);
g_free (display_name);
- g_object_unref (base);
g_free (uri);
g_free (year);
@@ -1152,6 +1136,22 @@ gth_catalog_get_file_for_date (GthDateTime *date_time)
}
+GFile *
+gth_catalog_get_file_for_tag (const char *tag,
+ const char *extension)
+{
+ char *uri;
+ GFile *catalog_file;
+
+ uri = g_strconcat ("catalog:///", _("Tags"), "/", NULL);
+ catalog_file = _g_file_new_for_display_name (uri, tag, extension);
+
+ g_free (uri);
+
+ return catalog_file;
+}
+
+
GthCatalog *
gth_catalog_load_from_file (GFile *file)
{
diff --git a/extensions/catalogs/gth-catalog.h b/extensions/catalogs/gth-catalog.h
index ec51bc1..5e0c266 100644
--- a/extensions/catalogs/gth-catalog.h
+++ b/extensions/catalogs/gth-catalog.h
@@ -88,8 +88,6 @@ void gth_catalog_set_order (GthCatalog *catalog,
gboolean inverse);
const char * gth_catalog_get_order (GthCatalog *catalog,
gboolean *inverse);
-void gth_catalog_set_for_date (GthCatalog *catalog,
- GthDateTime *date_time);
void gth_catalog_load_from_data (GthCatalog *catalog,
const void *buffer,
gsize count,
@@ -129,7 +127,10 @@ void gth_catalog_load_from_file_async (GFile *file,
GCancellable *cancellable,
ReadyCallback ready_func,
gpointer user_data);
-GFile * gth_catalog_get_file_for_date (GthDateTime *date_time);
+GFile * gth_catalog_get_file_for_date (GthDateTime *date_time,
+ const char *extension);
+GFile * gth_catalog_get_file_for_tag (const char *tag,
+ const char *extension);
GthCatalog * gth_catalog_load_from_file (GFile *file);
void gth_catalog_save (GthCatalog *catalog);
diff --git a/extensions/catalogs/gth-organize-task.c b/extensions/catalogs/gth-organize-task.c
index 4db06d1..53e6f2a 100644
--- a/extensions/catalogs/gth-organize-task.c
+++ b/extensions/catalogs/gth-organize-task.c
@@ -24,6 +24,7 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gthumb.h>
+#include <extensions/search/gth-search.h>
#include "gth-catalog.h"
#include "gth-organize-task.h"
@@ -56,6 +57,7 @@ struct _GthOrganizeTaskPrivate
GtkWidget *file_list;
int n_catalogs;
int n_files;
+ GthTest *filter;
};
@@ -75,6 +77,7 @@ gth_organize_task_finalize (GObject *object)
g_object_unref (self->priv->builder);
g_hash_table_destroy (self->priv->catalogs);
g_object_unref (self->priv->icon_pixbuf);
+ g_object_unref (self->priv->filter);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -132,8 +135,8 @@ save_catalogs (GthOrganizeTask *self)
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->results_liststore), &iter));
}
- g_hash_table_foreach (self->priv->catalogs, save_catalog, NULL);
+ g_hash_table_foreach (self->priv->catalogs, save_catalog, NULL);
gth_task_completed (GTH_TASK (self), NULL);
}
@@ -209,6 +212,193 @@ done_func (GError *error,
}
+static GthCatalog *
+add_catalog_for_date (GthOrganizeTask *self,
+ const char *catalog_key,
+ GTimeVal *timeval)
+{
+ GthCatalog *catalog;
+ GthDateTime *date_time;
+ GFile *catalog_file;
+ char *catalog_name;
+ GtkTreeIter iter;
+
+ catalog = g_hash_table_lookup (self->priv->catalogs, catalog_key);
+ if (catalog != NULL)
+ return catalog;
+
+ date_time = gth_datetime_new ();
+ gth_datetime_from_timeval (date_time, timeval);
+
+ catalog_file = NULL;
+
+ if (gth_main_extension_is_active ("search")) {
+ catalog_file = gth_catalog_get_file_for_date (date_time, ".search");
+ catalog = gth_catalog_load_from_file (catalog_file);
+ }
+
+ if (catalog == NULL) {
+ _g_object_unref (catalog_file);
+ catalog_file = gth_catalog_get_file_for_date (date_time, ".catalog");
+ catalog = gth_catalog_load_from_file (catalog_file);
+ }
+
+ if (catalog == NULL) {
+ if (gth_main_extension_is_active ("search")) {
+ GthTest *date_test;
+ GthTest *test_chain;
+
+ _g_object_unref (catalog_file);
+ catalog_file = gth_catalog_get_file_for_date (date_time, ".search");
+
+ catalog = (GthCatalog *) gth_search_new ();
+ gth_search_set_folder (GTH_SEARCH (catalog), self->priv->folder);
+ gth_search_set_recursive (GTH_SEARCH (catalog), self->priv->recursive);
+
+ date_test = gth_main_get_registered_object (GTH_TYPE_TEST, (self->priv->group_policy == GTH_GROUP_POLICY_MODIFIED_DATE) ? "file::mtime" : "Embedded::Photo::DateTimeOriginal");
+ gth_test_simple_set_data_as_date (GTH_TEST_SIMPLE (date_test), date_time->date);
+ g_object_set (GTH_TEST_SIMPLE (date_test), "op", GTH_TEST_OP_EQUAL, "negative", FALSE, NULL);
+ test_chain = gth_test_chain_new (GTH_MATCH_TYPE_ALL, date_test, NULL);
+ gth_search_set_test (GTH_SEARCH (catalog), GTH_TEST_CHAIN (test_chain));
+
+ g_object_unref (test_chain);
+ g_object_unref (date_test);
+ }
+ else
+ catalog = gth_catalog_new ();
+ }
+
+ gth_catalog_set_date (catalog, date_time);
+ gth_catalog_set_file (catalog, catalog_file);
+
+ g_hash_table_insert (self->priv->catalogs, g_strdup (catalog_key), catalog);
+ self->priv->n_catalogs++;
+
+ catalog_name = gth_datetime_strftime (date_time, "%x");
+
+ gtk_list_store_append (self->priv->results_liststore, &iter);
+ gtk_list_store_set (self->priv->results_liststore, &iter,
+ KEY_COLUMN, catalog_key,
+ NAME_COLUMN, catalog_name,
+ CARDINALITY_COLUMN, 0,
+ CREATE_CATALOG_COLUMN, TRUE,
+ ICON_COLUMN, self->priv->icon_pixbuf,
+ -1);
+
+ g_free (catalog_name);
+ g_object_unref (catalog_file);
+ gth_datetime_free (date_time);
+
+ return catalog;
+}
+
+
+static GthCatalog *
+add_catalog_for_tag (GthOrganizeTask *self,
+ const char *catalog_key,
+ const char *tag)
+{
+ GthCatalog *catalog;
+ GFile *catalog_file;
+ GtkTreeIter iter;
+
+ catalog = g_hash_table_lookup (self->priv->catalogs, catalog_key);
+ if (catalog != NULL)
+ return catalog;
+
+ catalog_file = NULL;
+
+ if (gth_main_extension_is_active ("search")) {
+ catalog_file = gth_catalog_get_file_for_tag (tag, ".search");
+ catalog = gth_catalog_load_from_file (catalog_file);
+ }
+
+ if (catalog == NULL) {
+ _g_object_unref (catalog_file);
+ catalog_file = gth_catalog_get_file_for_tag (tag, ".catalog");
+ catalog = gth_catalog_load_from_file (catalog_file);
+ }
+
+ if (catalog == NULL) {
+ if (gth_main_extension_is_active ("search")) {
+ GthTest *tag_test;
+ GthTest *test_chain;
+
+ _g_object_unref (catalog_file);
+ catalog_file = gth_catalog_get_file_for_tag (tag, ".search");
+
+ catalog = (GthCatalog *) gth_search_new ();
+ gth_search_set_folder (GTH_SEARCH (catalog), self->priv->folder);
+ gth_search_set_recursive (GTH_SEARCH (catalog), self->priv->recursive);
+
+ tag_test = gth_main_get_registered_object (GTH_TYPE_TEST, (self->priv->group_policy == GTH_GROUP_POLICY_TAG) ? "comment::category" : "general::tags");
+ gth_test_category_set (GTH_TEST_CATEGORY (tag_test), GTH_TEST_OP_EQUAL, FALSE, tag);
+ test_chain = gth_test_chain_new (GTH_MATCH_TYPE_ALL, tag_test, NULL);
+ gth_search_set_test (GTH_SEARCH (catalog), GTH_TEST_CHAIN (test_chain));
+
+ g_object_unref (test_chain);
+ g_object_unref (tag_test);
+ }
+ else
+ catalog = gth_catalog_new ();
+ }
+ gth_catalog_set_file (catalog, catalog_file);
+
+ g_hash_table_insert (self->priv->catalogs, g_strdup (catalog_key), catalog);
+ self->priv->n_catalogs++;
+
+ gtk_list_store_append (self->priv->results_liststore, &iter);
+ gtk_list_store_set (self->priv->results_liststore, &iter,
+ KEY_COLUMN, catalog_key,
+ NAME_COLUMN, tag,
+ CARDINALITY_COLUMN, 0,
+ CREATE_CATALOG_COLUMN, TRUE,
+ ICON_COLUMN, self->priv->icon_pixbuf,
+ -1);
+
+ g_object_unref (catalog_file);
+
+ return catalog;
+}
+
+
+static void
+add_file_to_catalog (GthOrganizeTask *self,
+ GthCatalog *catalog,
+ const char *catalog_key,
+ GthFileData *file_data)
+{
+ GtkTreeIter iter;
+ int n = 0;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->results_liststore), &iter)) {
+ do {
+ char *k;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (self->priv->results_liststore),
+ &iter,
+ KEY_COLUMN, &k,
+ CARDINALITY_COLUMN, &n,
+ -1);
+ if (g_strcmp0 (k, catalog_key) == 0) {
+ gtk_list_store_set (self->priv->results_liststore, &iter,
+ CARDINALITY_COLUMN, n + 1,
+ -1);
+ self->priv->n_files++;
+
+ g_free (k);
+ break;
+ }
+
+ g_free (k);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->results_liststore), &iter));
+ }
+
+ gth_catalog_insert_file (catalog, file_data->file, -1);
+}
+
+
static void
for_each_file_func (GFile *file,
GFileInfo *info,
@@ -216,103 +406,67 @@ for_each_file_func (GFile *file,
{
GthOrganizeTask *self = user_data;
GthFileData *file_data;
- char *key;
+ char *catalog_key;
+ GObject *metadata;
+ GthStringList *categories;
GTimeVal timeval;
GthCatalog *catalog;
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
return;
- key = NULL;
file_data = gth_file_data_new (file, info);
+
+ if (! gth_test_match (self->priv->filter, file_data)) {
+ g_object_unref (file_data);
+ return;
+ }
+
+ catalog_key = NULL;
+
switch (self->priv->group_policy) {
case GTH_GROUP_POLICY_DIGITALIZED_DATE:
- {
- GObject *metadata;
-
- metadata = g_file_info_get_attribute_object (info, "Embedded::Photo::DateTimeOriginal");
- if (metadata != NULL) {
- if (_g_time_val_from_exif_date (gth_metadata_get_raw (GTH_METADATA (metadata)), &timeval))
- key = _g_time_val_strftime (&timeval, KEY_FORMAT);
+ metadata = g_file_info_get_attribute_object (info, "Embedded::Photo::DateTimeOriginal");
+ if (metadata != NULL) {
+ if (_g_time_val_from_exif_date (gth_metadata_get_raw (GTH_METADATA (metadata)), &timeval)) {
+ catalog_key = _g_time_val_strftime (&timeval, KEY_FORMAT);
+ catalog = add_catalog_for_date (self, catalog_key, &timeval);
+ add_file_to_catalog (self, catalog, catalog_key, file_data);
}
}
break;
+
case GTH_GROUP_POLICY_MODIFIED_DATE:
timeval = *gth_file_data_get_modification_time (file_data);
- key = _g_time_val_strftime (&timeval, KEY_FORMAT);
+ catalog_key = _g_time_val_strftime (&timeval, KEY_FORMAT);
+ catalog = add_catalog_for_date (self, catalog_key, &timeval);
+ add_file_to_catalog (self, catalog, catalog_key, file_data);
break;
- }
- if (key == NULL)
- return;
-
- catalog = g_hash_table_lookup (self->priv->catalogs, key);
- if (catalog == NULL) {
- GthDateTime *date_time;
- GFile *catalog_file;
- char *name;
- GtkTreeIter iter;
-
- date_time = gth_datetime_new ();
- gth_datetime_from_timeval (date_time, &timeval);
-
- catalog_file = gth_catalog_get_file_for_date (date_time);
- catalog = gth_catalog_load_from_file (catalog_file);
- if (catalog == NULL)
- catalog = gth_catalog_new ();
- gth_catalog_set_for_date (catalog, date_time);
-
- g_hash_table_insert (self->priv->catalogs, g_strdup (key), catalog);
-
- name = gth_datetime_strftime (date_time, "%x");
- gtk_list_store_append (self->priv->results_liststore, &iter);
- gtk_list_store_set (self->priv->results_liststore, &iter,
- KEY_COLUMN, key,
- NAME_COLUMN, name,
- CARDINALITY_COLUMN, 0,
- CREATE_CATALOG_COLUMN, TRUE,
- ICON_COLUMN, self->priv->icon_pixbuf,
- -1);
- self->priv->n_catalogs++;
-
- g_free (name);
- g_object_unref (catalog_file);
- gth_datetime_free (date_time);
- }
-
- if (catalog != NULL) {
- GtkTreeIter iter;
- int n = 0;
-
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->results_liststore), &iter)) {
- do {
- char *k;
-
- gtk_tree_model_get (GTK_TREE_MODEL (self->priv->results_liststore),
- &iter,
- KEY_COLUMN, &k,
- CARDINALITY_COLUMN, &n,
- -1);
- if (g_strcmp0 (k, key) == 0) {
- gtk_list_store_set (self->priv->results_liststore, &iter,
- CARDINALITY_COLUMN, n + 1,
- -1);
- self->priv->n_files++;
-
- g_free (k);
- break;
- }
-
- g_free (k);
+ case GTH_GROUP_POLICY_TAG:
+ case GTH_GROUP_POLICY_TAG_EMBEDDED:
+ if (self->priv->group_policy == GTH_GROUP_POLICY_TAG)
+ categories = (GthStringList *) g_file_info_get_attribute_object (file_data->info, "comment::categories");
+ else
+ categories = (GthStringList *) g_file_info_get_attribute_object (file_data->info, "general::tags");
+ if (categories != NULL) {
+ GList *list;
+ GList *scan;
+
+ list = gth_string_list_get_list (categories);
+ for (scan = list; scan; scan = scan->next) {
+ char *tag = (char *) scan->data;
+
+ catalog_key = g_strdup (tag);
+ catalog = add_catalog_for_tag (self, catalog_key, tag);
+ add_file_to_catalog (self, catalog, catalog_key, file_data);
}
- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->results_liststore), &iter));
}
-
- gth_catalog_insert_file (catalog, file_data->file, -1);
+ break;
}
+ g_free (catalog_key);
g_object_unref (file_data);
- g_free (key);
}
@@ -349,15 +503,22 @@ gth_organize_task_exec (GthTask *base)
self->priv->n_catalogs = 0;
self->priv->n_files = 0;
gtk_list_store_clear (self->priv->results_liststore);
+
switch (self->priv->group_policy) {
case GTH_GROUP_POLICY_DIGITALIZED_DATE:
attributes = "standard::name,standard::type,time::modified,time::modified-usec,Embedded::Photo::DateTimeOriginal";
break;
case GTH_GROUP_POLICY_MODIFIED_DATE:
- default:
attributes = "standard::name,standard::type,time::modified,time::modified-usec";
break;
+ case GTH_GROUP_POLICY_TAG:
+ attributes = "standard::name,standard::type,time::modified,time::modified-usec,comment::categories";
+ break;
+ case GTH_GROUP_POLICY_TAG_EMBEDDED:
+ attributes = "standard::name,standard::type,time::modified,time::modified-usec,general::tags";
+ break;
}
+
g_directory_foreach_child (self->priv->folder,
self->priv->recursive,
TRUE,
@@ -382,7 +543,6 @@ gth_organize_task_exec (GthTask *base)
static void
gth_organize_task_cancelled (GthTask *base)
{
- /* FIXME */
}
@@ -584,6 +744,7 @@ gth_organize_task_init (GthOrganizeTask *self)
self->priv->builder = _gtk_builder_new_from_file ("organize-files-task.ui", "catalogs");
self->priv->results_liststore = (GtkListStore *) gtk_builder_get_object (self->priv->builder, "results_liststore");
self->priv->catalogs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ self->priv->filter = gth_main_get_general_filter ();
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->priv->results_liststore), KEY_COLUMN, GTK_SORT_ASCENDING);
g_object_set (GET_WIDGET ("catalog_name_cellrenderertext"), "editable", TRUE, NULL);
diff --git a/extensions/catalogs/gth-organize-task.h b/extensions/catalogs/gth-organize-task.h
index 6b88f7e..48271f2 100644
--- a/extensions/catalogs/gth-organize-task.h
+++ b/extensions/catalogs/gth-organize-task.h
@@ -28,7 +28,9 @@
typedef enum {
GTH_GROUP_POLICY_DIGITALIZED_DATE,
- GTH_GROUP_POLICY_MODIFIED_DATE
+ GTH_GROUP_POLICY_MODIFIED_DATE,
+ GTH_GROUP_POLICY_TAG,
+ GTH_GROUP_POLICY_TAG_EMBEDDED
} GthGroupPolicy;
#define GTH_TYPE_ORGANIZE_TASK (gth_organize_task_get_type ())
diff --git a/extensions/importer/gth-import-task.c b/extensions/importer/gth-import-task.c
index 944a0e4..eca93fd 100644
--- a/extensions/importer/gth-import-task.c
+++ b/extensions/importer/gth-import-task.c
@@ -158,11 +158,12 @@ catalog_imported_file (GthImportTask *self)
date_time = gth_datetime_new ();
gth_datetime_from_timeval (date_time, &timeval);
- catalog_file = gth_catalog_get_file_for_date (date_time);
+ catalog_file = gth_catalog_get_file_for_date (date_time, ".catalog");
catalog = gth_catalog_load_from_file (catalog_file);
if (catalog == NULL)
catalog = gth_catalog_new ();
- gth_catalog_set_for_date (catalog, date_time);
+ gth_catalog_set_date (catalog, date_time);
+ gth_catalog_set_file (catalog, catalog_file);
g_hash_table_insert (self->priv->catalogs, g_strdup (key), catalog);
diff --git a/gthumb/gth-info-bar.c b/gthumb/gth-info-bar.c
index f67d0ae..a11e5f0 100644
--- a/gthumb/gth-info-bar.c
+++ b/gthumb/gth-info-bar.c
@@ -151,6 +151,13 @@ gth_info_bar_new (const char *icon_stock_id,
}
+GtkWidget *
+gth_info_bar_get_primary_label (GthInfoBar *dialog)
+{
+ return dialog->priv->primary_text_label;
+}
+
+
void
gth_info_bar_set_icon (GthInfoBar *self,
const char *icon_stock_id)
diff --git a/gthumb/gth-info-bar.h b/gthumb/gth-info-bar.h
index f578b7f..5a9ea31 100644
--- a/gthumb/gth-info-bar.h
+++ b/gthumb/gth-info-bar.h
@@ -54,6 +54,7 @@ GType gth_info_bar_get_type (void) G_GNUC_CONST;
GtkWidget * gth_info_bar_new (const char *icon_stock_id,
const char *primary_text,
const char *secondary_text);
+GtkWidget * gth_info_bar_get_primary_label (GthInfoBar *dialog);
void gth_info_bar_set_icon (GthInfoBar *dialog,
const char *icon_stock_id);
void gth_info_bar_set_gicon (GthInfoBar *dialog,
diff --git a/gthumb/gth-test-category.c b/gthumb/gth-test-category.c
index 195f8a1..740cdd2 100644
--- a/gthumb/gth-test-category.c
+++ b/gthumb/gth-test-category.c
@@ -467,3 +467,15 @@ gth_test_category_get_type (void)
return type;
}
+
+
+void
+gth_test_category_set (GthTestCategory *self,
+ GthTestOp op,
+ gboolean negative,
+ const char *value)
+{
+ self->priv->op = op;
+ self->priv->negative = negative;
+ gth_test_category_set_category (self, value);
+}
diff --git a/gthumb/gth-test-category.h b/gthumb/gth-test-category.h
index 1c6a22c..8897718 100644
--- a/gthumb/gth-test-category.h
+++ b/gthumb/gth-test-category.h
@@ -49,5 +49,9 @@ struct _GthTestCategoryClass
};
GType gth_test_category_get_type (void) G_GNUC_CONST;
+void gth_test_category_set (GthTestCategory *self,
+ GthTestOp op,
+ gboolean negative,
+ const char *value);
#endif /* GTH_TEST_CATEGORY_H */
diff --git a/gthumb/gth-test-simple.c b/gthumb/gth-test-simple.c
index 101460c..9e6df3a 100644
--- a/gthumb/gth-test-simple.c
+++ b/gthumb/gth-test-simple.c
@@ -145,50 +145,6 @@ _gth_test_simple_free_data (GthTestSimple *test)
static void
-_gth_test_simple_set_data_as_string (GthTestSimple *test,
- const char *s)
-{
- _gth_test_simple_free_data (test);
- test->priv->data_type = GTH_TEST_DATA_TYPE_STRING;
- test->priv->data.s = g_strdup (s);
-}
-
-
-static void
-_gth_test_simple_set_data_as_int (GthTestSimple *test,
- guint64 i)
-{
- _gth_test_simple_free_data (test);
- test->priv->data_type = GTH_TEST_DATA_TYPE_INT;
- test->priv->data.i = i;
-}
-
-
-static void
-_gth_test_simple_set_data_as_size (GthTestSimple *test,
- guint64 i)
-{
- _gth_test_simple_free_data (test);
- test->priv->data_type = GTH_TEST_DATA_TYPE_SIZE;
- test->priv->data.i = i;
-}
-
-
-static void
-_gth_test_simple_set_data_as_date (GthTestSimple *test,
- GDate *date)
-{
- _gth_test_simple_free_data (test);
- test->priv->data_type = GTH_TEST_DATA_TYPE_DATE;
- test->priv->data.date = g_date_new ();
- if (date != NULL)
- *test->priv->data.date = *date;
- else
- g_date_clear (test->priv->data.date, 1);
-}
-
-
-static void
gth_test_simple_finalize (GObject *object)
{
GthTestSimple *test;
@@ -796,15 +752,15 @@ gth_test_simple_real_load_from_element (DomDomizable *base,
switch (self->priv->data_type) {
case GTH_TEST_DATA_TYPE_INT:
- _gth_test_simple_set_data_as_int (self, atol (value));
+ gth_test_simple_set_data_as_int (self, atol (value));
break;
case GTH_TEST_DATA_TYPE_SIZE:
- _gth_test_simple_set_data_as_size (self, atol (value));
+ gth_test_simple_set_data_as_size (self, atol (value));
break;
case GTH_TEST_DATA_TYPE_STRING:
- _gth_test_simple_set_data_as_string (self, value);
+ gth_test_simple_set_data_as_string (self, value);
break;
case GTH_TEST_DATA_TYPE_DATE:
@@ -813,7 +769,7 @@ gth_test_simple_real_load_from_element (DomDomizable *base,
dt = gth_datetime_new ();
gth_datetime_from_exif_date (dt, value);
- _gth_test_simple_set_data_as_date (self, dt->date);
+ gth_test_simple_set_data_as_date (self, dt->date);
gth_datetime_free (dt);
}
@@ -834,7 +790,7 @@ update_from_control_for_integer (GthTestSimple *self,
op_data = int_op_data[gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->text_op_combo_box))];
self->priv->op = op_data.op;
self->priv->negative = op_data.negative;
- _gth_test_simple_set_data_as_int (self, atol (gtk_entry_get_text (GTK_ENTRY (self->priv->text_entry))));
+ gth_test_simple_set_data_as_int (self, atol (gtk_entry_get_text (GTK_ENTRY (self->priv->text_entry))));
if (self->priv->data.i == 0) {
if (error != NULL)
@@ -860,7 +816,7 @@ update_from_control_for_size (GthTestSimple *self,
value = atol (gtk_entry_get_text (GTK_ENTRY (self->priv->text_entry)));
size = value * size_data[gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->size_combo_box))].size;
- _gth_test_simple_set_data_as_size (self, size);
+ gth_test_simple_set_data_as_size (self, size);
if ((self->priv->data.i == 0) && (self->priv->op == GTH_TEST_OP_LOWER)) {
if (error != NULL)
@@ -881,7 +837,7 @@ update_from_control_for_string (GthTestSimple *self,
op_data = text_op_data[gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->text_op_combo_box))];
self->priv->op = op_data.op;
self->priv->negative = op_data.negative;
- _gth_test_simple_set_data_as_string (self, gtk_entry_get_text (GTK_ENTRY (self->priv->text_entry)));
+ gth_test_simple_set_data_as_string (self, gtk_entry_get_text (GTK_ENTRY (self->priv->text_entry)));
if (g_strcmp0 (self->priv->data.s, "") == 0) {
if (error != NULL)
@@ -906,7 +862,7 @@ update_from_control_for_date (GthTestSimple *self,
dt = gth_datetime_new ();
gth_time_selector_get_value (GTH_TIME_SELECTOR (self->priv->time_selector), dt);
- _gth_test_simple_set_data_as_date (self, dt->date);
+ gth_test_simple_set_data_as_date (self, dt->date);
gth_datetime_free (dt);
if (! g_date_valid (self->priv->data.date)) {
@@ -973,19 +929,19 @@ gth_test_simple_real_duplicate (GthDuplicable *duplicable)
break;
case GTH_TEST_DATA_TYPE_INT:
- _gth_test_simple_set_data_as_int (new_test, test->priv->data.i);
+ gth_test_simple_set_data_as_int (new_test, test->priv->data.i);
break;
case GTH_TEST_DATA_TYPE_SIZE:
- _gth_test_simple_set_data_as_size (new_test, test->priv->data.i);
+ gth_test_simple_set_data_as_size (new_test, test->priv->data.i);
break;
case GTH_TEST_DATA_TYPE_STRING:
- _gth_test_simple_set_data_as_string (new_test, test->priv->data.s);
+ gth_test_simple_set_data_as_string (new_test, test->priv->data.s);
break;
case GTH_TEST_DATA_TYPE_DATE:
- _gth_test_simple_set_data_as_date (new_test, test->priv->data.date);
+ gth_test_simple_set_data_as_date (new_test, test->priv->data.date);
break;
}
@@ -1227,3 +1183,47 @@ gth_test_simple_get_type (void)
return type;
}
+
+
+void
+gth_test_simple_set_data_as_string (GthTestSimple *test,
+ const char *s)
+{
+ _gth_test_simple_free_data (test);
+ test->priv->data_type = GTH_TEST_DATA_TYPE_STRING;
+ test->priv->data.s = g_strdup (s);
+}
+
+
+void
+gth_test_simple_set_data_as_int (GthTestSimple *test,
+ guint64 i)
+{
+ _gth_test_simple_free_data (test);
+ test->priv->data_type = GTH_TEST_DATA_TYPE_INT;
+ test->priv->data.i = i;
+}
+
+
+void
+gth_test_simple_set_data_as_size (GthTestSimple *test,
+ guint64 i)
+{
+ _gth_test_simple_free_data (test);
+ test->priv->data_type = GTH_TEST_DATA_TYPE_SIZE;
+ test->priv->data.i = i;
+}
+
+
+void
+gth_test_simple_set_data_as_date (GthTestSimple *test,
+ GDate *date)
+{
+ _gth_test_simple_free_data (test);
+ test->priv->data_type = GTH_TEST_DATA_TYPE_DATE;
+ test->priv->data.date = g_date_new ();
+ if (date != NULL)
+ *test->priv->data.date = *date;
+ else
+ g_date_clear (test->priv->data.date, 1);
+}
diff --git a/gthumb/gth-test-simple.h b/gthumb/gth-test-simple.h
index 152192d..7ec222c 100644
--- a/gthumb/gth-test-simple.h
+++ b/gthumb/gth-test-simple.h
@@ -65,7 +65,15 @@ struct _GthTestSimpleClass
GthTestClass __parent_class;
};
-GType gth_test_simple_get_type (void) G_GNUC_CONST;
+GType gth_test_simple_get_type (void) G_GNUC_CONST;
+void gth_test_simple_set_data_as_string (GthTestSimple *test,
+ const char *s);
+void gth_test_simple_set_data_as_int (GthTestSimple *test,
+ guint64 i);
+void gth_test_simple_set_data_as_size (GthTestSimple *test,
+ guint64 i);
+void gth_test_simple_set_data_as_date (GthTestSimple *test,
+ GDate *date);
G_END_DECLS
diff --git a/gthumb/gth-time-selector.c b/gthumb/gth-time-selector.c
index f9751c1..d99b71d 100644
--- a/gthumb/gth-time-selector.c
+++ b/gthumb/gth-time-selector.c
@@ -26,6 +26,7 @@
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
+#include "glib-utils.h"
#include "gth-time-selector.h"
@@ -217,9 +218,11 @@ update_view_from_data (GthTimeSelector *self)
}
if (g_date_valid (self->priv->date_time->date)) {
- char *text;
+ struct tm tm;
+ char *text;
- text = gth_datetime_strftime (self->priv->date_time, "%x");
+ g_date_to_struct_tm (self->priv->date_time->date, &tm);
+ text = struct_tm_strftime (&tm, "%x");
gtk_entry_set_text (GTK_ENTRY (self->priv->date_entry), text);
if (gth_datetime_valid (self->priv->date_time)) {
diff --git a/gthumb/gth-time.c b/gthumb/gth-time.c
index bc09221..ed2c70e 100644
--- a/gthumb/gth-time.c
+++ b/gthumb/gth-time.c
@@ -285,14 +285,19 @@ gth_datetime_to_exif_date (GthDateTime *dt)
}
-void
+gboolean
gth_datetime_to_struct_tm (GthDateTime *dt,
struct tm *tm)
{
+ if (! gth_datetime_valid (dt))
+ return FALSE;
+
g_date_to_struct_tm (dt->date, tm);
tm->tm_hour = dt->time->hour;
tm->tm_min = dt->time->min;
tm->tm_sec = dt->time->sec;
+
+ return TRUE;
}
@@ -318,6 +323,8 @@ gth_datetime_strftime (GthDateTime *dt,
{
struct tm tm;
- gth_datetime_to_struct_tm (dt, &tm);
- return struct_tm_strftime (&tm, format);
+ if (gth_datetime_to_struct_tm (dt, &tm))
+ return struct_tm_strftime (&tm, format);
+ else
+ return g_strdup ("");
}
diff --git a/gthumb/gth-time.h b/gthumb/gth-time.h
index 3bc276a..b9ff775 100644
--- a/gthumb/gth-time.h
+++ b/gthumb/gth-time.h
@@ -64,7 +64,7 @@ void gth_datetime_from_struct_tm (GthDateTime *dt,
void gth_datetime_from_gdate (GthDateTime *dt,
GDate *date);
char * gth_datetime_to_exif_date (GthDateTime *dt);
-void gth_datetime_to_struct_tm (GthDateTime *dt,
+gboolean gth_datetime_to_struct_tm (GthDateTime *dt,
struct tm *tm);
gboolean gth_datetime_to_timeval (GthDateTime *dt,
GTimeVal *tv);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]