[gthumb] edit metadata: allow to save the metadata without closing the dialog
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] edit metadata: allow to save the metadata without closing the dialog
- Date: Mon, 5 Dec 2011 19:59:12 +0000 (UTC)
commit bbded358eead173cb57db0db3d7d398bf984e27e
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Nov 25 21:42:53 2011 +0100
edit metadata: allow to save the metadata without closing the dialog
[new feature]
extensions/edit_metadata/actions.c | 13 +-
extensions/edit_metadata/dlg-edit-metadata.c | 233 +++++++++++++++----
extensions/edit_metadata/dlg-edit-metadata.h | 3 +-
extensions/edit_metadata/gth-edit-comment-page.c | 7 +-
.../edit_metadata/gth-edit-metadata-dialog.c | 13 +-
gthumb/gth-file-data.c | 11 +-
6 files changed, 210 insertions(+), 70 deletions(-)
---
diff --git a/extensions/edit_metadata/actions.c b/extensions/edit_metadata/actions.c
index 429c2de..d6e6631 100644
--- a/extensions/edit_metadata/actions.c
+++ b/extensions/edit_metadata/actions.c
@@ -32,18 +32,7 @@ void
gth_browser_activate_action_edit_metadata (GtkAction *action,
GthBrowser *browser)
{
- GList *items;
- GList *file_data_list;
- GList *file_list;
-
- items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
- file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
- file_list = gth_file_data_list_to_file_list (file_data_list);
- dlg_edit_metadata (browser, file_list);
-
- _g_object_list_unref (file_list);
- _g_object_list_unref (file_data_list);
- _gtk_tree_path_list_free (items);
+ dlg_edit_metadata (browser);
}
diff --git a/extensions/edit_metadata/dlg-edit-metadata.c b/extensions/edit_metadata/dlg-edit-metadata.c
index 8f2224c..42d1039 100644
--- a/extensions/edit_metadata/dlg-edit-metadata.c
+++ b/extensions/edit_metadata/dlg-edit-metadata.c
@@ -26,30 +26,86 @@
#include "gth-edit-metadata-dialog.h"
+#define UPDATE_SELECTION_DELAY 300
+#define EDIT_METADATA_DIALOG_NAME "dlg-edit-metadata"
+
+
typedef struct {
+ int ref;
GthBrowser *browser;
GtkWidget *dialog;
- GList *files; /* GFile list */
GList *file_list; /* GthFileData list */
GList *parents;
+ gboolean never_shown;
+ gboolean close_dialog;
+ GthTask *loader;
+ gulong file_selection_changed_event;
+ guint update_selectection_event;
} DialogData;
+static DialogData *
+dialog_data_ref (DialogData *data)
+{
+ g_atomic_int_inc (&data->ref);
+ return data;
+}
+
+
+static void
+cancel_file_list_loading (DialogData *data)
+{
+ if (data->loader == NULL)
+ return;
+ gth_task_cancel (data->loader);
+ g_object_unref (data->loader);
+ data->loader = NULL;
+}
+
+
static void
-destroy_cb (GtkWidget *widget,
- DialogData *data)
+dialog_data_unref (DialogData *data)
{
+ if (! g_atomic_int_dec_and_test (&data->ref))
+ return;
+
+ if (data->file_selection_changed_event != 0) {
+ g_signal_handler_disconnect (gth_browser_get_file_list_view (data->browser),
+ data->file_selection_changed_event);
+ data->file_selection_changed_event = 0;
+ }
+ if (data->update_selectection_event != 0) {
+ g_source_remove (data->update_selectection_event);
+ data->update_selectection_event = 0;
+ }
+ cancel_file_list_loading (data);
+
+ gth_browser_set_dialog (data->browser, EDIT_METADATA_DIALOG_NAME, NULL);
+ gtk_widget_destroy (data->dialog);
+
_g_object_list_unref (data->file_list);
- _g_object_list_unref (data->files);
_g_object_list_unref (data->parents);
g_free (data);
}
static void
-save_file_data_task_completed_cb (GthTask *task,
- GError *error,
- gpointer user_data)
+close_dialog (DialogData *data)
+{
+ if (data->file_selection_changed_event != 0) {
+ g_signal_handler_disconnect (gth_browser_get_file_list_view (data->browser),
+ data->file_selection_changed_event);
+ data->file_selection_changed_event = 0;
+ }
+ gtk_widget_hide (data->dialog);
+ dialog_data_unref (data);
+}
+
+
+static void
+saver_completed_cb (GthTask *task,
+ GError *error,
+ gpointer user_data)
{
DialogData *data = user_data;
GthMonitor *monitor;
@@ -60,28 +116,25 @@ save_file_data_task_completed_cb (GthTask *task,
gth_monitor_resume (monitor, (GFile *) scan->data);
if (error != NULL) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not save the file metadata"), error);
- return;
+ if (! g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not save the file metadata"), error);
}
+ else {
+ for (scan = data->file_list; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+ GList *files;
- for (scan = data->file_list; scan; scan = scan->next) {
- GthFileData *file_data = scan->data;
- GFile *parent;
- GList *files;
-
- parent = g_file_get_parent (file_data->file);
- if (G_UNLIKELY (parent == NULL))
- continue;
-
- files = g_list_prepend (NULL, g_object_ref (file_data->file));
- /*gth_monitor_folder_changed (monitor, parent, files, GTH_MONITOR_EVENT_CHANGED);*/
- gth_monitor_metadata_changed (monitor, file_data);
+ files = g_list_prepend (NULL, g_object_ref (file_data->file));
+ gth_monitor_metadata_changed (monitor, file_data);
- _g_object_list_unref (files);
- g_object_unref (parent);
+ _g_object_list_unref (files);
+ }
}
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ if (data->close_dialog)
+ close_dialog (data);
+
+ dialog_data_unref (data);
}
@@ -96,11 +149,17 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
GList *scan;
GthTask *task;
- if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ if ((response != GTK_RESPONSE_OK) && (response != GTK_RESPONSE_APPLY)) {
+ cancel_file_list_loading (data);
+ close_dialog (data);
return;
}
+ if (data->file_list == NULL)
+ return;
+
+ data->close_dialog = (response == GTK_RESPONSE_OK);
+
/* get the parents list */
parents = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
@@ -115,6 +174,7 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
g_object_unref (parent);
}
}
+ _g_object_list_unref (data->parents);
data->parents = g_hash_table_get_keys (parents);
g_list_foreach (data->parents, (GFunc) g_object_ref, NULL);
g_hash_table_unref (parents);
@@ -127,10 +187,11 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
gth_edit_metadata_dialog_update_info (GTH_EDIT_METADATA_DIALOG (data->dialog), data->file_list);
+ dialog_data_ref (data);
task = gth_save_file_data_task_new (data->file_list, "*");
g_signal_connect (task,
"completed",
- G_CALLBACK (save_file_data_task_completed_cb),
+ G_CALLBACK (saver_completed_cb),
data);
gth_browser_exec_task (data->browser, task, FALSE);
@@ -139,55 +200,129 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
}
+typedef struct {
+ DialogData *data;
+ GList *files;
+} LoaderData;
+
+
+static void
+loader_data_free (LoaderData *loader_data)
+{
+ dialog_data_unref (loader_data->data);
+ _g_object_list_unref (loader_data->files);
+ g_free (loader_data);
+}
+
+
static void
-load_file_data_task_completed_cb (GthTask *task,
- GError *error,
- gpointer user_data)
+loader_completed_cb (GthTask *task,
+ GError *error,
+ gpointer user_data)
{
- DialogData *data = user_data;
+ LoaderData *loader_data = user_data;
+ DialogData *data = loader_data->data;
if (error != NULL) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Cannot read file information"), error);
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ if (! g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Cannot read file information"), error);
+ loader_data_free (loader_data);
+ if (data->never_shown)
+ close_dialog (data);
return;
}
+ _g_object_list_unref (data->file_list);
data->file_list = _g_object_list_ref (gth_load_file_data_task_get_result (GTH_LOAD_FILE_DATA_TASK (task)));
gth_edit_metadata_dialog_set_file_list (GTH_EDIT_METADATA_DIALOG (data->dialog), data->file_list);
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
- gtk_window_set_modal (GTK_WINDOW (data->dialog), TRUE);
+ gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
gtk_window_present (GTK_WINDOW (data->dialog));
+
+ data->never_shown = FALSE;
+
+ loader_data_free (loader_data);
+}
+
+
+static gboolean
+update_file_list (gpointer user_data)
+{
+ DialogData *data = user_data;
+ LoaderData *loader_data;
+ GList *items;
+ GList *file_data_list;
+
+ if (data->update_selectection_event != 0) {
+ g_source_remove (data->update_selectection_event);
+ data->update_selectection_event = 0;
+ }
+
+ cancel_file_list_loading (data);
+
+ loader_data = g_new0 (LoaderData, 1);
+ loader_data->data = dialog_data_ref (data);
+
+ items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (data->browser)));
+ file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (data->browser)), items);
+ loader_data->files = gth_file_data_list_to_file_list (file_data_list);
+
+ data->loader = gth_load_file_data_task_new (loader_data->files, "*");
+ g_signal_connect (data->loader,
+ "completed",
+ G_CALLBACK (loader_completed_cb),
+ loader_data);
+ gth_browser_exec_task (data->browser, data->loader, FALSE);
+
+ _g_object_list_unref (file_data_list);
+ _gtk_tree_path_list_free (items);
+
+ return FALSE;
+}
+
+
+static void
+file_selection_changed_cb (GthFileSelection *self,
+ DialogData *data)
+{
+ if (data->update_selectection_event != 0)
+ g_source_remove (data->update_selectection_event);
+ data->update_selectection_event = g_timeout_add (UPDATE_SELECTION_DELAY, update_file_list, data);
}
void
-dlg_edit_metadata (GthBrowser *browser,
- GList *files)
+dlg_edit_metadata (GthBrowser *browser)
{
DialogData *data;
- GthTask *task;
+
+ if (gth_browser_get_dialog (browser, EDIT_METADATA_DIALOG_NAME)) {
+ gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, EDIT_METADATA_DIALOG_NAME)));
+ return;
+ }
data = g_new0 (DialogData, 1);
+ data->ref = 1;
data->browser = browser;
- data->files = _g_object_list_ref (files);
data->dialog = gth_edit_metadata_dialog_new ();
+ data->never_shown = TRUE;
+
+ gth_browser_set_dialog (browser, EDIT_METADATA_DIALOG_NAME, data->dialog);
g_signal_connect (G_OBJECT (data->dialog),
- "destroy",
- G_CALLBACK (destroy_cb),
- data);
+ "delete-event",
+ G_CALLBACK (gtk_true),
+ NULL);
g_signal_connect (data->dialog,
"response",
G_CALLBACK (edit_metadata_dialog__response_cb),
data);
+ data->file_selection_changed_event =
+ g_signal_connect (gth_browser_get_file_list_view (data->browser),
+ "file-selection-changed",
+ G_CALLBACK (file_selection_changed_cb),
+ data);
- task = gth_load_file_data_task_new (data->files, "*");
- g_signal_connect (task,
- "completed",
- G_CALLBACK (load_file_data_task_completed_cb),
- data);
- gth_browser_exec_task (browser, task, FALSE);
-
- g_object_unref (task);
+ update_file_list (data);
}
diff --git a/extensions/edit_metadata/dlg-edit-metadata.h b/extensions/edit_metadata/dlg-edit-metadata.h
index 13ab8a1..fc5424b 100644
--- a/extensions/edit_metadata/dlg-edit-metadata.h
+++ b/extensions/edit_metadata/dlg-edit-metadata.h
@@ -24,7 +24,6 @@
#include <gthumb.h>
-void dlg_edit_metadata (GthBrowser *browser,
- GList *files /* GFile list */);
+void dlg_edit_metadata (GthBrowser *browser);
#endif /* DLG_EDIT_METADATA_H */
diff --git a/extensions/edit_metadata/gth-edit-comment-page.c b/extensions/edit_metadata/gth-edit-comment-page.c
index 176167c..eaee343 100644
--- a/extensions/edit_metadata/gth-edit-comment-page.c
+++ b/extensions/edit_metadata/gth-edit-comment-page.c
@@ -110,7 +110,7 @@ gth_edit_comment_page_real_set_file_list (GthEditMetadataPage *base,
gth_time_selector_set_exif_date (GTH_TIME_SELECTOR (self->priv->date_selector), gth_metadata_get_raw (metadata));
}
else {
- if (file_list->next == NULL)
+ if ((file_list != NULL) && (file_list->next == NULL))
gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->date_combobox), NO_DATE);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->date_combobox), NO_CHANGE);
@@ -144,7 +144,10 @@ gth_edit_comment_page_real_set_file_list (GthEditMetadataPage *base,
no_provider = TRUE;
- if (file_list->next == NULL) {
+ if (file_list == NULL) {
+ file_data = gth_file_data_new (NULL, NULL);
+ }
+ else if (file_list->next == NULL) {
GthFileData *first = file_list->data;
file_data = gth_file_data_new (first->file, first->info);
}
diff --git a/extensions/edit_metadata/gth-edit-metadata-dialog.c b/extensions/edit_metadata/gth-edit-metadata-dialog.c
index c391cc3..fcc5912 100644
--- a/extensions/edit_metadata/gth-edit-metadata-dialog.c
+++ b/extensions/edit_metadata/gth-edit-metadata-dialog.c
@@ -54,7 +54,8 @@ gth_edit_metadata_dialog_init (GthEditMetadataDialog *self)
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_OK);
+ gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_APPLY);
+ gtk_dialog_add_button (GTK_DIALOG (self), _("Sa_ve and Close"), GTK_RESPONSE_OK);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
@@ -108,9 +109,6 @@ gth_edit_metadata_dialog_set_file_list (GthEditMetadataDialog *dialog,
GList *pages;
GList *scan;
- if (file_list == NULL)
- return;
-
n_files = g_list_length (file_list);
if (n_files == 1) {
GthFileData *file_data = file_list->data;
@@ -131,6 +129,13 @@ gth_edit_metadata_dialog_set_file_list (GthEditMetadataDialog *dialog,
for (scan = pages; scan; scan = scan->next)
gth_edit_metadata_page_set_file_list (GTH_EDIT_METADATA_PAGE (scan->data), file_list);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_APPLY,
+ n_files > 0);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK,
+ n_files > 0);
+
g_list_free (pages);
g_free (title);
}
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 6da5551..c79223c 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -212,9 +212,14 @@ gth_file_data_get_mime_type (GthFileData *self)
content_type = g_file_info_get_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
if (content_type == NULL)
content_type = g_file_info_get_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
+
if (content_type == NULL) {
- char *filename = g_file_get_basename (self->file);
+ char *filename;
+
+ if (self->file == NULL)
+ return NULL;
+ filename = g_file_get_basename (self->file);
if (filename != NULL) {
content_type = g_content_type_guess (filename, NULL, 0, NULL);
g_free (filename);
@@ -515,6 +520,10 @@ gth_file_data_list_get_common_info (GList *file_data_list,
int i;
info = g_file_info_new ();
+
+ if (file_data_list == NULL)
+ return info;
+
g_file_info_copy_into (((GthFileData *) file_data_list->data)->info, info);
attributes_v = g_strsplit (attribtues, ",", -1);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]