diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index e327cb4b6..153c1a0ef 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -31,7 +31,7 @@ set (BASESOURCEFILES dirpyrequalizer.cc hsvequalizer.cc defringe.cc popupcommon.cc popupbutton.cc popuptogglebutton.cc sharpenedge.cc sharpenmicro.cc colorappearance.cc filmsimulation.cc prsharpening.cc - dynamicprofile.cc) + dynamicprofile.cc dynamicprofilepanel.cc) include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc new file mode 100644 index 000000000..bfe311efb --- /dev/null +++ b/rtgui/dynamicprofilepanel.cc @@ -0,0 +1,559 @@ +/* -*- C++ -*- + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 "dynamicprofilepanel.h" +#include "multilangmgr.h" +#include +#include + +namespace { + +template +Glib::ustring to_str(V n) +{ + std::ostringstream buf; + buf << std::setprecision(1) << std::fixed << n; + return buf.str(); +} + + +int to_int(const Glib::ustring &s) +{ + std::istringstream buf(s); + int r = -1; + buf >> r; + return r; +} + + +double to_double(const Glib::ustring &s) +{ + std::istringstream buf(s); + double r = 0.0; + buf >> r; + return r; +} + +} // namespace + + +//----------------------------------------------------------------------------- +// DynamicProfilePanel::EditDialog +//----------------------------------------------------------------------------- + +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); + + add_optional(M("DYNPROFILEEDITOR_CAMERA_MAKE"), has_make, make); + add_optional(M("DYNPROFILEEDITOR_CAMERA_MODEL"), has_model, model); + 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_button(M("GENERAL_OK"), 1); + add_button(M("GENERAL_CANCEL"), 2); + + set_ranges(); + + show_all_children(); +} + + +void DynamicProfilePanel::EditDialog::set_entry( + const DynamicProfileEntry &entry) +{ + iso_min_->set_value(entry.iso.min); + iso_max_->set_value(entry.iso.max); + + fnumber_min_->set_value(entry.fnumber.min); + fnumber_max_->set_value(entry.fnumber.max); + + focallen_min_->set_value(entry.focallen.min); + focallen_max_->set_value(entry.focallen.max); + + shutterspeed_min_->set_value(entry.shutterspeed.min); + shutterspeed_max_->set_value(entry.shutterspeed.max); + + expcomp_min_->set_value(entry.expcomp.min); + expcomp_max_->set_value(entry.expcomp.max); + + has_make->set_active(entry.make.enabled); + make->set_text(entry.make.value); + + has_model->set_active(entry.model.enabled); + model->set_text(entry.model.value); + + has_lens->set_active(entry.lens.enabled); + lens->set_text(entry.lens.value); + + profilepath_->updateProfileList(); + if (!profilepath_->setActiveRowFromFullPath(entry.profilepath)) { + profilepath_->setInternalEntry(); + } +} + + +DynamicProfileEntry DynamicProfilePanel::EditDialog::get_entry() +{ + DynamicProfileEntry ret; + ret.iso.min = iso_min_->get_value_as_int(); + ret.iso.max = iso_max_->get_value_as_int(); + + 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(); + + ret.shutterspeed.min = shutterspeed_min_->get_value(); + ret.shutterspeed.max = shutterspeed_max_->get_value(); + + ret.expcomp.min = expcomp_min_->get_value(); + ret.expcomp.max = expcomp_max_->get_value(); + + ret.make.enabled = has_make->get_active(); + ret.make.value = make->get_text(); + + ret.model.enabled = has_model->get_active(); + ret.model.value = model->get_text(); + + ret.lens.enabled = has_lens->get_active(); + ret.lens.value = lens->get_text(); + + ret.profilepath = profilepath_->getFullPathFromActiveRow(); + + return ret; +} + +void DynamicProfilePanel::EditDialog::set_ranges() +{ + DynamicProfileEntry default_entry; + 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_entry.iso.min, default_entry.iso.max); + iso_max_->set_range(default_entry.iso.min, default_entry.iso.max); + iso_min_->set_value(default_entry.iso.min); + iso_max_->set_value(default_entry.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); \ + name ## _min_->set_range(default_entry. name .min, \ + default_entry. name .max); \ + name ## _max_->set_range(default_entry. name .min, \ + default_entry. name .max); \ + name ## _min_->set_value(default_entry. name .min); \ + name ## _max_->set_value(default_entry. name .max) + + DOIT_(fnumber); + DOIT_(focallen); + DOIT_(shutterspeed); + DOIT_(expcomp); +#undef DOIT_ + + profilepath_->setInternalEntry(); +} + + +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); +} + + +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); +} + + +//----------------------------------------------------------------------------- +// DynamicProfilePanel +//----------------------------------------------------------------------------- + +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")) +{ + add(vbox_); + + //Add the TreeView, inside a ScrolledWindow, with the button underneath: + scrolledwindow_.add(treeview_); + + //Only show the scrollbars when they are necessary: + scrolledwindow_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + 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)); + + //Create the Tree model: + treemodel_ = Gtk::ListStore::create(columns_); + treeview_.set_model(treemodel_); + + //Add the TreeView's view columns: + 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( + *this, &DynamicProfilePanel::render_profilepath)); + } + cell = Gtk::manage(new Gtk::CellRendererText()); + cols_count = treeview_.append_column( + M("DYNPROFILEEDITOR_CAMERA_MAKE"), *cell); + col = treeview_.get_column(cols_count - 1); + if (col) { + col->set_cell_data_func( + *cell, sigc::mem_fun( + *this, &DynamicProfilePanel::render_make)); + } + cell = Gtk::manage(new Gtk::CellRendererText()); + cols_count = treeview_.append_column( + M("DYNPROFILEEDITOR_CAMERA_MODEL"), *cell); + col = treeview_.get_column(cols_count - 1); + if (col) { + col->set_cell_data_func( + *cell, sigc::mem_fun( + *this, &DynamicProfilePanel::render_model)); + } + 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( + *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); + if (col) { + 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); + if (col) { + 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); + if (col) { + 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); + if (col) { + 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); + if (col) { + col->set_cell_data_func( + *cell, sigc::mem_fun( + *this, &DynamicProfilePanel::render_expcomp)); + } + + show_all_children(); + + std::vector entries; + if (loadDynamicProfileEntries(entries)) { + for (auto &e : entries) { + add_entry(e); + } + } +} + + +void DynamicProfilePanel::update_entry(Gtk::TreeModel::Row row, + const DynamicProfileEntry &entry) +{ + row[columns_.iso] = entry.iso; + row[columns_.fnumber] = entry.fnumber; + row[columns_.focallen] = entry.focallen; + row[columns_.shutterspeed] = entry.shutterspeed; + row[columns_.expcomp] = entry.expcomp; + row[columns_.make] = entry.make; + row[columns_.model] = entry.model; + row[columns_.lens] = entry.lens; + row[columns_.profilepath] = entry.profilepath; +} + +void DynamicProfilePanel::add_entry(const DynamicProfileEntry &entry) +{ + auto row = *(treemodel_->append()); + update_entry(row, entry); +} + + +DynamicProfileEntry DynamicProfilePanel::to_entry(Gtk::TreeModel::Row row, + int serial) +{ + DynamicProfileEntry ret; + ret.serial_number = serial; + ret.iso = row[columns_.iso]; + ret.fnumber = row[columns_.fnumber]; + ret.focallen = row[columns_.focallen]; + ret.shutterspeed = row[columns_.shutterspeed]; + ret.expcomp = row[columns_.expcomp]; + ret.make = row[columns_.make]; + ret.model = row[columns_.model]; + ret.lens = row[columns_.lens]; + ret.profilepath = row[columns_.profilepath]; + return ret; +} + + +void DynamicProfilePanel::render_profilepath( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + auto row = *iter; + Gtk::CellRendererText *ct = static_cast(cell); + auto value = row[columns_.profilepath]; + ct->property_text() = value; +} + + +#define RENDER_RANGE_(tp, name) \ + auto row = *iter; \ + Gtk::CellRendererText *ct = static_cast(cell); \ + DynamicProfileEntry::Range r = row[columns_. name]; \ + auto value = to_str(r.min) + " - " + to_str(r.max); \ + ct->property_text() = value; + +void DynamicProfilePanel::render_iso( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_RANGE_(int, iso); +} + + +void DynamicProfilePanel::render_fnumber( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_RANGE_(double, fnumber); +} + + +void DynamicProfilePanel::render_focallen( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_RANGE_(double, focallen); +} + + +void DynamicProfilePanel::render_shutterspeed( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_RANGE_(double, shutterspeed); +} + + +void DynamicProfilePanel::render_expcomp( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_RANGE_(double, expcomp); +} + +#undef RENDER_RANGE_ + +#define RENDER_OPTIONAL_(name) \ + auto row = *iter; \ + Gtk::CellRendererText *ct = static_cast(cell); \ + DynamicProfileEntry::Optional o = row[columns_. name]; \ + if (o.enabled) { \ + ct->property_text() = o.value; \ + } else { \ + ct->property_text() = ""; \ + } + +void DynamicProfilePanel::render_make( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_(make); +} + + +void DynamicProfilePanel::render_model( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_(model); +} + + +void DynamicProfilePanel::render_lens( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_(lens); +} + +#undef RENDER_OPTIONAL_ + +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); + } +} + +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); + } +} + + +void DynamicProfilePanel::on_button_delete() +{ + auto s = treeview_.get_selection(); + if (!s->count_selected_rows()) { + return; + } + auto it = s->get_selected(); + treemodel_->erase(it); +} + + +void DynamicProfilePanel::on_button_new() +{ + EditDialog d(M("DYNPROFILEEDITOR_NEW_RULE"), + static_cast(*get_toplevel())); + int status = d.run(); + if (status == 1) { + DynamicProfileEntry entry = d.get_entry(); + add_entry(entry); + } +} + + +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())); + auto it = s->get_selected(); + Gtk::TreeModel::Row row = *(s->get_selected()); + d.set_entry(to_entry(row)); + int status = d.run(); + if (status == 1) { + update_entry(row, d.get_entry()); + } +} + + +void DynamicProfilePanel::save() +{ + std::vector entries; + int serial = 1; + for (auto row : treemodel_->children()) { + entries.emplace_back(to_entry(row, serial++)); + } + if (!storeDynamicProfileEntries(entries)) { + printf("Error in saving dynamic profile rules\n"); + } else { + printf("Saved %d dynamic profile rules\n", int(entries.size())); + } +} diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h new file mode 100644 index 000000000..c24f9bfcb --- /dev/null +++ b/rtgui/dynamicprofilepanel.h @@ -0,0 +1,149 @@ +/* -*- C++ -*- + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 _DYNAMICPROFILEPANEL_H_ +#define _DYNAMICPROFILEPANEL_H_ + +#include +#include "dynamicprofile.h" +#include "profilestore.h" + +class DynamicProfilePanel: public Gtk::VBox { +public: + DynamicProfilePanel(); + void save(); + +private: + void update_entry(Gtk::TreeModel::Row row, + const DynamicProfileEntry &entry); + void add_entry(const DynamicProfileEntry &entry); + DynamicProfileEntry to_entry(Gtk::TreeModel::Row row, int serial=0); + + //Signal handlers: + void on_button_quit(); + void on_button_up(); + void on_button_down(); + void on_button_new(); + void on_button_edit(); + void on_button_delete(); + + //Tree model columns: + class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord { + public: + DynamicProfileColumns() + { + add(iso); + add(fnumber); + add(focallen); + add(shutterspeed); + add(expcomp); + add(make); + add(model); + add(lens); + add(profilepath); + } + + Gtk::TreeModelColumn> iso; + Gtk::TreeModelColumn> fnumber; + Gtk::TreeModelColumn> focallen; + Gtk::TreeModelColumn> shutterspeed; + Gtk::TreeModelColumn> expcomp; + Gtk::TreeModelColumn> make; + Gtk::TreeModelColumn> model; + Gtk::TreeModelColumn> lens; + Gtk::TreeModelColumn profilepath; + }; + + // 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_make(Gtk::CellRenderer* cell, + const Gtk::TreeModel::iterator& iter); + void render_model(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 { + public: + EditDialog(const Glib::ustring &title, Gtk::Window &parent); + void set_entry(const DynamicProfileEntry &entry); + DynamicProfileEntry get_entry(); + + 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); + + Gtk::SpinButton *iso_min_; + Gtk::SpinButton *iso_max_; + + Gtk::SpinButton *fnumber_min_; + Gtk::SpinButton *fnumber_max_; + + Gtk::SpinButton *focallen_min_; + Gtk::SpinButton *focallen_max_; + + Gtk::SpinButton *shutterspeed_min_; + Gtk::SpinButton *shutterspeed_max_; + + Gtk::SpinButton *expcomp_min_; + Gtk::SpinButton *expcomp_max_; + + Gtk::CheckButton *has_make; + Gtk::Entry *make; + + Gtk::CheckButton *has_model; + Gtk::Entry *model; + + Gtk::CheckButton *has_lens; + Gtk::Entry *lens; + + ProfileStoreComboBox *profilepath_; + }; + + DynamicProfileColumns columns_; + + //Child widgets: + Gtk::Box vbox_; + + Gtk::ScrolledWindow scrolledwindow_; + Gtk::TreeView treeview_; + Glib::RefPtr treemodel_; + + Gtk::ButtonBox buttonbox_; + Gtk::Button button_up_; + Gtk::Button button_down_; + Gtk::Button button_new_; + Gtk::Button button_edit_; + Gtk::Button button_delete_; +}; + +#endif // _DYNAMICPROFILEPANEL_H_ diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 0de355bd2..e43138473 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -82,6 +82,7 @@ Preferences::Preferences (RTWindow *rtwindow) 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")); @@ -420,6 +421,14 @@ void Preferences::behSetRadioToggled (const Glib::ustring& path) iter->set_value (behavColumns.badd, false); } + +Gtk::Widget *Preferences::getDynProfilePanel() +{ + dynProfilePanel = Gtk::manage(new DynamicProfilePanel()); + return dynProfilePanel; +} + + Gtk::Widget* Preferences::getProcParamsPanel () { @@ -2020,6 +2029,7 @@ void Preferences::okPressed () options.copyFrom (&moptions); options.filterOutParsedExtensions(); Options::save (); + dynProfilePanel->save(); hide (); } @@ -2181,6 +2191,8 @@ void Preferences::updateProfileList() { rprofiles->updateProfileList(); iprofiles->updateProfileList(); + rprofiles->addRow(profileStore.getInternalDynamicPSE()); + iprofiles->addRow(profileStore.getInternalDynamicPSE()); } void Preferences::restoreValue() diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 91951a2df..50f72a957 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -24,6 +24,7 @@ #include "options.h" #include #include "rtwindow.h" +#include "dynamicprofilepanel.h" class Preferences : public Gtk::Dialog, public ProfileStoreListener { @@ -201,6 +202,8 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::CheckButton* ckbHideTPVScrollbar; Gtk::CheckButton* ckbUseIconNoText; + DynamicProfilePanel *dynProfilePanel; + Glib::ustring storedValueRaw; Glib::ustring storedValueImg; @@ -239,6 +242,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::Widget* getBatchProcPanel (); Gtk::Widget* getPerformancePanel (); Gtk::Widget* getSoundPanel (); + Gtk::Widget* getDynProfilePanel (); public: explicit Preferences (RTWindow *rtwindow); diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc index 9f32b735f..31b490ce1 100644 --- a/rtgui/profilestore.cc +++ b/rtgui/profilestore.cc @@ -627,7 +627,6 @@ void ProfileStoreComboBox::updateProfileList () // special case for the Internal default entry addRow(profileStore.getInternalDefaultPSE()); } - addRow(profileStore.getInternalDynamicPSE()); // releasing the profilestore's entry list mutex profileStore.releaseFileList();