From 511f6c2a7b9c65ee2d1e480b2e8ea663baea6054 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 20 Jul 2017 17:03:21 +0200 Subject: [PATCH] raise an exception when `Options::save` fails See #3975 #3976 --- rtgui/CMakeLists.txt | 2 +- rtgui/exportpanel.cc | 7 ++++- rtgui/main-cli.cc | 4 ++- rtgui/main.cc | 5 +++- rtgui/options.cc | 64 ++++++++++++++++++++++---------------------- rtgui/options.h | 19 ++++++++++--- rtgui/preferences.cc | 7 ++++- rtgui/rtwindow.cc | 7 ++++- 8 files changed, 73 insertions(+), 42 deletions(-) diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 629e3890f..05afd9af5 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -229,7 +229,7 @@ if((WIN32) AND NOT(UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")) set_target_properties(rth PROPERTIES LINK_FLAGS "-mwindows") endif() set_target_properties(rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee) -set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -DRAWTHERAPEE_CLI" OUTPUT_NAME rawtherapee-cli) +set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee-cli) # Add linked libraries dependencies to executables targets target_link_libraries(rth rtengine diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index 72cf30fdd..6f90792b3 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -303,7 +303,12 @@ void ExportPanel::SaveSettingsAsDefault() #undef FE_OPT_STORE_ if (changed) { - Options::save(); + try { + Options::save(); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd(getToplevelWindow(this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } } } diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 69c3d8487..7c120e9cf 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -153,7 +153,9 @@ int main(int argc, char **argv) bool quickstart = dontLoadCache(argc, argv); - if (!Options::load (quickstart)) { + try { + Options::load (quickstart); + } catch (Options::Error &) { printf("Fatal error!\nThe RT_SETTINGS and/or RT_PATH environment variables are set, but use a relative path. The path must be absolute!\n"); return -2; } diff --git a/rtgui/main.cc b/rtgui/main.cc index 099751f06..1e329c284 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -207,7 +207,10 @@ int processLineParams( int argc, char **argv ) bool init_rt() { - if (!Options::load ()) { + try { + Options::load(); + } catch (Options::Error &e) { + std::cout << "ERROR: " << e.get_msg() << std::endl; return false; } diff --git a/rtgui/options.cc b/rtgui/options.cc index 07b0f81ad..39d633e90 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -743,14 +743,15 @@ void Options::filterOutParsedExtensions () } } -int Options::readFromFile (Glib::ustring fname) +void Options::readFromFile (Glib::ustring fname) { setlocale (LC_NUMERIC, "C"); // to set decimal point to "." Glib::KeyFile keyFile; if ( !Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { - return 1; + Glib::ustring msg = Glib::ustring::compose("Options file %1 does not exist", fname); + throw Error(msg); } try { @@ -1858,21 +1859,22 @@ int Options::readFromFile (Glib::ustring fname) filterOutParsedExtensions (); - return 0; + return; } } catch (Glib::Error &err) { + Glib::ustring msg = Glib::ustring::compose("Options::readFromFile / Error code %1 while reading values from \"%2\":\n%3", err.code(), fname, err.what()); if (options.rtSettings.verbose) { - printf ("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + printf("%s\n", msg.c_str()); } + throw Error(msg); } catch (...) { + Glib::ustring msg = Glib::ustring::compose("Options::readFromFile / Unknown exception while trying to load \"%1\"!", fname); if (options.rtSettings.verbose) { - printf ("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); + printf ("%s\n", msg.c_str()); } + throw Error(msg); } - - return 1; - } bool Options::safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& section, @@ -1890,7 +1892,7 @@ bool Options::safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& sec return false; } -int Options::saveToFile (Glib::ustring fname) +void Options::saveToFile (Glib::ustring fname) { Glib::ustring keyData; @@ -2220,31 +2222,23 @@ int Options::saveToFile (Glib::ustring fname) keyData = keyFile.to_data (); - } catch (Glib::KeyFileError&) {} - - if (keyData.empty ()) { - return 1; + } catch (Glib::KeyFileError &e) { + throw Error(e.what()); } FILE *f = g_fopen (fname.c_str (), "wt"); if (f == nullptr) { std::cout << "Warning! Unable to save your preferences to: " << fname << std::endl; -#ifndef RAWTHERAPEE_CLI Glib::ustring msg_ = Glib::ustring::compose(M("MAIN_MSG_WRITEFAILED"), fname.c_str()); - //writeFailed (getToplevelWindow (this), msg_); - Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); - msgd.run (); -#endif - return 1; + throw Error(msg_); } else { fprintf (f, "%s", keyData.c_str ()); fclose (f); - return 0; } } -bool Options::load (bool lightweight) +void Options::load (bool lightweight) { // Find the application data path @@ -2258,7 +2252,8 @@ bool Options::load (bool lightweight) rtdir = Glib::ustring (path); if (!Glib::path_is_absolute (rtdir)) { - return false; + Glib::ustring msg = Glib::ustring::compose("Settings path %1 is not absolute", rtdir); + throw Error(msg); } } else { #ifdef WIN32 @@ -2283,7 +2278,11 @@ bool Options::load (bool lightweight) cacheBaseDir = Glib::build_filename (argv0, "cache"); // Read the global option file (the one located in the application's base folder) - options.readFromFile (Glib::build_filename (argv0, "options")); + try { + options.readFromFile (Glib::build_filename (argv0, "options")); + } catch (Options::Error &) { + // ignore errors here + } // Modify the path of the cache folder to the one provided in RT_CACHE environment variable path = g_getenv ("RT_CACHE"); @@ -2292,7 +2291,8 @@ bool Options::load (bool lightweight) cacheBaseDir = Glib::ustring (path); if (!Glib::path_is_absolute (cacheBaseDir)) { - return false; + Glib::ustring msg = Glib::ustring::compose("Cache base dir %1 is not absolute", cacheBaseDir); + throw Error(msg); } } // No environment variable provided, so falling back to the multi user mode, is enabled @@ -2308,12 +2308,14 @@ bool Options::load (bool lightweight) if (options.multiUser) { // Read the user option file (the one located somewhere in the user's home folder) // Those values supersets those of the global option file - int r = options.readFromFile (Glib::build_filename (rtdir, "options")); - - // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it - if (r && !g_mkdir_with_parents (rtdir.c_str (), 511)) { - // Save the option file - options.saveToFile (Glib::build_filename (rtdir, "options")); + try { + options.readFromFile (Glib::build_filename (rtdir, "options")); + } catch (Options::Error &) { + // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it + if (!g_mkdir_with_parents (rtdir.c_str (), 511)) { + // Save the option file + options.saveToFile (Glib::build_filename (rtdir, "options")); + } } #ifdef __APPLE__ @@ -2406,8 +2408,6 @@ bool Options::load (bool lightweight) langMgr.load (localeTranslation, new MultiLangMgr (languageTranslation, new MultiLangMgr (defaultTranslation))); rtengine::init (&options.rtSettings, argv0, rtdir, !lightweight); - - return true; } void Options::save () diff --git a/rtgui/options.h b/rtgui/options.h index 9253b7e2f..0b5882df0 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -21,6 +21,7 @@ #include #include "../rtengine/rtengine.h" +#include #define STARTUPDIR_CURRENT 0 #define STARTUPDIR_HOME 1 @@ -73,6 +74,16 @@ enum prevdemo_t {PD_Sidecar = 1, PD_Fast = 0}; class Options { +public: + class Error: public std::exception { + public: + Error(const Glib::ustring &msg): msg_(msg) {} + const char *what() const throw() { return msg_.c_str(); } + const Glib::ustring &get_msg() const throw() { return msg_; } + + private: + Glib::ustring msg_; + }; private: bool defProfRawMissing; @@ -325,10 +336,10 @@ public: Options* copyFrom (Options* other); void filterOutParsedExtensions (); void setDefaults (); - int readFromFile (Glib::ustring fname); - int saveToFile (Glib::ustring fname); - static bool load (bool lightweight = false); - static void save (); + void readFromFile(Glib::ustring fname); + void saveToFile(Glib::ustring fname); + static void load(bool lightweight = false); + static void save(); // if multiUser=false, send back the global profile path Glib::ustring getPreferredProfilePath(); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d211add4f..d9e016ae9 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2066,7 +2066,12 @@ void Preferences::okPressed () workflowUpdate(); options.copyFrom (&moptions); options.filterOutParsedExtensions(); - Options::save (); + try { + Options::save (); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd(getToplevelWindow(this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } dynProfilePanel->save(); hide (); } diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c51d1b7f0..c08781331 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -673,7 +673,12 @@ bool RTWindow::on_delete_event(GdkEventAny* event) options.windowMonitor = get_screen()->get_monitor_at_window(get_window()); - Options::save (); + try { + Options::save (); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd(getToplevelWindow(this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } hide(); on_delete_has_run = true;