[gthumb] "resize images" changes



commit 97905400a6182c65480782fc21b6d7ef9b3237c7
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Feb 7 17:29:06 2010 +0100

    "resize images" changes
    
    1) added ability to specify a destination folder
    2) show the overwrite dialog before overwriting a file.
    
    [bug #605914]

 data/ui/overwrite-dialog.ui                       |    8 +-
 extensions/catalogs/actions.c                     |    1 +
 extensions/catalogs/dlg-add-to-catalog.c          |    1 +
 extensions/catalogs/dlg-catalog-properties.c      |    1 +
 extensions/catalogs/gth-file-source-catalogs.c    |    3 +
 extensions/change_date/main.c                     |    2 +-
 extensions/desktop_background/main.c              |    2 +-
 extensions/gstreamer/actions.c                    |    1 +
 extensions/image_rotation/rotation-utils.c        |    2 +
 extensions/image_viewer/gth-image-viewer-page.c   |    1 +
 extensions/importer/gth-import-task.c             |    1 +
 extensions/rename_series/gth-rename-task.c        |    1 +
 extensions/resize_images/callbacks.c              |    2 +-
 extensions/resize_images/data/ui/resize-images.ui |  115 +++++++++++--
 extensions/resize_images/dlg-resize-images.c      |   18 ++
 extensions/resize_images/main.c                   |    2 +-
 extensions/search/gth-search-task.c               |    2 +
 gthumb/gio-utils.c                                |   46 +++++-
 gthumb/gio-utils.h                                |    1 +
 gthumb/gth-overwrite-dialog.c                     |   64 +++++---
 gthumb/gth-overwrite-dialog.h                     |    1 +
 gthumb/gth-pixbuf-list-task.c                     |  194 ++++++++++++++++++---
 gthumb/gth-pixbuf-list-task.h                     |   13 +-
 gthumb/pixbuf-io.c                                |    3 +
 gthumb/pixbuf-io.h                                |    2 +
 25 files changed, 417 insertions(+), 70 deletions(-)
---
diff --git a/data/ui/overwrite-dialog.ui b/data/ui/overwrite-dialog.ui
index 483a77b..e1f74cf 100644
--- a/data/ui/overwrite-dialog.ui
+++ b/data/ui/overwrite-dialog.ui
@@ -218,7 +218,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkTable" id="table16">
+              <object class="GtkTable" id="new_info_table">
                 <property name="visible">True</property>
                 <property name="n_rows">3</property>
                 <property name="n_columns">2</property>
@@ -269,7 +269,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label4">
+                  <object class="GtkLabel" id="new_filename_label">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Filename:</property>
@@ -282,7 +282,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label5">
+                  <object class="GtkLabel" id="new_size_label">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Size:</property>
@@ -297,7 +297,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label6">
+                  <object class="GtkLabel" id="new_modified_label">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Modified:</property>
diff --git a/extensions/catalogs/actions.c b/extensions/catalogs/actions.c
index c4911d2..4adfb71 100644
--- a/extensions/catalogs/actions.c
+++ b/extensions/catalogs/actions.c
@@ -142,6 +142,7 @@ catalog_buffer_ready_cb (void     **buffer,
 	g_write_file_async (data->gio_file,
 			    catalog_buffer,
 			    catalog_size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    NULL,
 			    catalog_save_done_cb,
diff --git a/extensions/catalogs/dlg-add-to-catalog.c b/extensions/catalogs/dlg-add-to-catalog.c
index 6d93425..ef2b6b9 100644
--- a/extensions/catalogs/dlg-add-to-catalog.c
+++ b/extensions/catalogs/dlg-add-to-catalog.c
@@ -146,6 +146,7 @@ catalog_ready_cb (GObject  *catalog,
 	g_write_file_async (gio_file,
 			    buffer,
 			    length,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    NULL,
 			    catalog_save_done_cb,
diff --git a/extensions/catalogs/dlg-catalog-properties.c b/extensions/catalogs/dlg-catalog-properties.c
index e6aef15..d17184e 100644
--- a/extensions/catalogs/dlg-catalog-properties.c
+++ b/extensions/catalogs/dlg-catalog-properties.c
@@ -138,6 +138,7 @@ save_button_clicked_cb (GtkButton  *button,
 	g_write_file_async (gio_file,
 			    buffer,
 			    size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    NULL,
 			    catalog_saved_cb,
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 00c02d5..d076fd3 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -250,6 +250,7 @@ write_metadata_load_buffer_ready_cb (void     **buffer,
 	g_write_file_async (gio_file,
 			    catalog_buffer,
 			    catalog_size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    gth_file_source_get_cancellable (GTH_FILE_SOURCE (metadata_op->catalogs)),
 			    write_metadata_write_buffer_ready_cb,
@@ -731,6 +732,7 @@ catalog_ready_cb (GObject  *catalog,
 	g_write_file_async (gio_file,
 			    buffer,
 			    size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    NULL,
 			    catalog_save_done_cb,
@@ -919,6 +921,7 @@ reorder_catalog_ready_cb (GObject  *object,
 	g_write_file_async (gio_file,
 			    buffer,
 			    size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    gth_file_source_get_cancellable (reorder_data->file_source),
 			    reorder_buffer_ready_cb,
diff --git a/extensions/change_date/main.c b/extensions/change_date/main.c
index a4fa559..8b57e3a 100644
--- a/extensions/change_date/main.c
+++ b/extensions/change_date/main.c
@@ -30,7 +30,7 @@
 G_MODULE_EXPORT void
 gthumb_extension_activate (void)
 {
-	gth_hook_add_callback ("gth-browser-construct", 40, G_CALLBACK (cd__gth_browser_construct_cb), NULL);
+	gth_hook_add_callback ("gth-browser-construct", 50, G_CALLBACK (cd__gth_browser_construct_cb), NULL);
 	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (cd__gth_browser_update_sensitivity_cb), NULL);
 }
 
diff --git a/extensions/desktop_background/main.c b/extensions/desktop_background/main.c
index ee5a7f4..1a02ee6 100644
--- a/extensions/desktop_background/main.c
+++ b/extensions/desktop_background/main.c
@@ -30,7 +30,7 @@
 G_MODULE_EXPORT void
 gthumb_extension_activate (void)
 {
-	gth_hook_add_callback ("gth-browser-construct", 40, G_CALLBACK (db__gth_browser_construct_cb), NULL);
+	gth_hook_add_callback ("gth-browser-construct", 20, G_CALLBACK (db__gth_browser_construct_cb), NULL);
 	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (db__gth_browser_update_sensitivity_cb), NULL);
 }
 
diff --git a/extensions/gstreamer/actions.c b/extensions/gstreamer/actions.c
index 0339fe4..dbd8da7 100644
--- a/extensions/gstreamer/actions.c
+++ b/extensions/gstreamer/actions.c
@@ -102,6 +102,7 @@ save_as_response_cb (GtkDialog  *file_sel,
 	_gdk_pixbuf_save_async (save_data->pixbuf,
 				save_data->file_data,
 				mime_type,
+				TRUE,
 				screenshot_saved_cb,
 				save_data);
 
diff --git a/extensions/image_rotation/rotation-utils.c b/extensions/image_rotation/rotation-utils.c
index 8a7bf0e..119e85b 100644
--- a/extensions/image_rotation/rotation-utils.c
+++ b/extensions/image_rotation/rotation-utils.c
@@ -292,6 +292,7 @@ file_buffer_ready_cb (void     **buffer,
 		g_write_file_async (tdata->file_data->file,
 				    out_buffer,
 		    		    out_buffer_size,
+		    		    TRUE,
 				    G_PRIORITY_DEFAULT,
 				    tdata->cancellable,
 				    write_file_ready_cb,
@@ -316,6 +317,7 @@ file_buffer_ready_cb (void     **buffer,
 		_gdk_pixbuf_save_async (transformed_pixbuf,
 					tdata->file_data,
 					gth_file_data_get_mime_type (tdata->file_data),
+					TRUE,
 					pixbuf_saved_cb,
 					tdata);
 
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 50bd35e..3bfd4a0 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -765,6 +765,7 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
 	_gdk_pixbuf_save_async (gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (self->priv->viewer)),
 			        current_file,
 			        mime_type,
+			        TRUE,
 				image_saved_cb,
 				data);
 }
diff --git a/extensions/importer/gth-import-task.c b/extensions/importer/gth-import-task.c
index a6588ff..814bfd4 100644
--- a/extensions/importer/gth-import-task.c
+++ b/extensions/importer/gth-import-task.c
@@ -322,6 +322,7 @@ file_buffer_ready_cb (void     **buffer,
 		g_write_file_async (self->priv->destination_file->file,
 				    *buffer,
 				    count,
+				    TRUE,
 				    G_PRIORITY_DEFAULT,
 				    gth_task_get_cancellable (GTH_TASK (self)),
 				    write_buffer_ready_cb,
diff --git a/extensions/rename_series/gth-rename-task.c b/extensions/rename_series/gth-rename-task.c
index 2569b00..1ecd104 100644
--- a/extensions/rename_series/gth-rename-task.c
+++ b/extensions/rename_series/gth-rename-task.c
@@ -179,6 +179,7 @@ _gth_rename_task_try_rename (GthRenameTask   *self,
 				GtkWidget *dialog;
 
 				dialog = gth_overwrite_dialog_new (source,
+								   NULL,
 								   destination,
 								   self->priv->default_response,
 								   self->priv->n_files == 1);
diff --git a/extensions/resize_images/callbacks.c b/extensions/resize_images/callbacks.c
index 60d780b..684c1b9 100644
--- a/extensions/resize_images/callbacks.c
+++ b/extensions/resize_images/callbacks.c
@@ -43,7 +43,7 @@ static const char *fixed_ui_info =
 
 static GtkActionEntry action_entries[] = {
 	{ "Tool_ResizeImages", NULL,
-	  N_("Resize Images"), NULL,
+	  N_("Resize Images..."), NULL,
 	  N_("Resize the selected images"),
 	  G_CALLBACK (gth_browser_activate_action_tool_resize_images) },
 };
diff --git a/extensions/resize_images/data/ui/resize-images.ui b/extensions/resize_images/data/ui/resize-images.ui
index 1a35e17..4207007 100644
--- a/extensions/resize_images/data/ui/resize-images.ui
+++ b/extensions/resize_images/data/ui/resize-images.ui
@@ -3,16 +3,16 @@
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkAdjustment" id="width_adjustment">
-    <property name="value">2</property>
     <property name="lower">2</property>
     <property name="upper">10000</property>
+    <property name="value">2</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
   <object class="GtkAdjustment" id="height_adjustment">
-    <property name="value">2</property>
     <property name="lower">2</property>
     <property name="upper">10000</property>
+    <property name="value">2</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
@@ -158,26 +158,34 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkComboBox" id="unit_combobox">
+                              <placeholder/>
+                            </child>
+                            <child>
+                              <object class="GtkHBox" id="hbox2">
                                 <property name="visible">True</property>
-                                <property name="model">unit_model</property>
-                                <property name="active">0</property>
                                 <child>
-                                  <object class="GtkCellRendererText" id="size_renderer"/>
-                                  <attributes>
-                                    <attribute name="text">0</attribute>
-                                  </attributes>
+                                  <object class="GtkComboBox" id="unit_combobox">
+                                    <property name="visible">True</property>
+                                    <property name="model">unit_model</property>
+                                    <property name="active">0</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="size_renderer"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
                                 </child>
                               </object>
                               <packing>
                                 <property name="left_attach">2</property>
                                 <property name="right_attach">3</property>
-                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
-                            <child>
-                              <placeholder/>
-                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -218,6 +226,85 @@
                 <property name="position">0</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkVBox" id="saving_box">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Saving</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">    </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkTable" id="table1">
+                        <property name="visible">True</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">6</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Destination:</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFileChooserButton" id="destination_filechooserbutton">
+                            <property name="visible">True</property>
+                            <property name="action">select-folder</property>
+                            <property name="title" translatable="yes">Choose destination folder</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -262,7 +349,7 @@
             </child>
             <child>
               <object class="GtkButton" id="ok_button">
-                <property name="label">gtk-ok</property>
+                <property name="label">gtk-execute</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
diff --git a/extensions/resize_images/dlg-resize-images.c b/extensions/resize_images/dlg-resize-images.c
index bc9f721..ebcab1f 100644
--- a/extensions/resize_images/dlg-resize-images.c
+++ b/extensions/resize_images/dlg-resize-images.c
@@ -40,6 +40,7 @@ typedef struct {
 	GList      *file_list;
 	GtkBuilder *builder;
 	GtkWidget  *dialog;
+	gboolean    use_destination;
 } DialogData;
 
 
@@ -149,6 +150,15 @@ ok_clicked_cb (GtkWidget  *widget,
 	list_task = gth_pixbuf_list_task_new (data->browser,
 					      data->file_list,
 					      GTH_PIXBUF_TASK (resize_task));
+	gth_pixbuf_list_task_set_overwrite_mode (GTH_PIXBUF_LIST_TASK (list_task), GTH_OVERWRITE_ASK);
+	if (data->use_destination) {
+		GFile *destination;
+
+		destination = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")));
+		gth_pixbuf_list_task_set_destination (GTH_PIXBUF_LIST_TASK (list_task), destination);
+
+		g_object_unref (destination);
+	}
 	gth_browser_exec_task (data->browser, list_task, FALSE);
 
 	g_object_unref (list_task);
@@ -187,6 +197,7 @@ dlg_resize_images (GthBrowser *browser,
 	data->browser = browser;
 	data->builder = _gtk_builder_new_from_file ("resize-images.ui", "resize_images");
 	data->file_list = gth_file_data_list_dup (file_list);
+	data->use_destination = GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source(browser));
 
 	/* Get the widgets. */
 
@@ -202,6 +213,13 @@ dlg_resize_images (GthBrowser *browser,
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_ratio_checkbutton")), eel_gconf_get_boolean (PREF_RESIZE_IMAGES_KEEP_RATIO, TRUE));
 	update_sensitivity (data);
 
+	if (data->use_destination) {
+		gtk_file_chooser_set_file (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), gth_browser_get_location (browser), NULL);
+		gtk_widget_show (GET_WIDGET ("saving_box"));
+	}
+	else
+		gtk_widget_hide (GET_WIDGET ("saving_box"));
+
 	/* Set the signals handlers. */
 
 	g_signal_connect (G_OBJECT (data->dialog),
diff --git a/extensions/resize_images/main.c b/extensions/resize_images/main.c
index cdae2ff..a199e26 100644
--- a/extensions/resize_images/main.c
+++ b/extensions/resize_images/main.c
@@ -30,7 +30,7 @@
 G_MODULE_EXPORT void
 gthumb_extension_activate (void)
 {
-	gth_hook_add_callback ("gth-browser-construct", 20, G_CALLBACK (ri__gth_browser_construct_cb), NULL);
+	gth_hook_add_callback ("gth-browser-construct", 40, G_CALLBACK (ri__gth_browser_construct_cb), NULL);
 	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (ri__gth_browser_update_sensitivity_cb), NULL);
 }
 
diff --git a/extensions/search/gth-search-task.c b/extensions/search/gth-search-task.c
index 48d216a..92e3908 100644
--- a/extensions/search/gth-search-task.c
+++ b/extensions/search/gth-search-task.c
@@ -157,6 +157,7 @@ done_func (GObject  *object,
 	g_write_file_async (search_result_real_file,
 			    data,
 			    size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    gth_task_get_cancellable (GTH_TASK (task)),
 			    save_search_result_copy_done_cb,
@@ -318,6 +319,7 @@ gth_search_task_exec (GthTask *base)
 	g_write_file_async (search_result_real_file,
 			    data,
 			    size,
+			    TRUE,
 			    G_PRIORITY_DEFAULT,
 			    gth_task_get_cancellable (GTH_TASK (task)),
 			    clear_search_result_copy_done_cb,
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index fd54af9..5de7c29 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1278,6 +1278,7 @@ copy_file_ready_cb (GObject      *source_object,
 				copy_file_data->dialog_callback (TRUE, copy_file_data->dialog_callback_data);
 
 			dialog = gth_overwrite_dialog_new (copy_file_data->source->file,
+							   NULL,
 							   copy_file_data->current_destination,
 							   copy_file_data->default_response,
 							   copy_file_data->tot_files == 1);
@@ -2130,10 +2131,38 @@ write_file__replace_ready_cb (GObject      *source_object,
 }
 
 
+static void
+write_file__create_ready_cb (GObject      *source_object,
+			     GAsyncResult *result,
+			     gpointer      user_data)
+{
+	WriteData     *write_data = user_data;
+	GOutputStream *stream;
+	GError        *error = NULL;
+
+	stream = (GOutputStream*) g_file_create_finish ((GFile*) source_object, result, &error);
+	if (stream == NULL) {
+		write_data->callback (&write_data->buffer, write_data->count, error, write_data->user_data);
+		write_data_free (write_data);
+		return;
+	}
+
+	write_data->written = 0;
+	g_output_stream_write_async (stream,
+				     write_data->buffer,
+				     write_data->count,
+				     write_data->io_priority,
+				     write_data->cancellable,
+				     write_file__stream_write_ready_cb,
+				     write_data);
+}
+
+
 void
 g_write_file_async (GFile               *file,
 		    void                *buffer,
 		    gsize                count,
+		    gboolean             replace,
 		    int                  io_priority,
 		    GCancellable        *cancellable,
 		    BufferReadyCallback  callback,
@@ -2149,7 +2178,22 @@ g_write_file_async (GFile               *file,
 	write_data->callback = callback;
 	write_data->user_data = user_data;
 
-	g_file_replace_async (file, NULL, FALSE, 0, io_priority, cancellable, write_file__replace_ready_cb, write_data);
+	if (replace)
+		g_file_replace_async (file,
+				      NULL,
+				      FALSE,
+				      0,
+				      io_priority,
+				      cancellable,
+				      write_file__replace_ready_cb,
+				      write_data);
+	else
+		g_file_create_async (file,
+				     0,
+				     io_priority,
+				     cancellable,
+				     write_file__create_ready_cb,
+				     write_data);
 }
 
 
diff --git a/gthumb/gio-utils.h b/gthumb/gio-utils.h
index 42a322f..c4456ee 100644
--- a/gthumb/gio-utils.h
+++ b/gthumb/gio-utils.h
@@ -155,6 +155,7 @@ gboolean g_write_file                (GFile                 *file,
 void     g_write_file_async          (GFile                 *file,
 				      void                  *buffer,
 		    		      gsize                  count,
+		    		      gboolean               replace,
 				      int                    io_priority,
 				      GCancellable          *cancellable,
 				      BufferReadyCallback    callback,
diff --git a/gthumb/gth-overwrite-dialog.c b/gthumb/gth-overwrite-dialog.c
index ceeebba..56afac4 100644
--- a/gthumb/gth-overwrite-dialog.c
+++ b/gthumb/gth-overwrite-dialog.c
@@ -35,6 +35,7 @@ static gpointer gth_overwrite_dialog_parent_class = NULL;
 struct _GthOverwriteDialogPrivate {
 	GtkBuilder *builder;
 	GFile      *source;
+	GdkPixbuf  *source_pixbuf;
 	GFile      *destination;
 	GtkWidget  *old_image_viewer;
 	GtkWidget  *new_image_viewer;
@@ -49,7 +50,8 @@ gth_overwrite_dialog_finalize (GObject *object)
         dialog = GTH_OVERWRITE_DIALOG (object);
 
         g_object_unref (dialog->priv->builder);
-        g_object_unref (dialog->priv->source);
+        _g_object_unref (dialog->priv->source);
+        _g_object_unref (dialog->priv->source_pixbuf);
         g_object_unref (dialog->priv->destination);
 
         G_OBJECT_CLASS (gth_overwrite_dialog_parent_class)->finalize (object);
@@ -107,7 +109,6 @@ info_ready_cb (GList    *files,
 	       gpointer  user_data)
 {
 	GthOverwriteDialog *self = user_data;
-	GthFileData        *source;
 	GthFileData        *destination;
 	char               *text;
 	GTimeVal           *timeval;
@@ -121,31 +122,47 @@ info_ready_cb (GList    *files,
 
 	/* new image */
 
-	source = files->data;
+	if (self->priv->source != NULL) {
+		GthFileData *source;
 
-	gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_filename_label")), g_file_info_get_display_name (source->info));
+		source = files->data;
 
-	text = g_format_size_for_display (g_file_info_get_size (source->info));
-	gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_size_label")), text);
-	g_free (text);
+		gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_filename_label")), g_file_info_get_display_name (source->info));
 
-	timeval = gth_file_data_get_modification_time (source);
-	text = _g_time_val_to_exif_date (timeval);
-	gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_time_label")), text);
-	g_free (text);
+		text = g_format_size_for_display (g_file_info_get_size (source->info));
+		gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_size_label")), text);
+		g_free (text);
 
-	icon = (GIcon*) g_file_info_get_attribute_object (source->info, "preview::icon");
-	pixbuf = _g_icon_get_pixbuf (icon, 256, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (self))));
-	if (pixbuf != NULL) {
-		gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), pixbuf);
-		g_object_unref (pixbuf);
-	}
+		timeval = gth_file_data_get_modification_time (source);
+		text = _g_time_val_to_exif_date (timeval);
+		gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_time_label")), text);
+		g_free (text);
 
-	gth_image_viewer_load (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), source);
+		icon = (GIcon*) g_file_info_get_attribute_object (source->info, "preview::icon");
+		pixbuf = _g_icon_get_pixbuf (icon, 256, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (self))));
+		if (pixbuf != NULL) {
+			gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), pixbuf);
+			g_object_unref (pixbuf);
+		}
+
+		gtk_widget_show (_gtk_builder_get_widget (self->priv->builder, "new_filename_label"));
+		gtk_widget_show (_gtk_builder_get_widget (self->priv->builder, "new_size_label"));
+		gtk_widget_show (_gtk_builder_get_widget (self->priv->builder, "new_modified_label"));
+		gth_image_viewer_load (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), source);
+	}
+	else if (self->priv->source_pixbuf != NULL) {
+		gtk_widget_hide (_gtk_builder_get_widget (self->priv->builder, "new_filename_label"));
+		gtk_widget_hide (_gtk_builder_get_widget (self->priv->builder, "new_size_label"));
+		gtk_widget_hide (_gtk_builder_get_widget (self->priv->builder, "new_modified_label"));
+		gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), self->priv->source_pixbuf);
+	}
 
 	/* old image  */
 
-	destination = files->next->data;
+	if (self->priv->source != NULL)
+		destination = files->next->data;
+	else
+		destination = files->data;
 
 	gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "old_image_filename_label")), g_file_info_get_display_name (destination->info));
 
@@ -158,6 +175,8 @@ info_ready_cb (GList    *files,
 	gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "old_image_time_label")), text);
 	g_free (text);
 
+	gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_entry")), g_file_info_get_edit_name (destination->info));
+
 	gth_image_viewer_load (GTH_IMAGE_VIEWER (self->priv->old_image_viewer), destination);
 }
 
@@ -242,7 +261,8 @@ gth_overwrite_dialog_construct (GthOverwriteDialog   *self,
 			  self);
 
 	files = NULL;
-	files = g_list_append (files, self->priv->source);
+	if (self->priv->source != NULL)
+		files = g_list_append (files, self->priv->source);
 	files = g_list_append (files, self->priv->destination);
 	_g_query_all_metadata_async (files, FALSE, TRUE, "standard::*,time::modified,time::modified-usec,preview::icon", NULL, info_ready_cb, self);
 
@@ -252,6 +272,7 @@ gth_overwrite_dialog_construct (GthOverwriteDialog   *self,
 
 GtkWidget *
 gth_overwrite_dialog_new (GFile                *source,
+			  GdkPixbuf            *source_pixbuf,
 			  GFile                *destination,
 			  GthOverwriteResponse  default_respose,
 			  gboolean              single_file)
@@ -259,7 +280,8 @@ gth_overwrite_dialog_new (GFile                *source,
 	GthOverwriteDialog *self;
 
 	self = g_object_new (GTH_TYPE_OVERWRITE_DIALOG, NULL);
-	self->priv->source = g_object_ref (source);
+	self->priv->source = _g_object_ref (source);
+	self->priv->source_pixbuf = _g_object_ref (source_pixbuf);
 	self->priv->destination = g_object_ref (destination);
 	gth_overwrite_dialog_construct (self, default_respose, single_file);
 
diff --git a/gthumb/gth-overwrite-dialog.h b/gthumb/gth-overwrite-dialog.h
index e198225..ff6c965 100644
--- a/gthumb/gth-overwrite-dialog.h
+++ b/gthumb/gth-overwrite-dialog.h
@@ -58,6 +58,7 @@ struct _GthOverwriteDialogClass {
 
 GType                 gth_overwrite_dialog_get_type      (void);
 GtkWidget *           gth_overwrite_dialog_new           (GFile                *source,
+							  GdkPixbuf            *source_pixbuf,
 						          GFile                *destination,
 						          GthOverwriteResponse  default_respose,
 						          gboolean              single_file);
diff --git a/gthumb/gth-pixbuf-list-task.c b/gthumb/gth-pixbuf-list-task.c
index a4cd40a..06384a0 100644
--- a/gthumb/gth-pixbuf-list-task.c
+++ b/gthumb/gth-pixbuf-list-task.c
@@ -23,22 +23,26 @@
 #include <config.h>
 #include "glib-utils.h"
 #include "gth-main.h"
+#include "gth-overwrite-dialog.h"
 #include "gth-pixbuf-list-task.h"
 #include "pixbuf-io.h"
 
 
 struct _GthPixbufListTaskPrivate {
-	GthBrowser *browser;
-	GList      *file_list;
-	GthTask    *task;
-	gulong      task_completed;
-	gulong      task_progress;
-	gulong      task_dialog;
-	GList      *current;
-	int         n_current;
-	int         n_files;
-	GdkPixbuf  *original_pixbuf;
-	GdkPixbuf  *new_pixbuf;
+	GthBrowser           *browser;
+	GList                *file_list;
+	GthTask              *task;
+	gulong                task_completed;
+	gulong                task_progress;
+	gulong                task_dialog;
+	GList                *current;
+	int                   n_current;
+	int                   n_files;
+	GdkPixbuf            *original_pixbuf;
+	GdkPixbuf            *new_pixbuf;
+	GFile                *destination;
+	GthOverwriteMode      overwrite_mode;
+	GthOverwriteResponse  overwrite_response;
 };
 
 
@@ -52,6 +56,7 @@ gth_pixbuf_list_task_finalize (GObject *object)
 
 	self = GTH_PIXBUF_LIST_TASK (object);
 
+	_g_object_unref (self->priv->destination);
 	_g_object_unref (self->priv->original_pixbuf);
 	_g_object_unref (self->priv->new_pixbuf);
 	g_signal_handler_disconnect (self->priv->task, self->priv->task_completed);
@@ -70,11 +75,75 @@ static void process_current_file (GthPixbufListTask *self);
 static void
 process_next_file (GthPixbufListTask *self)
 {
+	self->priv->n_current++;
 	self->priv->current = self->priv->current->next;
 	process_current_file (self);
 }
 
 
+static void pixbuf_task_save_current_pixbuf (GthPixbufListTask *self,
+					     GFile             *file,
+					     gboolean           replace);
+
+
+static void
+overwrite_dialog_response_cb (GtkDialog *dialog,
+                              gint       response_id,
+                              gpointer   user_data)
+{
+	GthPixbufListTask *self = user_data;
+
+	if (response_id != GTK_RESPONSE_OK)
+		self->priv->overwrite_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
+	else
+		self->priv->overwrite_response = gth_overwrite_dialog_get_response (GTH_OVERWRITE_DIALOG (dialog));
+
+	gtk_widget_hide (GTK_WIDGET (dialog));
+	gth_task_dialog (GTH_TASK (self), FALSE);
+
+	switch (self->priv->overwrite_response) {
+	case GTH_OVERWRITE_RESPONSE_NO:
+	case GTH_OVERWRITE_RESPONSE_ALWAYS_NO:
+	case GTH_OVERWRITE_RESPONSE_UNSPECIFIED:
+		if (self->priv->overwrite_response == GTH_OVERWRITE_RESPONSE_ALWAYS_NO)
+			self->priv->overwrite_mode = GTH_OVERWRITE_SKIP;
+		process_next_file (self);
+		break;
+
+	case GTH_OVERWRITE_RESPONSE_YES:
+	case GTH_OVERWRITE_RESPONSE_ALWAYS_YES:
+		if (self->priv->overwrite_response == GTH_OVERWRITE_RESPONSE_ALWAYS_YES)
+			self->priv->overwrite_mode = GTH_OVERWRITE_OVERWRITE;
+		pixbuf_task_save_current_pixbuf (self, NULL, TRUE);
+		break;
+
+	case GTH_OVERWRITE_RESPONSE_RENAME:
+		{
+			GFile *parent;
+			GFile *new_destination;
+
+			if (self->priv->destination != NULL) {
+				parent = g_object_ref (self->priv->destination);
+			}
+			else {
+				GthFileData *file_data;
+
+				file_data = self->priv->current->data;
+				parent = g_file_get_parent (file_data->file);
+			}
+			new_destination = g_file_get_child_for_display_name (parent, gth_overwrite_dialog_get_filename (GTH_OVERWRITE_DIALOG (dialog)), NULL);
+			pixbuf_task_save_current_pixbuf (self, new_destination, FALSE);
+
+			g_object_unref (new_destination);
+			g_object_unref (parent);
+		}
+		break;
+	}
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+
 static void
 pixbuf_saved_cb (GthFileData *file_data,
 		 GError      *error,
@@ -85,7 +154,31 @@ pixbuf_saved_cb (GthFileData *file_data,
 	GList             *file_list;
 
 	if (error != NULL) {
-		gth_task_completed (GTH_TASK (self), error);
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+			if (self->priv->overwrite_mode == GTH_OVERWRITE_SKIP) {
+				process_next_file (self);
+			}
+			else  {
+				GthFileData *file_data;
+				GtkWidget   *dialog;
+
+				gth_task_dialog (GTH_TASK (self), TRUE);
+
+				file_data = self->priv->current->data;
+				dialog = gth_overwrite_dialog_new (NULL,
+								   self->priv->new_pixbuf,
+								   file_data->file,
+								   GTH_OVERWRITE_RESPONSE_YES,
+								   (self->priv->n_files == 1));
+				g_signal_connect (dialog,
+						  "response",
+						  G_CALLBACK (overwrite_dialog_response_cb),
+						  self);
+				gtk_widget_show (dialog);
+			}
+		}
+		else
+			gth_task_completed (GTH_TASK (self), error);
 		return;
 	}
 
@@ -120,9 +213,52 @@ pixbuf_task_progress_cb (GthTask    *task,
 		         double      fraction,
 		         gpointer    user_data)
 {
-	/*GthPixbufListTask *self = user_data;*/
+	GthPixbufListTask *self = user_data;
+	double             total_fraction;
+	double             file_fraction;
+
+	total_fraction =  ((double) self->priv->n_current + 1) / (self->priv->n_files + 1);
+	if (pulse)
+		file_fraction = 0.5;
+	else
+		file_fraction = fraction;
+
+	if (details == NULL) {
+		GthFileData *file_data;
+
+		file_data = self->priv->current->data;
+		details = g_file_info_get_display_name (file_data->info);
+	}
+
+	gth_task_progress (GTH_TASK (self),
+			   description,
+			   details,
+			   FALSE,
+			   total_fraction + (file_fraction / (self->priv->n_files + 1)));
+}
+
+
+static void
+pixbuf_task_save_current_pixbuf (GthPixbufListTask *self,
+				 GFile             *file,
+				 gboolean           replace)
+{
+	GthFileData *file_data;
 
-	/* FIXME */
+	if (file != NULL)
+		file_data = gth_file_data_new (file, ((GthFileData *) self->priv->current->data)->info);
+	else
+		file_data = g_object_ref (self->priv->current->data);
+	_g_object_unref (self->priv->new_pixbuf);
+	self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (self->priv->task)->dest);
+	_gdk_pixbuf_save_async (self->priv->new_pixbuf,
+				file_data,
+				gth_file_data_get_mime_type (file_data),
+				replace,
+				pixbuf_saved_cb,
+				self);
+
+	g_object_unref (file_data);
 }
 
 
@@ -132,7 +268,6 @@ pixbuf_task_completed_cb (GthTask  *task,
 			  gpointer  user_data)
 {
 	GthPixbufListTask *self = user_data;
-	GthFileData       *file_data;
 
 	if (g_error_matches (error, GTH_TASK_ERROR, GTH_TASK_ERROR_SKIP_TO_NEXT_FILE)) {
 		process_next_file (self);
@@ -144,13 +279,9 @@ pixbuf_task_completed_cb (GthTask  *task,
 		return;
 	}
 
-	file_data = self->priv->current->data;
-	self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (task)->dest);
-	_gdk_pixbuf_save_async (self->priv->new_pixbuf,
-				file_data,
-				gth_file_data_get_mime_type (file_data),
-				pixbuf_saved_cb,
-				self);
+	pixbuf_task_save_current_pixbuf (self,
+					 NULL,
+					 (self->priv->overwrite_mode == GTH_OVERWRITE_OVERWRITE));
 }
 
 
@@ -250,6 +381,8 @@ gth_pixbuf_list_task_init (GthPixbufListTask *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskPrivate);
 	self->priv->original_pixbuf = NULL;
+	self->priv->destination = NULL;
+	self->priv->overwrite_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
 }
 
 
@@ -310,3 +443,20 @@ gth_pixbuf_list_task_new (GthBrowser    *browser,
 
 	return (GthTask *) self;
 }
+
+
+void
+gth_pixbuf_list_task_set_destination (GthPixbufListTask *self,
+				      GFile             *folder)
+{
+	_g_object_unref (self->priv->destination);
+	self->priv->destination = _g_object_ref (folder);
+}
+
+
+void
+gth_pixbuf_list_task_set_overwrite_mode (GthPixbufListTask    *self,
+					 GthOverwriteMode      overwrite_mode)
+{
+	self->priv->overwrite_mode = overwrite_mode;
+}
diff --git a/gthumb/gth-pixbuf-list-task.h b/gthumb/gth-pixbuf-list-task.h
index 7931619..0f97af0 100644
--- a/gthumb/gth-pixbuf-list-task.h
+++ b/gthumb/gth-pixbuf-list-task.h
@@ -26,6 +26,7 @@
 #include <glib.h>
 #include "gth-browser.h"
 #include "gth-pixbuf-task.h"
+#include "typedefs.h"
 
 G_BEGIN_DECLS
 
@@ -49,10 +50,14 @@ struct _GthPixbufListTaskClass {
 	GthTaskClass __parent;
 };
 
-GType      gth_pixbuf_list_task_get_type  (void);
-GthTask *  gth_pixbuf_list_task_new       (GthBrowser    *browser,
-					   GList         *file_list, /* GthFileData list */
-					   GthPixbufTask *task);
+GType      gth_pixbuf_list_task_get_type            (void);
+GthTask *  gth_pixbuf_list_task_new                 (GthBrowser           *browser,
+						     GList                *file_list, /* GthFileData list */
+						     GthPixbufTask        *task);
+void       gth_pixbuf_list_task_set_destination     (GthPixbufListTask    *self,
+						     GFile                *folder);
+void       gth_pixbuf_list_task_set_overwrite_mode  (GthPixbufListTask    *self,
+						     GthOverwriteMode      overwrite_mode);
 
 G_END_DECLS
 
diff --git a/gthumb/pixbuf-io.c b/gthumb/pixbuf-io.c
index 5a7d11b..d49a2fd 100644
--- a/gthumb/pixbuf-io.c
+++ b/gthumb/pixbuf-io.c
@@ -126,6 +126,7 @@ save_current_file (SaveData *save_data)
 	g_write_file_async (file->file,
 			    file->buffer,
 			    file->buffer_size,
+			    (g_file_equal (save_data->data->file_data->file, file->file) ? save_data->data->replace : TRUE),
 			    G_PRIORITY_DEFAULT,
 			    NULL,
 			    file_saved_cb,
@@ -154,6 +155,7 @@ void
 _gdk_pixbuf_save_async (GdkPixbuf        *pixbuf,
 			GthFileData      *file_data,
 			const char       *mime_type,
+			gboolean          replace,
 			GthFileDataFunc   ready_func,
 			gpointer          ready_data)
 {
@@ -185,6 +187,7 @@ _gdk_pixbuf_save_async (GdkPixbuf        *pixbuf,
 	data->file_data = g_object_ref (file_data);
 	data->pixbuf = g_object_ref (pixbuf);
 	data->mime_type = mime_type;
+	data->replace = replace;
 	data->buffer = buffer;
 	data->buffer_size = buffer_size;
 	data->files = NULL;
diff --git a/gthumb/pixbuf-io.h b/gthumb/pixbuf-io.h
index dea8144..fd0d974 100644
--- a/gthumb/pixbuf-io.h
+++ b/gthumb/pixbuf-io.h
@@ -43,6 +43,7 @@ typedef struct {
 	GthFileData  *file_data;
 	GdkPixbuf    *pixbuf;
 	const char   *mime_type;
+	gboolean      replace;
 	void         *buffer;
 	gsize         buffer_size;
 	GList        *files; 		/* SavePixbufFile list */
@@ -53,6 +54,7 @@ char *      get_pixbuf_type_from_mime_type     (const char       *mime_type);
 void        _gdk_pixbuf_save_async             (GdkPixbuf        *pixbuf,
 						GthFileData      *file_data,
 						const char       *mime_type,
+						gboolean          replace,
 						GthFileDataFunc   ready_func,
 						gpointer          data);
 GdkPixbuf * gth_pixbuf_new_from_file           (GthFileData      *file,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]