[shotwell: 1/3] Closes: https://gitlab.gnome.org/GNOME/shotwell/-/issues/92
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell: 1/3] Closes: https://gitlab.gnome.org/GNOME/shotwell/-/issues/92
- Date: Sun, 31 Jul 2022 07:31:16 +0000 (UTC)
commit 0c92be2913f4fb43492536aed6f53407ec1f9ef8
Author: maf <maf tkrat org>
Date: Mon Jul 25 11:39:14 2022 +0200
Closes: https://gitlab.gnome.org/GNOME/shotwell/-/issues/92
src/AppWindow.vala | 13 +++++-----
src/Exporter.vala | 74 +++++++++++++++++++++++++++++++++++++++---------------
src/util/file.vala | 8 ++++--
3 files changed, 66 insertions(+), 29 deletions(-)
---
diff --git a/src/AppWindow.vala b/src/AppWindow.vala
index 608d1807..130f5e03 100644
--- a/src/AppWindow.vala
+++ b/src/AppWindow.vala
@@ -541,22 +541,21 @@ public abstract class AppWindow : PageWindow {
return (Gtk.ResponseType) response;
}
- public static Gtk.ResponseType negate_affirm_all_cancel_question(string message,
- string negative, string affirmative, string affirmative_all, string? title = null,
- Gtk.Window? parent = null) {
+ public static int six_alt_question(string message,
+ string alt1, string alt2, string alt3, string alt4, string alt5, string alt6,
+ string? title = null, Gtk.Window? parent = null) {
Gtk.MessageDialog dialog = new Gtk.MessageDialog((parent != null) ? parent : get_instance(),
Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE, "%s", message);
dialog.title = (title != null) ? title : Resources.APP_TITLE;
- dialog.add_buttons(negative, Gtk.ResponseType.NO, affirmative, Gtk.ResponseType.YES,
- affirmative_all, Gtk.ResponseType.APPLY, _("_Cancel"), Gtk.ResponseType.CANCEL);
+ dialog.add_buttons(alt1, 1, alt2, 2, alt3, 3, alt4, 4, alt5, 5, alt6, 6);
int response = dialog.run();
dialog.destroy();
- return (Gtk.ResponseType) response;
+ return response;
}
-
+
public static void database_error(DatabaseError err) {
panic(_("A fatal error occurred when accessing Shotwell’s library. Shotwell cannot
continue.\n\n%s").printf(
err.message));
diff --git a/src/Exporter.vala b/src/Exporter.vala
index b9596f5d..6b47fe97 100644
--- a/src/Exporter.vala
+++ b/src/Exporter.vala
@@ -55,7 +55,9 @@ public class Exporter : Object {
YES,
NO,
CANCEL,
- REPLACE_ALL
+ REPLACE_ALL,
+ RENAME,
+ RENAME_ALL,
}
public delegate void CompletionCallback(Exporter exporter, bool is_cancelled);
@@ -116,6 +118,7 @@ public class Exporter : Object {
private unowned ProgressMonitor? monitor = null;
private Cancellable cancellable;
private bool replace_all = false;
+ private bool rename_all = false;
private bool aborted = false;
private ExportFormatParameters export_params;
@@ -193,6 +196,7 @@ public class Exporter : Object {
private bool process_queue() {
int submitted = 0;
+ Gee.HashSet<string> used = new Gee.HashSet<string>();
foreach (MediaSource source in to_export) {
File? use_source_file = null;
PhotoFileFormat real_export_format = PhotoFileFormat.get_system_default_format();
@@ -227,7 +231,7 @@ public class Exporter : Object {
if (export_dir == null) {
try {
bool collision;
- dest = generate_unique_file(AppDirs.get_temp_dir(), basename, out collision);
+ dest = generate_unique_file(AppDirs.get_temp_dir(), basename, out collision, used);
} catch (Error err) {
AppWindow.error_message(_("Unable to generate a temporary file for %s: %s").printf(
source.get_file().get_basename(), err.message));
@@ -236,17 +240,30 @@ public class Exporter : Object {
}
} else {
dest = dir.get_child(basename);
+ bool rename = false;
- if (!replace_all && dest.query_exists(null)) {
- switch (overwrite_callback(this, dest)) {
+ if (!replace_all && (dest.query_exists(null) || used.contains(basename))) {
+ if (rename_all) {
+ rename = true;
+ } else {
+ switch (overwrite_callback(this, dest)) {
case Overwrite.YES:
// continue
- break;
+ break;
case Overwrite.REPLACE_ALL:
replace_all = true;
- break;
-
+ break;
+
+ case Overwrite.RENAME:
+ rename = true;
+ break;
+
+ case Overwrite.RENAME_ALL:
+ rename = true;
+ rename_all = true;
+ break;
+
case Overwrite.CANCEL:
cancellable.cancel();
@@ -264,10 +281,22 @@ public class Exporter : Object {
}
continue;
+ }
+ }
+ if (rename) {
+ try {
+ bool collision;
+ dest = generate_unique_file(dir, basename, out collision, used);
+ } catch (Error err) {
+ AppWindow.error_message(_("Unable to generate a temporary file for %s:
%s").printf(
+ source.get_file().get_basename(), err.message));
+ break;
+ }
}
}
}
+ used.add(dest.get_basename());
workers.enqueue(new ExportJob(this, source, dest, scaling, export_params.quality,
real_export_format, cancellable, export_params.mode == ExportFormatMode.UNMODIFIED,
export_params.export_metadata));
submitted++;
@@ -315,29 +344,34 @@ public class ExporterUI {
private Exporter.Overwrite on_export_overwrite(Exporter exporter, File file) {
progress_dialog.set_modal(false);
string question = _("File %s already exists. Replace?").printf(file.get_basename());
- Gtk.ResponseType response = AppWindow.negate_affirm_all_cancel_question(question,
- _("_Skip"), _("_Replace"), _("Replace _All"), _("Export"));
+ int response = AppWindow.six_alt_question(question,
+ _("_Skip"), _("Rename"), _("Rename All"),_("_Replace"),
_("Replace _All"), _("_Cancel"), _("Export"));
progress_dialog.set_modal(true);
switch (response) {
- case Gtk.ResponseType.APPLY:
- return Exporter.Overwrite.REPLACE_ALL;
+ case 2:
+ return Exporter.Overwrite.RENAME;
- case Gtk.ResponseType.YES:
- return Exporter.Overwrite.YES;
+ case 3:
+ return Exporter.Overwrite.RENAME_ALL;
- case Gtk.ResponseType.CANCEL:
- return Exporter.Overwrite.CANCEL;
+ case 4:
+ return Exporter.Overwrite.YES;
- case Gtk.ResponseType.NO:
- default:
- return Exporter.Overwrite.NO;
+ case 5:
+ return Exporter.Overwrite.REPLACE_ALL;
+
+ case 6:
+ return Exporter.Overwrite.CANCEL;
+
+ case 1:
+ default:
+ return Exporter.Overwrite.NO;
}
}
private bool on_export_failed(Exporter exporter, File file, int remaining, Error err) {
return export_error_dialog(file, remaining > 0) != Gtk.ResponseType.CANCEL;
}
-}
-
+}
\ No newline at end of file
diff --git a/src/util/file.vala b/src/util/file.vala
index c6609d4c..838a0278 100644
--- a/src/util/file.vala
+++ b/src/util/file.vala
@@ -31,9 +31,11 @@ public bool claim_file(File file) throws Error {
// same or similar as what has been requested (adds numerals to the end of the name until a unique
// one has been found). The file may exist when this function returns, and it should be
// overwritten. It does *not* attempt to create the parent directory, however.
+// The used parameter allows you to pass in a collection of names which should be deemed to be
+// already claimed but which may not yet exist in the file system.
//
// This function is thread-safe.
-public File? generate_unique_file(File dir, string basename, out bool collision) throws Error {
+public File? generate_unique_file(File dir, string basename, out bool collision, Gee.Collection<string>?
used = null) throws Error {
// create the file to atomically "claim" it
File file = dir.get_child(basename);
if (claim_file(file)) {
@@ -51,7 +53,9 @@ public File? generate_unique_file(File dir, string basename, out bool collision)
// generate a unique filename
for (int ctr = 1; ctr < int.MAX; ctr++) {
string new_name = (ext != null) ? "%s_%d.%s".printf(name, ctr, ext) : "%s_%d".printf(name, ctr);
-
+ if (used != null && used.contains(new_name)) {
+ continue;
+ }
file = dir.get_child(new_name);
if (claim_file(file))
return file;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]