From fb5466bc8c51c0d4fafdf3a39d3b33310bb4e5a6 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 25 Apr 2017 00:50:18 +0200 Subject: [PATCH 01/11] Code reorganization to enable Dynamic profile with rt-cli (#3691) --- rtengine/CMakeLists.txt | 2 + {rtgui => rtengine}/dynamicprofile.cc | 62 ++-- {rtgui => rtengine}/dynamicprofile.h | 23 +- rtengine/init.cc | 4 +- {rtgui => rtengine}/profilestore.cc | 472 ++++---------------------- {rtgui => rtengine}/profilestore.h | 93 +---- rtgui/CMakeLists.txt | 47 ++- rtgui/dynamicprofilepanel.cc | 19 +- rtgui/dynamicprofilepanel.h | 4 +- rtgui/filebrowser.cc | 12 +- rtgui/filebrowser.h | 2 +- rtgui/main-cli.cc | 69 ++-- rtgui/main.cc | 25 +- rtgui/options.cc | 2 +- rtgui/preferences.cc | 16 +- rtgui/profilepanel.cc | 28 +- rtgui/profilepanel.h | 2 +- rtgui/profilestorecombobox.cc | 358 +++++++++++++++++++ rtgui/profilestorecombobox.h | 95 ++++++ rtgui/thumbnail.cc | 13 +- 20 files changed, 717 insertions(+), 631 deletions(-) rename {rtgui => rtengine}/dynamicprofile.cc (81%) rename {rtgui => rtengine}/dynamicprofile.h (83%) rename {rtgui => rtengine}/profilestore.cc (54%) rename {rtgui => rtengine}/profilestore.h (73%) create mode 100644 rtgui/profilestorecombobox.cc create mode 100644 rtgui/profilestorecombobox.h diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 273abb65f..c9a2b395b 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -50,6 +50,7 @@ set(RTENGINESOURCEFILES dfmanager.cc diagonalcurves.cc dirpyr_equalizer.cc + dynamicprofile.cc expo_before_b.cc fast_demo.cc ffmanager.cc @@ -98,6 +99,7 @@ set(RTENGINESOURCEFILES previewimage.cc processingjob.cc procparams.cc + profilestore.cc rawimage.cc rawimagesource.cc refreshmap.cc diff --git a/rtgui/dynamicprofile.cc b/rtengine/dynamicprofile.cc similarity index 81% rename from rtgui/dynamicprofile.cc rename to rtengine/dynamicprofile.cc index 4439a1562..4ee76dda6 100644 --- a/rtgui/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -17,8 +17,8 @@ * along with RawTherapee. If not, see . */ -#include "dynamicprofile.h" -#include "profilestore.h" +#include "../rtengine/dynamicprofile.h" + #include #include @@ -36,6 +36,7 @@ const double EXPCOMP_MAX = 20.0; } // namespace +DynamicProfileRules dynamicProfileRules; bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const { @@ -44,8 +45,7 @@ bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const } if (value.find("re:") == 0) { // this is a regexp - return Glib::Regex::match_simple(value.substr(3), val, - Glib::REGEX_CASELESS); + return Glib::Regex::match_simple(value.substr(3), val, Glib::REGEX_CASELESS); } else { // normal string comparison return value.casefold() == val.casefold(); @@ -156,14 +156,12 @@ void set_optional(Glib::KeyFile &kf, const Glib::ustring &group, } // namespace - -bool loadDynamicProfileRules(std::vector &out) +bool DynamicProfileRules::loadRules() { - out.clear(); + dynamicRules.clear(); Glib::KeyFile kf; try { - if (!kf.load_from_file( - Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"))) { + if (!kf.load_from_file(Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"))) { return false; } } catch (Glib::Error &e) { @@ -186,9 +184,9 @@ bool loadDynamicProfileRules(std::vector &out) if (options.rtSettings.verbose) { printf(" loading rule %d\n", serial); } - - out.emplace_back(DynamicProfileRule()); - DynamicProfileRule &rule = out.back(); + + dynamicRules.emplace_back(DynamicProfileRule()); + DynamicProfileRule &rule = dynamicRules.back(); rule.serial_number = serial; get_int_range(rule.iso, kf, group, "iso"); get_double_range(rule.fnumber, kf, group, "fnumber"); @@ -200,21 +198,21 @@ bool loadDynamicProfileRules(std::vector &out) try { rule.profilepath = kf.get_string(group, "profilepath"); } catch (Glib::KeyFileError &) { - out.pop_back(); + dynamicRules.pop_back(); } } - std::sort(out.begin(), out.end()); + std::sort(dynamicRules.begin(), dynamicRules.end()); + rulesLoaded = true; return true; } - -bool storeDynamicProfileRules(const std::vector &rules) +bool DynamicProfileRules::storeRules() { if (options.rtSettings.verbose) { printf("saving dynamic profiles...\n"); } Glib::KeyFile kf; - for (auto &rule : rules) { + for (auto &rule : dynamicRules) { std::ostringstream buf; buf << "rule " << rule.serial_number; Glib::ustring group = buf.str(); @@ -227,29 +225,15 @@ bool storeDynamicProfileRules(const std::vector &rules) set_optional(kf, group, "lens", rule.lens); kf.set_string(group, "profilepath", rule.profilepath); } - return kf.save_to_file( - Glib::build_filename(Options::rtdir, "dynamicprofile.cfg")); + return kf.save_to_file(Glib::build_filename(Options::rtdir, "dynamicprofile.cfg")); } - -PartialProfile *loadDynamicProfile(const ImageMetaData *im) +const std::vector &DynamicProfileRules::getRules() const { - PartialProfile *ret = new PartialProfile(true, true); - for (auto &rule : profileStore.getDynamicProfileRules()) { - if (rule.matches(im)) { - if (options.rtSettings.verbose) { - printf("found matching profile %s\n", - rule.profilepath.c_str()); - } - const PartialProfile *p = - profileStore.getProfile(rule.profilepath); - if (p != nullptr) { - p->applyTo(ret->pparams); - } else { - printf("ERROR loading matching profile from: %s\n", - rule.profilepath.c_str()); - } - } - } - return ret; + return dynamicRules; +} + +void DynamicProfileRules::setRules(const std::vector &r) +{ + dynamicRules = r; } diff --git a/rtgui/dynamicprofile.h b/rtengine/dynamicprofile.h similarity index 83% rename from rtgui/dynamicprofile.h rename to rtengine/dynamicprofile.h index 4c5e552e4..45c28f07c 100644 --- a/rtgui/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -21,8 +21,7 @@ #include #include -#include "options.h" - +#include "../rtgui/options.h" class DynamicProfileRule { public: @@ -46,7 +45,7 @@ public: bool operator()(const Glib::ustring &val) const; }; - + DynamicProfileRule(); bool matches(const rtengine::ImageMetaData *im) const; bool operator<(const DynamicProfileRule &other) const; @@ -62,13 +61,17 @@ public: Glib::ustring profilepath; }; +class DynamicProfileRules { +protected: + /** cache for dynamic profile rules */ + std::vector dynamicRules; + bool rulesLoaded; -bool loadDynamicProfileRules(std::vector &out); -bool storeDynamicProfileRules( - const std::vector &rules); - -rtengine::procparams::PartialProfile *loadDynamicProfile( - const rtengine::ImageMetaData *im); - +public: + bool loadRules(); + bool storeRules(); + const std::vector &getRules() const; + void setRules(const std::vector &r); +}; #endif // _DYNAMICPROFILE_H_ diff --git a/rtengine/init.cc b/rtengine/init.cc index 4c66cea68..2d157c762 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -16,6 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include "../rtgui/profilestorecombobox.h" #include "rtengine.h" #include "iccstore.h" #include "dcp.h" @@ -27,7 +28,7 @@ #include "dfmanager.h" #include "ffmanager.h" #include "rtthumbnail.h" -#include "../rtgui/profilestore.h" +#include "profilestore.h" #include "../rtgui/threadutils.h" namespace rtengine @@ -40,6 +41,7 @@ MyMutex* lcmsMutex = nullptr; int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir, bool loadAll) { settings = s; + ProfileStore::getInstance()->init (loadAll); ICCStore::getInstance()->init (s->iccDirectory, Glib::build_filename (baseDir, "iccprofiles"), loadAll); DCPStore::getInstance()->init (Glib::build_filename (baseDir, "dcpprofiles"), loadAll); diff --git a/rtgui/profilestore.cc b/rtengine/profilestore.cc similarity index 54% rename from rtgui/profilestore.cc rename to rtengine/profilestore.cc index d7bf18ab5..38619f0eb 100644 --- a/rtgui/profilestore.cc +++ b/rtengine/profilestore.cc @@ -17,49 +17,55 @@ * along with RawTherapee. If not, see . */ #include "profilestore.h" -#include "options.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "dynamicprofile.h" -ProfileStore profileStore; +#include "dynamicprofile.h" +#include "../rtgui/options.h" +#include "../rtgui/multilangmgr.h" using namespace rtengine; using namespace rtengine::procparams; -ProfileStore::ProfileStore () : parseMutex(nullptr), storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(nullptr), internalDefaultEntry(nullptr), internalDynamicEntry(nullptr), dynamicRules(new std::vector()) +ProfileStore::ProfileStore () : storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(nullptr), internalDefaultEntry(nullptr), internalDynamicEntry(nullptr), loadAll(true) { internalDefaultProfile = new AutoPartialProfile(); internalDefaultProfile->set(true); } -bool ProfileStore::init () +ProfileStore* ProfileStore::getInstance() +{ + static ProfileStore instance; + return &instance; +} + + +bool ProfileStore::init (bool loadAll) { if (storeState == STORESTATE_DELETED) { return false; } - if (storeState == STORESTATE_NOTINITIALIZED) { + this->loadAll = loadAll; + + if (storeState == STORESTATE_NOTINITIALIZED && loadAll) { storeState = STORESTATE_BEINGINITIALIZED; - parseMutex = new MyMutex(); _parseProfiles (); - loadDynamicProfileRules(*dynamicRules); storeState = STORESTATE_INITIALIZED; } - return true; + return storeState == STORESTATE_INITIALIZED; } ProfileStore::~ProfileStore () { - if (storeState == STORESTATE_NOTINITIALIZED) { return; } // This lock prevent object's suppression while scanning the directories storeState = STORESTATE_DELETED; - MyMutex::MyLock lock(*parseMutex); + + { + MyMutex::MyLock lock(parseMutex); clearProfileList (); partProfiles.clear (); @@ -67,9 +73,7 @@ ProfileStore::~ProfileStore () delete internalDefaultProfile; delete internalDefaultEntry; delete internalDynamicEntry; - lock.release(); - delete parseMutex; - parseMutex = nullptr; + } } /* @@ -84,21 +88,11 @@ ProfileStore::~ProfileStore () void ProfileStore::parseProfiles () { - if (!init()) - // I don't even know if this situation can occur - { - return; - } - for (auto listener : listeners) { listener->storeCurrentValue(); } - { - MyMutex::MyLock lock(*parseMutex); - - _parseProfiles (); - } + init (true); // safe even if already initialized for (auto listener : listeners) { listener->updateProfileList(); @@ -108,10 +102,6 @@ void ProfileStore::parseProfiles () void ProfileStore::_parseProfiles () { - - // Acquire the GUI, since the tree model can interact with combobox - GThreadLock threadLock; - // clear loaded profiles folders.clear(); clearFileList(); @@ -170,7 +160,6 @@ void ProfileStore::_parseProfiles () /// @return Returns true if some files has been found (directories are ignored) bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath, Glib::ustring& currDir, unsigned int parentId, unsigned char level, bool displayLevel0) { - bool fileFound = false; // reload the available profiles from the profile dir @@ -260,6 +249,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath int ProfileStore::findFolderId(const Glib::ustring &path) { + // initialization must have been done when calling this for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) { if (*i == path) { return i - folders.begin(); @@ -281,6 +271,10 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path return nullptr; } + if (storeState == STORESTATE_NOTINITIALIZED) { + parseProfiles(); + } + if (path == DEFPROFILE_INTERNAL || path == DEFPROFILE_DYNAMIC) { return internalDefaultEntry; } @@ -324,9 +318,11 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path } // 2. find the entry that match the given filename and parentFolderId - for (auto entry : entries) { - if (entry->parentFolderId == parentFolderId && entry->label == fName) { - return entry; + if (parentFolderId >= 0) { + for (auto entry : entries) { + if (entry->parentFolderId == parentFolderId && entry->label == fName) { + return entry; + } } } @@ -336,17 +332,15 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path /** Protected version of findEntryFromFullPathU */ const ProfileStoreEntry* ProfileStore::findEntryFromFullPath(Glib::ustring path) { - MyMutex::MyLock lock(*parseMutex); + MyMutex::MyLock lock(parseMutex); return findEntryFromFullPathU(path); } const PartialProfile* ProfileStore::getProfile (Glib::ustring path) { - if (!init()) - // I don't even know if this situation can occur - { - return nullptr; + if (storeState == STORESTATE_NOTINITIALIZED) { + parseProfiles(); } const ProfileStoreEntry *pse = findEntryFromFullPath(path); @@ -361,13 +355,11 @@ const PartialProfile* ProfileStore::getProfile (Glib::ustring path) const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry) { - if (!init()) - // I don't even know if this situation can occur - { - return nullptr; + if (storeState == STORESTATE_NOTINITIALIZED) { + parseProfiles(); } - MyMutex::MyLock lock(*parseMutex); + MyMutex::MyLock lock(parseMutex); if (entry == internalDefaultEntry) { return internalDefaultProfile; @@ -393,19 +385,19 @@ const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry) */ const std::vector* ProfileStore::getFileList () { - /*if (!init()) { - // I don't even know if this situation can occur - return NULL; - }*/ - parseMutex->lock(); + if (storeState == STORESTATE_NOTINITIALIZED) { + parseProfiles(); + } + + parseMutex.lock(); return &entries; } void ProfileStore::releaseFileList() { - parseMutex->unlock(); + parseMutex.unlock(); } /* @@ -416,13 +408,8 @@ void ProfileStore::releaseFileList() const ProcParams* ProfileStore::getDefaultProcParams (bool isRaw) { - if (!init()) - // I don't even know if this situation can occur - { - return nullptr; - } - //Note: the mutex is locked in getProfile, called below + // eventual initialization is done there too const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); @@ -441,13 +428,8 @@ const ProcParams* ProfileStore::getDefaultProcParams (bool isRaw) const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) { - if (!init()) - // I don't even know if this situation can occur - { - return nullptr; - } - //Note: the mutex is locked in getProfile, called below + // eventual initialization is done there too const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); @@ -460,6 +442,7 @@ const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) const Glib::ustring ProfileStore::getPathFromId(int folderId) { + // initialization must have been done when calling this return folders.at(folderId); } @@ -507,20 +490,34 @@ void ProfileStore::dumpFolderList() printf("\n"); } - -const std::vector &ProfileStore::getDynamicProfileRules() const +PartialProfile *ProfileStore::loadDynamicProfile(const ImageMetaData *im) { - return *dynamicRules; + if (storeState == STORESTATE_NOTINITIALIZED) { + parseProfiles(); + } + + PartialProfile *ret = new PartialProfile(true, true); + + if (!rulesLoaded) { + loadRules(); + } + + for (auto rule : dynamicRules) { + if (rule.matches(im)) { + if (options.rtSettings.verbose) { + printf("found matching profile %s\n", rule.profilepath.c_str()); + } + const PartialProfile *p = getProfile(rule.profilepath); + if (p != nullptr) { + p->applyTo(ret->pparams); + } else { + printf("ERROR loading matching profile from: %s\n", rule.profilepath.c_str()); + } + } + } + return ret; } - -void ProfileStore::setDynamicProfileRules(const std::vector &r) -{ - *dynamicRules = r; -} - - - ProfileStoreEntry::ProfileStoreEntry() : label(""), type(PSET_FOLDER), parentFolderId(0), folderId(0) {} ProfileStoreEntry::ProfileStoreEntry(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label(label), type(type), parentFolderId(parentFolder), folderId(folder) {} @@ -533,330 +530,3 @@ void ProfileStoreEntry::setValues(Glib::ustring label, PSEType type, unsigned sh folderId = folder; } -ProfileStoreLabel::ProfileStoreLabel(const ProfileStoreEntry *entry) : Gtk::Label(entry->label), entry(entry) -{ - set_alignment(0, 0.5); - set_ellipsize(Pango::ELLIPSIZE_END); - show(); -} - -ProfileStoreComboBox::ProfileStoreComboBox () -{ - updateProfileList(); - setPreferredWidth(50, 120); -} - -Glib::ustring ProfileStoreComboBox::getCurrentLabel() -{ - Glib::ustring currLabel; - Gtk::TreeModel::iterator currRow = get_active(); - - if (currRow) { - const ProfileStoreEntry *currEntry = (*currRow)[methodColumns.profileStoreEntry]; - return currEntry->label; - } - - return currLabel; -} - -const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() -{ - Gtk::TreeModel::iterator currRow_ = get_active(); - Gtk::TreeModel::Row currRow = *currRow_; - - if (currRow) { - return currRow[methodColumns.profileStoreEntry]; - } else { - return nullptr; - } -} - -/** @brief Recursive method to update the combobox entries */ -void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList) -{ - for (auto entry : *entryList) { - if (entry->parentFolderId == parentFolderId) { // filtering the entry of the same folder - if (entry->type == PSET_FOLDER) { - Glib::ustring folderPath( profileStore.getPathFromId(entry->folderId) ); - - if (options.useBundledProfiles || ((folderPath != "${G}" ) && (folderPath != "${U}" ))) { - // creating the new submenu - Gtk::TreeModel::Row newSubMenu; - - if (initial) { - newSubMenu = *(refTreeModel->append()); - } else { - newSubMenu = *(refTreeModel->append(parentRow->children())); - } - - // creating and assigning the custom Label object - newSubMenu[methodColumns.label] = entry->label; - newSubMenu[methodColumns.profileStoreEntry] = entry; -#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION == 18 - // HACK: Workaround for bug in Gtk+ 3.18... - Gtk::TreeModel::Row menuHeader = *(refTreeModel->append(newSubMenu->children())); - menuHeader[methodColumns.label] = "-"; - menuHeader[methodColumns.profileStoreEntry] = entry; -#endif - refreshProfileList_ (&newSubMenu, entry->folderId, false, entryList); - } else { - refreshProfileList_ (parentRow, entry->folderId, true, entryList); - } - } else { - Gtk::TreeModel::Row newItem; - - // creating a menu entry - if (initial) { - newItem = *(refTreeModel->append()); - } else { - newItem = *(refTreeModel->append(parentRow->children())); - } - - newItem[methodColumns.label] = entry->label; - newItem[methodColumns.profileStoreEntry] = entry; - } - } - } -} -/** @brief Get the ProfileStore's entry list and recreate the combobox entries. - * If you want to update the ProfileStore list itself (rescan the dir tree), use the "ProfileStore::parseProfiles" method instead - * - * This method has to be called by the ProfileStoreListener having a ProfileStoreComboBox. - */ -void ProfileStoreComboBox::updateProfileList () -{ - // clear items - clear(); - refTreeModel.clear(); - // Create the Tree model - refTreeModel = Gtk::TreeStore::create(methodColumns); - // Assign the model to the Combobox - set_model(refTreeModel); - - // this will lock the profilestore's entry list too - const std::vector *entryList = profileStore.getFileList(); - - //profileStore.dumpFolderList(); - refreshProfileList_ (NULL, entryList->at(0)->parentFolderId, true, entryList); - - if (entryList->at(0)->parentFolderId != 0) { - // special case for the Internal default entry - addRow(profileStore.getInternalDefaultPSE()); - } - - // releasing the profilestore's entry list mutex - profileStore.releaseFileList(); - - pack_start(methodColumns.label, false); - - Gtk::CellRendererText* cellRenderer = dynamic_cast(get_first_cell()); - cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; - cellRenderer->property_ellipsize_set() = true; -} - -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) -{ - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; - // Hombre: is there a smarter way of knowing if this row has childs? - const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; - - if (pse_->type == PSET_FOLDER) { - rowInSubLevel = findRowFromEntry_ (iter->children(), pse); - - if (rowInSubLevel) { - // entry found - return rowInSubLevel; - } - } else if (pse_ == pse) { - // entry found - return iter; - } - } - - return childs.end(); -} - -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) -{ - Gtk::TreeModel::Children childs = refTreeModel->children(); - - if (pse) { - Gtk::TreeIter row = findRowFromEntry_ (childs, pse); - return row; - } - - return childs.end(); -} - -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name) -{ - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; - // Hombre: is there a smarter way of knowing if this row has childs? - const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; - - if (pse->type == PSET_FOLDER) { - rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); - - if (rowInSubLevel) { - // entry found - return rowInSubLevel; - } - } else if (parentFolderId == pse->parentFolderId && name == pse->label) { - // entry found - return iter; - } - } - - return childs.end(); -} - -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) -{ - Gtk::TreeIter row; - - if (path.empty()) { - return row; - } - - if (path == DEFPROFILE_INTERNAL) { - row = findRowFromEntry(profileStore.getInternalDefaultPSE()); - return row; - } - - if (path == DEFPROFILE_DYNAMIC) { - row = findRowFromEntry(profileStore.getInternalDynamicPSE()); - return row; - } - - // removing the filename - Glib::ustring fName = Glib::path_get_basename(path); - - if (!fName.empty()) { - path = path.substr(0, path.length() - fName.length()); - } else { - // path is malformed; - return row; - } - - path = Glib::path_get_dirname(path); - int parentFolderId = profileStore.findFolderId(path); - - // 1. find the path in the folder list - if (parentFolderId != -1) { - row = findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); - } - - return row; -} - -/** @brief Get the absolute full path of the active row entry. - * @return The absolute full path of the active row entry, or the "Internal" keyword, - * or an empty string if the ComboBox is in an invalid state - */ -Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() -{ - Glib::ustring path; - Gtk::TreeModel::iterator currRowI = get_active(); - - if (!currRowI) { - return path; - } - - Gtk::TreeModel::Row currRow = *currRowI; - - if (currRow) { - - const ProfileStoreEntry *currEntry = currRow[methodColumns.profileStoreEntry]; - - if (!currEntry) { - return path; - } - - if (currEntry == profileStore.getInternalDefaultPSE()) { - return Glib::ustring(DEFPROFILE_INTERNAL); - } - - if (currEntry == profileStore.getInternalDynamicPSE()) { - return Glib::ustring(DEFPROFILE_DYNAMIC); - } - - path = Glib::build_filename(profileStore.getPathFromId(currEntry->parentFolderId), currEntry->label); - } - - return path; -} - -bool ProfileStoreComboBox::setActiveRowFromFullPath(Glib::ustring path) -{ - if (!path.empty()) { - Gtk::TreeIter row = findRowFromFullPath(path); - - if (row) { - set_active(row); - return true; - } - } - - return false; -} - -bool ProfileStoreComboBox::setActiveRowFromEntry(const ProfileStoreEntry *pse) -{ - if (pse) { - Gtk::TreeIter row = findRowFromEntry(pse); - - if (row) { - set_active(row); - return true; - } - } - - return false; -} - -bool ProfileStoreComboBox::setInternalEntry () -{ - return setActiveRowFromEntry(profileStore.getInternalDefaultPSE()); -} - -/** @brief Get the row from the first level of the tree that match the provided name */ -Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) -{ - Gtk::TreeIter row; - Gtk::TreeModel::Children childs = refTreeModel->children(); - - if (!name.empty()) { - Gtk::TreeModel::Row currRow; - - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - currRow = *iter; - const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; - - if (pse->label == name) { - return currRow; - } - } - } - - return childs.end(); - //return refTreeModel->get_iter(""); // is this fast? We want to send back a null, anvalid or end() iterator object here -} - -/** @brief Add a new row to the first level of the tree */ -Gtk::TreeIter ProfileStoreComboBox::addRow(const ProfileStoreEntry *profileStoreEntry) -{ - Gtk::TreeIter newEntry = refTreeModel->append(); - Gtk::TreeModel::Row row = *newEntry; - row[methodColumns.label] = profileStoreEntry->label; - row[methodColumns.profileStoreEntry] = profileStoreEntry; - return newEntry; -} - diff --git a/rtgui/profilestore.h b/rtengine/profilestore.h similarity index 73% rename from rtgui/profilestore.h rename to rtengine/profilestore.h index ad569c180..8ca5bf42a 100644 --- a/rtgui/profilestore.h +++ b/rtengine/profilestore.h @@ -23,16 +23,14 @@ #include #include -#include "../rtengine/rtengine.h" -#include "../rtengine/noncopyable.h" - -#include "threadutils.h" -#include "paramsedited.h" -#include "guiutils.h" +#include "rtengine.h" +#include "noncopyable.h" +#include "dynamicprofile.h" // forward decl class DynamicProfileRule; +class DynamicProfileRules; /** @brief This will implement callback functions for the ProfileStore * @@ -95,41 +93,17 @@ public: }; -/** - * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry - */ -class ProfileStoreLabel : public Gtk::Label -{ - -public: - const ProfileStoreEntry *entry; - -#ifndef NDEBUG - ProfileStoreLabel() : Gtk::Label("*** error ***"), entry(nullptr) {} -#else - ProfileStoreLabel() : Gtk::Label(""), entry(NULL) {} -#endif - - /** @brief Create a new ProfileStoreLabel - * - * @param entry Pointer to the ProfileStoreEntry object, be it a directory or a file - */ - explicit ProfileStoreLabel(const ProfileStoreEntry *entry); - ProfileStoreLabel (const ProfileStoreLabel &other); -}; - - /** @brief Store the profiles bundled with RawTharapee and created by the user. * * This store can be queried by the GUI to display a Tree of the profiles available * in the user's and system's profile directory and subdirectories. */ -class ProfileStore : - public rtengine::NonCopyable +class ProfileStore : public rtengine::NonCopyable, public DynamicProfileRules { typedef enum { STORESTATE_NOTINITIALIZED, + STORESTATE_LIGHTWEIGHT, STORESTATE_BEINGINITIALIZED, STORESTATE_INITIALIZED, STORESTATE_DELETED @@ -143,7 +117,7 @@ private: } }; - MyMutex *parseMutex; + MyMutex parseMutex; StoreState storeState; rtengine::procparams::AutoPartialProfile *internalDefaultProfile; ProfileStoreEntry *internalDefaultEntry; @@ -164,8 +138,8 @@ private: /** List of the client of this store */ std::list listeners; - /** cache for dynamic profile rules */ - std::unique_ptr> dynamicRules; + /** whereas we have to load all profile at init time or one by one upon request */ + bool loadAll; /** @brief Method to recursively parse a profile folder with a level depth arbitrarily limited to 3 * @@ -189,7 +163,9 @@ public: ProfileStore(); ~ProfileStore(); - bool init (); + static ProfileStore* getInstance(); + + bool init (bool loadAll = true); void parseProfiles (); int findFolderId(const Glib::ustring &path); const ProfileStoreEntry* findEntryFromFullPath(Glib::ustring path); @@ -210,53 +186,12 @@ public: return internalDynamicEntry; } - const std::vector &getDynamicProfileRules() const; - void setDynamicProfileRules(const std::vector &r); - void addListener(ProfileStoreListener *listener); void removeListener(ProfileStoreListener *listener); + rtengine::procparams::PartialProfile* loadDynamicProfile(const rtengine::ImageMetaData *im); + void dumpFolderList(); - }; -class ProfileStoreComboBox : public MyComboBox -{ - -protected: - class MethodColumns : public Gtk::TreeModel::ColumnRecord - { - public: - Gtk::TreeModelColumn label; - Gtk::TreeModelColumn profileStoreEntry; - MethodColumns() - { - add(label); - add(profileStoreEntry); - } - }; - - Glib::RefPtr refTreeModel; - MethodColumns methodColumns; - void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); - Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath_(Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); - -public: - ProfileStoreComboBox(); - void updateProfileList(); - Glib::ustring getCurrentLabel(); - const ProfileStoreEntry* getSelectedEntry(); - Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath (Glib::ustring path); - Glib::ustring getFullPathFromActiveRow (); - bool setActiveRowFromFullPath (Glib::ustring oldPath); - bool setActiveRowFromEntry (const ProfileStoreEntry *pse); - bool setInternalEntry (); - Gtk::TreeIter getRowFromLabel(Glib::ustring name); - Gtk::TreeIter addRow(const ProfileStoreEntry *profileStoreEntry); -}; - -extern ProfileStore profileStore; - #endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 300491e85..c317f8525 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -46,7 +46,6 @@ set(NONCLISOURCEFILES dirpyrdenoise.cc dirpyrequalizer.cc distortion.cc - dynamicprofile.cc dynamicprofilepanel.cc edit.cc editorpanel.cc @@ -107,7 +106,7 @@ set(NONCLISOURCEFILES previewmodepanel.cc previewwindow.cc profilepanel.cc - profilestore.cc + profilestorecombobox.cc prsharpening.cc rawcacorrection.cc rawexposure.cc @@ -219,15 +218,15 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY # Create new executables targets add_executable(rth ${EXTRA_SRC_NONCLI} ${NONCLISOURCEFILES}) -#add_executable(rth-cli ${EXTRA_SRC_CLI} ${CLISOURCEFILES}) +add_executable(rth-cli ${EXTRA_SRC_CLI} ${CLISOURCEFILES}) # Add dependencies to executables targets add_dependencies(rth UpdateInfo) -#add_dependencies(rth-cli UpdateInfo) +add_dependencies(rth-cli UpdateInfo) # Set executables targets properties, i.e. output filename and compile flags set_target_properties(rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee) -#set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" 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 @@ -251,25 +250,25 @@ target_link_libraries(rth rtengine ${ZLIB_LIBRARIES} ) -#target_link_libraries(rth-cli rtengine -# ${CAIROMM_LIBRARIES} -# ${EXPAT_LIBRARIES} -# ${EXTRA_LIB_RTGUI} -# ${FFTW3F_LIBRARIES} -# ${GIOMM_LIBRARIES} -# ${GIO_LIBRARIES} -# ${GLIB2_LIBRARIES} -# ${GLIBMM_LIBRARIES} -# ${GOBJECT_LIBRARIES} -# ${GTHREAD_LIBRARIES} -# ${IPTCDATA_LIBRARIES} -# ${JPEG_LIBRARIES} -# ${LCMS_LIBRARIES} -# ${PNG_LIBRARIES} -# ${TIFF_LIBRARIES} -# ${ZLIB_LIBRARIES} -# ) +target_link_libraries(rth-cli rtengine + ${CAIROMM_LIBRARIES} + ${EXPAT_LIBRARIES} + ${EXTRA_LIB_RTGUI} + ${FFTW3F_LIBRARIES} + ${GIOMM_LIBRARIES} + ${GIO_LIBRARIES} + ${GLIB2_LIBRARIES} + ${GLIBMM_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GTHREAD_LIBRARIES} + ${IPTCDATA_LIBRARIES} + ${JPEG_LIBRARIES} + ${LCMS_LIBRARIES} + ${PNG_LIBRARIES} + ${TIFF_LIBRARIES} + ${ZLIB_LIBRARIES} + ) # Install executables install(TARGETS rth DESTINATION ${BINDIR}) -#install(TARGETS rth-cli DESTINATION ${BINDIR}) +install(TARGETS rth-cli DESTINATION ${BINDIR}) diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index 172c06f47..eca96ece6 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -19,8 +19,9 @@ #include "dynamicprofilepanel.h" #include "multilangmgr.h" -#include "profilestore.h" +#include "../rtengine/profilestore.h" #include "../rtengine/rtengine.h" +#include "../rtengine/dynamicprofile.h" #include #include @@ -297,7 +298,7 @@ DynamicProfilePanel::DynamicProfilePanel(): show_all_children(); - for (auto &r : profileStore.getDynamicProfileRules()) { + for (auto &r : ProfileStore::getInstance()->getRules()) { add_rule(r); } } @@ -346,7 +347,7 @@ void DynamicProfilePanel::render_profilepath( auto row = *iter; Gtk::CellRendererText *ct = static_cast(cell); auto value = row[columns_.profilepath]; - auto pse = profileStore.findEntryFromFullPath(value); + auto pse = ProfileStore::getInstance()->findEntryFromFullPath(value); if (pse != nullptr) { ct->property_text() = pse->label; } else { @@ -521,12 +522,12 @@ void DynamicProfilePanel::save() for (auto row : treemodel_->children()) { rules.emplace_back(to_rule(row, serial++)); } - if (!storeDynamicProfileRules(rules)) { + + ProfileStore::getInstance()->setRules(rules); + + if (!ProfileStore::getInstance()->storeRules()) { printf("Error in saving dynamic profile rules\n"); - } else { - profileStore.setDynamicProfileRules(rules); - if (options.rtSettings.verbose) { - printf("Saved %d dynamic profile rules\n", int(rules.size())); - } + } else if (options.rtSettings.verbose) { + printf("Saved %d dynamic profile rules\n", int(rules.size())); } } diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index 72ff95b9a..629c5d9d4 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -20,8 +20,8 @@ #define _DYNAMICPROFILEPANEL_H_ #include -#include "dynamicprofile.h" -#include "profilestore.h" +#include "../rtengine/dynamicprofile.h" +#include "profilestorecombobox.h" class DynamicProfilePanel: public Gtk::VBox { public: diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index d96a89d09..dd37a740b 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -134,7 +134,7 @@ FileBrowser::FileBrowser () fbih->destroyed = false; fbih->pending = 0; - profileStore.addListener(this); + ProfileStore::getInstance()->addListener(this); int p = 0; pmenu = new Gtk::Menu (); @@ -457,7 +457,7 @@ FileBrowser::~FileBrowser () { idle_register.destroy(); - profileStore.removeListener(this); + ProfileStore::getInstance()->removeListener(this); delete pmenu; delete pmenuColorLabels; delete[] amiExtProg; @@ -1346,7 +1346,7 @@ void FileBrowser::applyMenuItemActivated (ProfileStoreLabel *label) { MYREADERLOCK(l, entryRW); - const rtengine::procparams::PartialProfile* partProfile = profileStore.getProfile (label->entry); + const rtengine::procparams::PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (label->entry); if (partProfile->pparams && !selected.empty()) { if (bppcl) { @@ -1376,7 +1376,7 @@ void FileBrowser::applyPartialMenuItemActivated (ProfileStoreLabel *label) } } - const rtengine::procparams::PartialProfile* srcProfiles = profileStore.getProfile (label->entry); + const rtengine::procparams::PartialProfile* srcProfiles = ProfileStore::getInstance()->getProfile (label->entry); if (srcProfiles->pparams) { @@ -1982,7 +1982,7 @@ void FileBrowser::updateProfileList () // submenu applmenu int p = 0; - const std::vector *profEntries = profileStore.getFileList(); // lock and get a pointer to the profiles' list + const std::vector *profEntries = ProfileStore::getInstance()->getFileList(); // lock and get a pointer to the profiles' list std::map subMenuList; // store the Gtk::Menu that Gtk::MenuItem will have to be attached to @@ -2067,7 +2067,7 @@ void FileBrowser::updateProfileList () applypartprof->set_submenu (*(subMenuList.at(0))); } - profileStore.releaseFileList(); + ProfileStore::getInstance()->releaseFileList(); subMenuList.clear(); } diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index faede2d8c..4bad832eb 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -29,7 +29,7 @@ #include "partialpastedlg.h" #include "exportpanel.h" #include "extprog.h" -#include "profilestore.h" +#include "profilestorecombobox.h" class ProfileStoreLabel; class FileBrowser; diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 3a601e18e..e59ebaf09 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -49,6 +49,9 @@ #include "conio.h" #endif +// Set this to 1 to make RT work when started with Eclipse and arguments, at least on Windows platform +#define ECLIPSE_ARGS 0 + extern Options options; // stores path to data files @@ -175,7 +178,11 @@ int main(int argc, char **argv) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); if (argc > 1 || options.rtSettings.verbose) { - if (options.rtSettings.verbose || ( !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_IS_DIR))) { + Glib::ustring fname(fname_to_utf8 (argv[1])); +#if ECLIPSE_ARGS + fname = fname.substr(1, fname.length()-2); +#endif + if (options.rtSettings.verbose || ( !Glib::file_test (fname, Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname, Glib::FILE_TEST_IS_DIR))) { bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001); bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001); @@ -268,8 +275,12 @@ void deleteProcParams(std::vector &pparam bool dontLoadCache( int argc, char **argv ) { - for( int iArg = 1; iArg < argc; iArg++) { - if( argv[iArg][0] == '-' && argv[iArg][1] == 'q' ) { + for (int iArg = 1; iArg < argc; iArg++) { + Glib::ustring currParam(argv[iArg]); +#if ECLIPSE_ARGS + currParam = currParam.substr(1, currParam.length()-2); +#endif + if( currParam.at(0) == '-' && currParam.at(1) == 'q' ) { return true; } } @@ -297,16 +308,22 @@ int processLineParams( int argc, char **argv ) unsigned errors = 0; for( int iArg = 1; iArg < argc; iArg++) { - if( argv[iArg][0] == '-' ) { - switch( argv[iArg][1] ) { + Glib::ustring currParam(argv[iArg]); +#if ECLIPSE_ARGS + currParam = currParam.substr(1, currParam.length()-2); +#endif + if( currParam.at(0) == '-' ) { + switch( currParam.at(1) ) { case 'O': copyParamsFile = true; case 'o': // outputfile or dir if( iArg + 1 < argc ) { iArg++; - outputPath = fname_to_utf8 (argv[iArg]); - + outputPath = Glib::ustring(fname_to_utf8(argv[iArg])); +#if ECLIPSE_ARGS + outputPath = outputPath.substr(1, outputPath.length()-2); +#endif if( Glib::file_test (outputPath, Glib::FILE_TEST_IS_DIR)) { outputDirectory = true; } @@ -319,7 +336,10 @@ int processLineParams( int argc, char **argv ) // RT stop if any of them can't be loaded for any reason. if( iArg + 1 < argc ) { iArg++; - Glib::ustring fname = fname_to_utf8 (argv[iArg]); + Glib::ustring fname(fname_to_utf8(argv[iArg])); +#if ECLIPSE_ARGS + fname = fname.substr(1, fname.length()-2); +#endif if (fname.at(0) == '-') { std::cerr << "Error: filename missing next to the -p switch" << std::endl; @@ -360,15 +380,15 @@ int processLineParams( int argc, char **argv ) break; case 'j': - if (strlen(argv[iArg]) > 2 && argv[iArg][2] == 's') { - if (strlen(argv[iArg]) == 3) { + if (currParam.length() > 2 && currParam.at(2) == 's') { + if (currParam.length() == 3) { std::cerr << "Error: the -js switch requires a mandatory value!" << std::endl; deleteProcParams(processingParams); return -3; } // looking for the subsampling parameter - sscanf(&argv[iArg][3], "%d", &subsampling); + subsampling = atoi(currParam.substr(3).c_str()); if (subsampling < 1 || subsampling > 3) { std::cerr << "Error: the value accompanying the -js switch has to be in the [1-3] range!" << std::endl; @@ -377,7 +397,7 @@ int processLineParams( int argc, char **argv ) } } else { outputType = "jpg"; - sscanf(&argv[iArg][2], "%d", &compression); + compression = atoi(currParam.substr(2).c_str()); if (compression < 0 || compression > 100) { std::cerr << "Error: the value accompanying the -j switch has to be in the [0-100] range!" << std::endl; @@ -389,7 +409,7 @@ int processLineParams( int argc, char **argv ) break; case 'b': - sscanf(&argv[iArg][2], "%d", &bits); + bits = atoi(currParam.substr(2).c_str()); if (bits != 8 && bits != 16) { std::cerr << "Error: specify -b8 for 8-bit or -b16 for 16-bit output." << std::endl; @@ -401,7 +421,7 @@ int processLineParams( int argc, char **argv ) case 't': outputType = "tif"; - compression = ((argv[iArg][2] != 'z') ? 0 : 1); + compression = ((currParam.at(2) != 'z') ? 0 : 1); break; case 'n': @@ -416,8 +436,10 @@ int processLineParams( int argc, char **argv ) case 'c': // MUST be last option while (iArg + 1 < argc) { iArg++; - - const auto argument = fname_to_utf8 (argv[iArg]); + Glib::ustring argument(fname_to_utf8(argv[iArg])); +#if ECLIPSE_ARGS + argument = argument.substr(1, argument.length()-2); +#endif if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { inputFiles.emplace_back (argument); @@ -546,7 +568,10 @@ int processLineParams( int argc, char **argv ) } } } else { - argv1 = fname_to_utf8 (argv[iArg]); + argv1 = Glib::ustring(fname_to_utf8(argv[iArg])); +#if ECLIPSE_ARGS + argv1 = argv1.substr(1, argv1.length()-2); +#endif if( outputDirectory ) { options.savePathFolder = outputPath; @@ -587,7 +612,7 @@ int processLineParams( int argc, char **argv ) rawParams = new rtengine::procparams::PartialProfile(true, true); Glib::ustring profPath = options.findProfilePath(options.defProfRaw); - if (options.is_defProfRawMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && rawParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, options.defProfRaw.substr(5) + paramFileExtension)))) { + if (options.is_defProfRawMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && rawParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, Glib::path_get_basename(options.defProfRaw) + paramFileExtension)))) { std::cerr << "Error: default raw processing profile not found" << std::endl; rawParams->deleteInstance(); delete rawParams; @@ -598,7 +623,7 @@ int processLineParams( int argc, char **argv ) imgParams = new rtengine::procparams::PartialProfile(true); profPath = options.findProfilePath(options.defProfImg); - if (options.is_defProfImgMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && imgParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, options.defProfImg.substr(5) + paramFileExtension)))) { + if (options.is_defProfImgMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && imgParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, Glib::path_get_basename(options.defProfImg) + paramFileExtension)))) { std::cerr << "Error: default non-raw processing profile not found" << std::endl; imgParams->deleteInstance(); delete imgParams; @@ -635,7 +660,7 @@ int processLineParams( int argc, char **argv ) } else if( outputDirectory ) { Glib::ustring s = Glib::path_get_basename( inputFile ); Glib::ustring::size_type ext = s.find_last_of('.'); - outputFile = outputPath + "/" + s.substr(0, ext) + "." + outputType; + outputFile = Glib::build_filename(outputPath, s.substr(0, ext) + "." + outputType); } else { Glib::ustring s = outputPath; Glib::ustring::size_type ext = s.find_last_of('.'); @@ -673,7 +698,7 @@ int processLineParams( int argc, char **argv ) if (options.defProfRaw == DEFPROFILE_DYNAMIC) { rawParams->deleteInstance(); delete rawParams; - rawParams = loadDynamicProfile(ii->getMetaData()); + rawParams = ProfileStore::getInstance()->loadDynamicProfile(ii->getMetaData()); } std::cout << " Merging default raw processing profile" << std::endl; rawParams->applyTo(¤tParams); @@ -681,7 +706,7 @@ int processLineParams( int argc, char **argv ) if (options.defProfImg == DEFPROFILE_DYNAMIC) { imgParams->deleteInstance(); delete imgParams; - imgParams = loadDynamicProfile(ii->getMetaData()); + imgParams = ProfileStore::getInstance()->loadDynamicProfile(ii->getMetaData()); } std::cout << " Merging default non-raw processing profile" << std::endl; imgParams->applyTo(¤tParams); diff --git a/rtgui/main.cc b/rtgui/main.cc index 88dc4ead4..495374f50 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -38,7 +38,7 @@ #include "rtimage.h" #include "version.h" #include "extprog.h" -#include "dynamicprofile.h" +#include "../rtengine/dynamicprofile.h" #ifndef WIN32 #include @@ -50,6 +50,9 @@ #include "conio.h" #endif +// Set this to 1 to make RT work when started with Eclipse and arguments, at least on Windows platform +#define ECLIPSE_ARGS 0 + extern Options options; // stores path to data files @@ -177,7 +180,6 @@ int main(int argc, char **argv) return -2; } - profileStore.init (); extProgStore->init(); SoundManager::init(); @@ -416,8 +418,12 @@ int processLineParams( int argc, char **argv ) unsigned errors = 0; for( int iArg = 1; iArg < argc; iArg++) { - if( argv[iArg][0] == '-' ) { - switch( argv[iArg][1] ) { + Glib::ustring currParam(argv[iArg]); +#if ECLIPSE_ARGS + currParam = currParam.substr(1, currParam.length()-2); +#endif + if( currParam.at(0) == '-' ) { + switch( currParam.at(1) ) { #ifdef WIN32 case 'w': // This case is handled outside this function @@ -437,9 +443,9 @@ int processLineParams( int argc, char **argv ) std::cout << std::endl; std::cout << "Symbols:" << std::endl; std::cout << " indicate parameters you can change." << std::endl; - std::cout << " [Square brackets] mean the parameter is optional." << std::endl; - std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; - std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; + //std::cout << " [Square brackets] mean the parameter is optional." << std::endl; + //std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; + //std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; std::cout << std::endl; std::cout << "Usage:" << std::endl; std::cout << " " << Glib::path_get_basename(argv[0]) << " Start File Browser inside folder." << std::endl; @@ -454,7 +460,10 @@ int processLineParams( int argc, char **argv ) } } } else { - argv1 = fname_to_utf8 (argv[iArg]); + argv1 = Glib::ustring(fname_to_utf8(argv[iArg])); +#if ECLIPSE_ARGS + argv1 = argv1.substr(1, argv1.length()-2); +#endif break; } } diff --git a/rtgui/options.cc b/rtgui/options.cc index 55b257ec8..daf11e62c 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -227,7 +227,7 @@ Glib::ustring Options::getPreferredProfilePath() /** @brief Get the absolute path of the given filename or the "Neutral" special value * *@param profName path + filename of the procparam to look for. A filename without path can be provided for backward compatibility. - * In this case, this parameter will be update with the new format. + * In this case, this parameter will be updated with the new format. *@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementor will have * to test for this particular value. If the absolute path is invalid (e.g. the file doesn't exist), it will return an empty string. */ diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 1acb7cfb4..12d6c2de7 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -100,7 +100,7 @@ Preferences::Preferences (RTWindow *rtwindow) #endif nb->set_current_page (0); - profileStore.addListener(this); + ProfileStore::getInstance()->addListener(this); fillPreferences (); @@ -111,7 +111,7 @@ Preferences::Preferences (RTWindow *rtwindow) Preferences::~Preferences () { - profileStore.removeListener(this); + ProfileStore::getInstance()->removeListener(this); get_size(options.preferencesWidth, options.preferencesHeight); } @@ -445,13 +445,14 @@ Gtk::Widget* Preferences::getProcParamsPanel () Gtk::VBox* vbpp = Gtk::manage (new Gtk::VBox ()); Gtk::Label* drlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORRAW") + ":", Gtk::ALIGN_START)); rprofiles = Gtk::manage (new ProfileStoreComboBox ()); - rprofiles->addRow(profileStore.getInternalDynamicPSE()); + const ProfileStoreEntry* dynpse = ProfileStore::getInstance()->getInternalDynamicPSE(); + rprofiles->addRow(dynpse); setExpandAlignProperties(rprofiles, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); rprofiles->set_size_request(50, -1); rpconn = rprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forRAWComboChanged) ); Gtk::Label* drimg = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORIMAGE") + ":", Gtk::ALIGN_START)); iprofiles = Gtk::manage (new ProfileStoreComboBox ()); - iprofiles->addRow(profileStore.getInternalDynamicPSE()); + iprofiles->addRow(dynpse); iprofiles->set_size_request(50, -1); setExpandAlignProperties(iprofiles, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); ipconn = iprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forImageComboChanged) ); @@ -2197,7 +2198,7 @@ void Preferences::bundledProfilesChanged () options.useBundledProfiles = useBundledProfiles->get_active (); // rescan the file's tree - profileStore.parseProfiles(); // This will call Preferences::updateProfileList in return + ProfileStore::getInstance()->parseProfiles(); // This will call Preferences::updateProfileList in return // restoring back the old value options.useBundledProfiles = currValue; @@ -2232,8 +2233,9 @@ void Preferences::updateProfileList() { rprofiles->updateProfileList(); iprofiles->updateProfileList(); - rprofiles->addRow(profileStore.getInternalDynamicPSE()); - iprofiles->addRow(profileStore.getInternalDynamicPSE()); + const ProfileStoreEntry* dynpse = ProfileStore::getInstance()->getInternalDynamicPSE(); + rprofiles->addRow(dynpse); + iprofiles->addRow(dynpse); } void Preferences::restoreValue() diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index b988418f0..06768cf56 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -18,9 +18,9 @@ */ #include "profilepanel.h" #include "options.h" -#include "profilestore.h" #include "clipboard.h" #include "multilangmgr.h" +#include "profilestorecombobox.h" #include "rtimage.h" using namespace rtengine; @@ -99,7 +99,7 @@ ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastFilename(""), image lastsaved = nullptr; dontupdate = false; - profileStore.addListener(this); + ProfileStore::getInstance()->addListener(this); changeconn = profiles->signal_changed().connect( sigc::mem_fun(*this, &ProfilePanel::selection_changed) ); @@ -114,7 +114,7 @@ ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastFilename(""), image ProfilePanel::~ProfilePanel () { - profileStore.removeListener(this); + ProfileStore::getInstance()->removeListener(this); if (custom) { custom->deleteInstance(); @@ -188,7 +188,7 @@ void ProfilePanel::storeCurrentValue () const ProfileStoreEntry *entry = profiles->getSelectedEntry(); const PartialProfile *currProfile; - if (entry && (currProfile = profileStore.getProfile(entry)) != nullptr) { + if (entry && (currProfile = ProfileStore::getInstance()->getProfile(entry)) != nullptr) { // now storedPProfile has the current entry's values storedPProfile = new PartialProfile(currProfile->pparams, currProfile->pedited, true); } else { @@ -318,7 +318,7 @@ void ProfilePanel::save_clicked (GdkEventButton* event) toSave = lastsaved; } else { const ProfileStoreEntry* entry = profiles->getSelectedEntry(); - toSave = entry ? profileStore.getProfile (profiles->getSelectedEntry()) : nullptr; + toSave = entry ? ProfileStore::getInstance()->getProfile (profiles->getSelectedEntry()) : nullptr; } if (toSave) { @@ -343,7 +343,7 @@ void ProfilePanel::save_clicked (GdkEventButton* event) } else { done = true; bool ccPrevState = changeconn.block(true); - profileStore.parseProfiles(); + ProfileStore::getInstance()->parseProfiles(); changeconn.block (ccPrevState); } } else { @@ -355,7 +355,7 @@ void ProfilePanel::save_clicked (GdkEventButton* event) } else { done = true; bool ccPrevState = changeconn.block(true); - profileStore.parseProfiles(); + ProfileStore::getInstance()->parseProfiles(); changeconn.block (ccPrevState); } } @@ -388,7 +388,7 @@ void ProfilePanel::copy_clicked (GdkEventButton* event) toSave = lastsaved; } else { const ProfileStoreEntry* entry = profiles->getSelectedEntry(); - toSave = entry ? profileStore.getProfile (entry) : nullptr; + toSave = entry ? ProfileStore::getInstance()->getProfile (entry) : nullptr; } // toSave has to be a complete procparams @@ -559,7 +559,7 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) const ProfileStoreEntry* entry = profiles->getSelectedEntry(); if (entry) { - const PartialProfile* partProfile = profileStore.getProfile (entry); + const PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (entry); *custom->pparams = *partProfile->pparams; } } @@ -576,7 +576,7 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) const ProfileStoreEntry* entry = profiles->getSelectedEntry(); if (entry) { - const PartialProfile* partProfile = profileStore.getProfile (entry); + const PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (entry); *custom->pparams = *partProfile->pparams; } } @@ -660,7 +660,7 @@ void ProfilePanel::selection_changed () currRow = profiles->get_active(); } - const PartialProfile* s = profileStore.getProfile (pse); + const PartialProfile* s = ProfileStore::getInstance()->getProfile (pse); if (s) { if (fillMode->get_active() && s->pedited) { @@ -745,12 +745,12 @@ void ProfilePanel::initProfile (const Glib::ustring& profileFullPath, ProcParams lasSavedEntry = getLastSavedRow(); } - if (!(pse = profileStore.findEntryFromFullPath(profileFullPath))) { + if (!(pse = ProfileStore::getInstance()->findEntryFromFullPath(profileFullPath))) { // entry not found, pse = the Internal ProfileStoreEntry - pse = profileStore.getInternalDefaultPSE(); + pse = ProfileStore::getInstance()->getInternalDefaultPSE(); } - defprofile = profileStore.getProfile (pse); + defprofile = ProfileStore::getInstance()->getProfile (pse); // selecting the "Internal" entry profiles->setInternalEntry (); diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index 8293c1803..72c9db36b 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -24,9 +24,9 @@ #include "../rtengine/rtengine.h" #include "pparamschangelistener.h" #include "profilechangelistener.h" -#include "profilestore.h" #include "partialpastedlg.h" #include "guiutils.h" +#include "profilestorecombobox.h" #include "rtimage.h" class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc new file mode 100644 index 000000000..bfdb406e7 --- /dev/null +++ b/rtgui/profilestorecombobox.cc @@ -0,0 +1,358 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "../rtengine/profilestore.h" +#include "profilestorecombobox.h" + +#include "../rtengine/dynamicprofile.h" +#include "options.h" +#include "toolpanel.h" +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ProfileStoreLabel::ProfileStoreLabel(const ProfileStoreEntry *entry) : Gtk::Label(entry->label), entry(entry) +{ + set_alignment(0, 0.5); + set_ellipsize(Pango::ELLIPSIZE_END); + show(); +} + +ProfileStoreComboBox::ProfileStoreComboBox () +{ + updateProfileList(); + setPreferredWidth(50, 120); +} + +Glib::ustring ProfileStoreComboBox::getCurrentLabel() +{ + Glib::ustring currLabel; + Gtk::TreeModel::iterator currRow = get_active(); + + if (currRow) { + const ProfileStoreEntry *currEntry = (*currRow)[methodColumns.profileStoreEntry]; + return currEntry->label; + } + + return currLabel; +} + +const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() +{ + Gtk::TreeModel::iterator currRow_ = get_active(); + Gtk::TreeModel::Row currRow = *currRow_; + + if (currRow) { + return currRow[methodColumns.profileStoreEntry]; + } else { + return nullptr; + } +} + +/** @brief Recursive method to update the combobox entries */ +void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList) +{ + for (auto entry : *entryList) { + if (entry->parentFolderId == parentFolderId) { // filtering the entry of the same folder + if (entry->type == PSET_FOLDER) { + Glib::ustring folderPath( ProfileStore::getInstance()->getPathFromId(entry->folderId) ); + + if (options.useBundledProfiles || ((folderPath != "${G}" ) && (folderPath != "${U}" ))) { + // creating the new submenu + Gtk::TreeModel::Row newSubMenu; + + if (initial) { + newSubMenu = *(refTreeModel->append()); + } else { + newSubMenu = *(refTreeModel->append(parentRow->children())); + } + + // creating and assigning the custom Label object + newSubMenu[methodColumns.label] = entry->label; + newSubMenu[methodColumns.profileStoreEntry] = entry; +#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION == 18 + // HACK: Workaround for bug in Gtk+ 3.18... + Gtk::TreeModel::Row menuHeader = *(refTreeModel->append(newSubMenu->children())); + menuHeader[methodColumns.label] = "-"; + menuHeader[methodColumns.profileStoreEntry] = entry; +#endif + refreshProfileList_ (&newSubMenu, entry->folderId, false, entryList); + } else { + refreshProfileList_ (parentRow, entry->folderId, true, entryList); + } + } else { + Gtk::TreeModel::Row newItem; + + // creating a menu entry + if (initial) { + newItem = *(refTreeModel->append()); + } else { + newItem = *(refTreeModel->append(parentRow->children())); + } + + newItem[methodColumns.label] = entry->label; + newItem[methodColumns.profileStoreEntry] = entry; + } + } + } +} +/** @brief Get the ProfileStore's entry list and recreate the combobox entries. + * If you want to update the ProfileStore list itself (rescan the dir tree), use the "ProfileStore::parseProfiles" method instead + * + * This method has to be called by the ProfileStoreListener having a ProfileStoreComboBox. + */ +void ProfileStoreComboBox::updateProfileList () +{ + // clear items + clear(); + refTreeModel.clear(); + // Create the Tree model + refTreeModel = Gtk::TreeStore::create(methodColumns); + // Assign the model to the Combobox + set_model(refTreeModel); + + // this will lock the profilestore's entry list too + const std::vector *entryList = ProfileStore::getInstance()->getFileList(); + + //profileStore.dumpFolderList(); + refreshProfileList_ (NULL, entryList->at(0)->parentFolderId, true, entryList); + + if (entryList->at(0)->parentFolderId != 0) { + // special case for the Internal default entry + addRow(ProfileStore::getInstance()->getInternalDefaultPSE()); + } + + // releasing the profilestore's entry list mutex + ProfileStore::getInstance()->releaseFileList(); + + pack_start(methodColumns.label, false); + + Gtk::CellRendererText* cellRenderer = dynamic_cast(get_first_cell()); + cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; + cellRenderer->property_ellipsize_set() = true; +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) +{ + Gtk::TreeModel::Row row; + Gtk::TreeIter rowInSubLevel; + + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + row = *iter; + // Hombre: is there a smarter way of knowing if this row has childs? + const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; + + if (pse_->type == PSET_FOLDER) { + rowInSubLevel = findRowFromEntry_ (iter->children(), pse); + + if (rowInSubLevel) { + // entry found + return rowInSubLevel; + } + } else if (pse_ == pse) { + // entry found + return iter; + } + } + + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) +{ + Gtk::TreeModel::Children childs = refTreeModel->children(); + + if (pse) { + Gtk::TreeIter row = findRowFromEntry_ (childs, pse); + return row; + } + + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name) +{ + Gtk::TreeModel::Row row; + Gtk::TreeIter rowInSubLevel; + + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + row = *iter; + // Hombre: is there a smarter way of knowing if this row has childs? + const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; + + if (pse->type == PSET_FOLDER) { + rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); + + if (rowInSubLevel) { + // entry found + return rowInSubLevel; + } + } else if (parentFolderId == pse->parentFolderId && name == pse->label) { + // entry found + return iter; + } + } + + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) +{ + Gtk::TreeIter row; + ProfileStore *profileStore = ProfileStore::getInstance(); + + if (path.empty()) { + return row; + } + + if (path == DEFPROFILE_INTERNAL) { + row = findRowFromEntry(profileStore->getInternalDefaultPSE()); + return row; + } + + if (path == DEFPROFILE_DYNAMIC) { + row = findRowFromEntry(profileStore->getInternalDynamicPSE()); + return row; + } + + // removing the filename + Glib::ustring fName = Glib::path_get_basename(path); + + if (!fName.empty()) { + path = path.substr(0, path.length() - fName.length()); + } else { + // path is malformed; + return row; + } + + path = Glib::path_get_dirname(path); + int parentFolderId = profileStore->findFolderId(path); + + // 1. find the path in the folder list + if (parentFolderId != -1) { + row = findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); + } + + return row; +} + +/** @brief Get the absolute full path of the active row entry. + * @return The absolute full path of the active row entry, or the "Internal" keyword, + * or an empty string if the ComboBox is in an invalid state + */ +Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() +{ + Glib::ustring path; + Gtk::TreeModel::iterator currRowI = get_active(); + ProfileStore *profileStore = ProfileStore::getInstance(); + + if (!currRowI) { + return path; + } + + Gtk::TreeModel::Row currRow = *currRowI; + + if (currRow) { + + const ProfileStoreEntry *currEntry = currRow[methodColumns.profileStoreEntry]; + + if (!currEntry) { + return path; + } + + if (currEntry == profileStore->getInternalDefaultPSE()) { + return Glib::ustring(DEFPROFILE_INTERNAL); + } + + if (currEntry == profileStore->getInternalDynamicPSE()) { + return Glib::ustring(DEFPROFILE_DYNAMIC); + } + + path = Glib::build_filename(profileStore->getPathFromId(currEntry->parentFolderId), currEntry->label); + } + + return path; +} + +bool ProfileStoreComboBox::setActiveRowFromFullPath(Glib::ustring path) +{ + if (!path.empty()) { + Gtk::TreeIter row = findRowFromFullPath(path); + + if (row) { + set_active(row); + return true; + } + } + + return false; +} + +bool ProfileStoreComboBox::setActiveRowFromEntry(const ProfileStoreEntry *pse) +{ + if (pse) { + Gtk::TreeIter row = findRowFromEntry(pse); + + if (row) { + set_active(row); + return true; + } + } + + return false; +} + +bool ProfileStoreComboBox::setInternalEntry () +{ + return setActiveRowFromEntry(ProfileStore::getInstance()->getInternalDefaultPSE()); +} + +/** @brief Get the row from the first level of the tree that match the provided name */ +Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) +{ + Gtk::TreeIter row; + Gtk::TreeModel::Children childs = refTreeModel->children(); + + if (!name.empty()) { + Gtk::TreeModel::Row currRow; + + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + currRow = *iter; + const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; + + if (pse->label == name) { + return currRow; + } + } + } + + return childs.end(); + //return refTreeModel->get_iter(""); // is this fast? We want to send back a null, anvalid or end() iterator object here +} + +/** @brief Add a new row to the first level of the tree */ +Gtk::TreeIter ProfileStoreComboBox::addRow(const ProfileStoreEntry *profileStoreEntry) +{ + Gtk::TreeIter newEntry = refTreeModel->append(); + Gtk::TreeModel::Row row = *newEntry; + row[methodColumns.label] = profileStoreEntry->label; + row[methodColumns.profileStoreEntry] = profileStoreEntry; + return newEntry; +} + diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h new file mode 100644 index 000000000..70ccd9298 --- /dev/null +++ b/rtgui/profilestorecombobox.h @@ -0,0 +1,95 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _PROFILESTORECOMBOBOX_ +#define _PROFILESTORECOMBOBOX_ + +#include +#include +#include + +#include "../rtengine/rtengine.h" +#include "../rtengine/noncopyable.h" +#include "../rtengine/profilestore.h" + +#include "threadutils.h" +#include "paramsedited.h" +#include "guiutils.h" + + +/** + * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry + */ +class ProfileStoreLabel : public Gtk::Label +{ + +public: + const ProfileStoreEntry *entry; + +#ifndef NDEBUG + ProfileStoreLabel() : Gtk::Label("*** error ***"), entry(nullptr) {} +#else + ProfileStoreLabel() : Gtk::Label(""), entry(NULL) {} +#endif + + /** @brief Create a new ProfileStoreLabel + * + * @param entry Pointer to the ProfileStoreEntry object, be it a directory or a file + */ + explicit ProfileStoreLabel(const ProfileStoreEntry *entry); + ProfileStoreLabel (const ProfileStoreLabel &other); +}; + +class ProfileStoreComboBox : public MyComboBox +{ + +protected: + class MethodColumns : public Gtk::TreeModel::ColumnRecord + { + public: + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn profileStoreEntry; + MethodColumns() + { + add(label); + add(profileStoreEntry); + } + }; + + Glib::RefPtr refTreeModel; + MethodColumns methodColumns; + void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); + Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); + Gtk::TreeIter findRowFromFullPath_(Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); + +public: + ProfileStoreComboBox(); + void updateProfileList(); + Glib::ustring getCurrentLabel(); + const ProfileStoreEntry* getSelectedEntry(); + Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse); + Gtk::TreeIter findRowFromFullPath (Glib::ustring path); + Glib::ustring getFullPathFromActiveRow (); + bool setActiveRowFromFullPath (Glib::ustring oldPath); + bool setActiveRowFromEntry (const ProfileStoreEntry *pse); + bool setInternalEntry (); + Gtk::TreeIter getRowFromLabel(Glib::ustring name); + Gtk::TreeIter addRow(const ProfileStoreEntry *profileStoreEntry); +}; + +#endif diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index cd33f393d..54527a5d5 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -26,11 +26,12 @@ #include #include "../rtengine/imagedata.h" #include + +#include "../rtengine/dynamicprofile.h" #include "guiutils.h" -#include "profilestore.h" #include "batchqueue.h" #include "extprog.h" -#include "dynamicprofile.h" +#include "profilestorecombobox.h" using namespace rtengine::procparams; @@ -177,7 +178,7 @@ const ProcParams& Thumbnail::getProcParamsU () if (pparamsValid) { return pparams; } else { - pparams = *(profileStore.getDefaultProcParams (getType() == FT_Raw)); + pparams = *(ProfileStore::getInstance()->getDefaultProcParams (getType() == FT_Raw)); if (pparams.wb.method == "Camera") { double ct; @@ -231,7 +232,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu } else { imageMetaData = rtengine::ImageMetaData::fromFile (fname, nullptr); } - PartialProfile *pp = loadDynamicProfile(imageMetaData); + PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData); int err = pp->pparams->save(outFName); pp->deleteInstance(); delete pp; @@ -239,7 +240,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu loadProcParams(); } } else if (create && defProf != DEFPROFILE_DYNAMIC) { - const PartialProfile *p = profileStore.getProfile(defProf); + const PartialProfile *p = ProfileStore::getInstance()->getProfile(defProf); if (p && !p->pparams->save(outFName)) { loadProcParams(); } @@ -315,7 +316,7 @@ void Thumbnail::loadProcParams () pparamsValid = false; pparams.setDefaults(); - const PartialProfile *defaultPP = profileStore.getDefaultPartialProfile(getType() == FT_Raw); + const PartialProfile *defaultPP = ProfileStore::getInstance()->getDefaultPartialProfile(getType() == FT_Raw); defaultPP->applyTo(&pparams); if (options.paramsLoadLocation == PLL_Input) { From 8c309d0f04bcee6cd5bc6268c596c6110777155b Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 25 Apr 2017 22:33:22 +0200 Subject: [PATCH 02/11] Several files astylized. --- rtengine/dynamicprofile.cc | 230 +++++++++--------- rtengine/dynamicprofile.h | 22 +- rtengine/profilestore.cc | 153 ++++++------ rtengine/profilestore.h | 20 +- rtgui/dynamicprofilepanel.cc | 427 ++++++++++++++++++---------------- rtgui/dynamicprofilepanel.h | 68 +++--- rtgui/preferences.cc | 14 +- rtgui/profilestorecombobox.cc | 76 +++--- rtgui/profilestorecombobox.h | 16 +- 9 files changed, 533 insertions(+), 493 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 4ee76dda6..380af29be 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -25,7 +25,8 @@ using namespace rtengine; using namespace rtengine::procparams; -namespace { +namespace +{ const int ISO_MAX = 512000; const double FNUMBER_MAX = 100.0; @@ -38,14 +39,15 @@ const double EXPCOMP_MAX = 20.0; DynamicProfileRules dynamicProfileRules; -bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const +bool DynamicProfileRule::Optional::operator() (const Glib::ustring &val) const { if (!enabled) { return true; } - if (value.find("re:") == 0) { + + if (value.find ("re:") == 0) { // this is a regexp - return Glib::Regex::match_simple(value.substr(3), val, Glib::REGEX_CASELESS); + return Glib::Regex::match_simple (value.substr (3), val, Glib::REGEX_CASELESS); } else { // normal string comparison return value.casefold() == val.casefold(); @@ -54,75 +56,79 @@ bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const DynamicProfileRule::DynamicProfileRule(): - serial_number(0), - iso(0, ISO_MAX), - fnumber(0, FNUMBER_MAX), - focallen(0, FOCALLEN_MAX), - shutterspeed(0, SHUTTERSPEED_MAX), - expcomp(EXPCOMP_MIN, EXPCOMP_MAX) + serial_number (0), + iso (0, ISO_MAX), + fnumber (0, FNUMBER_MAX), + focallen (0, FOCALLEN_MAX), + shutterspeed (0, SHUTTERSPEED_MAX), + expcomp (EXPCOMP_MIN, EXPCOMP_MAX) { } -bool DynamicProfileRule::operator<(const DynamicProfileRule &other) const +bool DynamicProfileRule::operator< (const DynamicProfileRule &other) const { return serial_number < other.serial_number; } -bool DynamicProfileRule::matches(const rtengine::ImageMetaData *im) const +bool DynamicProfileRule::matches (const rtengine::ImageMetaData *im) const { - return (iso(im->getISOSpeed()) - && fnumber(im->getFNumber()) - && focallen(im->getFocalLen()) - && shutterspeed(im->getShutterSpeed()) - && expcomp(im->getExpComp()) - && camera(im->getCamera()) - && lens(im->getLens())); + return (iso (im->getISOSpeed()) + && fnumber (im->getFNumber()) + && focallen (im->getFocalLen()) + && shutterspeed (im->getShutterSpeed()) + && expcomp (im->getExpComp()) + && camera (im->getCamera()) + && lens (im->getLens())); } -namespace { +namespace +{ -void get_int_range(DynamicProfileRule::Range &dest, +void get_int_range (DynamicProfileRule::Range &dest, + const Glib::KeyFile &kf, const Glib::ustring &group, + const Glib::ustring &key) +{ + try { + int min = kf.get_integer (group, key + "_min"); + int max = kf.get_integer (group, key + "_max"); + + if (min <= max) { + dest.min = min; + dest.max = max; + } + } catch (Glib::KeyFileError &e) { + } +} + + +void get_double_range (DynamicProfileRule::Range &dest, + const Glib::KeyFile &kf, const Glib::ustring &group, + const Glib::ustring &key) +{ + try { + double min = kf.get_double (group, key + "_min"); + double max = kf.get_double (group, key + "_max"); + + if (min <= max) { + dest.min = min; + dest.max = max; + } + } catch (Glib::KeyFileError &e) { + } +} + + +void get_optional (DynamicProfileRule::Optional &dest, const Glib::KeyFile &kf, const Glib::ustring &group, const Glib::ustring &key) { try { - int min = kf.get_integer(group, key + "_min"); - int max = kf.get_integer(group, key + "_max"); - if (min <= max) { - dest.min = min; - dest.max = max; - } - } catch (Glib::KeyFileError &e) { - } -} + bool e = kf.get_boolean (group, key + "_enabled"); - -void get_double_range(DynamicProfileRule::Range &dest, - const Glib::KeyFile &kf, const Glib::ustring &group, - const Glib::ustring &key) -{ - try { - double min = kf.get_double(group, key + "_min"); - double max = kf.get_double(group, key + "_max"); - if (min <= max) { - dest.min = min; - dest.max = max; - } - } catch (Glib::KeyFileError &e) { - } -} - - -void get_optional(DynamicProfileRule::Optional &dest, - const Glib::KeyFile &kf, const Glib::ustring &group, - const Glib::ustring &key) -{ - try { - bool e = kf.get_boolean(group, key + "_enabled"); if (e) { - Glib::ustring s = kf.get_string(group, key + "_value"); + Glib::ustring s = kf.get_string (group, key + "_value"); dest.enabled = e; dest.value = s; } @@ -130,28 +136,28 @@ void get_optional(DynamicProfileRule::Optional &dest, } } -void set_int_range(Glib::KeyFile &kf, const Glib::ustring &group, +void set_int_range (Glib::KeyFile &kf, const Glib::ustring &group, + const Glib::ustring &key, + const DynamicProfileRule::Range &val) +{ + kf.set_integer (group, key + "_min", val.min); + kf.set_integer (group, key + "_max", val.max); +} + +void set_double_range (Glib::KeyFile &kf, const Glib::ustring &group, + const Glib::ustring &key, + const DynamicProfileRule::Range &val) +{ + kf.set_double (group, key + "_min", val.min); + kf.set_double (group, key + "_max", val.max); +} + +void set_optional (Glib::KeyFile &kf, const Glib::ustring &group, const Glib::ustring &key, - const DynamicProfileRule::Range &val) + const DynamicProfileRule::Optional &val) { - kf.set_integer(group, key + "_min", val.min); - kf.set_integer(group, key + "_max", val.max); -} - -void set_double_range(Glib::KeyFile &kf, const Glib::ustring &group, - const Glib::ustring &key, - const DynamicProfileRule::Range &val) -{ - kf.set_double(group, key + "_min", val.min); - kf.set_double(group, key + "_max", val.max); -} - -void set_optional(Glib::KeyFile &kf, const Glib::ustring &group, - const Glib::ustring &key, - const DynamicProfileRule::Optional &val) -{ - kf.set_boolean(group, key + "_enabled", val.enabled); - kf.set_string(group, key + "_value", val.value); + kf.set_boolean (group, key + "_enabled", val.enabled); + kf.set_string (group, key + "_value", val.value); } } // namespace @@ -160,48 +166,57 @@ bool DynamicProfileRules::loadRules() { dynamicRules.clear(); Glib::KeyFile kf; + try { - if (!kf.load_from_file(Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"))) { + if (!kf.load_from_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"))) { return false; } } catch (Glib::Error &e) { return false; } + if (options.rtSettings.verbose) { - printf("loading dynamic profiles...\n"); + printf ("loading dynamic profiles...\n"); } + auto groups = kf.get_groups(); + for (auto group : groups) { // groups are of the form "rule N", where N is a positive integer - if (group.find("rule ") != 0) { + if (group.find ("rule ") != 0) { return false; } - std::istringstream buf(group.c_str() + 5); - int serial = 0; - if (!(buf >> serial) || !buf.eof()) { - return false; - } - if (options.rtSettings.verbose) { - printf(" loading rule %d\n", serial); - } - dynamicRules.emplace_back(DynamicProfileRule()); + std::istringstream buf (group.c_str() + 5); + int serial = 0; + + if (! (buf >> serial) || !buf.eof()) { + return false; + } + + if (options.rtSettings.verbose) { + printf (" loading rule %d\n", serial); + } + + dynamicRules.emplace_back (DynamicProfileRule()); DynamicProfileRule &rule = dynamicRules.back(); rule.serial_number = serial; - get_int_range(rule.iso, kf, group, "iso"); - get_double_range(rule.fnumber, kf, group, "fnumber"); - get_double_range(rule.focallen, kf, group, "focallen"); - get_double_range(rule.shutterspeed, kf, group, "shutterspeed"); - get_double_range(rule.expcomp, kf, group, "expcomp"); - get_optional(rule.camera, kf, group, "camera"); - get_optional(rule.lens, kf, group, "lens"); + get_int_range (rule.iso, kf, group, "iso"); + get_double_range (rule.fnumber, kf, group, "fnumber"); + get_double_range (rule.focallen, kf, group, "focallen"); + get_double_range (rule.shutterspeed, kf, group, "shutterspeed"); + get_double_range (rule.expcomp, kf, group, "expcomp"); + get_optional (rule.camera, kf, group, "camera"); + get_optional (rule.lens, kf, group, "lens"); + try { - rule.profilepath = kf.get_string(group, "profilepath"); + rule.profilepath = kf.get_string (group, "profilepath"); } catch (Glib::KeyFileError &) { dynamicRules.pop_back(); } } - std::sort(dynamicRules.begin(), dynamicRules.end()); + + std::sort (dynamicRules.begin(), dynamicRules.end()); rulesLoaded = true; return true; } @@ -209,23 +224,26 @@ bool DynamicProfileRules::loadRules() bool DynamicProfileRules::storeRules() { if (options.rtSettings.verbose) { - printf("saving dynamic profiles...\n"); + printf ("saving dynamic profiles...\n"); } + Glib::KeyFile kf; + for (auto &rule : dynamicRules) { std::ostringstream buf; buf << "rule " << rule.serial_number; Glib::ustring group = buf.str(); - set_int_range(kf, group, "iso", rule.iso); - set_double_range(kf, group, "fnumber", rule.fnumber); - set_double_range(kf, group, "focallen", rule.focallen); - set_double_range(kf, group, "shutterspeed", rule.shutterspeed); - set_double_range(kf, group, "expcomp", rule.expcomp); - set_optional(kf, group, "camera", rule.camera); - set_optional(kf, group, "lens", rule.lens); - kf.set_string(group, "profilepath", rule.profilepath); + set_int_range (kf, group, "iso", rule.iso); + set_double_range (kf, group, "fnumber", rule.fnumber); + set_double_range (kf, group, "focallen", rule.focallen); + set_double_range (kf, group, "shutterspeed", rule.shutterspeed); + set_double_range (kf, group, "expcomp", rule.expcomp); + set_optional (kf, group, "camera", rule.camera); + set_optional (kf, group, "lens", rule.lens); + kf.set_string (group, "profilepath", rule.profilepath); } - return kf.save_to_file(Glib::build_filename(Options::rtdir, "dynamicprofile.cfg")); + + return kf.save_to_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg")); } const std::vector &DynamicProfileRules::getRules() const @@ -233,7 +251,7 @@ const std::vector &DynamicProfileRules::getRules() const return dynamicRules; } -void DynamicProfileRules::setRules(const std::vector &r) +void DynamicProfileRules::setRules (const std::vector &r) { dynamicRules = r; } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index 45c28f07c..b59838e3f 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -23,15 +23,16 @@ #include #include "../rtgui/options.h" -class DynamicProfileRule { +class DynamicProfileRule +{ public: template struct Range { T min; T max; - explicit Range(T l=T(), T u=T()): min(l), max(u) {} + explicit Range (T l = T(), T u = T()): min (l), max (u) {} - bool operator()(T val) const + bool operator() (T val) const { return val >= min && val <= max; } @@ -40,15 +41,15 @@ public: struct Optional { Glib::ustring value; bool enabled; - explicit Optional(const Glib::ustring v="", bool e=false): - value(v), enabled(e) {} + explicit Optional (const Glib::ustring v = "", bool e = false): + value (v), enabled (e) {} - bool operator()(const Glib::ustring &val) const; + bool operator() (const Glib::ustring &val) const; }; DynamicProfileRule(); - bool matches(const rtengine::ImageMetaData *im) const; - bool operator<(const DynamicProfileRule &other) const; + bool matches (const rtengine::ImageMetaData *im) const; + bool operator< (const DynamicProfileRule &other) const; int serial_number; Range iso; @@ -61,7 +62,8 @@ public: Glib::ustring profilepath; }; -class DynamicProfileRules { +class DynamicProfileRules +{ protected: /** cache for dynamic profile rules */ std::vector dynamicRules; @@ -71,7 +73,7 @@ public: bool loadRules(); bool storeRules(); const std::vector &getRules() const; - void setRules(const std::vector &r); + void setRules (const std::vector &r); }; #endif // _DYNAMICPROFILE_H_ diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 38619f0eb..984ab9423 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -25,10 +25,10 @@ using namespace rtengine; using namespace rtengine::procparams; -ProfileStore::ProfileStore () : storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(nullptr), internalDefaultEntry(nullptr), internalDynamicEntry(nullptr), loadAll(true) +ProfileStore::ProfileStore () : storeState (STORESTATE_NOTINITIALIZED), internalDefaultProfile (nullptr), internalDefaultEntry (nullptr), internalDynamicEntry (nullptr), loadAll (true) { internalDefaultProfile = new AutoPartialProfile(); - internalDefaultProfile->set(true); + internalDefaultProfile->set (true); } ProfileStore* ProfileStore::getInstance() @@ -65,14 +65,14 @@ ProfileStore::~ProfileStore () storeState = STORESTATE_DELETED; { - MyMutex::MyLock lock(parseMutex); + MyMutex::MyLock lock (parseMutex); - clearProfileList (); - partProfiles.clear (); - clearFileList(); - delete internalDefaultProfile; - delete internalDefaultEntry; - delete internalDynamicEntry; + clearProfileList (); + partProfiles.clear (); + clearFileList(); + delete internalDefaultProfile; + delete internalDefaultEntry; + delete internalDynamicEntry; } } @@ -107,14 +107,14 @@ void ProfileStore::_parseProfiles () clearFileList(); clearProfileList (); - folders.push_back("<<< ROOT >>>"); // Fake path, so parentFolderId == 0 will be used to attach a ProfileStoreEntry to the root container, not sub-menu + folders.push_back ("<<< ROOT >>>"); // Fake path, so parentFolderId == 0 will be used to attach a ProfileStoreEntry to the root container, not sub-menu Glib::ustring p1 = options.getUserProfilePath(); Glib::ustring p2 = options.getGlobalProfilePath(); bool displayLevel0 = options.useBundledProfiles && !p1.empty() && !p2.empty() && p1 != p2; - Glib::ustring virtualPath("${U}"); - Glib::ustring currDir("${U}"); + Glib::ustring virtualPath ("${U}"); + Glib::ustring currDir ("${U}"); parseDir (p1, virtualPath, currDir, 0, 0, displayLevel0); if (displayLevel0) { @@ -124,35 +124,35 @@ void ProfileStore::_parseProfiles () } // sort profiles - std::sort(entries.begin(), entries.end(), SortProfiles() ); + std::sort (entries.begin(), entries.end(), SortProfiles() ); // entries and partProfiles are empty, but the entry and profiles already exist (they have survived to clearFileList and clearProfileList) if (!internalDefaultEntry) { - internalDefaultEntry = new ProfileStoreEntry(Glib::ustring("(") + M("PROFILEPANEL_PINTERNAL") + Glib::ustring(")"), PSET_FILE, 0, 0); + internalDefaultEntry = new ProfileStoreEntry (Glib::ustring ("(") + M ("PROFILEPANEL_PINTERNAL") + Glib::ustring (")"), PSET_FILE, 0, 0); } - entries.push_back(internalDefaultEntry); + entries.push_back (internalDefaultEntry); partProfiles[internalDefaultEntry] = internalDefaultProfile; if (!internalDynamicEntry) { - internalDynamicEntry = new ProfileStoreEntry(Glib::ustring("(") + M("PROFILEPANEL_PDYNAMIC") + Glib::ustring(")"), PSET_FILE, 0, 0); + internalDynamicEntry = new ProfileStoreEntry (Glib::ustring ("(") + M ("PROFILEPANEL_PDYNAMIC") + Glib::ustring (")"), PSET_FILE, 0, 0); // do not add it to the entries. This is here only for the preferences dialog } // Check if the default profiles has been found. - if (findEntryFromFullPathU(options.defProfRaw) == nullptr) { - options.setDefProfRawMissing(true); + if (findEntryFromFullPathU (options.defProfRaw) == nullptr) { + options.setDefProfRawMissing (true); if (options.rtSettings.verbose) { - printf("WARNING: Default profile \"%s\" for raw images not found!\n", options.defProfRaw.c_str()); + printf ("WARNING: Default profile \"%s\" for raw images not found!\n", options.defProfRaw.c_str()); } } - if (findEntryFromFullPathU(options.defProfImg) == nullptr) { - options.setDefProfImgMissing(true); + if (findEntryFromFullPathU (options.defProfImg) == nullptr) { + options.setDefProfImgMissing (true); if (options.rtSettings.verbose) { - printf("WARNING: Default profile \"%s\" for standard images not found!\n", options.defProfImg.c_str()); + printf ("WARNING: Default profile \"%s\" for standard images not found!\n", options.defProfImg.c_str()); } } } @@ -163,23 +163,23 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath bool fileFound = false; // reload the available profiles from the profile dir - if (!realPath.empty() && Glib::file_test(realPath, Glib::FILE_TEST_EXISTS) && Glib::file_test (realPath, Glib::FILE_TEST_IS_DIR)) { + if (!realPath.empty() && Glib::file_test (realPath, Glib::FILE_TEST_EXISTS) && Glib::file_test (realPath, Glib::FILE_TEST_IS_DIR)) { unsigned int folder = 0; // folder's own Id // add this entry to the folder list - folders.push_back(virtualPath); - folder = (unsigned int)(folders.size()) - 1; + folders.push_back (virtualPath); + folder = (unsigned int) (folders.size()) - 1; if (level > 0 || displayLevel0) { // replace the virtual folder name by a localized text if (currDir == "${U}") { - currDir = M("PROFILEPANEL_MYPROFILES"); + currDir = M ("PROFILEPANEL_MYPROFILES"); } else if (currDir == "${G}") { - currDir = M("PROFILEPANEL_GLOBALPROFILES"); + currDir = M ("PROFILEPANEL_GLOBALPROFILES"); } // add this localized text to the file list - entries.push_back( new ProfileStoreEntry(currDir, PSET_FOLDER, parentId, folder) ); + entries.push_back ( new ProfileStoreEntry (currDir, PSET_FOLDER, parentId, folder) ); } // walking through the directory @@ -193,22 +193,22 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath continue; } - Glib::ustring fname = Glib::build_filename(realPath, currDir); + Glib::ustring fname = Glib::build_filename (realPath, currDir); if (Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { - Glib::ustring vp(Glib::build_filename(virtualPath, currDir)); - Glib::ustring rp(Glib::build_filename(realPath, currDir)); + Glib::ustring vp (Glib::build_filename (virtualPath, currDir)); + Glib::ustring rp (Glib::build_filename (realPath, currDir)); fileFound = parseDir (rp, vp, currDir, folder, level + 1, 0); } else { size_t lastdot = currDir.find_last_of ('.'); - if (lastdot != Glib::ustring::npos && lastdot == currDir.length() - 4 && currDir.substr(lastdot).casefold() == paramFileExtension) { + if (lastdot != Glib::ustring::npos && lastdot == currDir.length() - 4 && currDir.substr (lastdot).casefold() == paramFileExtension) { // file found - if( options.rtSettings.verbose ) { + if ( options.rtSettings.verbose ) { printf ("Processing file %s...", fname.c_str()); } - Glib::ustring name = currDir.substr(0, lastdot); + Glib::ustring name = currDir.substr (0, lastdot); // create the partial profile AutoPartialProfile *pProf = new AutoPartialProfile(); @@ -217,18 +217,18 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath if (!res && pProf->pparams->ppVersion >= 220) { fileFound = true; - if( options.rtSettings.verbose ) { + if ( options.rtSettings.verbose ) { printf ("OK\n"); } // adding this file to the list - ProfileStoreEntry* filePSE = new ProfileStoreEntry(name, PSET_FILE, folder, 0); - entries.push_back(filePSE); + ProfileStoreEntry* filePSE = new ProfileStoreEntry (name, PSET_FILE, folder, 0); + entries.push_back (filePSE); // map the partial profile partProfiles[filePSE] = pProf; //partProfiles.insert( std::pair (filePSE, pProf) ); - } else if( options.rtSettings.verbose ) { + } else if ( options.rtSettings.verbose ) { printf ("failed!\n"); } } @@ -247,7 +247,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath return fileFound; } -int ProfileStore::findFolderId(const Glib::ustring &path) +int ProfileStore::findFolderId (const Glib::ustring &path) { // initialization must have been done when calling this for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) { @@ -265,7 +265,7 @@ int ProfileStore::findFolderId(const Glib::ustring &path) * but have to begin with a virtual location ( ${G} or ${U} ) * Will return null on invalid path or if the entry can't be found */ -const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path) +const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU (Glib::ustring path) { if (path.empty()) { return nullptr; @@ -281,37 +281,37 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path // consistently apply casefold() to make sure dot position is correct const Glib::ustring casefolded_path = path.casefold(); - const Glib::ustring::size_type lastdot_pos = casefolded_path.find_last_of('.'); + const Glib::ustring::size_type lastdot_pos = casefolded_path.find_last_of ('.'); if ( lastdot_pos != Glib::ustring::npos && lastdot_pos <= casefolded_path.size() - 4 - && !casefolded_path.compare(lastdot_pos, 4, paramFileExtension) + && !casefolded_path.compare (lastdot_pos, 4, paramFileExtension) ) { // removing the extension // now use dot position without casefold() - path = path.substr(0, path.find_last_of('.')); + path = path.substr (0, path.find_last_of ('.')); } // dir separator may come from options file and may be \ or /, we convert them to G_DIR_SEPARATOR_S if (path.size() > 4 && (path[4] == '/' || path[4] == '\\')) { - path = path.substr(0, 4) + G_DIR_SEPARATOR_S + path.substr(5); + path = path.substr (0, 4) + G_DIR_SEPARATOR_S + path.substr (5); } // removing the filename - Glib::ustring fName = Glib::path_get_basename(path); + Glib::ustring fName = Glib::path_get_basename (path); if (!fName.empty()) { - path = path.substr(0, path.length() - fName.length()); + path = path.substr (0, path.length() - fName.length()); } else { // path is malformed, returning NULL; return nullptr; } - path = Glib::path_get_dirname(path); + path = Glib::path_get_dirname (path); // 1. find the path in the folder list - int parentFolderId = findFolderId(path); + int parentFolderId = findFolderId (path); if (parentFolderId == -1) { return nullptr; @@ -330,10 +330,10 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path } /** Protected version of findEntryFromFullPathU */ -const ProfileStoreEntry* ProfileStore::findEntryFromFullPath(Glib::ustring path) +const ProfileStoreEntry* ProfileStore::findEntryFromFullPath (Glib::ustring path) { - MyMutex::MyLock lock(parseMutex); - return findEntryFromFullPathU(path); + MyMutex::MyLock lock (parseMutex); + return findEntryFromFullPathU (path); } const PartialProfile* ProfileStore::getProfile (Glib::ustring path) @@ -343,13 +343,13 @@ const PartialProfile* ProfileStore::getProfile (Glib::ustring path) parseProfiles(); } - const ProfileStoreEntry *pse = findEntryFromFullPath(path); + const ProfileStoreEntry *pse = findEntryFromFullPath (path); if (!pse) { return nullptr; } - return getProfile(pse); + return getProfile (pse); } const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry) @@ -359,20 +359,20 @@ const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry) parseProfiles(); } - MyMutex::MyLock lock(parseMutex); + MyMutex::MyLock lock (parseMutex); if (entry == internalDefaultEntry) { return internalDefaultProfile; } - std::map::iterator iter = partProfiles.find(entry); + std::map::iterator iter = partProfiles.find (entry); if (iter != partProfiles.end()) { return iter->second; } else { // This shouldn't happen! #ifndef NDEBUG - printf("WARNING! Profile not found!\n"); + printf ("WARNING! Profile not found!\n"); #endif return nullptr; } @@ -440,10 +440,10 @@ const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) return pProf; } -const Glib::ustring ProfileStore::getPathFromId(int folderId) +const Glib::ustring ProfileStore::getPathFromId (int folderId) { // initialization must have been done when calling this - return folders.at(folderId); + return folders.at (folderId); } @@ -469,60 +469,63 @@ void ProfileStore::clearProfileList() partProfiles.clear(); } -void ProfileStore::addListener(ProfileStoreListener *listener) +void ProfileStore::addListener (ProfileStoreListener *listener) { - listeners.push_back(listener); + listeners.push_back (listener); } -void ProfileStore::removeListener(ProfileStoreListener *listener) +void ProfileStore::removeListener (ProfileStoreListener *listener) { - listeners.remove(listener); + listeners.remove (listener); } void ProfileStore::dumpFolderList() { - printf("Folder list:\n------------\n"); + printf ("Folder list:\n------------\n"); for (unsigned int i = 0; i < folders.size(); i++) { - printf(" #%3ud - %s\n", i, folders.at(i).c_str()); + printf (" #%3ud - %s\n", i, folders.at (i).c_str()); } - printf("\n"); + printf ("\n"); } -PartialProfile *ProfileStore::loadDynamicProfile(const ImageMetaData *im) +PartialProfile *ProfileStore::loadDynamicProfile (const ImageMetaData *im) { if (storeState == STORESTATE_NOTINITIALIZED) { parseProfiles(); } - PartialProfile *ret = new PartialProfile(true, true); + PartialProfile *ret = new PartialProfile (true, true); if (!rulesLoaded) { loadRules(); } for (auto rule : dynamicRules) { - if (rule.matches(im)) { + if (rule.matches (im)) { if (options.rtSettings.verbose) { - printf("found matching profile %s\n", rule.profilepath.c_str()); + printf ("found matching profile %s\n", rule.profilepath.c_str()); } - const PartialProfile *p = getProfile(rule.profilepath); + + const PartialProfile *p = getProfile (rule.profilepath); + if (p != nullptr) { - p->applyTo(ret->pparams); + p->applyTo (ret->pparams); } else { - printf("ERROR loading matching profile from: %s\n", rule.profilepath.c_str()); + printf ("ERROR loading matching profile from: %s\n", rule.profilepath.c_str()); } } } + return ret; } -ProfileStoreEntry::ProfileStoreEntry() : label(""), type(PSET_FOLDER), parentFolderId(0), folderId(0) {} +ProfileStoreEntry::ProfileStoreEntry() : label (""), type (PSET_FOLDER), parentFolderId (0), folderId (0) {} -ProfileStoreEntry::ProfileStoreEntry(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label(label), type(type), parentFolderId(parentFolder), folderId(folder) {} +ProfileStoreEntry::ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label (label), type (type), parentFolderId (parentFolder), folderId (folder) {} -void ProfileStoreEntry::setValues(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) +void ProfileStoreEntry::setValues (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) { this->label = label; this->type = type; diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 8ca5bf42a..c6627b4c8 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -81,7 +81,7 @@ public: * @param parentFolder index of the elements's path in the folder list * @param folder index of the folder's own path in the folder list */ - ProfileStoreEntry(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); + ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); /** @brief Set the values of the object after its instantiation * @param label Label to be used in menu or combobox; also used as profile's filename @@ -89,7 +89,7 @@ public: * @param parentFolder index of the elements's path in the folder list * @param folder index of the folder's own path in the folder list */ - void setValues(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); + void setValues (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); }; @@ -111,7 +111,7 @@ class ProfileStore : public rtengine::NonCopyable, public DynamicProfileRules private: struct SortProfiles { - bool operator ()(const ProfileStoreEntry* const a1, const ProfileStoreEntry* const a2) + bool operator () (const ProfileStoreEntry* const a1, const ProfileStoreEntry* const a2) { return a1->parentFolderId == a2->parentFolderId ? a1->label < a2->label : a1->parentFolderId < a2->parentFolderId; } @@ -156,7 +156,7 @@ private: void _parseProfiles (); void clearFileList (); void clearProfileList (); - const ProfileStoreEntry* findEntryFromFullPathU(Glib::ustring path); + const ProfileStoreEntry* findEntryFromFullPathU (Glib::ustring path); public: @@ -167,15 +167,15 @@ public: bool init (bool loadAll = true); void parseProfiles (); - int findFolderId(const Glib::ustring &path); - const ProfileStoreEntry* findEntryFromFullPath(Glib::ustring path); + int findFolderId (const Glib::ustring &path); + const ProfileStoreEntry* findEntryFromFullPath (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (const ProfileStoreEntry* entry); const std::vector* getFileList (); void releaseFileList (); const rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); const rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw); - const Glib::ustring getPathFromId(int folderId); + const Glib::ustring getPathFromId (int folderId); const ProfileStoreEntry* getInternalDefaultPSE() { return internalDefaultEntry; @@ -186,10 +186,10 @@ public: return internalDynamicEntry; } - void addListener(ProfileStoreListener *listener); - void removeListener(ProfileStoreListener *listener); + void addListener (ProfileStoreListener *listener); + void removeListener (ProfileStoreListener *listener); - rtengine::procparams::PartialProfile* loadDynamicProfile(const rtengine::ImageMetaData *im); + rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::ImageMetaData *im); void dumpFolderList(); }; diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index eca96ece6..db3a19ed0 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -30,65 +30,63 @@ // DynamicProfilePanel::EditDialog //----------------------------------------------------------------------------- -DynamicProfilePanel::EditDialog::EditDialog(const Glib::ustring &title, - Gtk::Window &parent): - Gtk::Dialog(title, parent) +DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Window &parent): + Gtk::Dialog (title, parent) { - profilepath_ = Gtk::manage(new ProfileStoreComboBox()); - Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); - hb->pack_start(*Gtk::manage(new Gtk::Label(M("DYNPROFILEEDITOR_PROFILE"))), - false, false, 4); - hb->pack_start(*profilepath_, true, true, 2); - get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4); + profilepath_ = Gtk::manage (new ProfileStoreComboBox()); + Gtk::HBox *hb = Gtk::manage (new Gtk::HBox()); + hb->pack_start (*Gtk::manage (new Gtk::Label (M ("DYNPROFILEEDITOR_PROFILE"))), false, false, 4); + hb->pack_start (*profilepath_, true, true, 2); + get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4); - add_optional(M("EXIFFILTER_CAMERA"), has_camera_, camera_); - add_optional(M("EXIFFILTER_LENS"), has_lens_, lens_); - - add_range(M("EXIFFILTER_ISO"), iso_min_, iso_max_); - add_range(M("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_); - add_range(M("EXIFFILTER_FOCALLEN"), focallen_min_, focallen_max_); - add_range(M("EXIFFILTER_SHUTTER"), shutterspeed_min_, shutterspeed_max_); - add_range(M("EXIFFILTER_EXPOSURECOMPENSATION"), expcomp_min_, expcomp_max_); + add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_); + add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_); - add_button(M("GENERAL_OK"), 1); - add_button(M("GENERAL_CANCEL"), 2); + add_range (M ("EXIFFILTER_ISO"), iso_min_, iso_max_); + add_range (M ("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_); + add_range (M ("EXIFFILTER_FOCALLEN"), focallen_min_, focallen_max_); + add_range (M ("EXIFFILTER_SHUTTER"), shutterspeed_min_, shutterspeed_max_); + add_range (M ("EXIFFILTER_EXPOSURECOMPENSATION"), expcomp_min_, expcomp_max_); + + add_button (M ("GENERAL_OK"), 1); + add_button (M ("GENERAL_CANCEL"), 2); set_ranges(); - + show_all_children(); } -void DynamicProfilePanel::EditDialog::set_rule( +void DynamicProfilePanel::EditDialog::set_rule ( const DynamicProfileRule &rule) { - iso_min_->set_value(rule.iso.min); - iso_max_->set_value(rule.iso.max); + iso_min_->set_value (rule.iso.min); + iso_max_->set_value (rule.iso.max); - fnumber_min_->set_value(rule.fnumber.min); - fnumber_max_->set_value(rule.fnumber.max); + fnumber_min_->set_value (rule.fnumber.min); + fnumber_max_->set_value (rule.fnumber.max); - focallen_min_->set_value(rule.focallen.min); - focallen_max_->set_value(rule.focallen.max); + focallen_min_->set_value (rule.focallen.min); + focallen_max_->set_value (rule.focallen.max); - shutterspeed_min_->set_value(rule.shutterspeed.min); - shutterspeed_max_->set_value(rule.shutterspeed.max); + shutterspeed_min_->set_value (rule.shutterspeed.min); + shutterspeed_max_->set_value (rule.shutterspeed.max); - expcomp_min_->set_value(rule.expcomp.min); - expcomp_max_->set_value(rule.expcomp.max); + expcomp_min_->set_value (rule.expcomp.min); + expcomp_max_->set_value (rule.expcomp.max); - has_camera_->set_active(rule.camera.enabled); - camera_->set_text(rule.camera.value); + has_camera_->set_active (rule.camera.enabled); + camera_->set_text (rule.camera.value); - has_lens_->set_active(rule.lens.enabled); - lens_->set_text(rule.lens.value); + has_lens_->set_active (rule.lens.enabled); + lens_->set_text (rule.lens.value); profilepath_->updateProfileList(); - if (!profilepath_->setActiveRowFromFullPath(rule.profilepath)) { + + if (!profilepath_->setActiveRowFromFullPath (rule.profilepath)) { profilepath_->setInternalEntry(); } } - DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() { @@ -98,7 +96,7 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.fnumber.min = fnumber_min_->get_value(); ret.fnumber.max = fnumber_max_->get_value(); - + ret.focallen.min = focallen_min_->get_value(); ret.focallen.max = focallen_max_->get_value(); @@ -113,7 +111,7 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.lens.enabled = has_lens_->get_active(); ret.lens.value = lens_->get_text(); - + ret.profilepath = profilepath_->getFullPathFromActiveRow(); return ret; @@ -122,20 +120,20 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() void DynamicProfilePanel::EditDialog::set_ranges() { DynamicProfileRule default_rule; - iso_min_->set_digits(0); - iso_max_->set_digits(0); - iso_min_->set_increments(1, 10); - iso_max_->set_increments(1, 10); - iso_min_->set_range(default_rule.iso.min, default_rule.iso.max); - iso_max_->set_range(default_rule.iso.min, default_rule.iso.max); - iso_min_->set_value(default_rule.iso.min); - iso_max_->set_value(default_rule.iso.max); + iso_min_->set_digits (0); + iso_max_->set_digits (0); + iso_min_->set_increments (1, 10); + iso_max_->set_increments (1, 10); + iso_min_->set_range (default_rule.iso.min, default_rule.iso.max); + iso_max_->set_range (default_rule.iso.min, default_rule.iso.max); + iso_min_->set_value (default_rule.iso.min); + iso_max_->set_value (default_rule.iso.max); -#define DOIT_(name) \ - name ## _min_->set_digits(1); \ - name ## _max_->set_digits(1); \ - name ## _min_->set_increments(0.1, 1); \ - name ## _max_->set_increments(0.1, 1); \ +#define DOIT_(name) \ + name ## _min_->set_digits(1); \ + name ## _max_->set_digits(1); \ + name ## _min_->set_increments(0.1, 1); \ + name ## _max_->set_increments(0.1, 1); \ name ## _min_->set_range(default_rule. name .min, \ default_rule. name .max); \ name ## _max_->set_range(default_rule. name .min, \ @@ -143,45 +141,42 @@ void DynamicProfilePanel::EditDialog::set_ranges() name ## _min_->set_value(default_rule. name .min); \ name ## _max_->set_value(default_rule. name .max) - DOIT_(fnumber); - DOIT_(focallen); - DOIT_(shutterspeed); - DOIT_(expcomp); + DOIT_ (fnumber); + DOIT_ (focallen); + DOIT_ (shutterspeed); + DOIT_ (expcomp); #undef DOIT_ - shutterspeed_min_->set_digits(4); - shutterspeed_max_->set_digits(4); + shutterspeed_min_->set_digits (4); + shutterspeed_max_->set_digits (4); profilepath_->setInternalEntry(); } -void DynamicProfilePanel::EditDialog::add_range(const Glib::ustring &name, +void DynamicProfilePanel::EditDialog::add_range (const Glib::ustring &name, Gtk::SpinButton *&from, Gtk::SpinButton *&to) { - Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); - hb->pack_start(*Gtk::manage(new Gtk::Label(name)), false, false, 4); - from = Gtk::manage(new Gtk::SpinButton()); - to = Gtk::manage(new Gtk::SpinButton()); - from->set_numeric(true); - to->set_numeric(true); - hb->pack_start(*from, true, true, 2); - hb->pack_start(*Gtk::manage(new Gtk::Label(" - ")), - false, false, 4); - hb->pack_start(*to, true, true, 2); - get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4); + Gtk::HBox *hb = Gtk::manage (new Gtk::HBox()); + hb->pack_start (*Gtk::manage (new Gtk::Label (name)), false, false, 4); + from = Gtk::manage (new Gtk::SpinButton()); + to = Gtk::manage (new Gtk::SpinButton()); + from->set_numeric (true); + to->set_numeric (true); + hb->pack_start (*from, true, true, 2); + hb->pack_start (*Gtk::manage (new Gtk::Label (" - ")), false, false, 4); + hb->pack_start (*to, true, true, 2); + get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4); } - -void DynamicProfilePanel::EditDialog::add_optional(const Glib::ustring &name, - Gtk::CheckButton *&check, Gtk::Entry *&field) +void DynamicProfilePanel::EditDialog::add_optional (const Glib::ustring &name, Gtk::CheckButton *&check, Gtk::Entry *&field) { - check = Gtk::manage (new Gtk::CheckButton(name)); - Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); - hb->pack_start(*check, Gtk::PACK_SHRINK, 4); - field = Gtk::manage(new Gtk::Entry()); - hb->pack_start(*field, true, true, 2); - get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4); - field->set_tooltip_text(M("DYNPROFILEEDITOR_ENTRY_TOOLTIP")); + check = Gtk::manage (new Gtk::CheckButton (name)); + Gtk::HBox *hb = Gtk::manage (new Gtk::HBox()); + hb->pack_start (*check, Gtk::PACK_SHRINK, 4); + field = Gtk::manage (new Gtk::Entry()); + hb->pack_start (*field, true, true, 2); + get_content_area()->pack_start (*hb, Gtk::PACK_SHRINK, 4); + field->set_tooltip_text (M ("DYNPROFILEEDITOR_ENTRY_TOOLTIP")); } @@ -190,121 +185,135 @@ void DynamicProfilePanel::EditDialog::add_optional(const Glib::ustring &name, //----------------------------------------------------------------------------- DynamicProfilePanel::DynamicProfilePanel(): - vbox_(Gtk::ORIENTATION_VERTICAL), - button_up_(M("DYNPROFILEEDITOR_MOVE_UP")), - button_down_(M("DYNPROFILEEDITOR_MOVE_DOWN")), - button_new_(M("DYNPROFILEEDITOR_NEW")), - button_edit_(M("DYNPROFILEEDITOR_EDIT")), - button_delete_(M("DYNPROFILEEDITOR_DELETE")) + vbox_ (Gtk::ORIENTATION_VERTICAL), + button_up_ (M ("DYNPROFILEEDITOR_MOVE_UP")), + button_down_ (M ("DYNPROFILEEDITOR_MOVE_DOWN")), + button_new_ (M ("DYNPROFILEEDITOR_NEW")), + button_edit_ (M ("DYNPROFILEEDITOR_EDIT")), + button_delete_ (M ("DYNPROFILEEDITOR_DELETE")) { - add(vbox_); + add (vbox_); - treeview_.set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL); - scrolledwindow_.add(treeview_); + treeview_.set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_VERTICAL); + scrolledwindow_.add (treeview_); - scrolledwindow_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scrolledwindow_.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - vbox_.pack_start(scrolledwindow_); - vbox_.pack_start(buttonbox_, Gtk::PACK_SHRINK); + vbox_.pack_start (scrolledwindow_); + vbox_.pack_start (buttonbox_, Gtk::PACK_SHRINK); - buttonbox_.pack_start(button_new_, Gtk::PACK_SHRINK); - buttonbox_.pack_start(button_edit_, Gtk::PACK_SHRINK); - buttonbox_.pack_start(button_delete_, Gtk::PACK_SHRINK); - buttonbox_.pack_start(button_up_, Gtk::PACK_SHRINK); - buttonbox_.pack_start(button_down_, Gtk::PACK_SHRINK); - buttonbox_.set_border_width(5); - buttonbox_.set_layout(Gtk::BUTTONBOX_END); - button_up_.signal_clicked().connect( - sigc::mem_fun(*this, &DynamicProfilePanel::on_button_up)); - button_down_.signal_clicked().connect( - sigc::mem_fun(*this, &DynamicProfilePanel::on_button_down)); - button_new_.signal_clicked().connect( - sigc::mem_fun(*this, &DynamicProfilePanel::on_button_new)); - button_edit_.signal_clicked().connect( - sigc::mem_fun(*this, &DynamicProfilePanel::on_button_edit)); - button_delete_.signal_clicked().connect( - sigc::mem_fun(*this, &DynamicProfilePanel::on_button_delete)); + buttonbox_.pack_start (button_new_, Gtk::PACK_SHRINK); + buttonbox_.pack_start (button_edit_, Gtk::PACK_SHRINK); + buttonbox_.pack_start (button_delete_, Gtk::PACK_SHRINK); + buttonbox_.pack_start (button_up_, Gtk::PACK_SHRINK); + buttonbox_.pack_start (button_down_, Gtk::PACK_SHRINK); + buttonbox_.set_border_width (5); + buttonbox_.set_layout (Gtk::BUTTONBOX_END); + button_up_.signal_clicked().connect ( + sigc::mem_fun (*this, &DynamicProfilePanel::on_button_up)); + button_down_.signal_clicked().connect ( + sigc::mem_fun (*this, &DynamicProfilePanel::on_button_down)); + button_new_.signal_clicked().connect ( + sigc::mem_fun (*this, &DynamicProfilePanel::on_button_new)); + button_edit_.signal_clicked().connect ( + sigc::mem_fun (*this, &DynamicProfilePanel::on_button_edit)); + button_delete_.signal_clicked().connect ( + sigc::mem_fun (*this, &DynamicProfilePanel::on_button_delete)); - treemodel_ = Gtk::ListStore::create(columns_); - treeview_.set_model(treemodel_); + treemodel_ = Gtk::ListStore::create (columns_); + treeview_.set_model (treemodel_); + + auto cell = Gtk::manage (new Gtk::CellRendererText()); + int cols_count = treeview_.append_column ( M ("DYNPROFILEEDITOR_PROFILE"), *cell); + auto col = treeview_.get_column (cols_count - 1); - auto cell = Gtk::manage(new Gtk::CellRendererText()); - int cols_count = treeview_.append_column( - M("DYNPROFILEEDITOR_PROFILE"), *cell); - auto col = treeview_.get_column(cols_count - 1); if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_profilepath)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column( - M("EXIFFILTER_CAMERA"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column ( + M ("EXIFFILTER_CAMERA"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_camera)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column(M("EXIFFILTER_LENS"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_LENS"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_lens)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column(M("EXIFFILTER_ISO"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_ISO"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_iso)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column(M("EXIFFILTER_APERTURE"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_APERTURE"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_fnumber)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column(M("EXIFFILTER_FOCALLEN"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_FOCALLEN"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_focallen)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column(M("EXIFFILTER_SHUTTER"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_SHUTTER"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_shutterspeed)); } - cell = Gtk::manage(new Gtk::CellRendererText()); - cols_count = treeview_.append_column( - M("EXIFFILTER_EXPOSURECOMPENSATION"), *cell); - col = treeview_.get_column(cols_count - 1); + + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column ( + M ("EXIFFILTER_EXPOSURECOMPENSATION"), *cell); + col = treeview_.get_column (cols_count - 1); + if (col) { - col->set_cell_data_func( - *cell, sigc::mem_fun( + col->set_cell_data_func ( + *cell, sigc::mem_fun ( *this, &DynamicProfilePanel::render_expcomp)); } - + show_all_children(); for (auto &r : ProfileStore::getInstance()->getRules()) { - add_rule(r); + add_rule (r); } } -void DynamicProfilePanel::update_rule(Gtk::TreeModel::Row row, +void DynamicProfilePanel::update_rule (Gtk::TreeModel::Row row, const DynamicProfileRule &rule) { row[columns_.iso] = rule.iso; @@ -317,15 +326,15 @@ void DynamicProfilePanel::update_rule(Gtk::TreeModel::Row row, row[columns_.profilepath] = rule.profilepath; } -void DynamicProfilePanel::add_rule(const DynamicProfileRule &rule) +void DynamicProfilePanel::add_rule (const DynamicProfileRule &rule) { - auto row = *(treemodel_->append()); - update_rule(row, rule); + auto row = * (treemodel_->append()); + update_rule (row, rule); } -DynamicProfileRule DynamicProfilePanel::to_rule(Gtk::TreeModel::Row row, - int serial) +DynamicProfileRule DynamicProfilePanel::to_rule (Gtk::TreeModel::Row row, + int serial) { DynamicProfileRule ret; ret.serial_number = serial; @@ -341,13 +350,14 @@ DynamicProfileRule DynamicProfilePanel::to_rule(Gtk::TreeModel::Row row, } -void DynamicProfilePanel::render_profilepath( +void DynamicProfilePanel::render_profilepath ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { auto row = *iter; - Gtk::CellRendererText *ct = static_cast(cell); + Gtk::CellRendererText *ct = static_cast (cell); auto value = row[columns_.profilepath]; - auto pse = ProfileStore::getInstance()->findEntryFromFullPath(value); + auto pse = ProfileStore::getInstance()->findEntryFromFullPath (value); + if (pse != nullptr) { ct->property_text() = pse->label; } else { @@ -369,54 +379,56 @@ void DynamicProfilePanel::render_profilepath( } -namespace { +namespace +{ template -Glib::ustring to_str(V n, int precision=1) +Glib::ustring to_str (V n, int precision = 1) { std::ostringstream buf; - buf << std::setprecision(precision) << std::fixed << n; + buf << std::setprecision (precision) << std::fixed << n; return buf.str(); } } // namespace -void DynamicProfilePanel::render_iso( +void DynamicProfilePanel::render_iso ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_RANGE_(int, iso, to_str); + RENDER_RANGE_ (int, iso, to_str); } -void DynamicProfilePanel::render_fnumber( +void DynamicProfilePanel::render_fnumber ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_RANGE_(double, fnumber, - [](double f) - { return std::string("f/") + - rtengine::ImageMetaData::apertureToString(f); }); + RENDER_RANGE_ (double, fnumber, + [] (double f) { + return std::string ("f/") + + rtengine::ImageMetaData::apertureToString (f); + }); } -void DynamicProfilePanel::render_focallen( +void DynamicProfilePanel::render_focallen ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_RANGE_(double, focallen, to_str); + RENDER_RANGE_ (double, focallen, to_str); } -void DynamicProfilePanel::render_shutterspeed( +void DynamicProfilePanel::render_shutterspeed ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_RANGE_(double, shutterspeed, - rtengine::ImageMetaData::shutterToString); + RENDER_RANGE_ (double, shutterspeed, + rtengine::ImageMetaData::shutterToString); } -void DynamicProfilePanel::render_expcomp( +void DynamicProfilePanel::render_expcomp ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_RANGE_(double, expcomp, to_str); + RENDER_RANGE_ (double, expcomp, to_str); } #undef RENDER_RANGE_ @@ -431,17 +443,17 @@ void DynamicProfilePanel::render_expcomp( ct->property_text() = ""; \ } -void DynamicProfilePanel::render_camera( +void DynamicProfilePanel::render_camera ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_OPTIONAL_(camera); + RENDER_OPTIONAL_ (camera); } -void DynamicProfilePanel::render_lens( +void DynamicProfilePanel::render_lens ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { - RENDER_OPTIONAL_(lens); + RENDER_OPTIONAL_ (lens); } #undef RENDER_OPTIONAL_ @@ -449,28 +461,34 @@ void DynamicProfilePanel::render_lens( void DynamicProfilePanel::on_button_up() { auto s = treeview_.get_selection(); + if (!s->count_selected_rows()) { return; } + auto it = s->get_selected(); + if (it != treemodel_->children().begin()) { auto it2 = it; --it2; - treemodel_->iter_swap(it, it2); + treemodel_->iter_swap (it, it2); } } void DynamicProfilePanel::on_button_down() { auto s = treeview_.get_selection(); + if (!s->count_selected_rows()) { return; } + auto it = s->get_selected(); auto it2 = it; ++it2; + if (it2 != treemodel_->children().end()) { - treemodel_->iter_swap(it, it2); + treemodel_->iter_swap (it, it2); } } @@ -478,22 +496,25 @@ void DynamicProfilePanel::on_button_down() void DynamicProfilePanel::on_button_delete() { auto s = treeview_.get_selection(); + if (!s->count_selected_rows()) { return; } + auto it = s->get_selected(); - treemodel_->erase(it); + treemodel_->erase (it); } void DynamicProfilePanel::on_button_new() { - EditDialog d(M("DYNPROFILEEDITOR_NEW_RULE"), - static_cast(*get_toplevel())); + EditDialog d (M ("DYNPROFILEEDITOR_NEW_RULE"), + static_cast (*get_toplevel())); int status = d.run(); + if (status == 1) { DynamicProfileRule rule = d.get_rule(); - add_rule(rule); + add_rule (rule); } } @@ -501,16 +522,19 @@ void DynamicProfilePanel::on_button_new() void DynamicProfilePanel::on_button_edit() { auto s = treeview_.get_selection(); + if (!s->count_selected_rows()) { return; } - EditDialog d(M("DYNPROFILEEDITOR_EDIT_RULE"), - static_cast(*get_toplevel())); - Gtk::TreeModel::Row row = *(s->get_selected()); - d.set_rule(to_rule(row)); + + EditDialog d (M ("DYNPROFILEEDITOR_EDIT_RULE"), + static_cast (*get_toplevel())); + Gtk::TreeModel::Row row = * (s->get_selected()); + d.set_rule (to_rule (row)); int status = d.run(); + if (status == 1) { - update_rule(row, d.get_rule()); + update_rule (row, d.get_rule()); } } @@ -519,15 +543,16 @@ void DynamicProfilePanel::save() { std::vector rules; int serial = 1; + for (auto row : treemodel_->children()) { - rules.emplace_back(to_rule(row, serial++)); + rules.emplace_back (to_rule (row, serial++)); } - ProfileStore::getInstance()->setRules(rules); + ProfileStore::getInstance()->setRules (rules); if (!ProfileStore::getInstance()->storeRules()) { - printf("Error in saving dynamic profile rules\n"); + printf ("Error in saving dynamic profile rules\n"); } else if (options.rtSettings.verbose) { - printf("Saved %d dynamic profile rules\n", int(rules.size())); + printf ("Saved %d dynamic profile rules\n", int (rules.size())); } } diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index 629c5d9d4..dca62f1e6 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -23,17 +23,17 @@ #include "../rtengine/dynamicprofile.h" #include "profilestorecombobox.h" -class DynamicProfilePanel: public Gtk::VBox { +class DynamicProfilePanel: public Gtk::VBox +{ public: DynamicProfilePanel(); void save(); private: - void update_rule(Gtk::TreeModel::Row row, - const DynamicProfileRule &rule); - void add_rule(const DynamicProfileRule &rule); - DynamicProfileRule to_rule(Gtk::TreeModel::Row row, int serial=0); - + void update_rule (Gtk::TreeModel::Row row, const DynamicProfileRule &rule); + void add_rule (const DynamicProfileRule &rule); + DynamicProfileRule to_rule (Gtk::TreeModel::Row row, int serial = 0); + void on_button_quit(); void on_button_up(); void on_button_down(); @@ -41,18 +41,19 @@ private: void on_button_edit(); void on_button_delete(); - class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord { + class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord + { public: DynamicProfileColumns() { - add(iso); - add(fnumber); - add(focallen); - add(shutterspeed); - add(expcomp); - add(camera); - add(lens); - add(profilepath); + add (iso); + add (fnumber); + add (focallen); + add (shutterspeed); + add (expcomp); + add (camera); + add (lens); + add (profilepath); } Gtk::TreeModelColumn> iso; @@ -66,35 +67,26 @@ private: }; // cell renderers - void render_iso(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_fnumber(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_focallen(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_shutterspeed(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_expcomp(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_camera(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_lens(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); - void render_profilepath(Gtk::CellRenderer* cell, - const Gtk::TreeModel::iterator& iter); + void render_iso (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_fnumber (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_focallen (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_shutterspeed (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_expcomp (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_camera (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_lens (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_profilepath (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); - class EditDialog: public Gtk::Dialog { + class EditDialog: public Gtk::Dialog + { public: - EditDialog(const Glib::ustring &title, Gtk::Window &parent); - void set_rule(const DynamicProfileRule &rule); + EditDialog (const Glib::ustring &title, Gtk::Window &parent); + void set_rule (const DynamicProfileRule &rule); DynamicProfileRule get_rule(); private: void set_ranges(); - void add_range(const Glib::ustring &name, - Gtk::SpinButton *&from, Gtk::SpinButton *&to); - void add_optional(const Glib::ustring &name, - Gtk::CheckButton *&check, Gtk::Entry *&field); + void add_range (const Glib::ustring &name, Gtk::SpinButton *&from, Gtk::SpinButton *&to); + void add_optional (const Glib::ustring &name, Gtk::CheckButton *&check, Gtk::Entry *&field); Gtk::SpinButton *iso_min_; Gtk::SpinButton *iso_max_; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 12d6c2de7..d01d00327 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -87,16 +87,16 @@ Preferences::Preferences (RTWindow *rtwindow) get_action_area()->pack_end (*ok); get_action_area()->pack_end (*cancel); - nb->append_page (*getGeneralPanel(), M("PREFERENCES_TAB_GENERAL")); - nb->append_page (*getProcParamsPanel(), M("PREFERENCES_TAB_IMPROC")); - nb->append_page (*getDynProfilePanel(), M("PREFERENCES_TAB_DYNAMICPROFILE")); - nb->append_page (*getFileBrowserPanel(), M("PREFERENCES_TAB_BROWSER")); + nb->append_page (*getGeneralPanel(), M("PREFERENCES_TAB_GENERAL")); + nb->append_page (*getProcParamsPanel(), M("PREFERENCES_TAB_IMPROC")); + nb->append_page (*getDynProfilePanel(), M("PREFERENCES_TAB_DYNAMICPROFILE")); + nb->append_page (*getFileBrowserPanel(), M("PREFERENCES_TAB_BROWSER")); nb->append_page (*getColorManagementPanel(), M("PREFERENCES_TAB_COLORMGR")); - nb->append_page (*getBatchProcPanel(), M("PREFERENCES_BATCH_PROCESSING")); - nb->append_page (*getPerformancePanel(), M("PREFERENCES_TAB_PERFORMANCE")); + nb->append_page (*getBatchProcPanel(), M("PREFERENCES_BATCH_PROCESSING")); + nb->append_page (*getPerformancePanel(), M("PREFERENCES_TAB_PERFORMANCE")); // Sounds only on Windows and Linux #if defined(WIN32) || defined(__linux__) - nb->append_page (*getSoundPanel(), M("PREFERENCES_TAB_SOUND")); + nb->append_page (*getSoundPanel(), M("PREFERENCES_TAB_SOUND")); #endif nb->set_current_page (0); diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index bfdb406e7..186309aa3 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -27,17 +27,17 @@ using namespace rtengine; using namespace rtengine::procparams; -ProfileStoreLabel::ProfileStoreLabel(const ProfileStoreEntry *entry) : Gtk::Label(entry->label), entry(entry) +ProfileStoreLabel::ProfileStoreLabel (const ProfileStoreEntry *entry) : Gtk::Label (entry->label), entry (entry) { - set_alignment(0, 0.5); - set_ellipsize(Pango::ELLIPSIZE_END); + set_alignment (0, 0.5); + set_ellipsize (Pango::ELLIPSIZE_END); show(); } ProfileStoreComboBox::ProfileStoreComboBox () { updateProfileList(); - setPreferredWidth(50, 120); + setPreferredWidth (50, 120); } Glib::ustring ProfileStoreComboBox::getCurrentLabel() @@ -71,16 +71,16 @@ void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, for (auto entry : *entryList) { if (entry->parentFolderId == parentFolderId) { // filtering the entry of the same folder if (entry->type == PSET_FOLDER) { - Glib::ustring folderPath( ProfileStore::getInstance()->getPathFromId(entry->folderId) ); + Glib::ustring folderPath ( ProfileStore::getInstance()->getPathFromId (entry->folderId) ); if (options.useBundledProfiles || ((folderPath != "${G}" ) && (folderPath != "${U}" ))) { // creating the new submenu Gtk::TreeModel::Row newSubMenu; if (initial) { - newSubMenu = *(refTreeModel->append()); + newSubMenu = * (refTreeModel->append()); } else { - newSubMenu = *(refTreeModel->append(parentRow->children())); + newSubMenu = * (refTreeModel->append (parentRow->children())); } // creating and assigning the custom Label object @@ -88,7 +88,7 @@ void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, newSubMenu[methodColumns.profileStoreEntry] = entry; #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION == 18 // HACK: Workaround for bug in Gtk+ 3.18... - Gtk::TreeModel::Row menuHeader = *(refTreeModel->append(newSubMenu->children())); + Gtk::TreeModel::Row menuHeader = * (refTreeModel->append (newSubMenu->children())); menuHeader[methodColumns.label] = "-"; menuHeader[methodColumns.profileStoreEntry] = entry; #endif @@ -101,9 +101,9 @@ void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, // creating a menu entry if (initial) { - newItem = *(refTreeModel->append()); + newItem = * (refTreeModel->append()); } else { - newItem = *(refTreeModel->append(parentRow->children())); + newItem = * (refTreeModel->append (parentRow->children())); } newItem[methodColumns.label] = entry->label; @@ -123,27 +123,27 @@ void ProfileStoreComboBox::updateProfileList () clear(); refTreeModel.clear(); // Create the Tree model - refTreeModel = Gtk::TreeStore::create(methodColumns); + refTreeModel = Gtk::TreeStore::create (methodColumns); // Assign the model to the Combobox - set_model(refTreeModel); + set_model (refTreeModel); // this will lock the profilestore's entry list too const std::vector *entryList = ProfileStore::getInstance()->getFileList(); //profileStore.dumpFolderList(); - refreshProfileList_ (NULL, entryList->at(0)->parentFolderId, true, entryList); + refreshProfileList_ (NULL, entryList->at (0)->parentFolderId, true, entryList); - if (entryList->at(0)->parentFolderId != 0) { + if (entryList->at (0)->parentFolderId != 0) { // special case for the Internal default entry - addRow(ProfileStore::getInstance()->getInternalDefaultPSE()); + addRow (ProfileStore::getInstance()->getInternalDefaultPSE()); } // releasing the profilestore's entry list mutex ProfileStore::getInstance()->releaseFileList(); - pack_start(methodColumns.label, false); + pack_start (methodColumns.label, false); - Gtk::CellRendererText* cellRenderer = dynamic_cast(get_first_cell()); + Gtk::CellRendererText* cellRenderer = dynamic_cast (get_first_cell()); cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; cellRenderer->property_ellipsize_set() = true; } @@ -153,7 +153,7 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children Gtk::TreeModel::Row row; Gtk::TreeIter rowInSubLevel; - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; @@ -191,7 +191,7 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Childr Gtk::TreeModel::Row row; Gtk::TreeIter rowInSubLevel; - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; @@ -222,27 +222,27 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) } if (path == DEFPROFILE_INTERNAL) { - row = findRowFromEntry(profileStore->getInternalDefaultPSE()); + row = findRowFromEntry (profileStore->getInternalDefaultPSE()); return row; } if (path == DEFPROFILE_DYNAMIC) { - row = findRowFromEntry(profileStore->getInternalDynamicPSE()); + row = findRowFromEntry (profileStore->getInternalDynamicPSE()); return row; } // removing the filename - Glib::ustring fName = Glib::path_get_basename(path); + Glib::ustring fName = Glib::path_get_basename (path); if (!fName.empty()) { - path = path.substr(0, path.length() - fName.length()); + path = path.substr (0, path.length() - fName.length()); } else { // path is malformed; return row; } - path = Glib::path_get_dirname(path); - int parentFolderId = profileStore->findFolderId(path); + path = Glib::path_get_dirname (path); + int parentFolderId = profileStore->findFolderId (path); // 1. find the path in the folder list if (parentFolderId != -1) { @@ -277,26 +277,26 @@ Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() } if (currEntry == profileStore->getInternalDefaultPSE()) { - return Glib::ustring(DEFPROFILE_INTERNAL); + return Glib::ustring (DEFPROFILE_INTERNAL); } if (currEntry == profileStore->getInternalDynamicPSE()) { - return Glib::ustring(DEFPROFILE_DYNAMIC); + return Glib::ustring (DEFPROFILE_DYNAMIC); } - path = Glib::build_filename(profileStore->getPathFromId(currEntry->parentFolderId), currEntry->label); + path = Glib::build_filename (profileStore->getPathFromId (currEntry->parentFolderId), currEntry->label); } return path; } -bool ProfileStoreComboBox::setActiveRowFromFullPath(Glib::ustring path) +bool ProfileStoreComboBox::setActiveRowFromFullPath (Glib::ustring path) { if (!path.empty()) { - Gtk::TreeIter row = findRowFromFullPath(path); + Gtk::TreeIter row = findRowFromFullPath (path); if (row) { - set_active(row); + set_active (row); return true; } } @@ -304,13 +304,13 @@ bool ProfileStoreComboBox::setActiveRowFromFullPath(Glib::ustring path) return false; } -bool ProfileStoreComboBox::setActiveRowFromEntry(const ProfileStoreEntry *pse) +bool ProfileStoreComboBox::setActiveRowFromEntry (const ProfileStoreEntry *pse) { if (pse) { - Gtk::TreeIter row = findRowFromEntry(pse); + Gtk::TreeIter row = findRowFromEntry (pse); if (row) { - set_active(row); + set_active (row); return true; } } @@ -320,11 +320,11 @@ bool ProfileStoreComboBox::setActiveRowFromEntry(const ProfileStoreEntry *pse) bool ProfileStoreComboBox::setInternalEntry () { - return setActiveRowFromEntry(ProfileStore::getInstance()->getInternalDefaultPSE()); + return setActiveRowFromEntry (ProfileStore::getInstance()->getInternalDefaultPSE()); } /** @brief Get the row from the first level of the tree that match the provided name */ -Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) +Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (Glib::ustring name) { Gtk::TreeIter row; Gtk::TreeModel::Children childs = refTreeModel->children(); @@ -332,7 +332,7 @@ Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) if (!name.empty()) { Gtk::TreeModel::Row currRow; - for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { currRow = *iter; const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; @@ -347,7 +347,7 @@ Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) } /** @brief Add a new row to the first level of the tree */ -Gtk::TreeIter ProfileStoreComboBox::addRow(const ProfileStoreEntry *profileStoreEntry) +Gtk::TreeIter ProfileStoreComboBox::addRow (const ProfileStoreEntry *profileStoreEntry) { Gtk::TreeIter newEntry = refTreeModel->append(); Gtk::TreeModel::Row row = *newEntry; diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h index 70ccd9298..111e767c2 100644 --- a/rtgui/profilestorecombobox.h +++ b/rtgui/profilestorecombobox.h @@ -42,16 +42,16 @@ public: const ProfileStoreEntry *entry; #ifndef NDEBUG - ProfileStoreLabel() : Gtk::Label("*** error ***"), entry(nullptr) {} + ProfileStoreLabel() : Gtk::Label ("*** error ***"), entry (nullptr) {} #else - ProfileStoreLabel() : Gtk::Label(""), entry(NULL) {} + ProfileStoreLabel() : Gtk::Label (""), entry (NULL) {} #endif /** @brief Create a new ProfileStoreLabel * * @param entry Pointer to the ProfileStoreEntry object, be it a directory or a file */ - explicit ProfileStoreLabel(const ProfileStoreEntry *entry); + explicit ProfileStoreLabel (const ProfileStoreEntry *entry); ProfileStoreLabel (const ProfileStoreLabel &other); }; @@ -66,8 +66,8 @@ protected: Gtk::TreeModelColumn profileStoreEntry; MethodColumns() { - add(label); - add(profileStoreEntry); + add (label); + add (profileStoreEntry); } }; @@ -75,7 +75,7 @@ protected: MethodColumns methodColumns; void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath_(Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); + Gtk::TreeIter findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); public: ProfileStoreComboBox(); @@ -88,8 +88,8 @@ public: bool setActiveRowFromFullPath (Glib::ustring oldPath); bool setActiveRowFromEntry (const ProfileStoreEntry *pse); bool setInternalEntry (); - Gtk::TreeIter getRowFromLabel(Glib::ustring name); - Gtk::TreeIter addRow(const ProfileStoreEntry *profileStoreEntry); + Gtk::TreeIter getRowFromLabel (Glib::ustring name); + Gtk::TreeIter addRow (const ProfileStoreEntry *profileStoreEntry); }; #endif From d3ab1048187add2ac0b736931041cb54df5120d4 Mon Sep 17 00:00:00 2001 From: Hombre Date: Wed, 26 Apr 2017 00:07:20 +0200 Subject: [PATCH 03/11] Dynamic profiles wasn't loaded in Preference (#3691) --- rtengine/dynamicprofile.cc | 6 +++++- rtengine/dynamicprofile.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 380af29be..5ac408da5 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -246,8 +246,12 @@ bool DynamicProfileRules::storeRules() return kf.save_to_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg")); } -const std::vector &DynamicProfileRules::getRules() const +const std::vector &DynamicProfileRules::getRules() { + if (!rulesLoaded) { + loadRules(); + } + return dynamicRules; } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index b59838e3f..cfe46d9ba 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -72,7 +72,7 @@ protected: public: bool loadRules(); bool storeRules(); - const std::vector &getRules() const; + const std::vector &getRules(); void setRules (const std::vector &r); }; From cf47cdee2dc702a757a3c40d96f63a5a284b0a9b Mon Sep 17 00:00:00 2001 From: Hombre Date: Fri, 28 Apr 2017 02:17:13 +0200 Subject: [PATCH 04/11] A bugfix that wasn't pushed to main-cli.cc (#3691 #3768) --- rtgui/main-cli.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index e59ebaf09..18734e0da 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -198,8 +198,7 @@ int main(int argc, char **argv) break; } - if(Console) { - AllocConsole(); + if(Console && AllocConsole()) { AttachConsole( GetCurrentProcessId() ) ; // Don't allow CTRL-C in console to terminate RT SetConsoleCtrlHandler( NULL, true ); From 0f0f76df0b2079d4b7d80b9206344b1134ccc952 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Fri, 28 Apr 2017 20:08:07 +0200 Subject: [PATCH 05/11] Unregister handler with glib when callback function returns false --- rtgui/guiutils.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 8e4ae3613..01e95132b 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -56,6 +56,7 @@ void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) if (!data_wrapper->function(data_wrapper->data)) { data_wrapper->self->mutex.lock(); + g_source_remove(data_wrapper->self->ids[data_wrapper]); data_wrapper->self->ids.erase(data_wrapper); data_wrapper->self->mutex.unlock(); From 5d4bd4b3529b14f929eaf887b5413c95f961dba2 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 28 Apr 2017 17:20:44 +0200 Subject: [PATCH 06/11] changed implementation of BayerProcess::FrameCountChanged to use IdleRegister --- rtgui/bayerprocess.cc | 64 ++++++++++++++++++++++++++++++++----------- rtgui/bayerprocess.h | 2 ++ 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index eee97c2ad..d5a728a97 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -945,21 +945,53 @@ void BayerProcess::pixelShiftMotionMethodChanged () void BayerProcess::FrameCountChanged(int n, int frameNum) { - GThreadLock lock; - imageNumber->block (true); + struct Data { + BayerProcess *me; + int n; + int frameNum; + }; + const auto func = [](gpointer data) -> gboolean { + Data *d = static_cast(data); + BayerProcess *me = d->me; + me->imageNumber->block (true); + int n = d->n; + int frameNum = d->frameNum; - imageNumber->remove_all(); - imageNumber->append("1"); - for(int i = 2; i <= std::min(n, 4); ++i) { - std::ostringstream entry; - entry << i; - imageNumber->append(entry.str()); - } - imageNumber->set_active(std::min(frameNum, n - 1)); - if(n == 1) { - imageNumberBox->hide(); - } else { - imageNumberBox->show(); - } - imageNumber->block (false); + me->imageNumber->remove_all(); + me->imageNumber->append("1"); + for(int i = 2; i <= std::min(n, 4); ++i) { + std::ostringstream entry; + entry << i; + me->imageNumber->append(entry.str()); + } + me->imageNumber->set_active(std::min(frameNum, n - 1)); + if(n == 1) { + me->imageNumberBox->hide(); + } else { + me->imageNumberBox->show(); + } + me->imageNumber->block (false); + delete d; + return FALSE; + }; + + idle_register.add(func, new Data { this, n, frameNum }); + + // GThreadLock lock; + // imageNumber->block (true); + + // imageNumber->remove_all(); + // imageNumber->append("1"); + // for(int i = 2; i <= std::min(n, 4); ++i) { + // std::ostringstream entry; + // entry << i; + // imageNumber->append(entry.str()); + // } + // imageNumber->set_active(std::min(frameNum, n - 1)); + // if(n == 1) { + // imageNumberBox->hide(); + // } else { + // imageNumberBox->show(); + // } + // imageNumber->block (false); } diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index 3d15802a5..6d9dd6062 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -74,6 +74,8 @@ protected: Adjuster* pixelShiftRedBlueWeight; #endif int oldMethod; + + IdleRegister idle_register; public: BayerProcess (); From d8e0207b9a2b3a38a68f6fec3633622b2b2b761d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 28 Apr 2017 21:22:23 +0200 Subject: [PATCH 07/11] Fixed memory leak in IdleRegister::destroy --- rtgui/guiutils.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 01e95132b..977c07f42 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -43,20 +43,25 @@ IdleRegister::~IdleRegister() destroy(); } + +namespace { + +struct DataWrapper { + IdleRegister* const self; + GSourceFunc function; + gpointer data; +}; + +} // namespace + void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) { - struct DataWrapper { - IdleRegister* const self; - GSourceFunc function; - gpointer data; - }; - const auto dispatch = [](gpointer data) -> gboolean { DataWrapper* const data_wrapper = static_cast(data); if (!data_wrapper->function(data_wrapper->data)) { data_wrapper->self->mutex.lock(); - g_source_remove(data_wrapper->self->ids[data_wrapper]); + //g_source_remove(data_wrapper->self->ids[data_wrapper]); data_wrapper->self->ids.erase(data_wrapper); data_wrapper->self->mutex.unlock(); @@ -83,6 +88,8 @@ void IdleRegister::destroy() mutex.lock(); for (const auto id : ids) { g_source_remove(id.second); + DataWrapper *w = static_cast(id.first); + delete w; } mutex.unlock(); } From 7553d86b11b1448fb5a7412b19a0d9ab0dbf95ba Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 29 Apr 2017 14:48:54 +0200 Subject: [PATCH 08/11] clear the ids map in IdleRegister::destroy (prevent double deallocation) Fixes #3849 --- rtgui/guiutils.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 977c07f42..6dadde842 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -91,6 +91,7 @@ void IdleRegister::destroy() DataWrapper *w = static_cast(id.first); delete w; } + ids.clear(); mutex.unlock(); } From bc33b510939bc5ec5b23aab6a0053641b7b0c55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Tue, 2 May 2017 18:45:23 +0200 Subject: [PATCH 09/11] `IdleRegister` cleanups --- rtgui/guiutils.cc | 17 ++--------------- rtgui/guiutils.h | 8 +++++++- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 6dadde842..91284e983 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -43,17 +43,6 @@ IdleRegister::~IdleRegister() destroy(); } - -namespace { - -struct DataWrapper { - IdleRegister* const self; - GSourceFunc function; - gpointer data; -}; - -} // namespace - void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) { const auto dispatch = [](gpointer data) -> gboolean { @@ -61,7 +50,6 @@ void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) if (!data_wrapper->function(data_wrapper->data)) { data_wrapper->self->mutex.lock(); - //g_source_remove(data_wrapper->self->ids[data_wrapper]); data_wrapper->self->ids.erase(data_wrapper); data_wrapper->self->mutex.unlock(); @@ -86,10 +74,9 @@ void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) void IdleRegister::destroy() { mutex.lock(); - for (const auto id : ids) { + for (const auto& id : ids) { g_source_remove(id.second); - DataWrapper *w = static_cast(id.first); - delete w; + delete id.first; } ids.clear(); mutex.unlock(); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index b2ebaa80a..a6ec916f0 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -54,7 +54,13 @@ public: void destroy(); private: - std::map ids; + struct DataWrapper { + IdleRegister* const self; + GSourceFunc function; + gpointer data; + }; + + std::map ids; MyMutex mutex; }; From bcad76cd5ed68b96473053bccb33246a3a425788 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 2 May 2017 23:08:33 +0200 Subject: [PATCH 10/11] Processing a directory now look for image format set in options (#3691) See the updated '-c' and new '-a' help when using rawtherapee-cli.exe -h --- rtgui/main-cli.cc | 61 +++++++++++++++++++++++++++++++++++++---------- rtgui/options.cc | 21 ++++++++++++++++ rtgui/options.h | 1 + 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 18734e0da..91dfc9204 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -298,6 +298,7 @@ int processLineParams( int argc, char **argv ) bool sideProcParams = false; bool copyParamsFile = false; bool skipIfNoSidecar = false; + bool allExtensions = false; bool useDefault = false; unsigned int sideCarFilePos = 0; int compression = 92; @@ -378,6 +379,10 @@ int processLineParams( int argc, char **argv ) overwriteFiles = true; break; + case 'a': + allExtensions = true; + break; + case 'j': if (currParam.length() > 2 && currParam.at(2) == 's') { if (currParam.length() == 3) { @@ -431,7 +436,7 @@ int processLineParams( int argc, char **argv ) case 'f': fast_export = true; break; - + case 'c': // MUST be last option while (iArg + 1 < argc) { iArg++; @@ -440,11 +445,28 @@ int processLineParams( int argc, char **argv ) argument = argument.substr(1, argument.length()-2); #endif - if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { - inputFiles.emplace_back (argument); + if (!Glib::file_test (argument, Glib::FILE_TEST_EXISTS)) { + std::cout << "\"" << argument << "\" doesn't exist !" << std::endl; continue; } + if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { + bool notAll = allExtensions && !options.is_parse_extention (argument); + bool notRetained = !allExtensions && !options.has_retained_extention (argument); + if (notAll || notRetained) { + if (notAll) { + std::cout << "\"" << argument << "\" is not one of the file format to process: skipped" << std::endl; + } else if (notRetained) { + std::cout << "\"" << argument << "\" is not one of the retained file format to process: skipped" << std::endl; + } + } + else { + inputFiles.emplace_back (argument); + } + continue; + + } + if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) { auto dir = Gio::File::create_for_path (argument); @@ -459,19 +481,28 @@ int processLineParams( int argc, char **argv ) while (auto file = enumerator->next_file ()) { const auto fileName = Glib::build_filename (argument, file->get_name ()); + bool isDir = Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR); + bool notAll = allExtensions && !options.is_parse_extention (fileName); + bool notRetained = !allExtensions && !options.has_retained_extention (fileName); - if (Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR)) { + if (isDir || notAll || notRetained) { + if (isDir) { + std::cout << "\"" << fileName << "\" is a directory: skipped" << std::endl; + } else if (notAll) { + std::cout << "\"" << fileName << "\" is not one of the file format to process: skipped" << std::endl; + } else if (notRetained) { + std::cout << "\"" << fileName << "\" is not one of the retained file format to process: skipped" << std::endl; + } continue; + } - // skip files without extension and sidecar files - auto lastdot = fileName.find_last_of('.'); - if (lastdot == Glib::ustring::npos) { - continue; - } - - if (fileName.substr (lastdot).compare (paramFileExtension) == 0) { - continue; + if (sideProcParams && skipIfNoSidecar) { + // look for the sidecar proc params + if (!Glib::file_test(fileName + paramFileExtension, Glib::FILE_TEST_EXISTS)) { + std::cout << "\"" << fileName << "\" has no side-car file: image skipped" << std::endl; + continue; + } } inputFiles.emplace_back (fileName); @@ -521,12 +552,16 @@ int processLineParams( int argc, char **argv ) std::cout << " " << Glib::path_get_basename(argv[0]) << " [-o |-O ] [-s|-S] [-p [-p ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] [-f] -c " << std::endl; std::cout << std::endl; std::cout << " -q Quick Start mode : do not load cached files to speedup start time." << std::endl; - std::cout << " -c Specify one or more input files." << std::endl; + std::cout << " -c Specify one or more input files or directory." << std::endl; + std::cout << " When specifying directories, Rawtherapee will look for images files that comply with the" << std::endl; + std::cout << " selected extensions (see also '-a')." << std::endl; std::cout << " -c must be the last option." << std::endl; std::cout << " -o | Set output file or folder." << std::endl; std::cout << " Saves output file alongside input file if -o is not specified." << std::endl; std::cout << " -O | Set output file or folder and copy " << pparamsExt << " file into it." << std::endl; std::cout << " Saves output file alongside input file if -O is not specified." << std::endl; + std::cout << " -a stand for 'all'. When specifying a directory, process all images specified in the" << std::endl; + std::cout << " extension list from the options file, even those currently not seleted" << std::endl; std::cout << " -s Use the existing sidecar file to build the processing parameters," << std::endl; std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in the same folder." << std::endl; std::cout << " If the sidecar file does not exist, neutral values will be used." << std::endl; diff --git a/rtgui/options.cc b/rtgui/options.cc index daf11e62c..df68d0ac9 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -2365,6 +2365,27 @@ void Options::save () } } +/* + * return true if ext is a parsed extension (retained or not) + */ +bool Options::is_parse_extention (Glib::ustring fname) +{ + Glib::ustring ext = getExtension (fname).lowercase(); + + if (!ext.empty()) { + // there is an extension to the filename + + // look out if it has one of the listed extensions (selected or not) + for (unsigned int i = 0; i < parseExtensions.size(); i++) { + if (ext == parseExtensions[i]) { + return true; + } + } + } + + return false; +} + /* * return true if fname ends with one of the retained image file extensions */ diff --git a/rtgui/options.h b/rtgui/options.h index 1a5ae21ed..f67175c43 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -333,6 +333,7 @@ public: return globalProfilePath; } Glib::ustring findProfilePath(Glib::ustring &profName); + bool is_parse_extention (Glib::ustring fname); bool has_retained_extention (Glib::ustring fname); bool is_extention_enabled(Glib::ustring ext); bool is_defProfRawMissing() From edfea689b8d799a3e544115130929f989809c6bd Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 3 May 2017 00:19:01 +0200 Subject: [PATCH 11/11] improved adjustment of luma denoise params for the fast export pipeline --- rtengine/simpleprocess.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e7a71c81e..efbba78d1 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1416,11 +1416,12 @@ private: } params.wavelet.strength *= scale_factor; params.dirpyrDenoise.luma *= scale_factor; - params.dirpyrDenoise.Ldetail += (100 - params.dirpyrDenoise.Ldetail) * scale_factor; - //params.dirpyrDenoise.smethod = "shal"; - for (auto &p : params.dirpyrDenoise.lcurve) { - p *= scale_factor; + //params.dirpyrDenoise.Ldetail += (100 - params.dirpyrDenoise.Ldetail) * scale_factor; + auto &lcurve = params.dirpyrDenoise.lcurve; + for (size_t i = 2; i < lcurve.size(); i += 4) { + lcurve[i] *= min(scale_factor * 2, 1.0); } + noiseLCurve.Set(lcurve); const char *medmethods[] = { "soft", "33", "55soft", "55", "77", "99" }; if (params.dirpyrDenoise.median) { auto &key = params.dirpyrDenoise.methodmed == "RGB" ? params.dirpyrDenoise.rgbmethod : params.dirpyrDenoise.medmethod;