merge with dev
This commit is contained in:
@@ -30,7 +30,8 @@ set (BASESOURCEFILES
|
||||
darkframe.cc flatfield.cc rawcacorrection.cc rawexposure.cc wavelet.cc
|
||||
dirpyrequalizer.cc hsvequalizer.cc defringe.cc
|
||||
popupcommon.cc popupbutton.cc popuptogglebutton.cc sharpenedge.cc sharpenmicro.cc colorappearance.cc locallab.cc
|
||||
filmsimulation.cc prsharpening.cc)
|
||||
filmsimulation.cc prsharpening.cc
|
||||
dynamicprofile.cc dynamicprofilepanel.cc)
|
||||
|
||||
include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
|
||||
255
rtgui/dynamicprofile.cc
Normal file
255
rtgui/dynamicprofile.cc
Normal file
@@ -0,0 +1,255 @@
|
||||
/* -*- 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dynamicprofile.h"
|
||||
#include "profilestore.h"
|
||||
#include <stdlib.h>
|
||||
#include <glibmm/regex.h>
|
||||
|
||||
using namespace rtengine;
|
||||
using namespace rtengine::procparams;
|
||||
|
||||
namespace {
|
||||
|
||||
const int ISO_MAX = 512000;
|
||||
const double FNUMBER_MAX = 100.0;
|
||||
const double FOCALLEN_MAX = 10000.0;
|
||||
const double SHUTTERSPEED_MAX = 1000.0;
|
||||
const double EXPCOMP_MIN = -20.0;
|
||||
const double EXPCOMP_MAX = 20.0;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
bool DynamicProfileRule::Optional::operator()(const Glib::ustring &val) const
|
||||
{
|
||||
if (!enabled) {
|
||||
return true;
|
||||
}
|
||||
if (value.find("re:") == 0) {
|
||||
// this is a regexp
|
||||
return Glib::Regex::match_simple(value.substr(3), val,
|
||||
Glib::REGEX_CASELESS);
|
||||
} else {
|
||||
// normal string comparison
|
||||
return value.casefold() == val.casefold();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DynamicProfileRule::operator<(const DynamicProfileRule &other) const
|
||||
{
|
||||
return serial_number < other.serial_number;
|
||||
}
|
||||
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void get_int_range(DynamicProfileRule::Range<int> &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<double> &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");
|
||||
dest.enabled = e;
|
||||
dest.value = s;
|
||||
}
|
||||
} catch (Glib::KeyFileError &) {
|
||||
}
|
||||
}
|
||||
|
||||
void set_int_range(Glib::KeyFile &kf, const Glib::ustring &group,
|
||||
const Glib::ustring &key,
|
||||
const DynamicProfileRule::Range<int> &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<double> &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);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
bool loadDynamicProfileRules(std::vector<DynamicProfileRule> &out)
|
||||
{
|
||||
out.clear();
|
||||
Glib::KeyFile kf;
|
||||
try {
|
||||
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");
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
out.emplace_back(DynamicProfileRule());
|
||||
DynamicProfileRule &rule = out.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");
|
||||
try {
|
||||
rule.profilepath = kf.get_string(group, "profilepath");
|
||||
} catch (Glib::KeyFileError &) {
|
||||
out.pop_back();
|
||||
}
|
||||
}
|
||||
std::sort(out.begin(), out.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool storeDynamicProfileRules(const std::vector<DynamicProfileRule> &rules)
|
||||
{
|
||||
if (options.rtSettings.verbose) {
|
||||
printf("saving dynamic profiles...\n");
|
||||
}
|
||||
Glib::KeyFile kf;
|
||||
for (auto &rule : rules) {
|
||||
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);
|
||||
}
|
||||
return kf.save_to_file(
|
||||
Glib::build_filename(Options::rtdir, "dynamicprofile.cfg"));
|
||||
}
|
||||
|
||||
|
||||
PartialProfile *loadDynamicProfile(const ImageMetaData *im)
|
||||
{
|
||||
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;
|
||||
}
|
||||
74
rtgui/dynamicprofile.h
Normal file
74
rtgui/dynamicprofile.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DYNAMICPROFILE_H_
|
||||
#define _DYNAMICPROFILE_H_
|
||||
|
||||
#include <glibmm.h>
|
||||
#include <vector>
|
||||
#include "options.h"
|
||||
|
||||
|
||||
class DynamicProfileRule {
|
||||
public:
|
||||
template <class T>
|
||||
struct Range {
|
||||
T min;
|
||||
T max;
|
||||
explicit Range(T l=T(), T u=T()): min(l), max(u) {}
|
||||
|
||||
bool operator()(T val) const
|
||||
{
|
||||
return val >= min && val <= max;
|
||||
}
|
||||
};
|
||||
|
||||
struct Optional {
|
||||
Glib::ustring value;
|
||||
bool enabled;
|
||||
explicit Optional(const Glib::ustring v="", bool e=false):
|
||||
value(v), enabled(e) {}
|
||||
|
||||
bool operator()(const Glib::ustring &val) const;
|
||||
};
|
||||
|
||||
DynamicProfileRule();
|
||||
bool matches(const rtengine::ImageMetaData *im) const;
|
||||
bool operator<(const DynamicProfileRule &other) const;
|
||||
|
||||
int serial_number;
|
||||
Range<int> iso;
|
||||
Range<double> fnumber;
|
||||
Range<double> focallen;
|
||||
Range<double> shutterspeed;
|
||||
Range<double> expcomp;
|
||||
Optional camera;
|
||||
Optional lens;
|
||||
Glib::ustring profilepath;
|
||||
};
|
||||
|
||||
|
||||
bool loadDynamicProfileRules(std::vector<DynamicProfileRule> &out);
|
||||
bool storeDynamicProfileRules(
|
||||
const std::vector<DynamicProfileRule> &rules);
|
||||
|
||||
rtengine::procparams::PartialProfile *loadDynamicProfile(
|
||||
const rtengine::ImageMetaData *im);
|
||||
|
||||
|
||||
#endif // _DYNAMICPROFILE_H_
|
||||
533
rtgui/dynamicprofilepanel.cc
Normal file
533
rtgui/dynamicprofilepanel.cc
Normal file
@@ -0,0 +1,533 @@
|
||||
/* -*- 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dynamicprofilepanel.h"
|
||||
#include "multilangmgr.h"
|
||||
#include "profilestore.h"
|
||||
#include "../rtengine/rtengine.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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("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_button(M("GENERAL_OK"), 1);
|
||||
add_button(M("GENERAL_CANCEL"), 2);
|
||||
|
||||
set_ranges();
|
||||
|
||||
show_all_children();
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::EditDialog::set_rule(
|
||||
const DynamicProfileRule &rule)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_lens_->set_active(rule.lens.enabled);
|
||||
lens_->set_text(rule.lens.value);
|
||||
|
||||
profilepath_->updateProfileList();
|
||||
if (!profilepath_->setActiveRowFromFullPath(rule.profilepath)) {
|
||||
profilepath_->setInternalEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule()
|
||||
{
|
||||
DynamicProfileRule 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.camera.enabled = has_camera_->get_active();
|
||||
ret.camera.value = camera_->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()
|
||||
{
|
||||
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);
|
||||
|
||||
#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, \
|
||||
default_rule. name .max); \
|
||||
name ## _min_->set_value(default_rule. name .min); \
|
||||
name ## _max_->set_value(default_rule. name .max)
|
||||
|
||||
DOIT_(fnumber);
|
||||
DOIT_(focallen);
|
||||
DOIT_(shutterspeed);
|
||||
DOIT_(expcomp);
|
||||
#undef DOIT_
|
||||
shutterspeed_min_->set_digits(4);
|
||||
shutterspeed_max_->set_digits(4);
|
||||
|
||||
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);
|
||||
field->set_tooltip_text(M("DYNPROFILEEDITOR_ENTRY_TOOLTIP"));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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_);
|
||||
|
||||
treeview_.set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL);
|
||||
scrolledwindow_.add(treeview_);
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
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("EXIFFILTER_CAMERA"), *cell);
|
||||
col = treeview_.get_column(cols_count - 1);
|
||||
if (col) {
|
||||
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);
|
||||
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();
|
||||
|
||||
for (auto &r : profileStore.getDynamicProfileRules()) {
|
||||
add_rule(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::update_rule(Gtk::TreeModel::Row row,
|
||||
const DynamicProfileRule &rule)
|
||||
{
|
||||
row[columns_.iso] = rule.iso;
|
||||
row[columns_.fnumber] = rule.fnumber;
|
||||
row[columns_.focallen] = rule.focallen;
|
||||
row[columns_.shutterspeed] = rule.shutterspeed;
|
||||
row[columns_.expcomp] = rule.expcomp;
|
||||
row[columns_.camera] = rule.camera;
|
||||
row[columns_.lens] = rule.lens;
|
||||
row[columns_.profilepath] = rule.profilepath;
|
||||
}
|
||||
|
||||
void DynamicProfilePanel::add_rule(const DynamicProfileRule &rule)
|
||||
{
|
||||
auto row = *(treemodel_->append());
|
||||
update_rule(row, rule);
|
||||
}
|
||||
|
||||
|
||||
DynamicProfileRule DynamicProfilePanel::to_rule(Gtk::TreeModel::Row row,
|
||||
int serial)
|
||||
{
|
||||
DynamicProfileRule 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.camera = row[columns_.camera];
|
||||
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<Gtk::CellRendererText *>(cell);
|
||||
auto value = row[columns_.profilepath];
|
||||
auto pse = profileStore.findEntryFromFullPath(value);
|
||||
if (pse != nullptr) {
|
||||
ct->property_text() = pse->label;
|
||||
} else {
|
||||
ct->property_text() = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define RENDER_RANGE_(tp, name, tostr) \
|
||||
auto row = *iter; \
|
||||
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell); \
|
||||
DynamicProfileRule::Range<tp> r = row[columns_. name]; \
|
||||
DynamicProfileRule dflt; \
|
||||
if (r.min > dflt.name.min || r.max < dflt.name.max) { \
|
||||
auto value = tostr(r.min) + " - " + tostr(r.max); \
|
||||
ct->property_text() = value; \
|
||||
} else { \
|
||||
ct->property_text() = ""; \
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
template <class V>
|
||||
Glib::ustring to_str(V n, int precision=1)
|
||||
{
|
||||
std::ostringstream buf;
|
||||
buf << std::setprecision(precision) << std::fixed << n;
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DynamicProfilePanel::render_iso(
|
||||
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
|
||||
{
|
||||
RENDER_RANGE_(int, iso, to_str);
|
||||
}
|
||||
|
||||
|
||||
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); });
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::render_focallen(
|
||||
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
|
||||
{
|
||||
RENDER_RANGE_(double, focallen, to_str);
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::render_shutterspeed(
|
||||
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
|
||||
{
|
||||
RENDER_RANGE_(double, shutterspeed,
|
||||
rtengine::ImageMetaData::shutterToString);
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::render_expcomp(
|
||||
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
|
||||
{
|
||||
RENDER_RANGE_(double, expcomp, to_str);
|
||||
}
|
||||
|
||||
#undef RENDER_RANGE_
|
||||
|
||||
#define RENDER_OPTIONAL_(name) \
|
||||
auto row = *iter; \
|
||||
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell); \
|
||||
DynamicProfileRule::Optional o = row[columns_. name]; \
|
||||
if (o.enabled) { \
|
||||
ct->property_text() = o.value; \
|
||||
} else { \
|
||||
ct->property_text() = ""; \
|
||||
}
|
||||
|
||||
void DynamicProfilePanel::render_camera(
|
||||
Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter)
|
||||
{
|
||||
RENDER_OPTIONAL_(camera);
|
||||
}
|
||||
|
||||
|
||||
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<Gtk::Window &>(*get_toplevel()));
|
||||
int status = d.run();
|
||||
if (status == 1) {
|
||||
DynamicProfileRule rule = d.get_rule();
|
||||
add_rule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::on_button_edit()
|
||||
{
|
||||
auto s = treeview_.get_selection();
|
||||
if (!s->count_selected_rows()) {
|
||||
return;
|
||||
}
|
||||
EditDialog d(M("DYNPROFILEEDITOR_EDIT_RULE"),
|
||||
static_cast<Gtk::Window &>(*get_toplevel()));
|
||||
auto it = s->get_selected();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicProfilePanel::save()
|
||||
{
|
||||
std::vector<DynamicProfileRule> rules;
|
||||
int serial = 1;
|
||||
for (auto row : treemodel_->children()) {
|
||||
rules.emplace_back(to_rule(row, serial++));
|
||||
}
|
||||
if (!storeDynamicProfileRules(rules)) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
140
rtgui/dynamicprofilepanel.h
Normal file
140
rtgui/dynamicprofilepanel.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/* -*- 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DYNAMICPROFILEPANEL_H_
|
||||
#define _DYNAMICPROFILEPANEL_H_
|
||||
|
||||
#include <gtkmm.h>
|
||||
#include "dynamicprofile.h"
|
||||
#include "profilestore.h"
|
||||
|
||||
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 on_button_quit();
|
||||
void on_button_up();
|
||||
void on_button_down();
|
||||
void on_button_new();
|
||||
void on_button_edit();
|
||||
void on_button_delete();
|
||||
|
||||
class DynamicProfileColumns: public Gtk::TreeModel::ColumnRecord {
|
||||
public:
|
||||
DynamicProfileColumns()
|
||||
{
|
||||
add(iso);
|
||||
add(fnumber);
|
||||
add(focallen);
|
||||
add(shutterspeed);
|
||||
add(expcomp);
|
||||
add(camera);
|
||||
add(lens);
|
||||
add(profilepath);
|
||||
}
|
||||
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Range<int>> iso;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Range<double>> fnumber;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Range<double>> focallen;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Range<double>> shutterspeed;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Range<double>> expcomp;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Optional> camera;
|
||||
Gtk::TreeModelColumn<DynamicProfileRule::Optional> lens;
|
||||
Gtk::TreeModelColumn<Glib::ustring> 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_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 {
|
||||
public:
|
||||
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);
|
||||
|
||||
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_camera_;
|
||||
Gtk::Entry *camera_;
|
||||
|
||||
Gtk::CheckButton *has_lens_;
|
||||
Gtk::Entry *lens_;
|
||||
|
||||
ProfileStoreComboBox *profilepath_;
|
||||
};
|
||||
|
||||
DynamicProfileColumns columns_;
|
||||
|
||||
//Child widgets:
|
||||
Gtk::Box vbox_;
|
||||
|
||||
Gtk::ScrolledWindow scrolledwindow_;
|
||||
Gtk::TreeView treeview_;
|
||||
Glib::RefPtr<Gtk::ListStore> 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_
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "rtimage.h"
|
||||
#include "version.h"
|
||||
#include "extprog.h"
|
||||
#include "dynamicprofile.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <glibmm/fileutils.h>
|
||||
@@ -182,7 +183,7 @@ int main (int argc, char **argv)
|
||||
bool consoleOpened = false;
|
||||
|
||||
// suppression of annoying error boxes
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||
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))) {
|
||||
@@ -208,8 +209,8 @@ int main (int argc, char **argv)
|
||||
SetConsoleCtrlHandler ( NULL, true );
|
||||
// Set title of console
|
||||
char consoletitle[128];
|
||||
sprintf(consoletitle, "RawTherapee %s Console", RTVERSION);
|
||||
SetConsoleTitle(consoletitle);
|
||||
sprintf (consoletitle, "RawTherapee %s Console", RTVERSION);
|
||||
SetConsoleTitle (consoletitle);
|
||||
// increase size of screen buffer
|
||||
COORD c;
|
||||
c.X = 200;
|
||||
@@ -717,7 +718,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() || 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, options.defProfRaw.substr (5) + paramFileExtension)))) {
|
||||
std::cerr << "Error: default raw processing profile not found" << std::endl;
|
||||
rawParams->deleteInstance();
|
||||
delete rawParams;
|
||||
@@ -728,7 +729,7 @@ int processLineParams ( int argc, char **argv )
|
||||
imgParams = new rtengine::procparams::PartialProfile (true);
|
||||
profPath = options.findProfilePath (options.defProfImg);
|
||||
|
||||
if (options.is_defProfImgMissing() || profPath.empty() || 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, options.defProfImg.substr (5) + paramFileExtension)))) {
|
||||
std::cerr << "Error: default non-raw processing profile not found" << std::endl;
|
||||
imgParams->deleteInstance();
|
||||
delete imgParams;
|
||||
@@ -800,9 +801,21 @@ int processLineParams ( int argc, char **argv )
|
||||
|
||||
if (useDefault) {
|
||||
if (isRaw) {
|
||||
if (options.defProfRaw == DEFPROFILE_DYNAMIC) {
|
||||
rawParams->deleteInstance();
|
||||
delete rawParams;
|
||||
rawParams = loadDynamicProfile (ii->getMetaData());
|
||||
}
|
||||
|
||||
std::cout << " Merging default raw processing profile" << std::endl;
|
||||
rawParams->applyTo (¤tParams);
|
||||
} else {
|
||||
if (options.defProfImg == DEFPROFILE_DYNAMIC) {
|
||||
imgParams->deleteInstance();
|
||||
delete imgParams;
|
||||
imgParams = loadDynamicProfile (ii->getMetaData());
|
||||
}
|
||||
|
||||
std::cout << " Merging default non-raw processing profile" << std::endl;
|
||||
imgParams->applyTo (¤tParams);
|
||||
}
|
||||
|
||||
@@ -245,6 +245,10 @@ Glib::ustring Options::findProfilePath (Glib::ustring &profName)
|
||||
return profName;
|
||||
}
|
||||
|
||||
if (profName == DEFPROFILE_DYNAMIC) {
|
||||
return profName;
|
||||
}
|
||||
|
||||
Glib::ustring p = profName.substr (0, 4);
|
||||
|
||||
if (p == "${U}") {
|
||||
|
||||
@@ -39,11 +39,22 @@
|
||||
#define DEFPROFILE_IMG "Neutral"
|
||||
// Profile name to use for internal values' profile
|
||||
#define DEFPROFILE_INTERNAL "Neutral"
|
||||
// Special name for the Dynamic profile
|
||||
#define DEFPROFILE_DYNAMIC "Dynamic"
|
||||
|
||||
class SaveFormat
|
||||
{
|
||||
struct SaveFormat {
|
||||
SaveFormat() :
|
||||
format ("jpg"),
|
||||
pngBits (8),
|
||||
pngCompression (6),
|
||||
jpegQuality (90),
|
||||
jpegSubSamp (2),
|
||||
tiffBits (8),
|
||||
tiffUncompressed (true),
|
||||
saveParams (true)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
Glib::ustring format;
|
||||
int pngBits;
|
||||
int pngCompression;
|
||||
@@ -52,7 +63,6 @@ public:
|
||||
int tiffBits;
|
||||
bool tiffUncompressed;
|
||||
bool saveParams;
|
||||
SaveFormat () : format ("jpg"), pngBits (8), pngCompression (6), jpegQuality (90), jpegSubSamp (2), tiffBits (8), tiffUncompressed (true), saveParams (true) {};
|
||||
};
|
||||
|
||||
enum ThFileType {FT_Invalid = -1, FT_None = 0, FT_Raw = 1, FT_Jpeg = 2, FT_Tiff = 3, FT_Png = 4, FT_Custom = 5, FT_Tiff16 = 6, FT_Png16 = 7, FT_Custom16 = 8};
|
||||
|
||||
@@ -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"));
|
||||
@@ -247,11 +248,11 @@ Gtk::Widget* Preferences::getBatchProcPanel ()
|
||||
appendBehavList (mi, M ("TP_DIRPYRDENOISE_PASSES"), ADDSET_DIRPYRDN_PASSES, true);
|
||||
|
||||
mi = behModel->append ();
|
||||
mi->set_value (behavColumns.label, M("TP_WBALANCE_LABEL"));
|
||||
appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true);
|
||||
appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true);
|
||||
appendBehavList (mi, M("TP_WBALANCE_EQBLUERED"), ADDSET_WB_EQUAL, true);
|
||||
appendBehavList (mi, M("TP_WBALANCE_TEMPBIAS"), ADDSET_WB_TEMPBIAS, true);
|
||||
mi->set_value (behavColumns.label, M ("TP_WBALANCE_LABEL"));
|
||||
appendBehavList (mi, M ("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true);
|
||||
appendBehavList (mi, M ("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true);
|
||||
appendBehavList (mi, M ("TP_WBALANCE_EQBLUERED"), ADDSET_WB_EQUAL, true);
|
||||
appendBehavList (mi, M ("TP_WBALANCE_TEMPBIAS"), ADDSET_WB_TEMPBIAS, true);
|
||||
|
||||
mi = behModel->append ();
|
||||
mi->set_value (behavColumns.label, M ("TP_COLORAPP_LABEL"));
|
||||
@@ -440,6 +441,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 ()
|
||||
{
|
||||
|
||||
@@ -449,11 +458,13 @@ 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());
|
||||
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->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) );
|
||||
@@ -2106,6 +2117,7 @@ void Preferences::okPressed ()
|
||||
options.copyFrom (&moptions);
|
||||
options.filterOutParsedExtensions();
|
||||
Options::save ();
|
||||
dynProfilePanel->save();
|
||||
hide ();
|
||||
}
|
||||
|
||||
@@ -2269,6 +2281,8 @@ void Preferences::updateProfileList()
|
||||
{
|
||||
rprofiles->updateProfileList();
|
||||
iprofiles->updateProfileList();
|
||||
rprofiles->addRow (profileStore.getInternalDynamicPSE());
|
||||
iprofiles->addRow (profileStore.getInternalDynamicPSE());
|
||||
}
|
||||
|
||||
void Preferences::restoreValue()
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "options.h"
|
||||
#include <vector>
|
||||
#include "rtwindow.h"
|
||||
#include "dynamicprofilepanel.h"
|
||||
|
||||
class Preferences : public Gtk::Dialog, public ProfileStoreListener
|
||||
{
|
||||
@@ -204,6 +205,8 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener
|
||||
Gtk::CheckButton* ckbHideTPVScrollbar;
|
||||
Gtk::CheckButton* ckbUseIconNoText;
|
||||
|
||||
DynamicProfilePanel *dynProfilePanel;
|
||||
|
||||
Glib::ustring storedValueRaw;
|
||||
Glib::ustring storedValueImg;
|
||||
|
||||
@@ -242,6 +245,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);
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
#include "options.h"
|
||||
#include "toolpanel.h"
|
||||
#include "guiutils.h"
|
||||
#include "dynamicprofile.h"
|
||||
|
||||
ProfileStore profileStore;
|
||||
|
||||
using namespace rtengine;
|
||||
using namespace rtengine::procparams;
|
||||
|
||||
ProfileStore::ProfileStore () : parseMutex(nullptr), storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(nullptr), internalDefaultEntry(nullptr)
|
||||
ProfileStore::ProfileStore () : parseMutex(nullptr), storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(nullptr), internalDefaultEntry(nullptr), internalDynamicEntry(nullptr), dynamicRules(new std::vector<DynamicProfileRule>())
|
||||
{
|
||||
internalDefaultProfile = new AutoPartialProfile();
|
||||
internalDefaultProfile->set(true);
|
||||
@@ -42,6 +43,7 @@ bool ProfileStore::init ()
|
||||
storeState = STORESTATE_BEINGINITIALIZED;
|
||||
parseMutex = new MyMutex();
|
||||
_parseProfiles ();
|
||||
loadDynamicProfileRules(*dynamicRules);
|
||||
storeState = STORESTATE_INITIALIZED;
|
||||
}
|
||||
|
||||
@@ -63,6 +65,8 @@ ProfileStore::~ProfileStore ()
|
||||
partProfiles.clear ();
|
||||
clearFileList();
|
||||
delete internalDefaultProfile;
|
||||
delete internalDefaultEntry;
|
||||
delete internalDynamicEntry;
|
||||
lock.release();
|
||||
delete parseMutex;
|
||||
parseMutex = nullptr;
|
||||
@@ -140,6 +144,10 @@ void ProfileStore::_parseProfiles ()
|
||||
entries.push_back(internalDefaultEntry);
|
||||
partProfiles[internalDefaultEntry] = internalDefaultProfile;
|
||||
|
||||
if (!internalDynamicEntry) {
|
||||
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) {
|
||||
@@ -273,7 +281,7 @@ const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (path == DEFPROFILE_INTERNAL) {
|
||||
if (path == DEFPROFILE_INTERNAL || path == DEFPROFILE_DYNAMIC) {
|
||||
return internalDefaultEntry;
|
||||
}
|
||||
|
||||
@@ -499,6 +507,20 @@ void ProfileStore::dumpFolderList()
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
const std::vector<DynamicProfileRule> &ProfileStore::getDynamicProfileRules() const
|
||||
{
|
||||
return *dynamicRules;
|
||||
}
|
||||
|
||||
|
||||
void ProfileStore::setDynamicProfileRules(const std::vector<DynamicProfileRule> &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) {}
|
||||
@@ -570,12 +592,12 @@ void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow,
|
||||
// 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] = entry->label;
|
||||
menuHeader[methodColumns.label] = "-";
|
||||
menuHeader[methodColumns.profileStoreEntry] = entry;
|
||||
|
||||
#endif
|
||||
refreshProfileList_ (&newSubMenu, entry->folderId, false, entryList);
|
||||
} else {
|
||||
refreshProfileList_ (parentRow, entry->folderId, true, entryList);
|
||||
@@ -603,7 +625,6 @@ void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow,
|
||||
*/
|
||||
void ProfileStoreComboBox::updateProfileList ()
|
||||
{
|
||||
|
||||
// clear items
|
||||
clear();
|
||||
refTreeModel.clear();
|
||||
@@ -710,6 +731,11 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path)
|
||||
return row;
|
||||
}
|
||||
|
||||
if (path == DEFPROFILE_DYNAMIC) {
|
||||
row = findRowFromEntry(profileStore.getInternalDynamicPSE());
|
||||
return row;
|
||||
}
|
||||
|
||||
// removing the filename
|
||||
Glib::ustring fName = Glib::path_get_basename(path);
|
||||
|
||||
@@ -758,6 +784,10 @@ Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow()
|
||||
return Glib::ustring(DEFPROFILE_INTERNAL);
|
||||
}
|
||||
|
||||
if (currEntry == profileStore.getInternalDynamicPSE()) {
|
||||
return Glib::ustring(DEFPROFILE_DYNAMIC);
|
||||
}
|
||||
|
||||
path = Glib::build_filename(profileStore.getPathFromId(currEntry->parentFolderId), currEntry->label);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include "guiutils.h"
|
||||
|
||||
|
||||
// forward decl
|
||||
class DynamicProfileRule;
|
||||
|
||||
/** @brief This will implement callback functions for the ProfileStore
|
||||
*
|
||||
*/
|
||||
@@ -144,6 +147,7 @@ private:
|
||||
StoreState storeState;
|
||||
rtengine::procparams::AutoPartialProfile *internalDefaultProfile;
|
||||
ProfileStoreEntry *internalDefaultEntry;
|
||||
ProfileStoreEntry *internalDynamicEntry;
|
||||
|
||||
/** Alphabetically ordered list of folder and files through Gtk::Label sub-class;
|
||||
* ready to be used in Menu and Combobox
|
||||
@@ -160,6 +164,9 @@ private:
|
||||
/** List of the client of this store */
|
||||
std::list<ProfileStoreListener*> listeners;
|
||||
|
||||
/** cache for dynamic profile rules */
|
||||
std::unique_ptr<std::vector<DynamicProfileRule>> dynamicRules;
|
||||
|
||||
/** @brief Method to recursively parse a profile folder with a level depth arbitrarily limited to 3
|
||||
*
|
||||
* @param realPath current full path of the scanned directory ; e.g.: ~/MyProfiles/
|
||||
@@ -198,6 +205,14 @@ public:
|
||||
return internalDefaultEntry;
|
||||
}
|
||||
|
||||
const ProfileStoreEntry* getInternalDynamicPSE()
|
||||
{
|
||||
return internalDynamicEntry;
|
||||
}
|
||||
|
||||
const std::vector<DynamicProfileRule> &getDynamicProfileRules() const;
|
||||
void setDynamicProfileRules(const std::vector<DynamicProfileRule> &r);
|
||||
|
||||
void addListener(ProfileStoreListener *listener);
|
||||
void removeListener(ProfileStoreListener *listener);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "guiutils.h"
|
||||
#include "rtimage.h"
|
||||
|
||||
#include "../rtengine/utils.h"
|
||||
|
||||
extern Options options;
|
||||
|
||||
SaveAsDialog::SaveAsDialog (const Glib::ustring &initialDir, Gtk::Window* parent)
|
||||
@@ -217,41 +219,57 @@ SaveFormat SaveAsDialog::getFormat ()
|
||||
|
||||
void SaveAsDialog::okPressed ()
|
||||
{
|
||||
|
||||
fname = fchooser->get_filename();
|
||||
|
||||
// checking if the filename field is empty. The user have to click Cancel if he don't want to specify a filename
|
||||
// NB: There seem to be a bug in Gtkmm2.22 / FileChooserWidget : if you suppress the filename entry and
|
||||
// click on a folder in the list, the filename field is empty but get_filename will return the folder's path :/
|
||||
if (!fname.length() || Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) {
|
||||
Glib::ustring msg_ = Glib::ustring("<b>") + M("MAIN_MSG_EMPTYFILENAME") + "</b>";
|
||||
Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
|
||||
msgd.run ();
|
||||
if (Glib::file_test(fname, Glib::FILE_TEST_IS_DIR)) {
|
||||
fname = fchooser->get_current_name();
|
||||
}
|
||||
|
||||
// Checking if the filename field is empty. The user have to click Cancel if he don't want to specify a filename
|
||||
if (fname.empty()) {
|
||||
Gtk::MessageDialog(
|
||||
*this,
|
||||
Glib::ustring("<b>")
|
||||
+ M("MAIN_MSG_EMPTYFILENAME")
|
||||
+ "</b>",
|
||||
true,
|
||||
Gtk::MESSAGE_WARNING,
|
||||
Gtk::BUTTONS_OK,
|
||||
true
|
||||
).run();
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve extension ambiguities
|
||||
SaveFormat sf = formatOpts->getFormat ();
|
||||
Glib::ustring extLower = getExtension (fname).lowercase ();
|
||||
bool extIsEmpty = (extLower == "");
|
||||
bool extIsJpeg = (extLower == "jpg" || extLower == "jpeg" || extLower == "jpe");
|
||||
bool extIsTiff = (extLower == "tif" || extLower == "tiff");
|
||||
bool extIsPng = (extLower == "png");
|
||||
if (getExtension(fname).empty()) {
|
||||
// Extension is either empty or unfamiliar
|
||||
fname += '.' + formatOpts->getFormat().format;
|
||||
} else if (
|
||||
!rtengine::hasJpegExtension(fname)
|
||||
&& !rtengine::hasTiffExtension(fname)
|
||||
&& !rtengine::hasPngExtension(fname)
|
||||
) {
|
||||
// Create dialog to warn user that the filename may have two extensions on the end
|
||||
Gtk::MessageDialog msgd(
|
||||
*this,
|
||||
Glib::ustring("<b>")
|
||||
+ M("GENERAL_WARNING")
|
||||
+ ": "
|
||||
+ M("SAVEDLG_WARNFILENAME")
|
||||
+ " \""
|
||||
+ Glib::path_get_basename (fname)
|
||||
+ '.'
|
||||
+ formatOpts->getFormat().format
|
||||
+ "\"</b>",
|
||||
true,
|
||||
Gtk::MESSAGE_WARNING,
|
||||
Gtk::BUTTONS_OK_CANCEL,
|
||||
true
|
||||
);
|
||||
|
||||
if (extIsEmpty || !(extIsJpeg || extIsTiff || extIsPng)) {
|
||||
// extension is either empty or unfamiliar.
|
||||
fname += Glib::ustring (".") + sf.format;
|
||||
} else if ( !(sf.format == "jpg" && extIsJpeg)
|
||||
&& !(sf.format == "tif" && extIsTiff)
|
||||
&& !(sf.format == "png" && extIsPng ) ) {
|
||||
// create dialog to warn user that the filename may have two extensions on the end.
|
||||
Glib::ustring msg_ = Glib::ustring ("<b>") + M("GENERAL_WARNING") + ": "
|
||||
+ M("SAVEDLG_WARNFILENAME") + " \"" + Glib::path_get_basename (fname)
|
||||
+ "." + sf.format + "\"</b>";
|
||||
Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true);
|
||||
|
||||
if (msgd.run () == Gtk::RESPONSE_OK) {
|
||||
fname += Glib::ustring (".") + sf.format;
|
||||
if (msgd.run() == Gtk::RESPONSE_OK) {
|
||||
fname += "." + formatOpts->getFormat().format;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "profilestore.h"
|
||||
#include "batchqueue.h"
|
||||
#include "extprog.h"
|
||||
#include "dynamicprofile.h"
|
||||
|
||||
using namespace rtengine::procparams;
|
||||
|
||||
@@ -216,8 +217,31 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
|
||||
|
||||
const CacheImageData* cfs = getCacheImageData();
|
||||
Glib::ustring defaultPparamsPath = options.findProfilePath(defProf);
|
||||
const bool create = (!hasProcParams() || forceCPB);
|
||||
|
||||
if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) {
|
||||
const Glib::ustring outFName =
|
||||
(options.paramsLoadLocation == PLL_Input) ?
|
||||
fname + paramFileExtension :
|
||||
getCacheFileName("profiles", paramFileExtension);
|
||||
|
||||
if (defProf == DEFPROFILE_DYNAMIC && create && cfs && cfs->exifValid) {
|
||||
rtengine::ImageMetaData* imageMetaData;
|
||||
if (getType() == FT_Raw) {
|
||||
rtengine::RawMetaDataLocation metaData = rtengine::Thumbnail::loadMetaDataFromRaw(fname);
|
||||
imageMetaData = rtengine::ImageMetaData::fromFile (fname, &metaData);
|
||||
} else {
|
||||
imageMetaData = rtengine::ImageMetaData::fromFile (fname, nullptr);
|
||||
}
|
||||
PartialProfile *pp = loadDynamicProfile(imageMetaData);
|
||||
int err = pp->pparams->save(outFName);
|
||||
pp->deleteInstance();
|
||||
delete pp;
|
||||
if (!err) {
|
||||
loadProcParams();
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && create && cfs && cfs->exifValid) {
|
||||
// First generate the communication file, with general values and EXIF metadata
|
||||
rtengine::ImageMetaData* imageMetaData;
|
||||
|
||||
@@ -233,14 +257,6 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
|
||||
const rtexif::TagDirectory* exifDir = nullptr;
|
||||
|
||||
if (imageMetaData && (exifDir = imageMetaData->getExifData())) {
|
||||
Glib::ustring outFName;
|
||||
|
||||
if (options.paramsLoadLocation == PLL_Input) {
|
||||
outFName = fname + paramFileExtension;
|
||||
} else {
|
||||
outFName = getCacheFileName("profiles", paramFileExtension);
|
||||
}
|
||||
|
||||
exifDir->CPBDump(tmpFileName, fname, outFName,
|
||||
defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension),
|
||||
cfs,
|
||||
|
||||
Reference in New Issue
Block a user