/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #include #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 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* addKWImg = Gtk::manage(new RTImage("add-small.png")); setExpandAlignProperties(addKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); Gtk::Image* delKWImg = Gtk::manage(new RTImage("remove-small.png")); 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* addSCImg = Gtk::manage(new RTImage("add-small.png")); setExpandAlignProperties(addSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); Gtk::Image* delSCImg = Gtk::manage(new RTImage("remove-small.png")); 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.png", "redo.png"))); 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.png"))); 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.png"))); 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.png"))); 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 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 selection = keywords->get_selected(); if (!selection.empty()) { std::vector 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 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 selection = suppCategories->get_selected(); if (!selection.empty()) { std::vector 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 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 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 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(); }