diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK)
index 8806f0f11..b1c58da85 100644
--- a/rtdata/languages/English (UK)
+++ b/rtdata/languages/English (UK)
@@ -712,3 +712,13 @@ HISTOGRAM_BUTTON_L;L
###
CURVEEDITOR_NURBS;Control cage
+
+###
+
+MAIN_BUTTON_SAVE_TOOLTIP;Save current image Ctrl+S
+MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add current image to processing queue Ctrl+Q
+MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor Ctrl+E
+
+###
+
+SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US)
index cfa30f8d8..059aaa914 100644
--- a/rtdata/languages/English (US)
+++ b/rtdata/languages/English (US)
@@ -721,3 +721,6 @@ MAIN_BUTTON_SAVE_TOOLTIP;Save current image Ctrl+S
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add current image to processing queue Ctrl+Q
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor Ctrl+E
+###
+
+SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index 07d2f5b4a..0becaf548 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -723,3 +723,6 @@ MAIN_BUTTON_SAVE_TOOLTIP;Enregistrer l'image courante Ctrl+S
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Ajouter l'image courante à la file de traitement Ctrl+Q
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Éditer l'image courante dans l'éditeur externe Ctrl+E
+###
+
+SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà
diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc
index 61713d845..898e319bc 100644
--- a/rtgui/batchqueue.cc
+++ b/rtgui/batchqueue.cc
@@ -204,7 +204,10 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
err = img->saveAsJPEG (fname, saveFormat.jpegQuality);
img->free ();
if (!err && saveFormat.saveParams)
- processing->params.save (removeExtension(fname) + paramFileExtension);
+ // We keep the extension to avoid overwriting the profile when we have
+ // the same output filename with different extension
+ //processing->params.save (removeExtension(fname) + paramFileExtension);
+ processing->params.save (fname + paramFileExtension);
if (processing->thumbnail) {
processing->thumbnail->imageDeveloped ();
processing->thumbnail->imageRemovedFromQueue ();
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index a60e7a22f..3c1e00190 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -642,7 +642,10 @@ bool EditorPanel::idle_imageSaved(ProgressConnector *pc,rtengine::IImage16*
if (sf.saveParams) {
rtengine::procparams::ProcParams pparams;
ipc->getParams (&pparams);
- pparams.save (removeExtension (fname) + ".out" + paramFileExtension);
+ // We keep the extension to avoid overwriting the profile when we have
+ // the same output filename with different extension
+ //pparams.save (removeExtension (fname) + ".out" + paramFileExtension);
+ pparams.save (fname + ".out" + paramFileExtension);
}
}else{
Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image saving\n";
@@ -659,51 +662,82 @@ bool EditorPanel::idle_imageSaved(ProgressConnector *pc,rtengine::IImage16*
void EditorPanel::saveAsPressed () {
- // obtaining short name without extension
- saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName())));
- saveAsDialog->run ();
- Glib::ustring fname = saveAsDialog->getFileName ();
- if (fname=="")
- return;
+ bool fnameOK = false;
+ Glib::ustring fname;
- options.lastSaveAsPath = saveAsDialog->getDirectory ();
- options.saveAsDialogWidth = saveAsDialog->get_width();
- options.saveAsDialogHeight = saveAsDialog->get_height();
+ saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName())));
+ do {
+ saveAsDialog->run ();
+ fname = saveAsDialog->getFileName ();
+ if (fname=="")
+ return;
+
+ options.lastSaveAsPath = saveAsDialog->getDirectory ();
+ options.saveAsDialogWidth = saveAsDialog->get_width();
+ options.saveAsDialogHeight = saveAsDialog->get_height();
+
+ SaveFormat sf = saveAsDialog->getFormat ();
- SaveFormat sf = saveAsDialog->getFormat ();
- if (getExtension (fname)!=sf.format)
- fname = fname + "." + sf.format;
-
options.saveFormat = sf;
+ options.autoSuffix = saveAsDialog->getAutoSuffix();
- if (saveAsDialog->getImmediately ()) {
- // check if it exists
- if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
- Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "";
- Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
- int response = msgd.run ();
- if (response==Gtk::RESPONSE_NO)
- return;
- }
- // save image
- rtengine::procparams::ProcParams pparams;
- ipc->getParams (&pparams);
- rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
- fname = removeExtension (fname);
- ProgressConnector *ld = new ProgressConnector();
- ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
- sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_saveImage ),ld,fname,sf,false ));
- saveimgas->set_sensitive(false);
- sendtogimp->set_sensitive(false);
- }
- else {
- BatchQueueEntry* bqe = createBatchQueueEntry ();
- bqe->outFileName = fname;
- bqe->saveFormat = saveAsDialog->getFormat ();
- parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
- }
- // ask parent to redraw file browser
- // ... or does it automatically when the tab is switched to it
+ if (saveAsDialog->getImmediately ()) {
+ // separate filename and the path to the destination directory
+ Glib::ustring dstdir = Glib::path_get_dirname (fname);
+ Glib::ustring dstfname = Glib::path_get_basename (removeExtension(fname));
+
+ if (saveAsDialog->getAutoSuffix()) {
+
+ Glib::ustring fnameTemp;
+ for (int tries=0; tries<100; tries++) {
+ if (tries==0)
+ fnameTemp = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), sf.format);
+ else
+ fnameTemp = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, sf.format);
+
+ if (!Glib::file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) {
+ fname = fnameTemp;
+ fnameOK = true;
+ break;
+ }
+ }
+ }
+ // check if it exists
+ if (!fnameOK) {
+ fname = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), sf.format);
+ if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
+ Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "";
+ Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
+ int response = msgd.run ();
+ if (response==Gtk::RESPONSE_YES)
+ fnameOK = true;
+ }
+ else fnameOK = true;
+ }
+
+ if (fnameOK) {
+ // save image
+ rtengine::procparams::ProcParams pparams;
+ ipc->getParams (&pparams);
+ rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
+ fname = removeExtension (fname);
+ ProgressConnector *ld = new ProgressConnector();
+ ld->startFunc(sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, parent->getProgressListener() ),
+ sigc::bind(sigc::mem_fun( *this,&EditorPanel::idle_saveImage ),ld,fname,sf,false ));
+ saveimgas->set_sensitive(false);
+ sendtogimp->set_sensitive(false);
+ }
+ }
+ else {
+ BatchQueueEntry* bqe = createBatchQueueEntry ();
+ bqe->outFileName = fname;
+ bqe->saveFormat = saveAsDialog->getFormat ();
+ parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
+ fnameOK = true;
+ }
+ // ask parent to redraw file browser
+ // ... or does it automatically when the tab is switched to it
+ } while (!fnameOK);
}
void EditorPanel::queueImgPressed () {
diff --git a/rtgui/options.cc b/rtgui/options.cc
index 72be1277f..88164e918 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -90,6 +90,7 @@ void Options::setDefaults () {
maxCacheEntries = 10000;
thumbnailFormat = FT_Custom16;
thumbInterp = 1;
+ autoSuffix = false;
saveParamsFile = false;
saveParamsCache = true;
paramsLoadLocation = PLL_Cache;
@@ -198,6 +199,7 @@ if (keyFile.has_group ("Output")) {
if (keyFile.has_key ("Output", "Path")) savePathTemplate = keyFile.get_string ("Output", "Path");
if (keyFile.has_key ("Output", "PathTemplate")) savePathTemplate = keyFile.get_string ("Output", "PathTemplate");
if (keyFile.has_key ("Output", "PathFolder")) savePathFolder = keyFile.get_string ("Output", "PathFolder");
+ if (keyFile.has_key ("Output", "AutoSuffix")) autoSuffix = keyFile.get_boolean("Output", "AutoSuffix");
if (keyFile.has_key ("Output", "UsePathTemplate")) saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate");
if (keyFile.has_key ("Output", "LastSaveAsPath")) lastSaveAsPath = keyFile.get_string ("Output", "LastSaveAsPath");
}
@@ -357,6 +359,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams);
keyFile.set_string ("Output", "PathTemplate", savePathTemplate);
keyFile.set_string ("Output", "PathFolder", savePathFolder);
+ keyFile.set_boolean("Output", "AutoSuffix", autoSuffix);
keyFile.set_boolean("Output", "UsePathTemplate", saveUsePathTemplate);
keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath);
diff --git a/rtgui/options.h b/rtgui/options.h
index e7d05e78c..75ff029fb 100644
--- a/rtgui/options.h
+++ b/rtgui/options.h
@@ -95,6 +95,7 @@ class Options {
Glib::ustring language;
Glib::ustring theme;
static Glib::ustring cacheBaseDir;
+ bool autoSuffix;
bool saveParamsFile;
bool saveParamsCache;
PPLoadLocation paramsLoadLocation;
diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc
index 6bfaa815d..5d6f0a99d 100644
--- a/rtgui/previewwindow.cc
+++ b/rtgui/previewwindow.cc
@@ -39,11 +39,7 @@ void PreviewWindow::on_realize () {
Gtk::DrawingArea::on_realize ();
add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
cCropMoving = new Gdk::Cursor (Gdk::FLEUR);
-#ifdef _WIN32
- cNormal = new Gdk::Cursor (Gdk::LAST_CURSOR);
-#else
cNormal = new Gdk::Cursor (Gdk::ARROW);
-#endif
}
void PreviewWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) {
diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc
index 021a54207..d985100cf 100644
--- a/rtgui/saveasdlg.cc
+++ b/rtgui/saveasdlg.cc
@@ -22,6 +22,8 @@
extern Options options;
SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
+ set_title(M("GENERAL_SAVE"));
+
Gtk::VBox* vbox = get_vbox ();
fchooser = new Gtk::FileChooserWidget (Gtk::FILE_CHOOSER_ACTION_SAVE);
@@ -41,6 +43,16 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
Gtk::HSeparator* hsep1 = new Gtk::HSeparator ();
vbox->pack_start (*hsep1, Gtk::PACK_SHRINK, 2);
+// Unique filename option
+// ~~~~~~~~~~~~~~~~~~~~~~
+ autoSuffix = new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX"));
+ autoSuffix->set_active(options.autoSuffix);
+
+ vbox->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4);
+
+ Gtk::HSeparator* hsep2 = new Gtk::HSeparator ();
+ vbox->pack_start (*hsep2, Gtk::PACK_SHRINK, 2);
+
// Output Options
// ~~~~~~~~~~~~~~
formatOpts = new SaveFormatPanel ();
@@ -49,8 +61,8 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
vbox->pack_start (*formatOpts, Gtk::PACK_SHRINK, 4);
- Gtk::HSeparator* hsep2 = new Gtk::HSeparator ();
- vbox->pack_start (*hsep2, Gtk::PACK_SHRINK, 2);
+ Gtk::HSeparator* hsep3 = new Gtk::HSeparator ();
+ vbox->pack_start (*hsep3, Gtk::PACK_SHRINK, 2);
// queue/immediate
// ~~~~~~~~~~~~~
@@ -83,6 +95,11 @@ SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) {
show_all_children ();
}
+bool SaveAsDialog::getAutoSuffix () {
+
+ return autoSuffix->get_active();
+}
+
bool SaveAsDialog::getImmediately () {
return immediately->get_active ();
diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h
index 7df8d8392..1914461c4 100644
--- a/rtgui/saveasdlg.h
+++ b/rtgui/saveasdlg.h
@@ -28,6 +28,7 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
protected:
Gtk::FileChooserWidget* fchooser;
+ Gtk::CheckButton* autoSuffix;
SaveFormatPanel* formatOpts;
Glib::ustring fname;
Gtk::FileFilter filter_jpg;
@@ -43,6 +44,7 @@ class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener {
Glib::ustring getFileName ();
Glib::ustring getDirectory ();
SaveFormat getFormat ();
+ bool getAutoSuffix ();
bool getImmediately ();
bool getToHeadOfQueue ();
bool getToTailOfQueue ();