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 ();