From eb8f121709c37b38ada6cee9eb6f27b9b4767027 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 13 May 2021 12:41:22 +0200 Subject: [PATCH] Add ability to export to an external editor within the same folder as the original file - issue 6195 (#6232) * import and change the art code -thanks to Alberto * Possible fixed for white space in folder * Added verbose when white-space * Replace WS only if windows and Gimp * Fixed Windows and Gimp bug for external editor - thanks to Lawrence37 * Fix LGTM alert for reused variable name Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> --- rtdata/languages/default | 6 ++++ rtengine/procparams.cc | 2 +- rtengine/procparams.h | 1 + rtgui/editorpanel.cc | 35 +++++++++++++++++----- rtgui/extprog.cc | 4 +-- rtgui/options.cc | 30 +++++++++++++++++++ rtgui/options.h | 10 +++++++ rtgui/preferences.cc | 65 +++++++++++++++++++++++++++++++++++++++- rtgui/preferences.h | 8 +++++ 9 files changed, 149 insertions(+), 12 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 7fc3a6f40..150d16705 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1762,6 +1762,12 @@ PREFERENCES_DIRSOFTWARE;Installation directory PREFERENCES_EDITORCMDLINE;Custom command line PREFERENCES_EDITORLAYOUT;Editor layout PREFERENCES_EXTERNALEDITOR;External Editor +PREFERENCES_EXTEDITOR_DIR;Output directory +PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir +PREFERENCES_EXTEDITOR_DIR_CURRENT;Same as input image +PREFERENCES_EXTEDITOR_DIR_CUSTOM;Custom +PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output +PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Bypass output profile PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser PREFERENCES_FLATFIELDFOUND;Found diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 35ba742f3..5768f9c3e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2206,6 +2206,7 @@ bool ResizeParams::operator !=(const ResizeParams& other) const } const Glib::ustring ColorManagementParams::NoICMString = Glib::ustring("No ICM: sRGB output"); +const Glib::ustring ColorManagementParams::NoProfileString = Glib::ustring("(none)"); ColorManagementParams::ColorManagementParams() : inputProfile("(cameraICC)"), @@ -6505,7 +6506,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo {RI_RELATIVE, "Relative"}, {RI_SATURATION, "Saturation"}, {RI_ABSOLUTE, "Absolute"} - }, icm.outputIntent, keyFile diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 07db23a32..ef14a6e05 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1718,6 +1718,7 @@ struct ColorManagementParams { bool outputBPC; static const Glib::ustring NoICMString; + static const Glib::ustring NoProfileString; ColorManagementParams(); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 7f2352b5a..a365a8599 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1972,6 +1972,9 @@ void EditorPanel::sendToGimpPressed () // develop image rtengine::procparams::ProcParams pparams; ipc->getParams (&pparams); + if (options.editor_bypass_output_profile) { + pparams.icm.outputProfile = rtengine::procparams::ColorManagementParams::NoProfileString; + } rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); ProgressConnector *ld = new ProgressConnector(); ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ), @@ -2045,24 +2048,40 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p if (img) { // get file name base - const Glib::ustring shortname = removeExtension (Glib::path_get_basename (fname)); - const Glib::ustring dirname = Glib::get_tmp_dir (); - const Glib::ustring lfname = Glib::build_filename (dirname, shortname); + Glib::ustring shortname = removeExtension(Glib::path_get_basename(fname)); + Glib::ustring dirname; + switch (options.editor_out_dir) { + case Options::EDITOR_OUT_DIR_CURRENT: + dirname = Glib::path_get_dirname(fname); + break; + case Options::EDITOR_OUT_DIR_CUSTOM: + dirname = options.editor_custom_out_dir; + break; + default: // Options::EDITOR_OUT_DIR_TEMP + dirname = Glib::get_tmp_dir(); + break; + } + Glib::ustring fullFileName = Glib::build_filename(dirname, shortname); SaveFormat sf; sf.format = "tif"; - sf.tiffBits = 16; - sf.tiffFloat = false; + if (options.editor_float32) { + sf.tiffBits = 32; + sf.tiffFloat = true; + } else { + sf.tiffBits = 16; + sf.tiffFloat = false; + } + sf.tiffUncompressed = true; sf.saveParams = true; - Glib::ustring fileName = Glib::ustring::compose ("%1.%2", lfname, sf.format); + Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fullFileName, sf.format); // TODO: Just list all file with a suitable name instead of brute force... int tries = 1; - while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) { - fileName = Glib::ustring::compose ("%1-%2.%3", lfname, tries, sf.format); + fileName = Glib::ustring::compose ("%1-%2.%3", fullFileName, tries, sf.format); tries++; } diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 57d57ecd8..34dd35e54 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -276,8 +276,8 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename (options.gimpDir, "bin", Glib::ustring::compose (Glib::ustring("gimp-2.%1.exe"), ver)); - auto lsuccess = ShellExecute( NULL, "open", executable.c_str(), fileName.c_str(), NULL, SW_SHOWNORMAL ); - + Glib::ustring escapedFileName = Glib::ustring::compose ("\"%1\"", fileName); + auto lsuccess = ShellExecute( NULL, "open", executable.c_str(), escapedFileName.c_str(), NULL, SW_SHOWNORMAL ); if (reinterpret_cast(lsuccess) > 32) { return true; } diff --git a/rtgui/options.cc b/rtgui/options.cc index ce03db434..e17b2f074 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -415,6 +415,10 @@ void Options::setDefaults() customEditorProg = ""; CPBKeys = CPBKT_TID; editorToSendTo = 1; + editor_out_dir = EDITOR_OUT_DIR_TEMP; + editor_custom_out_dir = ""; + editor_float32 = false; + editor_bypass_output_profile = false; favoriteDirs.clear(); tpOpen.clear(); autoSaveTpOpen = true; @@ -824,6 +828,28 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "CustomEditor")) { customEditorProg = keyFile.get_string("External Editor", "CustomEditor"); } + + if (keyFile.has_key("External Editor", "OutputDir")) { + int v = keyFile.get_integer("External Editor", "OutputDir"); + if (v < int(EDITOR_OUT_DIR_TEMP) || v > int(EDITOR_OUT_DIR_CUSTOM)) { + editor_out_dir = EDITOR_OUT_DIR_TEMP; + } else { + editor_out_dir = EditorOutDir(v); + } + } + + if (keyFile.has_key("External Editor", "CustomOutputDir")) { + editor_custom_out_dir = keyFile.get_string("External Editor", "CustomOutputDir"); + } + + if (keyFile.has_key("External Editor", "Float32")) { + editor_float32 = keyFile.get_boolean("External Editor", "Float32"); + } + + if (keyFile.has_key("External Editor", "BypassOutputProfile")) { + editor_bypass_output_profile = keyFile.get_boolean("External Editor", "BypassOutputProfile"); + } + } if (keyFile.has_group("Output")) { @@ -2115,6 +2141,10 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("External Editor", "GimpDir", gimpDir); keyFile.set_string("External Editor", "PhotoshopDir", psDir); keyFile.set_string("External Editor", "CustomEditor", customEditorProg); + keyFile.set_integer("External Editor", "OutputDir", int(editor_out_dir)); + keyFile.set_string("External Editor", "CustomOutputDir", editor_custom_out_dir); + keyFile.set_boolean("External Editor", "Float32", editor_float32); + keyFile.set_boolean("External Editor", "BypassOutputProfile", editor_bypass_output_profile); keyFile.set_boolean("File Browser", "BrowseOnlyRaw", fbOnlyRaw); keyFile.set_boolean("File Browser", "BrowserShowsDate", fbShowDateTime); diff --git a/rtgui/options.h b/rtgui/options.h index 03b551efe..52e1c0270 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -280,6 +280,16 @@ public: Glib::ustring CPBPath; // Custom Profile Builder's path CPBKeyType CPBKeys; // Custom Profile Builder's key type int editorToSendTo; + enum EditorOutDir { + EDITOR_OUT_DIR_TEMP, + EDITOR_OUT_DIR_CURRENT, + EDITOR_OUT_DIR_CUSTOM + }; + EditorOutDir editor_out_dir; // output directory for "open in external editor" + Glib::ustring editor_custom_out_dir; + bool editor_float32; + bool editor_bypass_output_profile; + int maxThumbnailHeight; int maxThumbnailWidth; std::size_t maxCacheEntries; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 9d9603297..11e9d34fa 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1244,7 +1244,48 @@ Gtk::Widget* Preferences::getGeneralPanel() externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1); #endif - fdg->add(*externaleditorGrid); + + // fdg->add(*externaleditorGrid); + editor_dir_temp = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_TEMP"))); + editor_dir_current = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_CURRENT"))); + editor_dir_custom = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_CUSTOM") + ": ")); + editor_dir_custom_path = Gtk::manage(new MyFileChooserButton("", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + ge = editor_dir_temp->get_group(); + editor_dir_current->set_group(ge); + editor_dir_custom->set_group(ge); + + editor_float32 = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_EXTEDITOR_FLOAT32"))); + editor_bypass_output_profile = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE"))); + { + Gtk::Frame *f = Gtk::manage(new Gtk::Frame(M("PREFERENCES_EXTEDITOR_DIR"))); + setExpandAlignProperties(f, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + Gtk::Box *vb = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + vb->pack_start(*editor_dir_temp); + vb->pack_start(*editor_dir_current); + Gtk::Box *hb = Gtk::manage(new Gtk::Box()); + hb->pack_start(*editor_dir_custom, Gtk::PACK_SHRINK); + hb->pack_start(*editor_dir_custom_path, Gtk::PACK_EXPAND_WIDGET, 2); + vb->pack_start(*hb); + f->add(*vb); + + hb = Gtk::manage(new Gtk::Box()); + hb->pack_start(*externaleditorGrid); + hb->pack_start(*f, Gtk::PACK_EXPAND_WIDGET, 4); + + vb = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + vb->pack_start(*hb); + hb = Gtk::manage(new Gtk::Box()); + //I disabled these 2 functionnalities...easy to enable +// hb->pack_start(*editor_float32, Gtk::PACK_SHRINK); +// hb->pack_start(*editor_bypass_output_profile, Gtk::PACK_SHRINK, 4); + vb->pack_start(*hb, Gtk::PACK_SHRINK, 4); + + vb->show_all_children(); + vb->show(); + fdg->add(*vb); + } + + vbGeneral->attach_next_to (*fdg, *fclip, Gtk::POS_BOTTOM, 2, 1); langAutoDetectConn = ckbLangAutoDetect->signal_toggled().connect(sigc::mem_fun(*this, &Preferences::langAutoDetectToggled)); tconn = themeCBT->signal_changed().connect ( sigc::mem_fun (*this, &Preferences::themeChanged) ); @@ -1727,6 +1768,17 @@ void Preferences::storePreferences() moptions.editorToSendTo = 3; } + if (editor_dir_temp->get_active()) { + moptions.editor_out_dir = Options::EDITOR_OUT_DIR_TEMP; + } else if (editor_dir_current->get_active()) { + moptions.editor_out_dir = Options::EDITOR_OUT_DIR_CURRENT; + } else { + moptions.editor_out_dir = Options::EDITOR_OUT_DIR_CUSTOM; + } + moptions.editor_custom_out_dir = editor_dir_custom_path->get_filename(); + moptions.editor_float32 = editor_float32->get_active(); + moptions.editor_bypass_output_profile = editor_bypass_output_profile->get_active(); + moptions.CPBPath = txtCustProfBuilderPath->get_text(); moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); @@ -2010,6 +2062,17 @@ void Preferences::fillPreferences() #endif editorToSendTo->set_text(moptions.customEditorProg); + editor_dir_temp->set_active(moptions.editor_out_dir == Options::EDITOR_OUT_DIR_TEMP); + editor_dir_current->set_active(moptions.editor_out_dir == Options::EDITOR_OUT_DIR_CURRENT); + editor_dir_custom->set_active(moptions.editor_out_dir == Options::EDITOR_OUT_DIR_CUSTOM); + if (Glib::file_test(moptions.editor_custom_out_dir, Glib::FILE_TEST_IS_DIR)) { + editor_dir_custom_path->set_current_folder(moptions.editor_custom_out_dir); + } else { + editor_dir_custom_path->set_current_folder(Glib::get_tmp_dir()); + } + editor_float32->set_active(moptions.editor_float32); + editor_bypass_output_profile->set_active(moptions.editor_bypass_output_profile); + txtCustProfBuilderPath->set_text(moptions.CPBPath); custProfBuilderLabelType->set_active(moptions.CPBKeys); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index df4e3327a..d5e888251 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -101,6 +101,14 @@ class Preferences final : Gtk::RadioButton* edGimp; Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; + + Gtk::RadioButton *editor_dir_temp; + Gtk::RadioButton *editor_dir_current; + Gtk::RadioButton *editor_dir_custom; + MyFileChooserButton *editor_dir_custom_path; + Gtk::CheckButton *editor_float32; + Gtk::CheckButton *editor_bypass_output_profile; + MyFileChooserButton* darkFrameDir; MyFileChooserButton* flatFieldDir; MyFileChooserButton* clutsDir;