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.
kipi-plugins/kipi-plugins/metadataedit/exifdatetime.cpp

422 lines
16 KiB

/* ============================================================
*
* This file is a part of kipi-plugins project
* http://www.kipi-plugins.org
*
* Date : 2006-10-18
* Description : EXIF date and time settings page.
*
* 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 <tqlayout.h>
#include <tqlabel.h>
#include <tqwhatsthis.h>
#include <tqvalidator.h>
#include <tqcheckbox.h>
// KDE includes.
#include <tdelocale.h>
#include <kdialog.h>
#include <kdatetimewidget.h>
#include <knuminput.h>
#include <tdeapplication.h>
#include <tdeaboutdata.h>
#include <kseparator.h>
// LibKExiv2 includes.
#include <libkexiv2/kexiv2.h>
// Local includes.
#include "exifdatetime.h"
#include "exifdatetime.moc"
namespace KIPIMetadataEditPlugin
{
class EXIFDateTimePriv
{
public:
EXIFDateTimePriv()
{
dateCreatedSel = 0;
dateOriginalSel = 0;
dateDigitalizedSel = 0;
dateCreatedSubSecEdit = 0;
dateOriginalSubSecEdit = 0;
dateDigitalizedSubSecEdit = 0;
dateCreatedCheck = 0;
dateOriginalCheck = 0;
dateDigitalizedCheck = 0;
dateCreatedSubSecCheck = 0;
dateOriginalSubSecCheck = 0;
dateDigitalizedSubSecCheck = 0;
syncHOSTDateCheck = 0;
syncIPTCDateCheck = 0;
}
TQCheckBox *dateCreatedCheck;
TQCheckBox *dateOriginalCheck;
TQCheckBox *dateDigitalizedCheck;
TQCheckBox *dateCreatedSubSecCheck;
TQCheckBox *dateOriginalSubSecCheck;
TQCheckBox *dateDigitalizedSubSecCheck;
TQCheckBox *syncHOSTDateCheck;
TQCheckBox *syncIPTCDateCheck;
KIntSpinBox *dateCreatedSubSecEdit;
KIntSpinBox *dateOriginalSubSecEdit;
KIntSpinBox *dateDigitalizedSubSecEdit;
KDateTimeWidget *dateCreatedSel;
KDateTimeWidget *dateOriginalSel;
KDateTimeWidget *dateDigitalizedSel;
};
EXIFDateTime::EXIFDateTime(TQWidget* parent)
: TQWidget(parent)
{
d = new EXIFDateTimePriv;
TQGridLayout* grid = new TQGridLayout(parent, 9, 3, KDialog::spacingHint());
// --------------------------------------------------------
d->dateCreatedCheck = new TQCheckBox(i18n("Creation date and time"), parent);
d->dateCreatedSubSecCheck = new TQCheckBox(i18n("Creation sub-second"), parent);
d->dateCreatedSel = new KDateTimeWidget(parent);
d->dateCreatedSubSecEdit = new KIntSpinBox(0, 999, 1, 0, 10, parent);
d->dateCreatedSel->setDateTime(TQDateTime::currentDateTime());
d->syncHOSTDateCheck = new TQCheckBox(i18n("Sync creation date entered through %1")
.arg(TDEApplication::kApplication()->aboutData()->appName()),
parent);
d->syncIPTCDateCheck = new TQCheckBox(i18n("Sync IPTC creation date"), parent);
KSeparator *line = new KSeparator(Horizontal, parent);
grid->addMultiCellWidget(d->dateCreatedCheck, 0, 0, 0, 0);
grid->addMultiCellWidget(d->dateCreatedSubSecCheck, 0, 0, 1, 2);
grid->addMultiCellWidget(d->dateCreatedSel, 1, 1, 0, 0);
grid->addMultiCellWidget(d->dateCreatedSubSecEdit, 1, 1, 1, 1);
grid->addMultiCellWidget(d->syncHOSTDateCheck, 2, 2, 0, 3);
grid->addMultiCellWidget(d->syncIPTCDateCheck, 3, 3, 0, 3);
grid->addMultiCellWidget(line, 4, 4, 0, 3);
TQWhatsThis::add(d->dateCreatedSel, i18n("<p>Set here the date and time of image creation. "
"In this standard it is the date and time the file was changed."));
TQWhatsThis::add(d->dateCreatedSubSecEdit, i18n("<p>Set here the fractions of seconds for the date "
"and time of image creation."));
// --------------------------------------------------------
d->dateOriginalCheck = new TQCheckBox(i18n("Original date and time"), parent);
d->dateOriginalSubSecCheck = new TQCheckBox(i18n("Original sub-second"), parent);
d->dateOriginalSel = new KDateTimeWidget(parent);
d->dateOriginalSubSecEdit = new KIntSpinBox(0, 999, 1, 0, 10, parent);
d->dateOriginalSel->setDateTime(TQDateTime::currentDateTime());
grid->addMultiCellWidget(d->dateOriginalCheck, 5, 5, 0, 0);
grid->addMultiCellWidget(d->dateOriginalSubSecCheck, 5, 5, 1, 2);
grid->addMultiCellWidget(d->dateOriginalSel, 6, 6, 0, 0);
grid->addMultiCellWidget(d->dateOriginalSubSecEdit, 6, 6, 1, 1);
TQWhatsThis::add(d->dateOriginalSel, i18n("<p>Set here the date and time when the original image "
"data was generated. For a digital still camera the date and "
"time the picture was taken are recorded."));
TQWhatsThis::add(d->dateOriginalSubSecEdit, i18n("<p>Set here the fractions of seconds for the date "
"and time when the original image data was generated."));
// --------------------------------------------------------
d->dateDigitalizedCheck = new TQCheckBox(i18n("Digitization date and time"), parent);
d->dateDigitalizedSubSecCheck = new TQCheckBox(i18n("Digitization sub-second"), parent);
d->dateDigitalizedSel = new KDateTimeWidget(parent);
d->dateDigitalizedSubSecEdit = new KIntSpinBox(0, 999, 1, 0, 10, parent);
d->dateDigitalizedSel->setDateTime(TQDateTime::currentDateTime());
grid->addMultiCellWidget(d->dateDigitalizedCheck, 7, 7, 0, 0);
grid->addMultiCellWidget(d->dateDigitalizedSubSecCheck, 7, 7, 1, 2);
grid->addMultiCellWidget(d->dateDigitalizedSel, 8, 8, 0, 0);
grid->addMultiCellWidget(d->dateDigitalizedSubSecEdit, 8, 8, 1, 1);
TQWhatsThis::add(d->dateDigitalizedSel, i18n("<p>Set here the date and time when the image was "
"stored as digital data. If, for example, an image was "
"captured by a digital still camera and at the same "
"time the file was recorded, then Original and Digitization "
"date and time will have the same contents."));
TQWhatsThis::add(d->dateDigitalizedSubSecEdit, i18n("<p>Set here the fractions of seconds for the date "
"and time when the image was stored as digital data."));
grid->setColStretch(3, 10);
grid->setRowStretch(9, 10);
// --------------------------------------------------------
connect(d->dateCreatedCheck, TQT_SIGNAL(toggled(bool)),
d->dateCreatedSel, TQT_SLOT(setEnabled(bool)));
connect(d->dateOriginalCheck, TQT_SIGNAL(toggled(bool)),
d->dateOriginalSel, TQT_SLOT(setEnabled(bool)));
connect(d->dateDigitalizedCheck, TQT_SIGNAL(toggled(bool)),
d->dateDigitalizedSel, TQT_SLOT(setEnabled(bool)));
connect(d->dateCreatedSubSecCheck, TQT_SIGNAL(toggled(bool)),
d->dateCreatedSubSecEdit, TQT_SLOT(setEnabled(bool)));
connect(d->dateOriginalSubSecCheck, TQT_SIGNAL(toggled(bool)),
d->dateOriginalSubSecEdit, TQT_SLOT(setEnabled(bool)));
connect(d->dateDigitalizedSubSecCheck, TQT_SIGNAL(toggled(bool)),
d->dateDigitalizedSubSecEdit, TQT_SLOT(setEnabled(bool)));
connect(d->dateCreatedCheck, TQT_SIGNAL(toggled(bool)),
d->syncHOSTDateCheck, TQT_SLOT(setEnabled(bool)));
connect(d->dateCreatedCheck, TQT_SIGNAL(toggled(bool)),
d->syncIPTCDateCheck, TQT_SLOT(setEnabled(bool)));
// --------------------------------------------------------
connect(d->dateCreatedCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateOriginalCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateDigitalizedCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateCreatedSubSecCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateOriginalSubSecCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateDigitalizedSubSecCheck, TQT_SIGNAL(toggled(bool)),
this, TQT_SIGNAL(signalModified()));
// --------------------------------------------------------
connect(d->dateCreatedSubSecEdit, TQT_SIGNAL(valueChanged(int)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateOriginalSubSecEdit, TQT_SIGNAL(valueChanged(int)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateDigitalizedSubSecEdit, TQT_SIGNAL(valueChanged(int)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateCreatedSel, TQT_SIGNAL(valueChanged (const TQDateTime &)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateOriginalSel, TQT_SIGNAL(valueChanged (const TQDateTime &)),
this, TQT_SIGNAL(signalModified()));
connect(d->dateDigitalizedSel, TQT_SIGNAL(valueChanged (const TQDateTime &)),
this, TQT_SIGNAL(signalModified()));
}
EXIFDateTime::~EXIFDateTime()
{
delete d;
}
bool EXIFDateTime::syncHOSTDateIsChecked()
{
return d->syncHOSTDateCheck->isChecked();
}
bool EXIFDateTime::syncIPTCDateIsChecked()
{
return d->syncIPTCDateCheck->isChecked();
}
void EXIFDateTime::setCheckedSyncHOSTDate(bool c)
{
d->syncHOSTDateCheck->setChecked(c);
}
void EXIFDateTime::setCheckedSyncIPTCDate(bool c)
{
d->syncIPTCDateCheck->setChecked(c);
}
TQDateTime EXIFDateTime::getEXIFCreationDate()
{
return d->dateCreatedSel->dateTime();
}
void EXIFDateTime::readMetadata(TQByteArray& exifData)
{
blockSignals(true);
KExiv2Iface::KExiv2 exiv2Iface;
exiv2Iface.setExif(exifData);
TQDateTime datetime;
TQString datetimeStr, data;
d->dateCreatedSel->setDateTime(TQDateTime::currentDateTime());
d->dateCreatedCheck->setChecked(false);
datetimeStr = exiv2Iface.getExifTagString("Exif.Image.DateTime", false);
if (!datetimeStr.isEmpty())
{
datetime = TQDateTime::fromString(datetimeStr, TQt::ISODate);
if (datetime.isValid())
{
d->dateCreatedSel->setDateTime(datetime);
d->dateCreatedCheck->setChecked(true);
}
}
d->dateCreatedSel->setEnabled(d->dateCreatedCheck->isChecked());
d->syncHOSTDateCheck->setEnabled(d->dateCreatedCheck->isChecked());
d->syncIPTCDateCheck->setEnabled(d->dateCreatedCheck->isChecked());
d->dateCreatedSubSecEdit->setValue(0);
d->dateCreatedSubSecCheck->setChecked(false);
data = exiv2Iface.getExifTagString("Exif.Photo.SubSecTime", false);
if (!data.isNull())
{
bool ok = false;
int subsec = data.toInt(&ok);
if (ok)
{
d->dateCreatedSubSecEdit->setValue(subsec);
d->dateCreatedSubSecCheck->setChecked(true);
}
}
d->dateCreatedSubSecEdit->setEnabled(d->dateCreatedSubSecCheck->isChecked());
d->dateOriginalSel->setDateTime(TQDateTime::currentDateTime());
d->dateOriginalCheck->setChecked(false);
datetimeStr = exiv2Iface.getExifTagString("Exif.Photo.DateTimeOriginal", false);
if (!datetimeStr.isEmpty())
{
datetime = TQDateTime::fromString(datetimeStr, TQt::ISODate);
if (datetime.isValid())
{
d->dateOriginalSel->setDateTime(datetime);
d->dateOriginalCheck->setChecked(true);
}
}
d->dateOriginalSel->setEnabled(d->dateOriginalCheck->isChecked());
d->dateOriginalSubSecEdit->setValue(0);
d->dateOriginalSubSecCheck->setChecked(false);
data = exiv2Iface.getExifTagString("Exif.Photo.SubSecTimeOriginal", false);
if (!data.isNull())
{
bool ok = false;
int subsec = data.toInt(&ok);
if (ok)
{
d->dateOriginalSubSecEdit->setValue(subsec);
d->dateOriginalSubSecCheck->setChecked(true);
}
}
d->dateOriginalSubSecEdit->setEnabled(d->dateOriginalSubSecCheck->isChecked());
d->dateDigitalizedSel->setDateTime(TQDateTime::currentDateTime());
d->dateDigitalizedCheck->setChecked(false);
datetimeStr = exiv2Iface.getExifTagString("Exif.Photo.DateTimeDigitized", false);
if (!datetimeStr.isEmpty())
{
datetime = TQDateTime::fromString(datetimeStr, TQt::ISODate);
if (datetime.isValid())
{
d->dateDigitalizedSel->setDateTime(datetime);
d->dateDigitalizedCheck->setChecked(true);
}
}
d->dateDigitalizedSel->setEnabled(d->dateDigitalizedCheck->isChecked());
d->dateDigitalizedSubSecEdit->setValue(0);
d->dateDigitalizedSubSecCheck->setChecked(false);
data = exiv2Iface.getExifTagString("Exif.Photo.SubSecTimeDigitized", false);
if (!data.isNull())
{
bool ok = false;
int subsec = data.toInt(&ok);
if (ok)
{
d->dateDigitalizedSubSecEdit->setValue(subsec);
d->dateDigitalizedSubSecCheck->setChecked(true);
}
}
d->dateDigitalizedSubSecEdit->setEnabled(d->dateDigitalizedSubSecCheck->isChecked());
blockSignals(false);
}
void EXIFDateTime::applyMetadata(TQByteArray& exifData, TQByteArray& iptcData)
{
KExiv2Iface::KExiv2 exiv2Iface;
exiv2Iface.setExif(exifData);
exiv2Iface.setIptc(iptcData);
if (d->dateCreatedCheck->isChecked())
{
exiv2Iface.setExifTagString("Exif.Image.DateTime",
d->dateCreatedSel->dateTime().toString(TQString("yyyy:MM:dd hh:mm:ss")).ascii());
if (syncIPTCDateIsChecked())
{
exiv2Iface.setIptcTagString("Iptc.Application2.DateCreated",
d->dateCreatedSel->dateTime().date().toString(TQt::ISODate));
exiv2Iface.setIptcTagString("Iptc.Application2.TimeCreated",
d->dateCreatedSel->dateTime().time().toString(TQt::ISODate));
}
}
else
exiv2Iface.removeExifTag("Exif.Image.DateTime");
if (d->dateCreatedSubSecCheck->isChecked())
exiv2Iface.setExifTagString("Exif.Photo.SubSecTime",
TQString::number(d->dateCreatedSubSecEdit->value()).ascii());
else
exiv2Iface.removeExifTag("Exif.Photo.SubSecTime");
if (d->dateOriginalCheck->isChecked())
exiv2Iface.setExifTagString("Exif.Photo.DateTimeOriginal",
d->dateOriginalSel->dateTime().toString(TQString("yyyy:MM:dd hh:mm:ss")).ascii());
else
exiv2Iface.removeExifTag("Exif.Photo.DateTimeOriginal");
if (d->dateOriginalSubSecCheck->isChecked())
exiv2Iface.setExifTagString("Exif.Photo.SubSecTimeOriginal",
TQString::number(d->dateOriginalSubSecEdit->value()).ascii());
else
exiv2Iface.removeExifTag("Exif.Photo.SubSecTimeOriginal");
if (d->dateDigitalizedCheck->isChecked())
exiv2Iface.setExifTagString("Exif.Photo.DateTimeDigitized",
d->dateDigitalizedSel->dateTime().toString(TQString("yyyy:MM:dd hh:mm:ss")).ascii());
else
exiv2Iface.removeExifTag("Exif.Photo.DateTimeDigitized");
if (d->dateDigitalizedSubSecCheck->isChecked())
exiv2Iface.setExifTagString("Exif.Photo.SubSecTimeDigitized",
TQString::number(d->dateDigitalizedSubSecEdit->value()).ascii());
else
exiv2Iface.removeExifTag("Exif.Photo.SubSecTimeDigitized");
exifData = exiv2Iface.getExif();
iptcData = exiv2Iface.getIptc();
}
} // namespace KIPIMetadataEditPlugin