diff --git a/rtdata/images/svg/edit-small.svg b/rtdata/images/svg/edit-small.svg
new file mode 100644
index 000000000..6306f06df
--- /dev/null
+++ b/rtdata/images/svg/edit-small.svg
@@ -0,0 +1,128 @@
+
+
+
+
diff --git a/rtdata/images/svg/edit.svg b/rtdata/images/svg/edit.svg
new file mode 100644
index 000000000..71f3d0b06
--- /dev/null
+++ b/rtdata/images/svg/edit.svg
@@ -0,0 +1,136 @@
+
+
+
+
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 4c0087cd3..a5ce4fa54 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -77,8 +77,7 @@ EXIFPANEL_RESET;Reset
EXIFPANEL_RESETALL;Reset All
EXIFPANEL_RESETALLHINT;Reset all tags to their original values.
EXIFPANEL_RESETHINT;Reset the selected tags to their original values.
-EXIFPANEL_SHOWALL;Show all
-EXIFPANEL_SUBDIRECTORY;Subdirectory
+EXIFPANEL_BASIC_GROUP;Basic
EXPORT_BYPASS;Processing steps to bypass
EXPORT_BYPASS_ALL;Select / Unselect All
EXPORT_BYPASS_DEFRINGE;Bypass Defringe
@@ -1548,7 +1547,7 @@ MAIN_TAB_COLOR;Color
MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c
MAIN_TAB_DETAIL;Detail
MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d
-MAIN_TAB_DEVELOP; Batch Edit
+MAIN_TAB_DEVELOP; Batch Edit
MAIN_TAB_EXIF;Exif
MAIN_TAB_EXPORT; Fast Export
MAIN_TAB_EXPOSURE;Exposure
diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc
index 42286cd40..52a9fa297 100644
--- a/rtengine/imagedata.cc
+++ b/rtengine/imagedata.cc
@@ -699,3 +699,36 @@ double FramesMetaData::apertureFromString(std::string s)
return std::atof(s.c_str());
}
+
+
+namespace {
+
+template
+void set_exif(Exiv2::ExifData &exif, const std::string &key, T val)
+{
+ try {
+ exif[key] = val;
+ } catch (std::exception &exc) {}
+}
+
+} // namespace
+
+void FramesData::fillBasicTags(Exiv2::ExifData &exif) const
+{
+ if (!hasExif()) {
+ return;
+ }
+ set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed());
+ set_exif(exif, "Exif.Photo.FNumber", Exiv2::DoubleValue(getFNumber()));
+ //set_exif(exif, "Exif.Photo.ExposureTime", Exiv2::DoubleValue(getShutterSpeed()));
+ set_exif(exif, "Exif.Photo.ExposureTime", shutterToString(getShutterSpeed()));
+ set_exif(exif, "Exif.Photo.FocalLength", Exiv2::DoubleValue(getFocalLen()));
+ set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(getExpComp()));
+ set_exif(exif, "Exif.Image.Make", getMake());
+ set_exif(exif, "Exif.Image.Model", getModel());
+ set_exif(exif, "Exif.Photo.LensModel", getLens());
+ char buf[256];
+ auto t = getDateTime();
+ strftime(buf, 256, "%Y:%m:%d %H:%M:%S", &t);
+ set_exif(exif, "Exif.Photo.DateTimeOriginal", buf);
+}
diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h
index 306c3b6f9..3a915c15d 100644
--- a/rtengine/imagedata.h
+++ b/rtengine/imagedata.h
@@ -23,6 +23,7 @@
#include
#include "imageio.h"
+#include "metadata.h"
namespace Glib
{
@@ -83,6 +84,8 @@ public:
std::string getOrientation() const override;
Glib::ustring getFileName() const override;
int getRating() const override;
+
+ void fillBasicTags(Exiv2::ExifData &exif) const;
};
}
diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc
index af2a7ef8a..d04b979fe 100644
--- a/rtengine/metadata.cc
+++ b/rtengine/metadata.cc
@@ -26,6 +26,7 @@
#include "metadata.h"
#include "settings.h"
+#include "imagedata.h"
#include "../rtgui/version.h"
#include "../rtgui/pathutils.h"
@@ -309,6 +310,16 @@ void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const
static const std::vector badpatterns = {
"Exif.SubImage"
};
+
+ if (exif_keys_ && !src_.empty()) {
+ try {
+ FramesData fd(src_);
+ fd.fillBasicTags(dst);
+ } catch (std::exception &exc) {
+ std::cout << "Error reading metadata from " << src_
+ << std::endl;
+ }
+ }
for (auto it = dst.begin(); it != dst.end(); ) {
if (badtags.find(it->key()) != badtags.end()) {
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 5076e147f..06ea2be6a 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -379,33 +379,6 @@ bool saveToKeyfile(
return false;
}
-const std::map exif_keys = {
- {"Copyright", "Exif.Image.Copyright"},
- {"Artist", "Exif.Image.Artist"},
- {"ImageDescription", "Exif.Image.ImageDescription"},
- {"Exif.UserComment", "Exif.Photo.UserComment"}
-};
-
-const std::map iptc_keys = {
- {"Title", "Iptc.Application2.ObjectName"},
- {"Category", "Iptc.Application2.Category"},
- {"SupplementalCategories", "Iptc.Application2.SuppCategory"},
- {"Keywords", "Iptc.Application2.Keywords"},
- {"Instructions", "Iptc.Application2.SpecialInstructions"},
- {"DateCreated", "Iptc.Application2.DateCreated"},
- {"Creator", "Iptc.Application2.Byline"},
- {"CreatorJobTitle", "Iptc.Application2.BylineTitle"},
- {"City", "Iptc.Application2.City"},
- {"Province", "Iptc.Application2.ProvinceState"},
- {"Country", "Iptc.Application2.CountryName"},
- {"TransReference", "Iptc.Application2.TransmissionReference"},
- {"Headline", "Iptc.Application2.Headline"},
- {"Credit", "Iptc.Application2.Credit"},
- {"Source", "Iptc.Application2.Source"},
- {"Copyright", "Iptc.Application2.Copyright"},
- {"Caption", "Iptc.Application2.Caption"},
- {"CaptionWriter", "Iptc.Application2.Writer"}
-};
} // namespace
@@ -5247,23 +5220,6 @@ Glib::ustring RAWParams::getFlatFieldBlurTypeString(FlatFieldBlurType type)
}
-MetaDataParams::MetaDataParams():
- mode(MetaDataParams::TUNNEL),
- exifKeys{"ALL"}
-{
-}
-
-bool MetaDataParams::operator==(const MetaDataParams &other) const
-{
- return mode == other.mode
- && exifKeys == other.exifKeys;
-}
-
-bool MetaDataParams::operator!=(const MetaDataParams &other) const
-{
- return !(*this == other);
-}
-
FilmNegativeParams::FilmNegativeParams() :
enabled(false),
redRatio(1.36),
@@ -5316,6 +5272,90 @@ bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const
return !(*this == other);
}
+
+namespace {
+
+const std::map exif_keys = {
+ {"Copyright", "Exif.Image.Copyright"},
+ {"Artist", "Exif.Image.Artist"},
+ {"ImageDescription", "Exif.Image.ImageDescription"},
+ {"Exif.UserComment", "Exif.Photo.UserComment"},
+ {"ISOSpeed", "Exif.Photo.ISOSpeedRatings"},
+ {"FNumber", "Exif.Photo.FNumber"},
+ {"ShutterSpeed", "Exif.Photo.ExposureTime"},
+ {"FocalLength", "Exif.Photo.FocalLength"},
+ {"ExpComp", "Exif.Photo.ExposureBiasValue"},
+ {"Flash", "Exif.Photo.Flash"},
+ {"Make", "Exif.Image.Make"},
+ {"Model", "Exif.Image.Model"},
+ {"Lens", "Exif.Photo.LensModel"},
+ {"DateTime", "Exif.Photo.DateTimeOriginal"}
+};
+
+const std::map iptc_keys = {
+ {"Title", "Iptc.Application2.ObjectName"},
+ {"Category", "Iptc.Application2.Category"},
+ {"SupplementalCategories", "Iptc.Application2.SuppCategory"},
+ {"Keywords", "Iptc.Application2.Keywords"},
+ {"Instructions", "Iptc.Application2.SpecialInstructions"},
+ {"DateCreated", "Iptc.Application2.DateCreated"},
+ {"Creator", "Iptc.Application2.Byline"},
+ {"CreatorJobTitle", "Iptc.Application2.BylineTitle"},
+ {"City", "Iptc.Application2.City"},
+ {"Province", "Iptc.Application2.ProvinceState"},
+ {"Country", "Iptc.Application2.CountryName"},
+ {"TransReference", "Iptc.Application2.TransmissionReference"},
+ {"Headline", "Iptc.Application2.Headline"},
+ {"Credit", "Iptc.Application2.Credit"},
+ {"Source", "Iptc.Application2.Source"},
+ {"Copyright", "Iptc.Application2.Copyright"},
+ {"Caption", "Iptc.Application2.Caption"},
+ {"CaptionWriter", "Iptc.Application2.Writer"}
+};
+
+} // namespace
+
+
+std::vector MetaDataParams::basicExifKeys = {
+ "Exif.Image.Copyright",
+ "Exif.Image.Artist",
+ "Exif.Image.ImageDescription",
+ "Exif.Photo.UserComment",
+ "Exif.Image.Make",
+ "Exif.Image.Model",
+ "Exif.Photo.LensModel",
+ "Exif.Photo.FNumber",
+ "Exif.Photo.ExposureTime",
+ "Exif.Photo.FocalLength",
+ "Exif.Photo.ISOSpeedRatings",
+ "Exif.Photo.ExposureBiasValue",
+ "Exif.Photo.Flash",
+ "Exif.Photo.DateTimeOriginal"
+};
+
+
+MetaDataParams::MetaDataParams():
+ mode(MetaDataParams::TUNNEL),
+ exifKeys{"*"},
+ exif{},
+ iptc{}
+{
+}
+
+bool MetaDataParams::operator==(const MetaDataParams &other) const
+{
+ return mode == other.mode
+ && exifKeys == other.exifKeys
+ && exif == other.exif
+ && iptc == other.iptc;
+}
+
+bool MetaDataParams::operator!=(const MetaDataParams &other) const
+{
+ return !(*this == other);
+}
+
+
ProcParams::ProcParams()
{
setDefaults();
@@ -5414,8 +5454,8 @@ void ProcParams::setDefaults()
raw = {};
metadata = {};
- exif.clear();
- iptc.clear();
+ //exif.clear();
+ //iptc.clear();
// -1 means that there's no pp3 data with rank yet. In this case, the
// embedded Rating metadata should take precedence. -1 should never be
@@ -6876,10 +6916,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
for (auto &p : exif_keys) {
m[p.second] = p.first;
}
- for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) {
- auto it = m.find(i->first);
+ for (auto &p : metadata.exif) {
+ auto it = m.find(p.first);
if (it != m.end()) {
- keyFile.set_string("Exif", it->second, i->second);
+ keyFile.set_string("Exif", it->second, p.second);
}
}
}
@@ -6890,10 +6930,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
for (auto &p : iptc_keys) {
m[p.second] = p.first;
}
- for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); ++i) {
- auto it = m.find(i->first);
+ for (auto &p : metadata.iptc) {
+ auto it = m.find(p.first);
if (it != m.end()) {
- Glib::ArrayHandle values = i->second;
+ Glib::ArrayHandle values = p.second;
keyFile.set_string_list("IPTC", it->second, values);
}
}
@@ -9383,7 +9423,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
for (const auto& key : keyFile.get_keys("Exif")) {
auto it = exif_keys.find(key);
if (it != exif_keys.end()) {
- exif[it->second] = keyFile.get_string("Exif", key);
+ metadata.exif[it->second] = keyFile.get_string("Exif", key);
if (pedited) {
pedited->exif = true;
@@ -9413,16 +9453,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
}
auto kk = it->second;
- const IPTCPairs::iterator element = iptc.find(kk);
+ const IPTCPairs::iterator element = metadata.iptc.find(kk);
- if (element != iptc.end()) {
+ if (element != metadata.iptc.end()) {
// it already exist so we cleanup the values
element->second.clear();
}
// TODO: look out if merging Keywords and SupplementalCategories from the procparams chain would be interesting
for (const auto& currLoadedTagValue : keyFile.get_string_list("IPTC", key)) {
- iptc[kk].push_back(currLoadedTagValue);
+ metadata.iptc[kk].push_back(currLoadedTagValue);
}
if (pedited) {
@@ -9500,8 +9540,6 @@ bool ProcParams::operator ==(const ProcParams& other) const
&& rgbCurves == other.rgbCurves
&& colorToning == other.colorToning
&& metadata == other.metadata
- && exif == other.exif
- && iptc == other.iptc
&& dehaze == other.dehaze
&& filmNegative == other.filmNegative;
}
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index dd6872630..d874a9b13 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1718,25 +1718,6 @@ struct ColorManagementParams {
bool operator !=(const ColorManagementParams& other) const;
};
-/**
- * Parameters for metadata handling
- */
-struct MetaDataParams {
- enum Mode {
- TUNNEL,
- EDIT,
- STRIP
- };
- Mode mode;
- std::vector exifKeys;
-
- MetaDataParams();
-
- bool operator ==(const MetaDataParams &other) const;
- bool operator !=(const MetaDataParams &other) const;
-};
-
-
/**
* Minimal wrapper allowing forward declaration for representing a key/value for the exif metadata information
*/
@@ -1841,6 +1822,29 @@ private:
std::map> pairs;
};
+/**
+ * Parameters for metadata handling
+ */
+struct MetaDataParams {
+ enum Mode {
+ TUNNEL,
+ EDIT,
+ STRIP
+ };
+ Mode mode;
+ std::vector exifKeys;
+ ExifPairs exif;
+ IPTCPairs iptc;
+
+ MetaDataParams();
+
+ bool operator ==(const MetaDataParams &other) const;
+ bool operator !=(const MetaDataParams &other) const;
+
+ static std::vector basicExifKeys;
+};
+
+
struct WaveletParams {
std::vector ccwcurve;
std::vector wavdenoise;
@@ -2355,8 +2359,8 @@ public:
int ppVersion; ///< Version of the PP file from which the parameters have been read
MetaDataParams metadata; ///< Metadata parameters
- ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image
- IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image
+ // ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image
+ // IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image
/**
* The constructor only sets the hand-wired defaults.
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index c8ee5e147..ef5592074 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -1737,9 +1737,9 @@ private:
readyImg->setMetadata(std::move(info));
break;
case MetaDataParams::EDIT:
- info.setExif(params.exif);
- info.setIptc(params.iptc);
- if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "ALL")) {
+ info.setExif(params.metadata.exif);
+ info.setIptc(params.metadata.iptc);
+ if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "*")) {
info.setExifKeys(&(params.metadata.exifKeys));
}
readyImg->setMetadata(std::move(info));
diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc
index ba612f615..a130a09b8 100644
--- a/rtgui/exifpanel.cc
+++ b/rtgui/exifpanel.cc
@@ -34,15 +34,12 @@ using namespace rtengine::procparams;
ExifPanel::ExifPanel() :
idata(nullptr),
changeList(new rtengine::procparams::ExifPairs),
- defChangeList(new rtengine::procparams::ExifPairs),
- editableTags{
- {"Exif.Photo.UserComment", "User Comment"},
- {"Exif.Image.Artist", "Artist"},
- {"Exif.Image.Copyright", "Copyright"},
- {"Exif.Image.ImageDescription", "Image Description"},
- { "Exif.Photo.LensModel", "Lens Model" }
- }
+ defChangeList(new rtengine::procparams::ExifPairs)
{
+ for (auto &k : MetaDataParams::basicExifKeys) {
+ editableTags.push_back(std::make_pair(k, ""));
+ }
+
set_orientation(Gtk::ORIENTATION_VERTICAL);
exifTree = Gtk::manage (new Gtk::TreeView());
scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow());
@@ -60,11 +57,29 @@ ExifPanel::ExifPanel() :
exifTreeModel = Gtk::TreeStore::create(exifColumns);
exifTree->set_model(exifTreeModel);
exifTree->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE);
- //exifTree->set_show_expanders(false);
+ exifTree->set_show_expanders(false);
exifTree->set_tooltip_column(0);
+ exifTree->set_enable_search(false);
- keepicon = RTImage::createPixbufFromFile ("tick-small.png");
- editicon = RTImage::createPixbufFromFile("add-small.png");
+ //keepicon = RTImage::createPixbufFromFile("tick-small.png");
+ editicon = RTImage::createPixbufFromFile("edit-small.png");
+ open_icon_ = RTImage::createPixbufFromFile("expander-open-small.png");
+ closed_icon_ = RTImage::createPixbufFromFile("expander-closed-small.png");
+
+ exif_active_renderer_.property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+ exif_active_renderer_.signal_toggled().connect(sigc::mem_fun(this, &ExifPanel::onKeyActiveToggled));
+ exif_active_column_.pack_start(exif_active_renderer_);
+ exif_active_column_.set_cell_data_func(exif_active_renderer_, sigc::mem_fun(this, &ExifPanel::setKeyActive));
+
+ exifTree->append_column(exif_active_column_);
+
+ // {
+ // Gtk::TreeView::Column *c = Gtk::manage(new Gtk::TreeView::Column(""));
+ // Gtk::CellRendererPixbuf *pb = Gtk::manage(new Gtk::CellRendererPixbuf());
+ // c->pack_start(*pb, false);
+ // c->add_attribute(*pb, "pixbuf", exifColumns.expander_icon);
+ // exifTree->append_column(*c);
+ // }
Gtk::TreeView::Column *viewcol = Gtk::manage (new Gtk::TreeView::Column ("Field Name"));
Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ());
@@ -85,15 +100,8 @@ ExifPanel::ExifPanel() :
render_pb->property_yalign() = 0;
render_txt->property_yalign() = 0;
- exif_active_renderer_.property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
- exif_active_renderer_.signal_toggled().connect(sigc::mem_fun(this, &ExifPanel::onKeyActiveToggled));
- exif_active_column_.pack_start(exif_active_renderer_);
- exif_active_column_.set_cell_data_func(exif_active_renderer_, sigc::mem_fun(this, &ExifPanel::setKeyActive));
-
- exifTree->append_column(exif_active_column_);
-
exifTree->append_column(*viewcol);
- exifTree->set_expander_column(*viewcol);
+ //exifTree->set_expander_column(*viewcol);
Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value"));
Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText());
@@ -131,14 +139,14 @@ ExifPanel::ExifPanel() :
activate_all_ = addbtn("EXIFPANEL_ACTIVATE_ALL_HINT", "tick.png");
activate_none_ = addbtn("EXIFPANEL_ACTIVATE_NONE_HINT", "box.png");
- add = addbtn("EXIFPANEL_ADDEDIT", "add.png");
+ add = addbtn("EXIFPANEL_ADDEDIT", "edit.png");
reset = addbtn("EXIFPANEL_RESETHINT", "undo.png", "redo.png");
resetAll = addbtn("EXIFPANEL_RESETALLHINT", "undo-all.png", "redo-all.png");
pack_end (*buttons1, Gtk::PACK_SHRINK);
exifTree->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ExifPanel::exifSelectionChanged));
- // exifTree->signal_row_activated().connect (sigc::mem_fun (*this, &ExifPanel::row_activated));
+ exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowActivated));
reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) );
resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) );
@@ -146,6 +154,10 @@ ExifPanel::ExifPanel() :
activate_all_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateAllPressed));
activate_none_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateNonePressed));
+ exifTree->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &ExifPanel::onExifTreeClick));
+ exifTree->signal_row_expanded().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowExpanded));
+ exifTree->signal_row_collapsed().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowCollapsed));
+
show_all ();
}
@@ -157,7 +169,7 @@ void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
{
disableListener();
- *changeList = pp->exif;
+ *changeList = pp->metadata.exif;
initial_active_keys_.clear();
initial_active_keys_.insert(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end());
cur_active_keys_ = initial_active_keys_;
@@ -170,54 +182,15 @@ void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited)
{
- pp->exif = *changeList;
-
- std::unordered_set prev;
- bool all_active = (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "ALL");
-
- if (!all_active) {
- prev = cur_active_keys_;
- }
-
- pp->metadata.exifKeys.clear();
-
- bool none_active = true;
-
- auto root = exifTreeModel->children();
- // for (auto &entry : root->children()) {
- // Glib::ustring key = entry[exifColumns.key];
- // prev.erase(key);
- // if (entry[exifColumns.active]) {
- // pp->metadata.exifKeys.push_back(key);
- // none_active = false;
- // } else {
- // all_active = false;
- // }
- // }
- for (auto &group : root->children()) {
- for (auto &entry : group.children()) {
- std::string key = entry[exifColumns.key];
- prev.erase(key);
- if (entry[exifColumns.active]) {
- pp->metadata.exifKeys.push_back(key);
- none_active = false;
- } else {
- all_active = false;
- }
- }
- }
-
- if (all_active) {
- pp->metadata.exifKeys = { "ALL" };
- } else if (!none_active) {
- pp->metadata.exifKeys.insert(pp->metadata.exifKeys.end(), prev.begin(), prev.end());
- }
+ pp->metadata.exif = *changeList;
+ cur_active_keys_ = get_active_keys();
+ pp->metadata.exifKeys.assign(cur_active_keys_.begin(), cur_active_keys_.end());
std::sort(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end());
}
void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
{
- *defChangeList = defParams->exif;
+ *defChangeList = defParams->metadata.exif;
}
void ExifPanel::setImageData (const FramesMetaData* id)
@@ -240,11 +213,13 @@ void ExifPanel::addTag(const std::string &key, const std::pairchildren();
- for (auto it = root.rbegin(), end = root.rend(); it != end; ++it) {
- auto row = *it;
+ // for (auto it = root.rbegin(), end = root.rend(); it != end; ++it) {
+ // auto row = *it;
+ for (auto &row : root) {
+ // auto row = *it;
std::string key = row[exifColumns.key];
if (row[exifColumns.is_group] && key == label.first) {
- return it->children();
+ return row./*it->*/children();
}
}
auto it = exifTreeModel->append(root);
@@ -253,7 +228,7 @@ void ExifPanel::addTag(const std::string &key, const std::pair" + label.first + "";
+ row[exifColumns.label] = "" + label.first + "";
row[exifColumns.value_nopango] = "";
row[exifColumns.value] = "";
row[exifColumns.is_group] = true;
@@ -275,13 +250,13 @@ void ExifPanel::addTag(const std::string &key, const std::pair Glib::ustring
@@ -338,6 +314,9 @@ void ExifPanel::refreshTags()
return "(Not shown)";
};
+ if (const rtengine::FramesData *fd = dynamic_cast(idata)) {
+ fd->fillBasicTags(exif);
+ }
for (const auto& p : *changeList) {
try {
@@ -346,12 +325,18 @@ void ExifPanel::refreshTags()
}
}
- for (const auto& p : editableTags) {
- const auto pos = exif.findKey(Exiv2::ExifKey(p.first));
+ for (auto& p : editableTags) {
+ Exiv2::ExifKey k(p.first);
+ const auto pos = exif.findKey(k);
+ bool edited = false;
+ Glib::ustring value = "";
+ auto lbl = std::make_pair(M("EXIFPANEL_BASIC_GROUP"), k.tagLabel());
+ p.second = k.tagLabel();
if (pos != exif.end() && pos->size()) {
- const bool edited = changeList->find(pos->key()) != changeList->end();
- addTag(pos->key(), to_label(*pos), pos->print(&exif), true, edited);
+ edited = changeList->find(pos->key()) != changeList->end();
+ value = pos->print(&exif);
}
+ addTag(p.first, lbl, value, true, edited);
}
std::set keyset;
for (const auto& tag : exif) {
@@ -406,6 +391,7 @@ void ExifPanel::resetIt(const Gtk::TreeModel::const_iterator& iter)
void ExifPanel::resetPressed()
{
+ cur_active_keys_ = get_active_keys();
std::vector sel = exifTree->get_selection()->get_selected_rows();
@@ -490,10 +476,13 @@ void ExifPanel::addPressed ()
hb2->show ();
if (dialog->run () == Gtk::RESPONSE_OK) {
+ cur_active_keys_ = get_active_keys();
auto key = editableTags[tcombo->get_active_row_number()].first;
const auto value = ventry->get_text();
(*changeList)[key] = value;
- cur_active_keys_.insert(key);
+ if (!all_keys_active()) {
+ cur_active_keys_.insert(key);
+ }
refreshTags();
notifyListener();
}
@@ -556,6 +545,11 @@ void ExifPanel::onKeyActiveToggled(const Glib::ustring &path)
for (auto &c : row.children()) {
c[exifColumns.active] = b;
}
+ } else if (!b) {
+ it = row.parent();
+ if (it) {
+ (*it)[exifColumns.active] = b;
+ }
}
notifyListener();
}
@@ -568,3 +562,78 @@ void ExifPanel::setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::
static_cast(renderer)->set_active(row[exifColumns.active]);
}
+
+bool ExifPanel::all_keys_active() const
+{
+ return (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "*");
+}
+
+
+std::unordered_set ExifPanel::get_active_keys() const
+{
+ bool all_active = true;
+ std::unordered_set ret;
+ auto root = exifTreeModel->children();
+ for (auto &group : root->children()) {
+ for (auto &entry : group.children()) {
+ std::string key = entry[exifColumns.key];
+ if (entry[exifColumns.active]) {
+ ret.insert(key);
+ } else {
+ all_active = false;
+ }
+ }
+ }
+ if (all_active) {
+ ret.clear();
+ ret.insert("*");
+ }
+ return ret;
+}
+
+void ExifPanel::onExifTreeClick(GdkEventButton *event)
+{
+ Gtk::TreeModel::Path pth;
+ Gtk::TreeViewColumn *col;
+ int cell_x;
+ int cell_y;
+ if (exifTree->get_path_at_pos(event->x, event->y, pth, col, cell_x, cell_y) && col == exifTree->get_column(1) && cell_x <= 22) {
+ auto it = exifTreeModel->get_iter(pth);
+ auto row = *it;
+ if (row[exifColumns.is_group]) {
+ if (exifTree->row_expanded(pth)) {
+ exifTree->collapse_row(pth);
+ } else {
+ exifTree->expand_row(pth, false);
+ }
+ }
+ }
+}
+
+
+void ExifPanel::onExifRowExpanded(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path)
+{
+ auto row = *it;
+ if (row[exifColumns.is_group]) {
+ row[exifColumns.icon] = open_icon_;
+ }
+}
+
+
+void ExifPanel::onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path)
+{
+ auto row = *it;
+ if (row[exifColumns.is_group]) {
+ row[exifColumns.icon] = closed_icon_;
+ }
+}
+
+
+void ExifPanel::onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column)
+{
+ auto it = exifTreeModel->get_iter(path);
+ auto row = *it;
+ if (row[exifColumns.editable]) {
+ addPressed();
+ }
+}
diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h
index 32ce10dc7..da4cc1e37 100644
--- a/rtgui/exifpanel.h
+++ b/rtgui/exifpanel.h
@@ -50,7 +50,8 @@ private:
class ExifColumns : public Gtk::TreeModelColumnRecord
{
public:
- Gtk::TreeModelColumn > icon;
+ // Gtk::TreeModelColumn> expander_icon;
+ Gtk::TreeModelColumn> icon;
Gtk::TreeModelColumn key;
Gtk::TreeModelColumn label;
Gtk::TreeModelColumn value;
@@ -71,10 +72,13 @@ private:
add(editable);
add(active);
add(is_group);
+ // add(expander_icon);
}
};
- Glib::RefPtr keepicon;
+ //Glib::RefPtr keepicon;
Glib::RefPtr editicon;
+ Glib::RefPtr open_icon_;
+ Glib::RefPtr closed_icon_;
ExifColumns exifColumns;
Gtk::TreeView* exifTree;
@@ -90,7 +94,7 @@ private:
Gtk::CellRendererToggle exif_active_renderer_;
Gtk::TreeView::Column exif_active_column_;
- const std::vector> editableTags;
+ std::vector> editableTags;
std::unordered_set initial_active_keys_;
std::unordered_set cur_active_keys_;
@@ -106,7 +110,14 @@ private:
void setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it);
void onKeyActiveToggled(const Glib::ustring &path);
-
+
+ bool all_keys_active() const;
+ std::unordered_set get_active_keys() const;
+
+ void onExifTreeClick(GdkEventButton *event);
+ void onExifRowExpanded(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path);
+ void onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path);
+ void onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column);
public:
ExifPanel ();
diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc
index f476e7513..bee7ec74a 100644
--- a/rtgui/iptcpanel.cc
+++ b/rtgui/iptcpanel.cc
@@ -467,8 +467,8 @@ void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
disableListener ();
changeList->clear();
- if (!pp->iptc.empty()) {
- *changeList = pp->iptc;
+ if (!pp->metadata.iptc.empty()) {
+ *changeList = pp->metadata.iptc;
} else {
*changeList = *embeddedData;
}
@@ -480,13 +480,13 @@ void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited)
{
- pp->iptc = *changeList;
+ pp->metadata.iptc = *changeList;
}
void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
{
- *defChangeList = defParams->iptc;
+ *defChangeList = defParams->metadata.iptc;
}
void IPTCPanel::setImageData (const FramesMetaData* id)
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 8459d4013..98abe2869 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -6612,15 +6612,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
// Exif changes are added to the existing ones
if (exif) {
- for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) {
- toEdit.exif[i->first] = i->second;
+ for (procparams::ExifPairs::const_iterator i = mods.metadata.exif.begin(); i != mods.metadata.exif.end(); ++i) {
+ toEdit.metadata.exif[i->first] = i->second;
}
}
// IPTC changes are added to the existing ones
if (iptc) {
- for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); ++i) {
- toEdit.iptc[i->first] = i->second;
+ for (procparams::IPTCPairs::const_iterator i = mods.metadata.iptc.begin(); i != mods.metadata.iptc.end(); ++i) {
+ toEdit.metadata.iptc[i->first] = i->second;
}
}
}
diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc
index ce5138d28..dfc1bfeb7 100644
--- a/rtgui/thumbnail.cc
+++ b/rtgui/thumbnail.cc
@@ -1215,7 +1215,7 @@ void Thumbnail::saveMetadata()
return;
}
- if (pparams->exif.empty() && pparams->iptc.empty()) {
+ if (pparams->metadata.exif.empty() && pparams->metadata.iptc.empty()) {
return;
}
@@ -1224,8 +1224,8 @@ void Thumbnail::saveMetadata()
auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname);
rtengine::Exiv2Metadata meta;
meta.xmpData() = std::move(xmp);
- meta.setExif(pparams->exif);
- meta.setIptc(pparams->iptc);
+ meta.setExif(pparams->metadata.exif);
+ meta.setIptc(pparams->metadata.iptc);
meta.saveToXmp(fn);
if (options.rtSettings.verbose) {
std::cout << "saved edited metadata for " << fname << " to "
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 920585aed..fde949606 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -141,7 +141,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit
addfavoritePanel (detailsPanel, dehaze);
addfavoritePanel (advancedPanel, wavelet);
addfavoritePanel(locallabPanel, locallab);
-
+
addfavoritePanel (transformPanel, crop);
addfavoritePanel (transformPanel, resize);
addPanel (resize->getPackBox(), prsharpening, 2);
@@ -187,7 +187,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit
transformPanelSW = Gtk::manage (new MyScrolledWindow ());
rawPanelSW = Gtk::manage (new MyScrolledWindow ());
advancedPanelSW = Gtk::manage (new MyScrolledWindow ());
- locallabPanelSW = Gtk::manage(new MyScrolledWindow());
+ locallabPanelSW = Gtk::manage(new MyScrolledWindow());
// load panel endings
for (int i = 0; i < 8; i++) {
@@ -585,8 +585,8 @@ void ToolPanelCoordinator::profileChange(
// Reset IPTC values when switching procparams from the History
if (event == rtengine::EvHistoryBrowsed) {
- mergedParams->iptc.clear();
- mergedParams->exif.clear();
+ mergedParams->metadata.iptc.clear();
+ mergedParams->metadata.exif.clear();
}
// And apply the partial profile nparams to mergedParams