You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
413 lines
13 KiB
413 lines
13 KiB
15 years ago
|
/* ============================================================
|
||
|
*
|
||
|
* This file is a part of kipi-plugins project
|
||
|
* http://www.kipi-plugins.org
|
||
|
*
|
||
|
* Date : 2006-10-12
|
||
|
* Description : a dialog to edit IPTC metadata
|
||
|
*
|
||
|
* Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||
|
*
|
||
|
* This program 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 2, or (at your option) any later version.
|
||
|
*
|
||
|
* This program 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.
|
||
|
*
|
||
|
* ============================================================ */
|
||
|
|
||
|
// Qt includes.
|
||
|
|
||
|
#include <qtimer.h>
|
||
|
#include <qframe.h>
|
||
|
#include <qlayout.h>
|
||
|
#include <qpushbutton.h>
|
||
|
|
||
|
// KDE includes.
|
||
|
|
||
|
#include <klocale.h>
|
||
|
#include <kconfig.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <kiconloader.h>
|
||
|
#include <kapplication.h>
|
||
|
#include <kmessagebox.h>
|
||
|
#include <khelpmenu.h>
|
||
|
#include <kpopupmenu.h>
|
||
|
|
||
|
// LibKIPI includes.
|
||
|
|
||
|
#include <libkipi/imagecollection.h>
|
||
|
#include <libkipi/plugin.h>
|
||
|
|
||
|
// LibKExiv2 includes.
|
||
|
|
||
|
#include <libkexiv2/kexiv2.h>
|
||
|
|
||
|
// Local includes.
|
||
|
|
||
|
#include "kpaboutdata.h"
|
||
|
#include "pluginsversion.h"
|
||
|
#include "iptccaption.h"
|
||
|
#include "iptccredits.h"
|
||
|
#include "iptcstatus.h"
|
||
|
#include "iptcorigin.h"
|
||
|
#include "iptcdatetime.h"
|
||
|
#include "iptckeywords.h"
|
||
|
#include "iptcsubjects.h"
|
||
|
#include "iptccategories.h"
|
||
|
#include "iptceditdialog.h"
|
||
|
#include "iptceditdialog.moc"
|
||
|
|
||
|
namespace KIPIMetadataEditPlugin
|
||
|
{
|
||
|
|
||
|
class IPTCEditDialogDialogPrivate
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
IPTCEditDialogDialogPrivate()
|
||
|
{
|
||
|
modified = false;
|
||
|
isReadOnly = false;
|
||
|
page_caption = 0;
|
||
|
page_datetime = 0;
|
||
|
page_subjects = 0;
|
||
|
page_keywords = 0;
|
||
|
page_categories = 0;
|
||
|
page_credits = 0;
|
||
|
page_status = 0;
|
||
|
page_origin = 0;
|
||
|
|
||
|
about = 0;
|
||
|
|
||
|
captionPage = 0;
|
||
|
datetimePage = 0;
|
||
|
subjectsPage = 0;
|
||
|
keywordsPage = 0;
|
||
|
categoriesPage = 0;
|
||
|
creditsPage = 0;
|
||
|
statusPage = 0;
|
||
|
originPage = 0;
|
||
|
}
|
||
|
|
||
|
bool modified;
|
||
|
bool isReadOnly;
|
||
|
|
||
|
QByteArray exifData;
|
||
|
QByteArray iptcData;
|
||
|
|
||
|
QFrame *page_caption;
|
||
|
QFrame *page_datetime;
|
||
|
QFrame *page_subjects;
|
||
|
QFrame *page_keywords;
|
||
|
QFrame *page_categories;
|
||
|
QFrame *page_credits;
|
||
|
QFrame *page_status;
|
||
|
QFrame *page_origin;
|
||
|
|
||
|
KURL::List urls;
|
||
|
|
||
|
KURL::List::iterator currItem;
|
||
|
|
||
|
IPTCCaption *captionPage;
|
||
|
IPTCDateTime *datetimePage;
|
||
|
IPTCSubjects *subjectsPage;
|
||
|
IPTCKeywords *keywordsPage;
|
||
|
IPTCCategories *categoriesPage;
|
||
|
IPTCCredits *creditsPage;
|
||
|
IPTCStatus *statusPage;
|
||
|
IPTCOrigin *originPage;
|
||
|
|
||
|
KIPI::Interface *interface;
|
||
|
|
||
|
KIPIPlugins::KPAboutData *about;
|
||
|
};
|
||
|
|
||
|
IPTCEditDialog::IPTCEditDialog(QWidget* parent, KURL::List urls, KIPI::Interface *iface)
|
||
|
: KDialogBase(IconList, QString::null,
|
||
|
urls.count() > 1 ? Help|User1|User2|Stretch|Ok|Apply|Close
|
||
|
: Help|Stretch|Ok|Apply|Close,
|
||
|
Ok, parent, 0, true, true,
|
||
|
KStdGuiItem::guiItem(KStdGuiItem::Forward),
|
||
|
KStdGuiItem::guiItem(KStdGuiItem::Back) )
|
||
|
{
|
||
|
d = new IPTCEditDialogDialogPrivate;
|
||
|
d->urls = urls;
|
||
|
d->interface = iface;
|
||
|
d->currItem = d->urls.begin();
|
||
|
|
||
|
// ---------------------------------------------------------------
|
||
|
|
||
|
d->page_caption = addPage(i18n("Caption"), i18n("Caption Information"),
|
||
|
BarIcon("editclear", KIcon::SizeMedium));
|
||
|
d->captionPage = new IPTCCaption(d->page_caption);
|
||
|
|
||
|
d->page_datetime = addPage(i18n("Date & Time"), i18n("Date and Time Information"),
|
||
|
BarIcon("today", KIcon::SizeMedium));
|
||
|
d->datetimePage = new IPTCDateTime(d->page_datetime);
|
||
|
|
||
|
d->page_subjects = addPage(i18n("Subjects"), i18n("Subjects Information"),
|
||
|
BarIcon("cookie", KIcon::SizeMedium));
|
||
|
d->subjectsPage = new IPTCSubjects(d->page_subjects);
|
||
|
|
||
|
d->page_keywords = addPage(i18n("Keywords"), i18n("Keywords Information"),
|
||
|
BarIcon("bookmark", KIcon::SizeMedium));
|
||
|
d->keywordsPage = new IPTCKeywords(d->page_keywords);
|
||
|
|
||
|
d->page_categories = addPage(i18n("Categories"), i18n("Categories Information"),
|
||
|
BarIcon("bookmark_folder", KIcon::SizeMedium));
|
||
|
d->categoriesPage = new IPTCCategories(d->page_categories);
|
||
|
|
||
|
d->page_credits = addPage(i18n("Credits"), i18n("Credits Information"),
|
||
|
BarIcon("identity", KIcon::SizeMedium));
|
||
|
d->creditsPage = new IPTCCredits(d->page_credits);
|
||
|
|
||
|
d->page_status = addPage(i18n("Status"), i18n("Status Information"),
|
||
|
BarIcon("messagebox_info", KIcon::SizeMedium));
|
||
|
d->statusPage = new IPTCStatus(d->page_status);
|
||
|
|
||
|
d->page_origin = addPage(i18n("Origin"), i18n("Origin Information"),
|
||
|
BarIcon("www", KIcon::SizeMedium));
|
||
|
d->originPage = new IPTCOrigin(d->page_origin);
|
||
|
|
||
|
// ---------------------------------------------------------------
|
||
|
// About data and help button.
|
||
|
|
||
|
d->about = new KIPIPlugins::KPAboutData(I18N_NOOP("Edit Metadata"),
|
||
|
0,
|
||
|
KAboutData::License_GPL,
|
||
|
I18N_NOOP("A Plugin to edit image metadata"),
|
||
|
"(c) 2006-2008, Gilles Caulier");
|
||
|
|
||
|
d->about->addAuthor("Gilles Caulier", I18N_NOOP("Author and Maintainer"),
|
||
|
"caulier dot gilles at gmail dot com");
|
||
|
|
||
|
KHelpMenu* helpMenu = new KHelpMenu(this, d->about, false);
|
||
|
helpMenu->menu()->removeItemAt(0);
|
||
|
helpMenu->menu()->insertItem(i18n("Plugin Handbook"),
|
||
|
this, SLOT(slotHelp()), 0, -1, 0);
|
||
|
actionButton(Help)->setPopup( helpMenu->menu() );
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
|
||
|
connect(d->captionPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->datetimePage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->subjectsPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->keywordsPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->categoriesPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->creditsPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->statusPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
connect(d->originPage, SIGNAL(signalModified()),
|
||
|
this, SLOT(slotModified()));
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
|
||
|
readSettings();
|
||
|
slotItemChanged();
|
||
|
}
|
||
|
|
||
|
IPTCEditDialog::~IPTCEditDialog()
|
||
|
{
|
||
|
delete d->about;
|
||
|
delete d;
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotHelp()
|
||
|
{
|
||
|
KApplication::kApplication()->invokeHelp("metadataedit", "kipi-plugins");
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::closeEvent(QCloseEvent *e)
|
||
|
{
|
||
|
if (!e) return;
|
||
|
saveSettings();
|
||
|
e->accept();
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotClose()
|
||
|
{
|
||
|
saveSettings();
|
||
|
KDialogBase::slotClose();
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::readSettings()
|
||
|
{
|
||
|
KConfig config("kipirc");
|
||
|
config.setGroup("Metadata Edit Settings");
|
||
|
showPage(config.readNumEntry("IPTC Edit Page", 0));
|
||
|
d->captionPage->setCheckedSyncJFIFComment(config.readBoolEntry("Sync JFIF Comment", true));
|
||
|
d->captionPage->setCheckedSyncHOSTComment(config.readBoolEntry("Sync Host Comment", true));
|
||
|
d->captionPage->setCheckedSyncEXIFComment(config.readBoolEntry("Sync EXIF Comment", true));
|
||
|
d->datetimePage->setCheckedSyncHOSTDate(config.readBoolEntry("Sync Host Date", true));
|
||
|
d->datetimePage->setCheckedSyncEXIFDate(config.readBoolEntry("Sync EXIF Date", true));
|
||
|
resize(configDialogSize(config, QString("IPTC Edit Dialog")));
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::saveSettings()
|
||
|
{
|
||
|
KConfig config("kipirc");
|
||
|
config.setGroup("Metadata Edit Settings");
|
||
|
config.writeEntry("IPTC Edit Page", activePageIndex());
|
||
|
config.writeEntry("Sync JFIF Comment", d->captionPage->syncJFIFCommentIsChecked());
|
||
|
config.writeEntry("Sync Host Comment", d->captionPage->syncHOSTCommentIsChecked());
|
||
|
config.writeEntry("Sync EXIF Comment", d->captionPage->syncEXIFCommentIsChecked());
|
||
|
config.writeEntry("Sync Host Date", d->datetimePage->syncHOSTDateIsChecked());
|
||
|
config.writeEntry("Sync EXIF Date", d->datetimePage->syncEXIFDateIsChecked());
|
||
|
saveDialogSize(config, QString("IPTC Edit Dialog"));
|
||
|
config.sync();
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotItemChanged()
|
||
|
{
|
||
|
KExiv2Iface::KExiv2 exiv2Iface;
|
||
|
exiv2Iface.load((*d->currItem).path());
|
||
|
d->exifData = exiv2Iface.getExif();
|
||
|
d->iptcData = exiv2Iface.getIptc();
|
||
|
d->captionPage->readMetadata(d->iptcData);
|
||
|
d->datetimePage->readMetadata(d->iptcData);
|
||
|
d->subjectsPage->readMetadata(d->iptcData);
|
||
|
d->keywordsPage->readMetadata(d->iptcData);
|
||
|
d->categoriesPage->readMetadata(d->iptcData);
|
||
|
d->creditsPage->readMetadata(d->iptcData);
|
||
|
d->statusPage->readMetadata(d->iptcData);
|
||
|
d->originPage->readMetadata(d->iptcData);
|
||
|
|
||
|
d->isReadOnly = KExiv2Iface::KExiv2::isReadOnly((*d->currItem).path());
|
||
|
d->page_caption->setEnabled(!d->isReadOnly);
|
||
|
d->page_datetime->setEnabled(!d->isReadOnly);
|
||
|
d->page_subjects->setEnabled(!d->isReadOnly);
|
||
|
d->page_keywords->setEnabled(!d->isReadOnly);
|
||
|
d->page_categories->setEnabled(!d->isReadOnly);
|
||
|
d->page_credits->setEnabled(!d->isReadOnly);
|
||
|
d->page_status->setEnabled(!d->isReadOnly);
|
||
|
d->page_origin->setEnabled(!d->isReadOnly);
|
||
|
enableButton(Apply, !d->isReadOnly);
|
||
|
|
||
|
setCaption(QString("%1 (%2/%3) - %4")
|
||
|
.arg((*d->currItem).filename())
|
||
|
.arg(d->urls.findIndex(*(d->currItem))+1)
|
||
|
.arg(d->urls.count())
|
||
|
.arg(i18n("Edit IPTC Metadata")) +
|
||
|
(d->isReadOnly ? QString(" - ") + i18n("(read only)") : QString::null));
|
||
|
enableButton(User1, *(d->currItem) != d->urls.last());
|
||
|
enableButton(User2, *(d->currItem) != d->urls.first());
|
||
|
enableButton(Apply, false);
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotApply()
|
||
|
{
|
||
|
if (d->modified && !d->isReadOnly)
|
||
|
{
|
||
|
KIPI::ImageInfo info = d->interface->info(*d->currItem);
|
||
|
|
||
|
if (d->captionPage->syncHOSTCommentIsChecked())
|
||
|
{
|
||
|
info.setDescription(d->captionPage->getIPTCCaption());
|
||
|
}
|
||
|
d->captionPage->applyMetadata(d->exifData, d->iptcData);
|
||
|
|
||
|
if (d->datetimePage->syncHOSTDateIsChecked())
|
||
|
{
|
||
|
info.setTime(d->datetimePage->getIPTCCreationDate());
|
||
|
}
|
||
|
d->datetimePage->applyMetadata(d->exifData, d->iptcData);
|
||
|
|
||
|
d->subjectsPage->applyMetadata(d->iptcData);
|
||
|
d->keywordsPage->applyMetadata(d->iptcData);
|
||
|
d->categoriesPage->applyMetadata(d->iptcData);
|
||
|
d->creditsPage->applyMetadata(d->iptcData);
|
||
|
d->statusPage->applyMetadata(d->iptcData);
|
||
|
d->originPage->applyMetadata(d->iptcData);
|
||
|
KExiv2Iface::KExiv2 exiv2Iface;
|
||
|
exiv2Iface.load((*d->currItem).path());
|
||
|
exiv2Iface.setExif(d->exifData);
|
||
|
exiv2Iface.setIptc(d->iptcData);
|
||
|
exiv2Iface.save((*d->currItem).path());
|
||
|
d->modified = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotUser1()
|
||
|
{
|
||
|
slotApply();
|
||
|
d->currItem++;
|
||
|
slotItemChanged();
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotUser2()
|
||
|
{
|
||
|
slotApply();
|
||
|
d->currItem--;
|
||
|
slotItemChanged();
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotModified()
|
||
|
{
|
||
|
if (!d->isReadOnly)
|
||
|
{
|
||
|
enableButton(Apply, true);
|
||
|
d->modified = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IPTCEditDialog::slotOk()
|
||
|
{
|
||
|
slotApply();
|
||
|
saveSettings();
|
||
|
accept();
|
||
|
}
|
||
|
|
||
|
bool IPTCEditDialog::eventFilter(QObject *, QEvent *e)
|
||
|
{
|
||
|
if ( e->type() == QEvent::KeyPress )
|
||
|
{
|
||
|
QKeyEvent *k = (QKeyEvent *)e;
|
||
|
|
||
|
if (k->state() == Qt::ControlButton &&
|
||
|
(k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
|
||
|
{
|
||
|
slotApply();
|
||
|
|
||
|
if (actionButton(User1)->isEnabled())
|
||
|
slotUser1();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
else if (k->state() == Qt::ShiftButton &&
|
||
|
(k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
|
||
|
{
|
||
|
slotApply();
|
||
|
|
||
|
if (actionButton(User2)->isEnabled())
|
||
|
slotUser2();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
} // namespace KIPIMetadataEditPlugin
|