mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 18:32:53 +00:00
gwenview: port to KExiv2
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
14098a3ef4
commit
cac9414148
20 changed files with 92 additions and 450 deletions
|
@ -20,14 +20,6 @@ set_package_properties(Threads PROPERTIES
|
|||
TYPE REQUIRED
|
||||
)
|
||||
|
||||
find_package(Exiv2 0.19)
|
||||
set_package_properties(Exiv2 PROPERTIES
|
||||
DESCRIPTION "Image Tag reader"
|
||||
URL "http://www.exiv2.org"
|
||||
PURPOSE "Support for image metadata"
|
||||
TYPE REQUIRED
|
||||
)
|
||||
|
||||
find_package(LibKonq)
|
||||
set_package_properties(LibKonq PROPERTIES
|
||||
URL "https://osdn.net/projects/kde/"
|
||||
|
@ -39,17 +31,11 @@ set_package_properties(LibKonq PROPERTIES
|
|||
|
||||
include_directories(
|
||||
${QDBUS_INCLUDE_DIRS}
|
||||
${EXIV2_INCLUDE_DIR}
|
||||
# for gwenview_export.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
${EXIV2_DEFINITIONS}
|
||||
${KDE4_ENABLE_EXCEPTIONS}
|
||||
)
|
||||
|
||||
## dirs to build
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(app)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${EXIV2_INCLUDE_DIR}
|
||||
${LIBKONQ_INCLUDE_DIR}
|
||||
# For lib/gwenviewconfig.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
|
|
|
@ -3,8 +3,7 @@ project(importer)
|
|||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
${EXIV2_INCLUDE_DIR}
|
||||
)
|
||||
)
|
||||
|
||||
set(importer_SRCS
|
||||
importerconfigdialog.cpp
|
||||
|
|
|
@ -4,7 +4,6 @@ project(gwenviewlib)
|
|||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${EXIV2_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(gwenviewlib_SRCS
|
||||
|
@ -42,7 +41,6 @@ set(gwenviewlib_SRCS
|
|||
eventwatcher.cpp
|
||||
historymodel.cpp
|
||||
datewidget.cpp
|
||||
exiv2imageloader.cpp
|
||||
flowlayout.cpp
|
||||
fullscreenbar.cpp
|
||||
hud/hudbutton.cpp
|
||||
|
@ -107,8 +105,8 @@ generate_export_header(gwenviewlib)
|
|||
target_link_libraries(gwenviewlib
|
||||
${KDE4_KFILE_LIBS}
|
||||
${KDE4_KIO_LIBS}
|
||||
${KDE4_KEXIV2_LIBS}
|
||||
${QT_QTGUI_LIBRARY}
|
||||
${EXIV2_LIBRARIES}
|
||||
${X11_X11_LIB}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
|
|
@ -77,11 +77,6 @@ void AbstractDocumentImpl::setDocumentKind(MimeTypeUtils::Kind kind)
|
|||
d->mDocument->setKind(kind);
|
||||
}
|
||||
|
||||
void AbstractDocumentImpl::setDocumentExiv2Image(Exiv2::Image::AutoPtr image)
|
||||
{
|
||||
d->mDocument->setExiv2Image(image);
|
||||
}
|
||||
|
||||
void AbstractDocumentImpl::setDocumentDownSampledImage(const QImage& image, int invertedZoom)
|
||||
{
|
||||
d->mDocument->setDownSampledImage(image, invertedZoom);
|
||||
|
|
|
@ -103,7 +103,6 @@ protected:
|
|||
void setDocumentImageSize(const QSize& size);
|
||||
void setDocumentKind(MimeTypeUtils::Kind);
|
||||
void setDocumentFormat(const QByteArray& format);
|
||||
void setDocumentExiv2Image(Exiv2::Image::AutoPtr);
|
||||
void setDocumentDownSampledImage(const QImage&, int invertedZoom);
|
||||
void setDocumentErrorString(const QString&);
|
||||
void switchToImpl(AbstractDocumentImpl* impl);
|
||||
|
|
|
@ -176,7 +176,6 @@ void Document::reload()
|
|||
d->mSize = QSize();
|
||||
d->mImage = QImage();
|
||||
d->mDownSampledImageMap.clear();
|
||||
d->mExiv2Image.reset();
|
||||
d->mKind = MimeTypeUtils::KIND_UNKNOWN;
|
||||
d->mFormat = QByteArray();
|
||||
d->mImageMetaInfoModel.setUrl(d->mUrl);
|
||||
|
@ -390,13 +389,6 @@ AbstractDocumentEditor* Document::editor()
|
|||
return d->mImpl->editor();
|
||||
}
|
||||
|
||||
void Document::setExiv2Image(Exiv2::Image::AutoPtr image)
|
||||
{
|
||||
d->mExiv2Image = image;
|
||||
d->mImageMetaInfoModel.setExiv2Image(d->mExiv2Image.get());
|
||||
emit metaInfoUpdated();
|
||||
}
|
||||
|
||||
void Document::setDownSampledImage(const QImage& image, int invertedZoom)
|
||||
{
|
||||
Q_ASSERT(!d->mDownSampledImageMap.contains(invertedZoom));
|
||||
|
|
|
@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include <lib/gwenviewlib_export.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <exiv2/image.hpp>
|
||||
|
||||
// Qt
|
||||
#include <QObject>
|
||||
|
@ -227,7 +226,6 @@ private:
|
|||
void setKind(MimeTypeUtils::Kind);
|
||||
void setFormat(const QByteArray&);
|
||||
void setSize(const QSize&);
|
||||
void setExiv2Image(Exiv2::Image::AutoPtr);
|
||||
void setDownSampledImage(const QImage&, int invertedZoom);
|
||||
void switchToImpl(AbstractDocumentImpl* impl);
|
||||
void setErrorString(const QString&);
|
||||
|
|
|
@ -55,7 +55,6 @@ struct DocumentPrivate
|
|||
QSize mSize;
|
||||
QImage mImage;
|
||||
QMap<int, QImage> mDownSampledImageMap;
|
||||
Exiv2::Image::AutoPtr mExiv2Image;
|
||||
MimeTypeUtils::Kind mKind;
|
||||
QByteArray mFormat;
|
||||
ImageMetaInfoModel mImageMetaInfoModel;
|
||||
|
|
|
@ -47,7 +47,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "documentjob.h"
|
||||
#include "documentloadedimpl.h"
|
||||
#include "emptydocumentimpl.h"
|
||||
#include "exiv2imageloader.h"
|
||||
#include "gvdebug.h"
|
||||
#include "imageutils.h"
|
||||
#include "orientation.h"
|
||||
|
@ -86,7 +85,6 @@ struct LoadingDocumentImplPrivate
|
|||
QByteArray mData;
|
||||
QByteArray mFormat;
|
||||
QSize mImageSize;
|
||||
Exiv2::Image::AutoPtr mExiv2Image;
|
||||
QImage mImage;
|
||||
|
||||
/**
|
||||
|
@ -202,11 +200,6 @@ struct LoadingDocumentImplPrivate
|
|||
LOG("mFormat" << mFormat);
|
||||
GV_RETURN_VALUE_IF_FAIL(!mFormat.isEmpty(), false);
|
||||
|
||||
Exiv2ImageLoader loader;
|
||||
if (loader.load(mData)) {
|
||||
mExiv2Image = loader.popImage();
|
||||
}
|
||||
|
||||
LOG("mImageSize" << mImageSize);
|
||||
|
||||
return true;
|
||||
|
@ -416,7 +409,6 @@ void LoadingDocumentImpl::slotMetaInfoLoaded()
|
|||
|
||||
setDocumentFormat(d->mFormat);
|
||||
setDocumentImageSize(d->mImageSize);
|
||||
setDocumentExiv2Image(d->mExiv2Image);
|
||||
|
||||
d->mMetaInfoLoaded = true;
|
||||
emit metaInfoLoaded();
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
// vim: set tabstop=4 shiftwidth=4 expandtab:
|
||||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2007 Aurélien Gâteau <agateau@kde.org>
|
||||
|
||||
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
|
||||
of the License, 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
// Self
|
||||
#include "exiv2imageloader.h"
|
||||
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
// KDE
|
||||
|
||||
// Exiv2
|
||||
#include <exiv2/exiv2.hpp>
|
||||
|
||||
// Local
|
||||
|
||||
namespace Gwenview
|
||||
{
|
||||
|
||||
struct Exiv2ImageLoaderPrivate
|
||||
{
|
||||
Exiv2::Image::AutoPtr mImage;
|
||||
QString mErrorMessage;
|
||||
};
|
||||
|
||||
Exiv2ImageLoader::Exiv2ImageLoader()
|
||||
: d(new Exiv2ImageLoaderPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
Exiv2ImageLoader::~Exiv2ImageLoader()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool Exiv2ImageLoader::load(const QByteArray& data)
|
||||
{
|
||||
try {
|
||||
d->mImage = Exiv2::ImageFactory::open((unsigned char*)data.constData(), data.size());
|
||||
d->mImage->readMetadata();
|
||||
#if EXIV2_VERSION >= EXIV2_MAKE_VERSION(0, 14, 0)
|
||||
// For some unknown reason, trying to catch Exiv2::Error fails with Exiv2
|
||||
// >=0.14. For now, just catch std::exception. I would welcome any
|
||||
// explanation.
|
||||
} catch (const std::exception& error) {
|
||||
d->mErrorMessage = error.what();
|
||||
#else
|
||||
// In libexiv2 0.12, Exiv2::Error::what() returns an std::string.
|
||||
} catch (const Exiv2::Error& error) {
|
||||
d->mErrorMessage = error.what().c_str();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Exiv2ImageLoader::errorMessage() const
|
||||
{
|
||||
return d->mErrorMessage;
|
||||
}
|
||||
|
||||
Exiv2::Image::AutoPtr Exiv2ImageLoader::popImage()
|
||||
{
|
||||
return d->mImage;
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -1,64 +0,0 @@
|
|||
// vim: set tabstop=4 shiftwidth=4 expandtab:
|
||||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2007 Aurélien Gâteau <agateau@kde.org>
|
||||
|
||||
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
|
||||
of the License, 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#ifndef EXIV2IMAGELOADER_H
|
||||
#define EXIV2IMAGELOADER_H
|
||||
|
||||
#include <lib/gwenviewlib_export.h>
|
||||
|
||||
// Qt
|
||||
|
||||
// KDE
|
||||
|
||||
// Exiv2
|
||||
#include <string.h>
|
||||
#include <exiv2/exiv2.hpp>
|
||||
|
||||
// Local
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
namespace Gwenview
|
||||
{
|
||||
|
||||
struct Exiv2ImageLoaderPrivate;
|
||||
|
||||
/**
|
||||
* This helper class loads image using libexiv2, and takes care of exception
|
||||
* handling for the different versions of libexiv2.
|
||||
*/
|
||||
class GWENVIEWLIB_EXPORT Exiv2ImageLoader
|
||||
{
|
||||
public:
|
||||
Exiv2ImageLoader();
|
||||
~Exiv2ImageLoader();
|
||||
|
||||
bool load(const QByteArray&);
|
||||
QString errorMessage() const;
|
||||
Exiv2::Image::AutoPtr popImage();
|
||||
|
||||
private:
|
||||
Exiv2ImageLoaderPrivate* const d;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif /* EXIV2IMAGELOADER_H */
|
|
@ -28,9 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include <KFileItem>
|
||||
#include <KGlobal>
|
||||
#include <KLocale>
|
||||
|
||||
// Exiv2
|
||||
#include <exiv2/exiv2.hpp>
|
||||
#include <KExiv2>
|
||||
|
||||
// Local
|
||||
|
||||
|
@ -245,53 +243,6 @@ struct ImageMetaInfoModelPrivate
|
|||
group->addEntry("General.ImageSize", i18nc("@item:intable", "Image Size"), QString());
|
||||
group->addEntry("General.Comment", i18nc("@item:intable", "Comment"), QString());
|
||||
}
|
||||
|
||||
template <class Container, class Iterator>
|
||||
void fillExivGroup(const QModelIndex& parent, MetaInfoGroup* group, const Container& container)
|
||||
{
|
||||
// key aren't always unique (for example, "Iptc.Application2.Keywords"
|
||||
// may appear multiple times) so we can't know how many rows we will
|
||||
// insert before going through them. That's why we create a hash
|
||||
// before.
|
||||
typedef QHash<QString, MetaInfoGroup::Entry*> EntryHash;
|
||||
EntryHash hash;
|
||||
|
||||
Iterator
|
||||
it = container.begin(),
|
||||
end = container.end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
try {
|
||||
// Skip metadatum if its tag is an hex number
|
||||
if (it->tagName().substr(0, 2) == "0x") {
|
||||
continue;
|
||||
}
|
||||
QString key = QString::fromUtf8(it->key().c_str());
|
||||
QString label = QString::fromLocal8Bit(it->tagLabel().c_str());
|
||||
std::ostringstream stream;
|
||||
stream << *it;
|
||||
QString value = QString::fromLocal8Bit(stream.str().c_str());
|
||||
|
||||
EntryHash::iterator hashIt = hash.find(key);
|
||||
if (hashIt != hash.end()) {
|
||||
hashIt.value()->appendValue(value);
|
||||
} else {
|
||||
hash.insert(key, new MetaInfoGroup::Entry(key, label, value));
|
||||
}
|
||||
} catch (const Exiv2::Error& error) {
|
||||
kWarning() << "Failed to read some meta info:" << error.what();
|
||||
}
|
||||
}
|
||||
|
||||
if (hash.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
q->beginInsertRows(parent, 0, hash.size() - 1);
|
||||
Q_FOREACH(MetaInfoGroup::Entry * entry, hash) {
|
||||
group->addEntry(entry);
|
||||
}
|
||||
q->endInsertRows();
|
||||
}
|
||||
};
|
||||
|
||||
ImageMetaInfoModel::ImageMetaInfoModel()
|
||||
|
@ -320,6 +271,57 @@ void ImageMetaInfoModel::setUrl(const KUrl& url)
|
|||
d->setGroupEntryValue(GeneralGroup, "General.Name", item.name());
|
||||
d->setGroupEntryValue(GeneralGroup, "General.Size", sizeString);
|
||||
d->setGroupEntryValue(GeneralGroup, "General.Time", item.timeString());
|
||||
|
||||
KExiv2 kexiv2(url.path());
|
||||
const KExiv2::DataMap kexiv2datamap = kexiv2.data();
|
||||
QList<QByteArray> exifkeys;
|
||||
QList<QByteArray> iptckeys;
|
||||
QList<QByteArray> xmpkeys;
|
||||
foreach (const QByteArray &kexiv2key, kexiv2datamap.keys()) {
|
||||
if (kexiv2key.startsWith("Exif.")) {
|
||||
exifkeys.append(kexiv2key);
|
||||
} else if (kexiv2key.startsWith("Xmp.")) {
|
||||
iptckeys.append(kexiv2key);
|
||||
} else if (kexiv2key.startsWith("Iptc.")) {
|
||||
xmpkeys.append(kexiv2key);
|
||||
} else {
|
||||
kWarning() << "Unknown Exif2 key" << kexiv2key;
|
||||
}
|
||||
}
|
||||
|
||||
MetaInfoGroup* exifGroup = d->mMetaInfoGroupVector[ExifGroup];
|
||||
MetaInfoGroup* iptcGroup = d->mMetaInfoGroupVector[IptcGroup];
|
||||
MetaInfoGroup* xmpGroup = d->mMetaInfoGroupVector[XmpGroup];
|
||||
QModelIndex exifIndex = index(ExifGroup, 0);
|
||||
QModelIndex iptcIndex = index(IptcGroup, 0);
|
||||
QModelIndex xmpIndex = index(XmpGroup, 0);
|
||||
d->clearGroup(exifGroup, exifIndex);
|
||||
d->clearGroup(iptcGroup, iptcIndex);
|
||||
d->clearGroup(xmpGroup, xmpIndex);
|
||||
|
||||
if (!exifkeys.isEmpty()) {
|
||||
beginInsertRows(exifIndex, 0, exifkeys.size() - 1);
|
||||
foreach (const QByteArray &exifkey, exifkeys) {
|
||||
exifGroup->addEntry(exifkey, kexiv2.label(exifkey), kexiv2datamap.value(exifkey));
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
if (!iptckeys.isEmpty()) {
|
||||
beginInsertRows(iptcIndex, 0, iptckeys.size() - 1);
|
||||
foreach (const QByteArray &iptckey, iptckeys) {
|
||||
iptcGroup->addEntry(iptckey, kexiv2.label(iptckey), kexiv2datamap.value(iptckey));
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
if (!xmpkeys.isEmpty()) {
|
||||
beginInsertRows(xmpIndex, 0, xmpkeys.size() - 1);
|
||||
foreach (const QByteArray &xmpkey, xmpkeys) {
|
||||
xmpGroup->addEntry(xmpkey, kexiv2.label(xmpkey), kexiv2datamap.value(xmpkey));
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageMetaInfoModel::setImageSize(const QSize& size)
|
||||
|
@ -344,40 +346,6 @@ void ImageMetaInfoModel::setImageSize(const QSize& size)
|
|||
d->setGroupEntryValue(GeneralGroup, "General.ImageSize", imageSize);
|
||||
}
|
||||
|
||||
void ImageMetaInfoModel::setExiv2Image(const Exiv2::Image* image)
|
||||
{
|
||||
MetaInfoGroup* exifGroup = d->mMetaInfoGroupVector[ExifGroup];
|
||||
MetaInfoGroup* iptcGroup = d->mMetaInfoGroupVector[IptcGroup];
|
||||
MetaInfoGroup* xmpGroup = d->mMetaInfoGroupVector[XmpGroup];
|
||||
QModelIndex exifIndex = index(ExifGroup, 0);
|
||||
QModelIndex iptcIndex = index(IptcGroup, 0);
|
||||
QModelIndex xmpIndex = index(XmpGroup, 0);
|
||||
d->clearGroup(exifGroup, exifIndex);
|
||||
d->clearGroup(iptcGroup, iptcIndex);
|
||||
d->clearGroup(xmpGroup, xmpIndex);
|
||||
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->setGroupEntryValue(GeneralGroup, "General.Comment", QString::fromUtf8(image->comment().c_str()));
|
||||
|
||||
if (image->checkMode(Exiv2::mdExif) & Exiv2::amRead) {
|
||||
const Exiv2::ExifData& exifData = image->exifData();
|
||||
d->fillExivGroup<Exiv2::ExifData, Exiv2::ExifData::const_iterator>(exifIndex, exifGroup, exifData);
|
||||
}
|
||||
|
||||
if (image->checkMode(Exiv2::mdIptc) & Exiv2::amRead) {
|
||||
const Exiv2::IptcData& iptcData = image->iptcData();
|
||||
d->fillExivGroup<Exiv2::IptcData, Exiv2::IptcData::const_iterator>(iptcIndex, iptcGroup, iptcData);
|
||||
}
|
||||
|
||||
if (image->checkMode(Exiv2::mdXmp) & Exiv2::amRead) {
|
||||
const Exiv2::XmpData& xmpData = image->xmpData();
|
||||
d->fillExivGroup<Exiv2::XmpData, Exiv2::XmpData::const_iterator>(xmpIndex, xmpGroup, xmpData);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageMetaInfoModel::getInfoForKey(const QString& key, QString* label, QString* value) const
|
||||
{
|
||||
MetaInfoGroup* group;
|
||||
|
|
|
@ -32,11 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
class KUrl;
|
||||
|
||||
namespace Exiv2
|
||||
{
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace Gwenview
|
||||
{
|
||||
|
||||
|
@ -50,7 +45,6 @@ public:
|
|||
|
||||
void setUrl(const KUrl&);
|
||||
void setImageSize(const QSize&);
|
||||
void setExiv2Image(const Exiv2::Image*);
|
||||
|
||||
QString keyForIndex(const QModelIndex&) const;
|
||||
void getInfoForKey(const QString& key, QString* label, QString* value) const;
|
||||
|
|
|
@ -28,13 +28,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
|
|||
#include <KDateTime>
|
||||
#include <KDebug>
|
||||
#include <KFileItem>
|
||||
|
||||
// Exiv2
|
||||
#include <exiv2/exif.hpp>
|
||||
#include <exiv2/image.hpp>
|
||||
#include <KExiv2>
|
||||
|
||||
// Local
|
||||
#include <lib/exiv2imageloader.h>
|
||||
#include <lib/urlutils.h>
|
||||
|
||||
namespace Gwenview
|
||||
|
@ -43,25 +39,6 @@ namespace Gwenview
|
|||
namespace TimeUtils
|
||||
{
|
||||
|
||||
static Exiv2::ExifData::const_iterator findDateTimeKey(const Exiv2::ExifData& exifData)
|
||||
{
|
||||
// Ordered list of keys to try
|
||||
static QList<Exiv2::ExifKey> lst = QList<Exiv2::ExifKey>()
|
||||
<< Exiv2::ExifKey("Exif.Photo.DateTimeOriginal")
|
||||
<< Exiv2::ExifKey("Exif.Image.DateTimeOriginal")
|
||||
<< Exiv2::ExifKey("Exif.Photo.DateTimeDigitized")
|
||||
<< Exiv2::ExifKey("Exif.Image.DateTime");
|
||||
|
||||
Exiv2::ExifData::const_iterator it, end = exifData.end();
|
||||
Q_FOREACH(const Exiv2::ExifKey& key, lst) {
|
||||
it = exifData.findKey(key);
|
||||
if (it != end) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
struct CacheItem
|
||||
{
|
||||
KDateTime fileMTime;
|
||||
|
@ -86,49 +63,36 @@ struct CacheItem
|
|||
if (!UrlUtils::urlIsFastLocalFile(url)) {
|
||||
return false;
|
||||
}
|
||||
QString path = url.path();
|
||||
Exiv2ImageLoader loader;
|
||||
QByteArray header;
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
kWarning() << "Could not open" << path << "for reading";
|
||||
return false;
|
||||
}
|
||||
header = file.read(65536); // FIXME: Is this big enough?
|
||||
}
|
||||
|
||||
if (!loader.load(header)) {
|
||||
const QString path = url.path();
|
||||
KExiv2 kexiv2(path);
|
||||
const KExiv2::DataMap kexiv2datamap = kexiv2.data();
|
||||
// Ordered list of keys to try
|
||||
static QList<QByteArray> lst = QList<QByteArray>()
|
||||
<< QByteArray("Exif.Photo.DateTimeOriginal")
|
||||
<< QByteArray("Exif.Image.DateTimeOriginal")
|
||||
<< QByteArray("Exif.Photo.DateTimeDigitized")
|
||||
<< QByteArray("Exif.Image.DateTime");
|
||||
QString exifvalue;
|
||||
foreach (const QByteArray &exifkey, lst) {
|
||||
exifvalue = kexiv2datamap.value(exifkey);
|
||||
if (!exifvalue.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exifvalue.isEmpty()) {
|
||||
kWarning() << "No date in exif header of" << path;
|
||||
return false;
|
||||
}
|
||||
Exiv2::Image::AutoPtr img = loader.popImage();
|
||||
try {
|
||||
Exiv2::ExifData exifData = img->exifData();
|
||||
if (exifData.empty()) {
|
||||
return false;
|
||||
}
|
||||
Exiv2::ExifData::const_iterator it = findDateTimeKey(exifData);
|
||||
if (it == exifData.end()) {
|
||||
kWarning() << "No date in exif header of" << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << *it;
|
||||
QString value = QString::fromLocal8Bit(stream.str().c_str());
|
||||
|
||||
KDateTime dt = KDateTime::fromString(value, "%Y:%m:%d %H:%M:%S");
|
||||
if (!dt.isValid()) {
|
||||
kWarning() << "Invalid date in exif header of" << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
realTime = dt;
|
||||
return true;
|
||||
} catch (const Exiv2::Error& error) {
|
||||
kWarning() << "Failed to read date from exif header of" << path << ". Error:" << error.what();
|
||||
KDateTime dt = KDateTime::fromString(exifvalue, "%Y:%m:%d %H:%M:%S");
|
||||
if (!dt.isValid()) {
|
||||
kWarning() << "Invalid date in exif header of" << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
realTime = dt;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${EXIV2_INCLUDE_DIR}
|
||||
)
|
||||
)
|
||||
|
||||
set(gvpart_SRCS
|
||||
gvbrowserextension.cpp
|
||||
gvpart.cpp
|
||||
)
|
||||
)
|
||||
|
||||
kde4_add_plugin(gvpart ${gvpart_SRCS})
|
||||
|
||||
target_link_libraries(gvpart ${KDE4_KPARTS_LIBS} gwenviewlib)
|
||||
|
||||
install(TARGETS gvpart DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
|
||||
install(FILES gvpart.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR})
|
||||
install(FILES gvpart.rc
|
||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/gvpart)
|
||||
install(
|
||||
TARGETS gvpart
|
||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||
)
|
||||
install(
|
||||
FILES gvpart.desktop
|
||||
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||
)
|
||||
install(
|
||||
FILES gvpart.rc
|
||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/gvpart
|
||||
)
|
||||
|
|
|
@ -31,6 +31,5 @@ gv_add_unit_test(importertest
|
|||
)
|
||||
gv_add_unit_test(sorteddirmodeltest testutils.cpp)
|
||||
gv_add_unit_test(slidecontainerautotest slidecontainerautotest.cpp)
|
||||
gv_add_unit_test(imagemetainfomodeltest testutils.cpp)
|
||||
gv_add_unit_test(recursivedirmodeltest testutils.cpp)
|
||||
gv_add_unit_test(contextmanagertest testutils.cpp)
|
||||
|
|
|
@ -38,8 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "../lib/transformimageoperation.h"
|
||||
#include "testutils.h"
|
||||
|
||||
#include <exiv2/exif.hpp>
|
||||
|
||||
#include "moc_documenttest.cpp"
|
||||
|
||||
QTEST_KDEMAIN(DocumentTest, GUI)
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2012 Aurélien Gâteau <agateau@kde.org>
|
||||
|
||||
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
|
||||
of the License, 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
// Qt
|
||||
|
||||
// KDE
|
||||
#include <KDebug>
|
||||
#include <qtest_kde.h>
|
||||
|
||||
// Local
|
||||
#include "../lib/exiv2imageloader.h"
|
||||
#include "../lib/imagemetainfomodel.h"
|
||||
#include "testutils.h"
|
||||
|
||||
#include <exiv2/exif.hpp>
|
||||
|
||||
#include "moc_imagemetainfomodeltest.cpp"
|
||||
|
||||
QTEST_KDEMAIN(ImageMetaInfoModelTest, GUI)
|
||||
|
||||
using namespace Gwenview;
|
||||
|
||||
void ImageMetaInfoModelTest::testCatchExiv2Errors()
|
||||
{
|
||||
QByteArray data;
|
||||
{
|
||||
QString path = pathForTestFile("302350_exiv_0.23_exception.jpg");
|
||||
QFile file(path);
|
||||
QVERIFY(file.open(QIODevice::ReadOnly));
|
||||
data = file.readAll();
|
||||
}
|
||||
|
||||
Exiv2::Image::AutoPtr image;
|
||||
{
|
||||
Exiv2ImageLoader loader;
|
||||
QVERIFY(loader.load(data));
|
||||
image = loader.popImage();
|
||||
}
|
||||
|
||||
ImageMetaInfoModel model;
|
||||
model.setExiv2Image(image.get());
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2012 Aurélien Gâteau <agateau@kde.org>
|
||||
|
||||
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
|
||||
of the License, 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#ifndef IMAGEMETAINFOMODELTEST_H
|
||||
#define IMAGEMETAINFOMODELTEST_H
|
||||
|
||||
// Qt
|
||||
#include <QObject>
|
||||
|
||||
// KDE
|
||||
|
||||
// Local
|
||||
|
||||
class ImageMetaInfoModelTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void testCatchExiv2Errors();
|
||||
};
|
||||
|
||||
#endif // IMAGEMETAINFOMODELTEST_H
|
Loading…
Add table
Reference in a new issue