rawTherapee/rtgui/iptcpanel.cc
Daniel Gao 711f274403 Get rid of relative include paths
* Use target_include_directories to specify include paths
* Specify project root (parent of rtgui and rtengine) as include path
* Replace relative includes with normal includes
2024-11-16 17:20:02 -05:00

806 lines
33 KiB
C++

/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include <set>
#include "iptcpanel.h"
#include "clipboard.h"
#include "rtimage.h"
#include "rtengine/imagedata.h"
#include "rtengine/metadata.h"
#include "rtengine/procparams.h"
using namespace rtengine;
using namespace rtengine::procparams;
namespace {
const std::string CAPTION("Iptc.Application2.Caption");
const std::string CAPTION_WRITER("Iptc.Application2.Writer");
const std::string CATEGORY("Iptc.Application2.Category");
const std::string CITY("Iptc.Application2.City");
const std::string COPYRIGHT("Iptc.Application2.Copyright");
const std::string COUNTRY("Iptc.Application2.CountryName");
const std::string CREATOR("Iptc.Application2.Byline");
const std::string CREATOR_JOB_TITLE("Iptc.Application2.BylineTitle");
const std::string CREDIT("Iptc.Application2.Credit");
const std::string DATE_CREATED("Iptc.Application2.DateCreated");
const std::string HEADLINE("Iptc.Application2.Headline");
const std::string INSTRUCTIONS("Iptc.Application2.SpecialInstructions");
const std::string KEYWORDS("Iptc.Application2.Keywords");
const std::string PROVINCE("Iptc.Application2.ProvinceState");
const std::string SOURCE("Iptc.Application2.Source");
const std::string SUPPLEMENTAL_CATEGORIES("Iptc.Application2.SuppCategory");
const std::string TITLE("Iptc.Application2.ObjectName");
const std::string TRANS_REFERENCE("Iptc.Application2.TransmissionReference");
const std::set<std::string> iptc_keys = {
CAPTION,
CAPTION_WRITER,
CATEGORY,
CITY,
COPYRIGHT,
COUNTRY,
CREATOR,
CREATOR_JOB_TITLE,
CREDIT,
DATE_CREATED,
HEADLINE,
INSTRUCTIONS,
KEYWORDS,
PROVINCE,
SOURCE,
SUPPLEMENTAL_CATEGORIES,
TITLE,
TRANS_REFERENCE
};
} // namespace
IPTCPanel::IPTCPanel():
changeList(new rtengine::procparams::IPTCPairs),
defChangeList(new rtengine::procparams::IPTCPairs),
embeddedData(new rtengine::procparams::IPTCPairs)
{
set_orientation(Gtk::ORIENTATION_VERTICAL);
set_spacing(4);
Gtk::Grid* iptc = Gtk::manage(new Gtk::Grid());
setExpandAlignProperties(iptc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
iptc->set_row_spacing(3);
int row = 0;
Gtk::Label* capl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DESCRIPTION") + ":"));
setExpandAlignProperties(capl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
captionText = Gtk::TextBuffer::create();
captionView = Gtk::manage(new Gtk::TextView(captionText));
setExpandAlignProperties(captionView, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
Gtk::ScrolledWindow* scrolledWindowc = Gtk::manage(new Gtk::ScrolledWindow());
setExpandAlignProperties(scrolledWindowc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
scrolledWindowc->set_min_content_height(100);
scrolledWindowc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scrolledWindowc->add(*captionView);
capl->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONHINT"));
captionView->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONHINT"));
captionView->set_size_request(35, 95);
iptc->attach(*capl, 0, row++, 1, 1);
iptc->attach(*scrolledWindowc, 0, row++, 1, 1);
// --------------------------
Gtk::Label* capwl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DESCRIPTIONWRITER") + ":"));
setExpandAlignProperties(capwl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
captionWriter = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(captionWriter, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
capwl->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONWRITERHINT"));
captionWriter->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONWRITERHINT"));
iptc->attach(*capwl, 0, row++, 1, 1);
iptc->attach(*captionWriter, 0, row++, 1, 1);
// --------------------------
Gtk::Label* headl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_HEADLINE") + ":"));
setExpandAlignProperties(headl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
headline = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(headline, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
headl->set_tooltip_text(M("IPTCPANEL_HEADLINEHINT"));
headline->set_tooltip_text(M("IPTCPANEL_HEADLINEHINT"));
iptc->attach(*headl, 0, row++, 1, 1);
iptc->attach(*headline, 0, row++, 1, 1);
// --------------------------
Gtk::Label* instl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_INSTRUCTIONS") + ":"));
setExpandAlignProperties(instl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
instructions = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(instructions, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
instl->set_tooltip_text(M("IPTCPANEL_INSTRUCTIONSHINT"));
instructions->set_tooltip_text(M("IPTCPANEL_INSTRUCTIONSHINT"));
iptc->attach(*instl, 0, row++, 1, 1);
iptc->attach(*instructions, 0, row++, 1, 1);
// --------------------------
Gtk::Separator* hsep1 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
setExpandAlignProperties(hsep1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
iptc->attach(*hsep1, 0, row++, 2, 1);
// --------------------------
Gtk::Label* keyl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_KEYWORDS") + ":"));
setExpandAlignProperties(keyl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
keyl->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT"));
keywords = Gtk::manage(new Gtk::ListViewText(1, false, Gtk::SELECTION_MULTIPLE));
setExpandAlignProperties(keywords, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
keywords->set_headers_visible(false);
keywords->set_size_request(50, 95);
Gtk::ScrolledWindow* scrolledWindowkw = Gtk::manage(new Gtk::ScrolledWindow());
setExpandAlignProperties(scrolledWindowkw, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
scrolledWindowkw->set_min_content_height(100);
scrolledWindowkw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scrolledWindowkw->add(*keywords);
keyword = Gtk::manage(new MyComboBoxText(true));
setExpandAlignProperties(keyword, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
keyword->set_size_request(75);
keywords->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT"));
keyword->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT"));
addKW = Gtk::manage(new Gtk::Button());
setExpandAlignProperties(addKW, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
delKW = Gtk::manage(new Gtk::Button());
setExpandAlignProperties(delKW, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
Gtk::Image* const addKWImg = Gtk::manage(new RTImage("add-small", Gtk::ICON_SIZE_BUTTON));
setExpandAlignProperties(addKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
Gtk::Image* const delKWImg = Gtk::manage(new RTImage("remove-small", Gtk::ICON_SIZE_BUTTON));
setExpandAlignProperties(delKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
addKW->add(*addKWImg);
delKW->add(*delKWImg);
Gtk::Grid* kwgrid = Gtk::manage(new Gtk::Grid());
setExpandAlignProperties(kwgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
kwgrid->attach(*keyword, 0, 0, 1, 1);
kwgrid->attach(*addKW, 1, 0, 1, 1);
kwgrid->attach(*delKW, 2, 0, 1, 1);
iptc->attach(*keyl, 0, row++, 1, 1);
iptc->attach(*kwgrid, 0, row++, 1, 1);
// --------------------------
iptc->attach(*scrolledWindowkw, 0, row++, 2, 1);
// --------------------------
Gtk::Separator* hsep2 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
setExpandAlignProperties(hsep2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
iptc->attach(*hsep2, 0, row++, 2, 1);
// --------------------------
Gtk::Label* catl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CATEGORY") + ":"));
setExpandAlignProperties(catl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
category = Gtk::manage(new MyComboBoxText(true));
category->set_size_request(75);
setExpandAlignProperties(category, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
catl->set_tooltip_text(M("IPTCPANEL_CATEGORYHINT"));
category->set_tooltip_text(M("IPTCPANEL_CATEGORYHINT"));
Gtk::Label* scl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_SUPPCATEGORIES") + ":"));
setExpandAlignProperties(scl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
suppCategories = Gtk::manage(new Gtk::ListViewText(1, false, Gtk::SELECTION_MULTIPLE));
setExpandAlignProperties(suppCategories, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
suppCategories->set_headers_visible(false);
suppCategories->set_size_request(50, 95);
Gtk::ScrolledWindow* scrolledWindowsc = Gtk::manage(new Gtk::ScrolledWindow());
setExpandAlignProperties(scrolledWindowsc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
scrolledWindowsc->set_min_content_height(100);
scrolledWindowsc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scrolledWindowsc->add(*suppCategories);
suppCategory = Gtk::manage(new MyComboBoxText(true));
suppCategory->set_size_request(75);
setExpandAlignProperties(suppCategory, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
scl->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT"));
suppCategories->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT"));
suppCategory->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT"));
addSC = Gtk::manage(new Gtk::Button());
setExpandAlignProperties(addSC, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
delSC = Gtk::manage(new Gtk::Button());
setExpandAlignProperties(delSC, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
Gtk::Image* const addSCImg = Gtk::manage(new RTImage("add-small", Gtk::ICON_SIZE_BUTTON));
setExpandAlignProperties(addSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
Gtk::Image* const delSCImg = Gtk::manage(new RTImage("remove-small", Gtk::ICON_SIZE_BUTTON));
setExpandAlignProperties(delSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
addSC->add(*addSCImg);
delSC->add(*delSCImg);
Gtk::Grid* scgrid = Gtk::manage(new Gtk::Grid());
setExpandAlignProperties(scgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
scgrid->attach(*suppCategory, 0, 0, 1, 1);
scgrid->attach(*addSC, 1, 0, 1, 1);
scgrid->attach(*delSC, 2, 0, 1, 1);
iptc->attach(*catl, 0, row++, 1, 1);
iptc->attach(*category, 0, row++, 1, 1);
// --------------------------
iptc->attach(*scl, 0, row++, 1, 1);
iptc->attach(*scgrid, 0, row++, 1, 1);
// --------------------------
iptc->attach(*scrolledWindowsc, 0, row++, 2, 1);
// --------------------------
Gtk::Separator* hsep3 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
setExpandAlignProperties(hsep3, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
iptc->attach(*hsep3, 0, row++, 2, 1);
// --------------------------
Gtk::Label* creatorLbl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREATOR") + ":"));
setExpandAlignProperties(creatorLbl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
creator = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(creator, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
creatorLbl->set_tooltip_text(M("IPTCPANEL_CREATORHINT"));
creator->set_tooltip_text(M("IPTCPANEL_CREATORHINT"));
iptc->attach(*creatorLbl, 0, row++, 1, 1);
iptc->attach(*creator, 0, row++, 1, 1);
// --------------------------
Gtk::Label* creatorJobTitleLbl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREATORJOBTITLE") + ":"));
setExpandAlignProperties(creatorJobTitleLbl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
creatorJobTitle = Gtk::manage( new Gtk::Entry());
setExpandAlignProperties(creatorJobTitle, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
creatorJobTitleLbl->set_tooltip_text(M("IPTCPANEL_CREATORJOBTITLEHINT"));
creatorJobTitle->set_tooltip_text(M("IPTCPANEL_CREATORJOBTITLEHINT"));
iptc->attach(*creatorJobTitleLbl, 0, row++, 1, 1);
iptc->attach(*creatorJobTitle, 0, row++, 1, 1);
// --------------------------
Gtk::Label* credl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREDIT") + ":"));
setExpandAlignProperties(credl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
credit = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(credit, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
credl->set_tooltip_text(M("IPTCPANEL_CREDITHINT"));
credit->set_tooltip_text(M("IPTCPANEL_CREDITHINT"));
iptc->attach(*credl, 0, row++, 1, 1);
iptc->attach(*credit, 0, row++, 1, 1);
// --------------------------
Gtk::Label* sourl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_SOURCE") + ":"));
setExpandAlignProperties(sourl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
source = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(source, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
sourl->set_tooltip_text(M("IPTCPANEL_SOURCEHINT"));
source->set_tooltip_text(M("IPTCPANEL_SOURCEHINT"));
iptc->attach(*sourl, 0, row++, 1, 1);
iptc->attach(*source, 0, row++, 1, 1);
// --------------------------
Gtk::Label* cprl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_COPYRIGHT") + ":"));
setExpandAlignProperties(cprl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
copyright = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(copyright, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
cprl->set_tooltip_text(M("IPTCPANEL_COPYRIGHTHINT"));
copyright->set_tooltip_text(M("IPTCPANEL_COPYRIGHTHINT"));
iptc->attach(*cprl, 0, row++, 1, 1);
iptc->attach(*copyright, 0, row++, 1, 1);
// --------------------------
Gtk::Separator* hsep4 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
setExpandAlignProperties(hsep4, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
iptc->attach(*hsep4, 0, row++, 2, 1);
// --------------------------
Gtk::Label* cityl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CITY") + ":"));
setExpandAlignProperties(cityl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
city = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(city, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
cityl->set_tooltip_text(M("IPTCPANEL_CITYHINT"));
city->set_tooltip_text(M("IPTCPANEL_CITYHINT"));
iptc->attach(*cityl, 0, row++, 1, 1);
iptc->attach(*city, 0, row++, 1, 1);
// --------------------------
Gtk::Label* provl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_PROVINCE") + ":"));
setExpandAlignProperties(provl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
province = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(province, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
provl->set_tooltip_text(M("IPTCPANEL_PROVINCEHINT"));
province->set_tooltip_text(M("IPTCPANEL_PROVINCEHINT"));
iptc->attach(*provl, 0, row++, 1, 1);
iptc->attach(*province, 0, row++, 1, 1);
// --------------------------
Gtk::Label* ctrl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_COUNTRY") + ":"));
setExpandAlignProperties(ctrl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
country = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(country, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
ctrl->set_tooltip_text(M("IPTCPANEL_COUNTRYHINT"));
country->set_tooltip_text(M("IPTCPANEL_COUNTRYHINT"));
iptc->attach(*ctrl, 0, row++, 1, 1);
iptc->attach(*country, 0, row++, 1, 1);
// --------------------------
Gtk::Label* titll = Gtk::manage(new Gtk::Label(M("IPTCPANEL_TITLE") + ":"));
setExpandAlignProperties(titll, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
title = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(title, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
titll->set_tooltip_text(M("IPTCPANEL_TITLEHINT"));
title->set_tooltip_text(M("IPTCPANEL_TITLEHINT"));
iptc->attach(*titll, 0, row++, 1, 1);
iptc->attach(*title, 0, row++, 1, 1);
// --------------------------
Gtk::Label* dcl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DATECREATED") + ":"));
setExpandAlignProperties(dcl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
dateCreated = Gtk::manage( new Gtk::Entry());
setExpandAlignProperties(dateCreated, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
dcl->set_tooltip_text(M("IPTCPANEL_DATECREATEDHINT"));
dateCreated->set_tooltip_text(M("IPTCPANEL_DATECREATEDHINT"));
iptc->attach(*dcl, 0, row++, 1, 1);
iptc->attach(*dateCreated, 0, row++, 1, 1);
// --------------------------
Gtk::Label* trl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_TRANSREFERENCE") + ":"));
setExpandAlignProperties(trl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
transReference = Gtk::manage(new Gtk::Entry());
setExpandAlignProperties(transReference, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
trl->set_tooltip_text(M("IPTCPANEL_TRANSREFERENCEHINT"));
transReference->set_tooltip_text(M("IPTCPANEL_TRANSREFERENCEHINT"));
iptc->attach(*trl, 0, row++, 1, 1);
iptc->attach(*transReference, 0, row++, 1, 1);
// --------------------------
Gtk::ScrolledWindow* scrolledWindow = Gtk::manage(new Gtk::ScrolledWindow());
setExpandAlignProperties(scrolledWindow, false, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE);
scrolledWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_RIGHT);
scrolledWindow->add(*iptc);
pack_start(*scrolledWindow);
Gtk::Grid* bbox = Gtk::manage(new Gtk::Grid());
setExpandAlignProperties(bbox, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
reset = Gtk::manage(new Gtk::Button()); // M("IPTCPANEL_RESET")
reset->get_style_context()->add_class("Left");
reset->set_image(*Gtk::manage(new RTImage("undo", Gtk::ICON_SIZE_BUTTON)));
setExpandAlignProperties(reset, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
bbox->attach_next_to(*reset, Gtk::POS_LEFT, 1, 1);
file = Gtk::manage(new Gtk::Button()); // M("IPTCPANEL_EMBEDDED")
file->get_style_context()->add_class("MiddleH");
file->set_image(*Gtk::manage(new RTImage("folder-open", Gtk::ICON_SIZE_BUTTON)));
setExpandAlignProperties(file, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
bbox->attach_next_to(*file, Gtk::POS_RIGHT, 1, 1);
copy = Gtk::manage(new Gtk::Button());
copy->get_style_context()->add_class("MiddleH");
copy->set_image(*Gtk::manage(new RTImage("copy", Gtk::ICON_SIZE_BUTTON)));
setExpandAlignProperties(copy, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
bbox->attach_next_to(*copy, Gtk::POS_RIGHT, 1, 1);
paste = Gtk::manage(new Gtk::Button());
paste->get_style_context()->add_class("Right");
paste->set_image(*Gtk::manage(new RTImage("paste", Gtk::ICON_SIZE_BUTTON)));
setExpandAlignProperties(paste, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
bbox->attach_next_to(*paste, Gtk::POS_RIGHT, 1, 1);
pack_end(*bbox, Gtk::PACK_SHRINK, 2);
reset->set_tooltip_text(M("IPTCPANEL_RESETHINT"));
file->set_tooltip_text(M("IPTCPANEL_EMBEDDEDHINT"));
copy->set_tooltip_text(M("IPTCPANEL_COPYHINT"));
paste->set_tooltip_text(M("IPTCPANEL_PASTEHINT"));
reset->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::resetClicked));
file->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::fileClicked));
copy->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::copyClicked));
paste->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::pasteClicked));
addKW->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::addKeyWord));
delKW->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::delKeyWord));
addSC->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::addSuppCategory));
delSC->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::delSuppCategory));
keyword->get_entry()->signal_activate().connect(sigc::mem_fun(*this, &IPTCPanel::addKeyWord));
suppCategory->get_entry()->signal_activate().connect(sigc::mem_fun(*this, &IPTCPanel::addSuppCategory));
conns[0] = captionText->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[1] = captionWriter->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[2] = headline->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[3] = instructions->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[4] = category->get_entry()->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[5] = creator->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[6] = creatorJobTitle->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[7] = credit->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[8] = source->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[9] = copyright->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[10] = city->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[11] = province->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[12] = country->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[13] = title->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[14] = dateCreated->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
conns[15] = transReference->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList));
category->get_entry()->set_max_length(3);
keyword->get_entry()->set_max_length(64);
captionWriter->set_max_length(32);
instructions->set_max_length(256);
creator->set_max_length(32);
creatorJobTitle->set_max_length(32);
credit->set_max_length(32);
source->set_max_length(32);
copyright->set_max_length(128);
city->set_max_length(32);
province->set_max_length(32);
country->set_max_length(64);
title->set_max_length(64);
dateCreated->set_max_length(10);
transReference->set_max_length(32);
show_all();
}
void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
{
disableListener();
changeList->clear();
if (!pp->metadata.iptc.empty()) {
*changeList = pp->metadata.iptc;
changelist_valid_ = true;
} else {
*changeList = *embeddedData;
changelist_valid_ = false;
}
applyChangeList();
enableListener();
}
void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited)
{
if (changelist_valid_) {
pp->metadata.iptc = *changeList;
} else {
pp->metadata.iptc.clear();
}
}
void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
{
*defChangeList = defParams->metadata.iptc;
}
void IPTCPanel::setImageData(const FramesMetaData* id)
{
embeddedData->clear();
if (id) {
try {
rtengine::Exiv2Metadata meta(id->getFileName());
meta.load();
auto& iptc = meta.iptcData();
for (const auto& tag : iptc) {
if (iptc_keys.find(tag.key()) != iptc_keys.end()) {
(*embeddedData)[tag.key()].push_back(tag.toString());
}
}
} catch (const std::exception& exc) {
embeddedData->clear();
}
}
file->set_sensitive(!embeddedData->empty());
}
void IPTCPanel::notifyListener()
{
if (listener) {
listener->panelChanged(EvIPTC, M("HISTORY_CHANGED"));
}
}
void IPTCPanel::addKeyWord()
{
keyword->get_entry()->select_region(0, keyword->get_entry()->get_text().size());
for (unsigned int i = 0; i < keywords->size(); i++) {
if (keywords->get_text(i) == keyword->get_entry()->get_text()) {
return;
}
}
keywords->append(keyword->get_entry()->get_text());
keyword->prepend(keyword->get_entry()->get_text());
std::vector<Glib::ustring> items;
for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i != keyword->get_model()->children().end(); ++i) {
Glib::ustring s;
i->get_value(0, s);
items.push_back(s);
}
keyword->remove_all();
for (unsigned int i = 0; i < 10 && i < items.size(); i++) {
keyword->append(items[i]);
}
keywords->scroll_to_row(keywords->get_model()->get_path(--keywords->get_model()->children().end()));
updateChangeList();
}
void IPTCPanel::delKeyWord()
{
std::vector<int> selection = keywords->get_selected();
if (!selection.empty()) {
std::vector<Glib::ustring> keep;
for (unsigned int i = 0; i < keywords->size(); i++)
if (std::find(selection.begin(), selection.end(), i) == selection.end()) {
keep.push_back(keywords->get_text(i));
}
keywords->clear_items();
for(unsigned int i = 0; i < keep.size(); i++) {
keywords->append(keep[i]);
}
}
updateChangeList();
}
void IPTCPanel::addSuppCategory()
{
for (unsigned int i = 0; i < suppCategories->size(); i++)
if (suppCategories->get_text(i) == suppCategory->get_entry()->get_text()) {
return;
}
suppCategories->append(suppCategory->get_entry()->get_text());
suppCategory->prepend(suppCategory->get_entry()->get_text());
std::vector<Glib::ustring> items;
for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i != suppCategory->get_model()->children().end(); ++i) {
Glib::ustring s;
i->get_value(0, s);
items.push_back(s);
}
suppCategory->remove_all();
for (unsigned int i = 0; i < 10 && i < items.size(); i++) {
suppCategory->append(items[i]);
}
suppCategories->scroll_to_row(suppCategories->get_model()->get_path(--suppCategories->get_model()->children().end()));
suppCategory->get_entry()->select_region(0, suppCategory->get_entry()->get_text().size());
updateChangeList();
}
void IPTCPanel::delSuppCategory()
{
std::vector<int> selection = suppCategories->get_selected();
if (!selection.empty()) {
std::vector<Glib::ustring> keep;
for (unsigned int i = 0; i < suppCategories->size(); i++)
if (std::find(selection.begin(), selection.end(), i) == selection.end()) {
keep.push_back(suppCategories->get_text(i));
}
suppCategories->clear_items();
for (unsigned int i = 0; i < keep.size(); i++) {
suppCategories->append(keep[i]);
}
}
updateChangeList();
}
void IPTCPanel::updateChangeList()
{
changelist_valid_ = true;
changeList->clear();
(*changeList)[CAPTION].push_back(captionText->get_text());
(*changeList)[CAPTION_WRITER].push_back(captionWriter->get_text());
(*changeList)[HEADLINE].push_back(headline->get_text());
(*changeList)[INSTRUCTIONS].push_back(instructions->get_text());
std::set<Glib::ustring> sset;
sset.clear();
for (unsigned int i = 0; i < keywords->size(); i++) {
sset.insert(keywords->get_text(i));
}
for (auto &s : sset) {
(*changeList)[KEYWORDS].push_back(s);
}
(*changeList)[CATEGORY].push_back(category->get_entry()->get_text());
sset.clear();
for (unsigned int i = 0; i < suppCategories->size(); i++) {
sset.insert(suppCategories->get_text(i));
}
for (auto &s : sset) {
(*changeList)[SUPPLEMENTAL_CATEGORIES].push_back(s);
}
(*changeList)[CREATOR].push_back(creator->get_text());
(*changeList)[CREATOR_JOB_TITLE].push_back(creatorJobTitle->get_text());
(*changeList)[CREDIT].push_back(credit->get_text());
(*changeList)[SOURCE].push_back(source->get_text());
(*changeList)[COPYRIGHT].push_back(copyright->get_text());
(*changeList)[CITY].push_back(city->get_text());
(*changeList)[PROVINCE].push_back(province->get_text());
(*changeList)[COUNTRY].push_back(country->get_text());
(*changeList)[TITLE].push_back(title->get_text());
(*changeList)[DATE_CREATED].push_back(dateCreated->get_text());
(*changeList)[TRANS_REFERENCE].push_back(transReference->get_text());
for (auto &p : *embeddedData) {
auto it = changeList->find(p.first);
if (it != changeList->end() && p.second == it->second) {
changeList->erase(it);
}
}
notifyListener();
}
void IPTCPanel::applyChangeList()
{
for (int i = 0; i < 16; i++) {
conns[i].block(true);
}
captionText->set_text("");
captionWriter->set_text("");
headline->set_text("");
instructions->set_text("");
keywords->clear_items();
category->get_entry()->set_text("");
suppCategories->clear_items();
creator->set_text("");
creatorJobTitle->set_text("");
credit->set_text("");
source->set_text("");
copyright->set_text("");
city->set_text("");
province->set_text("");
country->set_text("");
title->set_text("");
dateCreated->set_text("");
transReference->set_text("");
keyword->get_entry()->set_text("");
suppCategory->get_entry()->set_text("");
for (rtengine::procparams::IPTCPairs::const_iterator i = changeList->begin(); i != changeList->end(); ++i) {
if (i->first == CAPTION && !i->second.empty()) {
captionText->set_text(i->second.at(0));
} else if (i->first == CAPTION_WRITER && !i->second.empty()) {
captionWriter->set_text(i->second.at(0));
} else if (i->first == HEADLINE && !i->second.empty()) {
headline->set_text(i->second.at(0));
} else if (i->first == INSTRUCTIONS && !i->second.empty()) {
instructions->set_text(i->second.at(0));
} else if (i->first == KEYWORDS) {
std::set<Glib::ustring> sset;
for (unsigned int j = 0; j < i->second.size(); j++) {
sset.insert(i->second[j]);
}
for (auto &s : sset) {
keywords->append(s);
}
} else if (i->first == CATEGORY && !i->second.empty()) {
category->get_entry()->set_text(i->second.at(0));
} else if (i->first == SUPPLEMENTAL_CATEGORIES) {
std::set<Glib::ustring> sset;
for (unsigned int j = 0; j < i->second.size(); j++) {
sset.insert(i->second[j]);
}
for (auto &s : sset) {
suppCategories->append(s);
}
} else if (i->first == CREATOR && !i->second.empty()) {
creator->set_text(i->second.at(0));
} else if (i->first == CREATOR_JOB_TITLE && !i->second.empty()) {
creatorJobTitle->set_text(i->second.at(0));
} else if (i->first == CREDIT && !i->second.empty()) {
credit->set_text(i->second.at(0));
} else if (i->first == SOURCE && !i->second.empty()) {
source->set_text(i->second.at(0));
} else if (i->first == COPYRIGHT && !i->second.empty()) {
copyright->set_text(i->second.at(0));
} else if (i->first == CITY && !i->second.empty()) {
city->set_text(i->second.at(0));
} else if (i->first == PROVINCE && !i->second.empty()) {
province->set_text(i->second.at(0));
} else if (i->first == COUNTRY && !i->second.empty()) {
country->set_text(i->second.at(0));
} else if (i->first == TITLE && !i->second.empty()) {
title->set_text(i->second.at(0));
} else if (i->first == DATE_CREATED && !i->second.empty()) {
dateCreated->set_text(i->second.at(0));
} else if (i->first == TRANS_REFERENCE && !i->second.empty()) {
transReference->set_text(i->second.at(0));
}
}
for (int i = 0; i < 16; i++) {
conns[i].block(false);
}
}
void IPTCPanel::resetClicked()
{
disableListener();
*changeList = *defChangeList;
changelist_valid_ = false;
applyChangeList();
enableListener();
notifyListener();
}
void IPTCPanel::fileClicked()
{
disableListener();
*changeList = *embeddedData;
applyChangeList();
enableListener();
notifyListener();
}
void IPTCPanel::copyClicked()
{
clipboard.setIPTC(*changeList);
}
void IPTCPanel::pasteClicked()
{
disableListener();
*changeList = clipboard.getIPTC();
applyChangeList();
enableListener();
notifyListener();
}