From 6f3d5688d82f3cace89423e364741f01a5d320c7 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 19 Oct 2017 16:03:33 +0200 Subject: [PATCH 1/5] Fixed bug in finding lensfun lens when maker name consists of multiple words --- rtengine/rtlensfun.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index ddbeca9bf..ed19f44f0 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -393,14 +393,22 @@ LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) c lname = camera.getModel(); // "Standard" } auto found = data_->FindLenses(camera.data_, nullptr, lname.c_str()); - if (!found) { - // try to split the maker from the model of the lens + for (size_t pos = 0; !found && pos < name.size(); ) { + // try to split the maker from the model of the lens -- we have to + // guess a bit here, since there are makers with a multi-word name + // (e.g. "Leica Camera AG") + if (name.find("f/", pos) == 0) { + break; // no need to search further + } Glib::ustring make, model; - auto i = name.find_first_of(' '); + auto i = name.find(' ', pos); if (i != Glib::ustring::npos) { make = name.substr(0, i); model = name.substr(i+1); found = data_->FindLenses(camera.data_, make.c_str(), model.c_str()); + pos = i+1; + } else { + break; } } if (found) { From e2433214a370977a6837c6977e167b11b9fc36b4 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 19 Oct 2017 16:20:31 +0200 Subject: [PATCH 2/5] Fixed bug in updating the GUI value of the lensfun lens when maker name consists of multiple words It might happen in the lensfun DB that there are multiple makers sharing a similar name (at present, this only happens for "Leica" and "Leica Camera AG"). The logic for finding the lens in the combo box was not considering this... --- rtgui/lensprofile.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 3efe54347..6415c1fce 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -420,7 +420,8 @@ bool LensProfilePanel::setLensfunLens(const Glib::ustring &lens) if (it && (*it)[lf->lensfunModelLens.lens] == lens) { return true; } - + + bool first_maker_found = false; for (auto row : lf->lensfunLensModel->children()) { if (lens.find(row[lf->lensfunModelLens.lens]) == 0) { auto &c = row.children(); @@ -431,6 +432,11 @@ bool LensProfilePanel::setLensfunLens(const Glib::ustring &lens) return true; } } + // we do not break immediately here, because there might be multiple makers + // sharing the same prefix (e.g. "Leica" and "Leica Camera AG"). + // therefore, we break below when the lens doesn't match any of them + first_maker_found = true; + } else if (first_maker_found) { break; } } From c2c213efac28078603746a6fb75fe1c449fa427c Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 19 Oct 2017 19:00:28 +0200 Subject: [PATCH 3/5] Wrong translations calls in code, #4153 --- rtgui/diagonalcurveeditorsubgroup.cc | 10 +++++----- rtgui/flatcurveeditorsubgroup.cc | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index b64034b96..43a58b674 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -67,9 +67,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointCustom = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCustom, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointCustom, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editCustom = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCustom, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editCustom, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editCustom->hide(); copyCustom = Gtk::manage (new Gtk::Button ()); initButton(*copyCustom, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); @@ -144,9 +144,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointNURBS = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointNURBS, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointNURBS, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editNURBS = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editNURBS, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editNURBS, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editNURBS->hide(); copyNURBS = Gtk::manage (new Gtk::Button ()); initButton(*copyNURBS, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); @@ -224,7 +224,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, shcSelector->set_name("CurveSHCSelector"); // To handle the 4px gap between the SHCSelector and the curve through CSS editParam = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editParam, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editParam, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editParam->hide(); copyParam = Gtk::manage (new Gtk::Button ()); initButton(*copyParam, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 2e690f32a..a9d51abec 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -63,9 +63,9 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u } editCPoints = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCPoints, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editCPoints, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editPointCPoints = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCPoints, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointCPoints, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); copyCPoints = Gtk::manage (new Gtk::Button ()); initButton(*copyCPoints, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); pasteCPoints = Gtk::manage (new Gtk::Button ()); From 41cd29d201096b44035cd7f7942941a3c323cf8f Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 19 Oct 2017 20:37:03 +0200 Subject: [PATCH 4/5] Create PartialProfileDlg (Partial Profile Dialog) on demand instead of in advance when starting rt (saves another few ms when starting rt). fixes #4151 --- rtgui/profilepanel.cc | 29 +++++++++++++++++++++++++---- rtgui/profilepanel.h | 4 ++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index 6d317f5a4..57204f8b1 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -26,12 +26,12 @@ using namespace rtengine; using namespace rtengine::procparams; -PartialPasteDlg* ProfilePanel::partialProfileDlg; +PartialPasteDlg* ProfilePanel::partialProfileDlg = nullptr; +Gtk::Window* ProfilePanel::parent; - -void ProfilePanel::init (Gtk::Window* parent) +void ProfilePanel::init (Gtk::Window* parentWindow) { - partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + parent = parentWindow; } void ProfilePanel::cleanup () @@ -336,6 +336,9 @@ void ProfilePanel::save_clicked (GdkEventButton* event) if (toSave) { if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -407,6 +410,9 @@ void ProfilePanel::copy_clicked (GdkEventButton* event) if (toSave) { if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_COPYPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -475,6 +481,9 @@ void ProfilePanel::load_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_LOADPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -514,6 +523,9 @@ void ProfilePanel::load_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited & partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe); } else { // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited ) @@ -551,6 +563,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) } if (event->state & Gdk::CONTROL_MASK) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_PASTEPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -613,6 +628,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited & partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe); } else { // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited ) @@ -626,6 +644,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = clipboard.pparams filtered by ( partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, nullptr, &pp, nullptr); } else { // custom.pparams = clipboard.pparams non filtered diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index ddd7133ca..dc07e2006 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -66,7 +66,7 @@ protected: ProfileChangeListener* tpc; bool dontupdate; sigc::connection changeconn; - + static Gtk::Window* parent; void changeTo (const rtengine::procparams::PartialProfile* newpp, Glib::ustring profname); public: @@ -79,7 +79,7 @@ public: tpc = ppl; } - static void init (Gtk::Window* parent); + static void init (Gtk::Window* parentWindow); static void cleanup (); void storeCurrentValue(); void updateProfileList (); From 8c328cafd1697d69d0b4dbc7fc0dd683a366a1e8 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 20 Oct 2017 21:05:19 +0200 Subject: [PATCH 5/5] get rid of fallbackMgr in MultiLangMgr, fixes #4154 --- rtgui/multilangmgr.cc | 64 +++++++++++++++++++------------------------ rtgui/multilangmgr.h | 18 ++++-------- rtgui/options.cc | 2 +- 3 files changed, 34 insertions(+), 50 deletions(-) diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 886f7bfd3..7cc79d19a 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -19,7 +19,6 @@ #include "multilangmgr.h" #include -#include #ifdef WIN32 #include @@ -107,59 +106,52 @@ MultiLangMgr::MultiLangMgr () { } -MultiLangMgr::MultiLangMgr (const Glib::ustring& fname, MultiLangMgr* fallbackMgr) +void MultiLangMgr::load (const std::vector &fnames) { - load (fname, fallbackMgr); -} + translations.clear(); -bool MultiLangMgr::load (const Glib::ustring& fname, MultiLangMgr* fallbackMgr) -{ - this->fallbackMgr.reset(fallbackMgr); - - std::ifstream file(fname.c_str()); - if (!file.is_open()) { - return false; - } - - std::map translations; - std::string entry; - - while (std::getline(file, entry)) { - - if (entry.empty() || entry.front() == '#' || entry.front() == '!') { + for (const auto& fname : fnames) { + if(fname.empty()) { continue; } - std::string key, value; - - std::istringstream line(entry); - - if (!std::getline(line, key, ';') || !std::getline(line, value)) { + std::ifstream file(fname.c_str()); + if (!file.is_open()) { continue; } - static const std::regex newline("\\\\n"); - value = std::regex_replace(value, newline, "\n"); + std::string entry; + auto hint = translations.begin(); + while (std::getline(file, entry)) { - translations.emplace(key, value); + if (entry.empty() || entry.front() == '#' || entry.front() == '!') { + continue; + } + + std::string key, value; + + std::istringstream line(entry); + + if(std::getline(line, key, ';') && translations.find(key) == translations.end() && std::getline(line, value)) { + size_t pos = 0; + while((pos = value.find("\\n", pos)) != std::string::npos) { + value.replace(pos, 2, "\n"); + pos++; + } + hint = translations.emplace_hint(hint, key, value); + } + } } - - this->translations.swap(translations); - return true; } Glib::ustring MultiLangMgr::getStr (const std::string& key) const { - const auto iterator = translations.find (key); + const auto iterator = translations.find(key); - if (iterator != translations.end ()) { + if (iterator != translations.end()) { return iterator->second; } - if (fallbackMgr) { - return fallbackMgr->getStr (key); - } - return key; } diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index be46b1197..d439307e3 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -20,8 +20,8 @@ #define _MULTILANGMGR_ #include -#include #include +#include #include @@ -29,22 +29,14 @@ class MultiLangMgr { public: MultiLangMgr (); - MultiLangMgr (const Glib::ustring& fname, MultiLangMgr* fallbackMgr = nullptr); -public: - bool load (const Glib::ustring& fname, MultiLangMgr* fallbackMgr = nullptr); - -public: - Glib::ustring getStr (const std::string& key) const; - -public: - static bool isOSLanguageDetectSupported (); - static Glib::ustring getOSUserLanguage (); + void load(const std::vector &fnames); + Glib::ustring getStr(const std::string& key) const; + static bool isOSLanguageDetectSupported(); + static Glib::ustring getOSUserLanguage(); private: std::map translations; - std::unique_ptr fallbackMgr; - }; extern MultiLangMgr langMgr; diff --git a/rtgui/options.cc b/rtgui/options.cc index 98db977fc..3906a293d 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -2327,7 +2327,7 @@ void Options::load (bool lightweight) } } - langMgr.load (localeTranslation, new MultiLangMgr (languageTranslation, new MultiLangMgr (defaultTranslation))); + langMgr.load ({localeTranslation, languageTranslation, defaultTranslation}); rtengine::init (&options.rtSettings, argv0, rtdir, !lightweight); }