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.
422 lines
16 KiB
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, TQ_SIGNAL(toggled(bool)),
|
|
d->dateCreatedSel, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateOriginalCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->dateOriginalSel, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateDigitalizedCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->dateDigitalizedSel, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateCreatedSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->dateCreatedSubSecEdit, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateOriginalSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->dateOriginalSubSecEdit, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateDigitalizedSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->dateDigitalizedSubSecEdit, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateCreatedCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->syncHOSTDateCheck, TQ_SLOT(setEnabled(bool)));
|
|
|
|
connect(d->dateCreatedCheck, TQ_SIGNAL(toggled(bool)),
|
|
d->syncIPTCDateCheck, TQ_SLOT(setEnabled(bool)));
|
|
|
|
// --------------------------------------------------------
|
|
|
|
connect(d->dateCreatedCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateOriginalCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateDigitalizedCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateCreatedSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateOriginalSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateDigitalizedSubSecCheck, TQ_SIGNAL(toggled(bool)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
// --------------------------------------------------------
|
|
|
|
connect(d->dateCreatedSubSecEdit, TQ_SIGNAL(valueChanged(int)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateOriginalSubSecEdit, TQ_SIGNAL(valueChanged(int)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateDigitalizedSubSecEdit, TQ_SIGNAL(valueChanged(int)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateCreatedSel, TQ_SIGNAL(valueChanged (const TQDateTime &)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateOriginalSel, TQ_SIGNAL(valueChanged (const TQDateTime &)),
|
|
this, TQ_SIGNAL(signalModified()));
|
|
|
|
connect(d->dateDigitalizedSel, TQ_SIGNAL(valueChanged (const TQDateTime &)),
|
|
this, TQ_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
|
|
|