From e8536298540560e78375d153a0991343256542c8 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 26 Dec 2015 12:14:09 +0100 Subject: [PATCH] Move the external command helper into the external program store singleton. --- rtengine/safegtk.cc | 34 ----- rtengine/safegtk.h | 3 - rtgui/editorpanel.cc | 92 +------------ rtgui/extprog.cc | 311 ++++++++++++++++++++++++++++++------------- rtgui/extprog.h | 44 ++++-- rtgui/filebrowser.cc | 16 +-- rtgui/filebrowser.h | 2 +- rtgui/thumbnail.cc | 3 +- 8 files changed, 269 insertions(+), 236 deletions(-) diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc index 6e6ac99ae..ef15a4d3a 100644 --- a/rtengine/safegtk.cc +++ b/rtengine/safegtk.cc @@ -80,40 +80,6 @@ std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str) return str; } -bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) -{ - std::string cmd; - bool success = false; - - try { - cmd = Glib::filename_from_utf8(cmd_utf8); - printf ("command line: %s\n", cmd.c_str()); - Glib::spawn_command_line_async (cmd.c_str()); - success = true; - } catch (Glib::Exception& ex) { - printf ("%s\n", ex.what().c_str()); - } - - return success; -} - -bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8) -{ - int exitStatus = -1; - - try { - //cmd = Glib::filename_from_utf8(cmd_utf8); - printf ("command line: %s\n", cmd_utf8.c_str()); - - // if it crashes here on windows, make sure you have the GTK runtime files gspawn-win32-helper*.exe files in RT directory - Glib::spawn_command_line_sync (cmd_utf8, NULL, NULL, &exitStatus); - } catch (Glib::Exception& ex) { - printf ("%s\n", ex.what().c_str()); - } - - return (exitStatus == 0); -} - // Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking) // (Important on Windows to prevent Explorer to crash RT when parallel scanning e.g. a currently written image file) FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname) diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h index 07553632c..560f1700c 100644 --- a/rtengine/safegtk.h +++ b/rtengine/safegtk.h @@ -5,9 +5,6 @@ #include #include -bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8); -bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8); - Glib::ustring safe_filename_to_utf8 (const std::string& src); Glib::ustring safe_locale_to_utf8 (const std::string& src); // from rtengine std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index e033c3ebb..2a699edc6 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1740,99 +1740,21 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc, rtengine::IImage16 parent->setProgressStr(""); parent->setProgress(0.); bool success = false; - Glib::ustring cmdLine; - Glib::ustring executable; - // start gimp if (options.editorToSendTo == 1) { -#ifdef WIN32 - executable = Glib::build_filename (Glib::build_filename(options.gimpDir, "bin"), "gimp-win-remote"); - cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" gimp-2.4.exe ") + Glib::ustring("\"") + filename + Glib::ustring("\""); - - if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) { - success = safe_spawn_command_line_async (cmdLine); - } - -#elif defined __APPLE__ - cmdLine = Glib::ustring("open -a /Applications/GIMP.app \'") + filename + Glib::ustring("\'"); - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#else - cmdLine = Glib::ustring("gimp \"") + filename + Glib::ustring("\""); - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#endif - - if (!success) { -#ifdef WIN32 - int ver = 12; - - while (!success && ver) { - executable = Glib::build_filename (Glib::build_filename(options.gimpDir, "bin"), Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); - - if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) { - cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + filename + Glib::ustring("\""); - success = safe_spawn_command_line_async (cmdLine); - } - - ver--; - } - -#elif defined __APPLE__ - cmdLine = Glib::ustring("open -a /Applications/Gimp.app/Contents/Resources/start \'") + filename + Glib::ustring("\'"); - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#else - cmdLine = Glib::ustring("gimp-remote \"") + filename + Glib::ustring("\""); - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#endif - } + success = ExtProgStore::openInGimp (filename); } else if (options.editorToSendTo == 2) { -#ifdef WIN32 - executable = Glib::build_filename(options.psDir, "Photoshop.exe"); - - if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) { - cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + filename + Glib::ustring("\""); - success = safe_spawn_command_line_async (cmdLine); - } - -#else -#ifdef __APPLE__ - cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir, "Photoshop.app\' ") + Glib::ustring("\'") + filename + Glib::ustring("\'"); -#else - cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + Glib::ustring("\" \"") + filename + Glib::ustring("\""); -#endif - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#endif + success = ExtProgStore::openInPhotoshop (filename); } else if (options.editorToSendTo == 3) { -#ifdef WIN32 - - if ( safe_file_test(options.customEditorProg, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) { - cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + filename + Glib::ustring("\""); - success = safe_spawn_command_line_async (cmdLine); - } - -#else -#ifdef __APPLE__ - cmdLine = options.customEditorProg + Glib::ustring(" \"") + filename + Glib::ustring("\""); -#else - cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + filename + Glib::ustring("\""); -#endif - success = safe_spawn_command_line_async (cmdLine); - std::cout << cmdLine << std::endl; -#endif + success = ExtProgStore::openInCustomEditor (filename); } if (!success) { - Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - msgd->set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); - msgd->set_title (M("MAIN_BUTTON_SENDTOEDITOR")); - msgd->run (); - delete msgd; + Gtk::MessageDialog msgd (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); + msgd.set_title (M("MAIN_BUTTON_SENDTOEDITOR")); + msgd.run (); } - } return false; diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index b6ef31255..a9fa293c3 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -16,183 +16,316 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include "extprog.h" + #include -#include "extprog.h" -#include "multilangmgr.h" -#include "../rtengine/safegtk.h" #ifdef WIN32 #include -// for GCC32 -#ifndef _WIN32_IE -#define _WIN32_IE 0x0600 -#endif #include #endif -using namespace std; +#include "options.h" +#include "multilangmgr.h" -ExtProgAction::ExtProgAction() {} - -ExtProgAction::ExtProgAction(const ExtProgAction* other, int target) - : target(target), filePathEXE(other->filePathEXE), preparams(other->preparams), name(other->name) { } - -Glib::ustring ExtProgAction::GetFullName() +Glib::ustring ExtProgAction::getFullName () const { return name + " [" + M(Glib::ustring::compose("EXTPROGTARGET_%1", target)) + "]"; } -bool ExtProgAction::Execute(std::vector fileNames) +bool ExtProgAction::execute (const std::vector& fileNames) const { - if (fileNames.empty()) { + if (fileNames.empty ()) { return false; } - // Check if they all exists (maybe not precessed yet) - for (int i = 0; i < fileNames.size(); i++) { - if (!safe_file_test(fileNames[i], Glib::FILE_TEST_EXISTS)) { - Gtk::MessageDialog msgd (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - msgd.run (); - return false; + // Check if they all exists as they may not be processed yet. + for (const auto& fileName : fileNames) { + + if (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS)) { + continue; } + + Gtk::MessageDialog (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true).run (); + return false; } Glib::ustring cmdLine = "\"" + filePathEXE + "\""; - if (preparams.length() > 0) { + if (!preparams.empty()) { cmdLine += " " + preparams; } - for (int i = 0; i < fileNames.size(); i++) { - cmdLine += " \"" + fileNames[i] + "\""; + for (const auto& fileName : fileNames) { + cmdLine += " \"" + fileName + "\""; } - return safe_spawn_command_line_async (cmdLine); + return ExtProgStore::spawnCommandAsync (cmdLine); } - -// Generates as singleton ExtProgStore* ExtProgStore::getInstance() { static ExtProgStore instance_; return &instance_; } -ExtProgStore::~ExtProgStore() -{ - for (list::iterator it = lActions.begin(); it != lActions.end(); it++) { - delete *it; - } -} - // Reads all profiles from the given profiles dir void ExtProgStore::init () { MyMutex::MyLock lock(mtx); - lActions.clear(); + actions.clear (); #ifdef WIN32 - SearchProg("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true); - SearchProg("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true); - SearchProg("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, true); - SearchProg("MS Image Composition Editor", "Microsoft Research\\Image Composite Editor\\ICE.exe", "", 0, false, true); - SearchProg("PTGui", "PTGui\\PTGui.exe", "", 0, false, true); - SearchProg("GeoSetter", "GeoSetter\\GeoSetter.exe", "", 0, true, true); - SearchProg("FastStone Image Viewer", "FastStone Image Viewer\\FSViewer.exe", "", 0, true, true); - SearchProg("FastPictureViewer", "FastPictureViewer\\FastPictureViewer.exe", "", 0, true, true); + // Please do not add obscure little tools here, only widely used programs. + // They should also have a proper setup program and therefore a standard path. - if (!SearchProg("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)) { - if ( !SearchProg("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, true, true)) { - if (!SearchProg("Autopano Giga 2", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 6, true, true)) { - SearchProg("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true); + searchProgram ("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true); + searchProgram ("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true); + searchProgram ("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, true); + searchProgram ("MS Image Composition Editor", "Microsoft Research\\Image Composite Editor\\ICE.exe", "", 0, false, true); + searchProgram ("PTGui", "PTGui\\PTGui.exe", "", 0, false, true); + searchProgram ("GeoSetter", "GeoSetter\\GeoSetter.exe", "", 0, true, true); + searchProgram ("FastStone Image Viewer", "FastStone Image Viewer\\FSViewer.exe", "", 0, true, true); + searchProgram ("FastPictureViewer", "FastPictureViewer\\FastPictureViewer.exe", "", 0, true, true); + + if (!searchProgram ("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)) { + if (!searchProgram ("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, true, true)) { + if (!searchProgram ("Autopano Giga 2", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 6, true, true)) { + searchProgram ("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true); } } } - // DO NOT add obscure little tools here, only widely used programs with proper setup program to have a standard path #endif } -bool ExtProgStore::SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess) +bool ExtProgStore::searchProgram (const Glib::ustring& name, + const Glib::ustring& exePath, + const Glib::ustring& exePath86, + int maxVer, + bool allowRaw, + bool allowQueueProcess) { - bool found = false; #ifdef WIN32 // get_user_special_dir crashes on some Windows configurations. - // so we use the safe native functions here static Glib::ustring progFilesDir, progFilesDirx86; - if (progFilesDir.empty()) { - WCHAR pathW[MAX_PATH] = {0}; + if (progFilesDir.empty ()) { + WCHAR pathW[MAX_PATH]; char pathA[MAX_PATH]; - // First prio folder (64bit, otherwise 32bit) - if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROGRAM_FILES, false)) { - char pathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0); - progFilesDir = Glib::ustring(pathA); + if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILES, false)) { + if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) { + progFilesDir = pathA; + } } - if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROGRAM_FILESX86, false)) { - WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0); - progFilesDirx86 = Glib::ustring(pathA); + if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILESX86, false)) { + if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) { + progFilesDirx86 = pathA; + } } } - if (exePath86.empty()) { - exePath86 = exePath; - } + ExtProgAction action; + action.name = name; + action.target = (allowRaw ? 1 : 2); - ExtProgAction *pAct = new ExtProgAction(); - pAct->name = name; - pAct->target = (allowRaw ? 1 : 2); + auto& filePath = action.filePathEXE; if (maxVer > 0) { - for (int verNo = maxVer; verNo >= 0; verNo--) { - pAct->filePathEXE = progFilesDir + "\\" + Glib::ustring::compose(exePath, verNo); - if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { + for (auto ver = maxVer; ver >= 0; ver--) { + + filePath = progFilesDir + "\\" + Glib::ustring::compose(exePath, ver); + + if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { break; } - pAct->filePathEXE = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, verNo); + if (!exePath86.empty ()) { - if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { - break; + filePath = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, ver); + + if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + break; + } } - pAct->filePathEXE = ""; + filePath.clear (); } } else { - pAct->filePathEXE = progFilesDir + "\\" + exePath; - if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { + do { - pAct->filePathEXE = progFilesDirx86 + "\\" + exePath86; + filePath = progFilesDir + "\\" + exePath; - if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { - pAct->filePathEXE = ""; + if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + break; } - } + + if (!exePath86.empty ()) { + + filePath = progFilesDirx86 + "\\" + exePath86; + + if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + break; + } + } + + filePath.clear (); + + } while (false); } - if (pAct->filePathEXE.length() > 0) { - lActions.push_back(pAct); + if (!action.filePathEXE.empty ()) { + + actions.push_back (action); - // Copy for second target if (allowRaw && allowQueueProcess) { - lActions.push_back(new ExtProgAction(pAct, 2)); + + action.target = 2; + actions.push_back (action); } - found = true; - } else { - delete pAct; + return true; } #endif - return found; + return false; +} + +bool ExtProgStore::spawnCommandAsync (const Glib::ustring& cmd) +{ + try { + + const auto encodedCmd = Glib::filename_from_utf8 (cmd); + Glib::spawn_command_line_async (encodedCmd.c_str ()); + + return true; + + } catch (const Glib::Exception& exception) { + + if (options.rtSettings.verbose) { + std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl; + } + + return false; + + } +} + +bool ExtProgStore::spawnCommandSync (const Glib::ustring& cmd) +{ + auto exitStatus = -1; + + try { + + Glib::spawn_command_line_sync (cmd, NULL, NULL, &exitStatus); + + } catch (const Glib::Exception& exception) { + + if (options.rtSettings.verbose) { + std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl; + } + + } + + return exitStatus == 0; +} + +bool ExtProgStore::openInGimp (const Glib::ustring& fileName) +{ +#if defined WIN32 + + auto executable = Glib::build_filename (options.gimpDir, "bin", "gimp-win-remote"); + auto cmdLine = Glib::ustring::compose ("\"%1\" gimp-2.4.exe \"%2\"", executable, fileName); + auto success = spawnCommandAsync (cmdLine); + +#elif defined __APPLE__ + + auto cmdLine = Glib::ustring("open -a /Applications/GIMP.app \'") + fileName + Glib::ustring("\'"); + auto success = spawnCommandAsync (cmdLine); + +#else + + auto cmdLine = Glib::ustring("gimp \"") + fileName + Glib::ustring("\""); + auto success = spawnCommandAsync (cmdLine); + +#endif + + if (success) { + return true; + } + +#ifdef WIN32 + + for (auto ver = 12; ver >= 0; --ver) { + + executable = Glib::build_filename (options.gimpDir, "bin", Glib::ustring::compose (Glib::ustring("gimp-2.%1.exe"), ver)); + cmdLine = Glib::ustring::compose ("\"%1\" \"%2\"", executable, fileName); + success = spawnCommandAsync (cmdLine); + + if (success) { + return true; + } + } + +#elif defined __APPLE__ + + cmdLine = Glib::ustring("open -a /Applications/Gimp.app/Contents/Resources/start \'") + fileName + Glib::ustring("\'"); + success = ExtProgStore::spawnCommandAsync (cmdLine); + +#else + + cmdLine = Glib::ustring("gimp-remote \"") + fileName + Glib::ustring("\""); + success = ExtProgStore::spawnCommandAsync (cmdLine); + +#endif + + return success; +} + +bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName) +{ +#if defined WIN32 + + const auto executable = Glib::build_filename(options.psDir, "Photoshop.exe"); + const auto cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + +#elif defined __APPLE__ + + const auto cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir, "Photoshop.app\' ") + Glib::ustring("\'") + fileName + Glib::ustring("\'"); + +#else + + const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + +#endif + + return spawnCommandAsync (cmdLine); +} + +bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) +{ +#if defined WIN32 + + const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + +#elif defined __APPLE__ + + const auto cmdLine = options.customEditorProg + Glib::ustring(" \"") + fileName + Glib::ustring("\""); + +#else + + const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + +#endif + + return spawnCommandAsync (cmdLine); } diff --git a/rtgui/extprog.h b/rtgui/extprog.h index 2069bc8e8..fe7375ce7 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -20,42 +20,58 @@ #ifndef _EXTPROG_ #define _EXTPROG_ -#include -#include +#include + +#include + #include "threadutils.h" -class ExtProgAction +struct ExtProgAction { -public: - ExtProgAction(); - ExtProgAction(const ExtProgAction* other, int target); - Glib::ustring filePathEXE; Glib::ustring preparams; // after EXE and before file names Glib::ustring name; // already localized if necessary int target; // 1=RAW files, 2=batch converted files - Glib::ustring GetFullName(); // e.g. "Photoshop (RAW)" + Glib::ustring getFullName () const; // e.g. "Photoshop (RAW)" - virtual bool Execute(std::vector fileNames); + bool execute (const std::vector& fileNames) const; }; // Stores all external programs that could be called by the user class ExtProgStore { MyMutex mtx; // covers actions + std::vector actions; - bool SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess); + bool searchProgram (const Glib::ustring& name, + const Glib::ustring& exePath, + const Glib::ustring& exePath86, + int maxVer, + bool allowRaw, + bool allowQueueProcess); public: - ~ExtProgStore(); - - void init(); // searches computer for installed standard programs static ExtProgStore* getInstance(); - std::list lActions; + // searches computer for installed standard programs + void init(); + + const std::vector& getActions () const; + + static bool spawnCommandAsync (const Glib::ustring& cmd); + static bool spawnCommandSync (const Glib::ustring& cmd); + + static bool openInGimp (const Glib::ustring& fileName); + static bool openInPhotoshop (const Glib::ustring& fileName); + static bool openInCustomEditor (const Glib::ustring& fileName); }; #define extProgStore ExtProgStore::getInstance() +inline const std::vector& ExtProgStore::getActions () const +{ + return actions; +} + #endif diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 73fd4b4d6..69dc4940c 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -232,11 +232,9 @@ FileBrowser::FileBrowser () mMenuExtProgs.clear(); amiExtProg = NULL; - for (std::list::iterator it = extProgStore->lActions.begin(); it != extProgStore->lActions.end(); it++) { - ExtProgAction* pAct = *it; - - if (pAct->target == 1 || pAct->target == 2) { - mMenuExtProgs[pAct->GetFullName()] = pAct; + for (const auto& action : extProgStore->getActions ()) { + if (action.target == 1 || action.target == 2) { + mMenuExtProgs[action.getFullName ()] = &action; } } @@ -255,7 +253,7 @@ FileBrowser::FileBrowser () p++; } - for (std::map::iterator it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { + for (auto it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { submenuExtProg->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1); p++; } @@ -268,7 +266,7 @@ FileBrowser::FileBrowser () p++; } - for (std::map::iterator it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { + for (auto it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { pmenu->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1); p++; } @@ -752,7 +750,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) for (int j = 0; j < mMenuExtProgs.size(); j++) { if (m == amiExtProg[j]) { - ExtProgAction* pAct = mMenuExtProgs[m->get_label()]; + const auto pAct = mMenuExtProgs[m->get_label()]; // Build vector of all file names std::vector selFileNames; @@ -768,7 +766,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) selFileNames.push_back(fn); } - pAct->Execute(selFileNames); + pAct->execute (selFileNames); return; } } diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index a444b0a0e..e037363c9 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -93,7 +93,7 @@ protected: Gtk::MenuItem* menuExtProg; Gtk::MenuItem** amiExtProg; Gtk::MenuItem* miOpenDefaultViewer; - std::map mMenuExtProgs; // key is menuitem label + std::map mMenuExtProgs; // key is menuitem label Gtk::MenuItem* menuDF; Gtk::MenuItem* selectDF; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 6528fc9af..ac6240435 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -29,6 +29,7 @@ #include "guiutils.h" #include "profilestore.h" #include "batchqueue.h" +#include "extprog.h" #include "../rtengine/safegtk.h" using namespace rtengine::procparams; @@ -254,7 +255,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine).c_str()); } - bool success = safe_spawn_command_line_sync (cmdLine); + bool success = ExtProgStore::spawnCommandSync (cmdLine); // Now they SHOULD be there (and potentially "partial"), so try to load them and store it as a full procparam if (success) {