File indexing completed on 2024-05-12 04:33:18
0001 /* 0002 SPDX-FileCopyrightText: 2009-2010 Michael G. Hansen <mike at mghansen dot de> 0003 SPDX-FileCopyrightText: 2011-2018 Gilles Caulier <caulier dot gilles at gmail dot com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kipiinterface.h" 0009 0010 // Qt includes 0011 0012 #include <QTextStream> 0013 #include <QDebug> 0014 #include <QIcon> 0015 #include <QFileInfo> 0016 0017 // Libkipi includes 0018 0019 #include "libkipi_version.h" 0020 #include "imagecollection.h" 0021 0022 // KF includes 0023 0024 #ifdef HAVE_KEXIV2 0025 # include <kexiv2/kexiv2.h> 0026 #endif 0027 0028 // Local includes 0029 0030 #include "kipiimageinfoshared.h" 0031 #include "kipiimagecollectionselector.h" 0032 #include "kipiuploadwidget.h" 0033 #include "kipiimagecollectionshared.h" 0034 #include "kipiwriteimage.h" 0035 0036 namespace KXMLKipiCmd 0037 { 0038 0039 KipiInterface::KipiInterface(QObject* const parent, const QString& name) 0040 : Interface(parent, name), 0041 m_selectedImages(), 0042 m_selectedAlbums(), 0043 m_albums() 0044 { 0045 } 0046 0047 KipiInterface::~KipiInterface() 0048 { 0049 } 0050 0051 ImageCollection KipiInterface::currentAlbum() 0052 { 0053 qDebug() << "Called by plugins"; 0054 0055 QUrl currentAlbumUrl; 0056 0057 if (!m_selectedAlbums.isEmpty()) 0058 { 0059 currentAlbumUrl = m_selectedAlbums.at(0); 0060 } 0061 0062 return (ImageCollection(new KipiImageCollectionShared(currentAlbumUrl))); 0063 } 0064 0065 ImageCollection KipiInterface::currentSelection() 0066 { 0067 qDebug() << "Called by plugins"; 0068 0069 return (ImageCollection(new KipiImageCollectionShared(m_selectedImages))); 0070 } 0071 0072 QList<ImageCollection> KipiInterface::allAlbums() 0073 { 0074 QList<ImageCollection> listAllAlbums; 0075 0076 for (QList<QUrl>::const_iterator it = m_albums.constBegin(); it!=m_albums.constEnd(); ++it) 0077 { 0078 listAllAlbums.append(ImageCollection(new KipiImageCollectionShared(*it))); 0079 } 0080 0081 // make sure albums which have been specified as selectedalbums are also in the allAlbums list: 0082 for (QList<QUrl>::const_iterator it = m_selectedAlbums.constBegin(); it!=m_selectedAlbums.constEnd(); ++it) 0083 { 0084 if (!m_albums.contains(*it)) 0085 { 0086 listAllAlbums.append(ImageCollection(new KipiImageCollectionShared(*it))); 0087 } 0088 } 0089 0090 return listAllAlbums; 0091 } 0092 0093 ImageInfo KipiInterface::info(const QUrl& url) 0094 { 0095 qDebug() << QString::fromLatin1( "Plugin wants information about image \"%1\"").arg( url.url() ); 0096 0097 return (ImageInfo(new KipiImageInfoShared(this, url))); 0098 } 0099 0100 bool KipiInterface::addImage(const QUrl& url, QString& errmsg) 0101 { 0102 Q_UNUSED(errmsg); 0103 qDebug() << QString::fromLatin1( "Plugin added an image: \"%1\"").arg( url.url() ); 0104 0105 return true; 0106 } 0107 0108 void KipiInterface::delImage(const QUrl& url) 0109 { 0110 qDebug() << QString::fromLatin1( "Plugin deleted an image: \"%1\"").arg( url.url() ); 0111 } 0112 0113 void KipiInterface::refreshImages(const QList<QUrl>& urls) 0114 { 0115 qDebug() << QString::fromLatin1( "Plugin asks to refresh %1 images:").arg( urls.size() ); 0116 0117 for (QList<QUrl>::ConstIterator it = urls.constBegin(); it!=urls.constEnd(); ++it) 0118 { 0119 qDebug() << QString::fromLatin1(" ") + (*it).url(); 0120 } 0121 } 0122 0123 int KipiInterface::features() const 0124 { 0125 qDebug() << "Called by plugins"; 0126 0127 return ImagesHasTime 0128 #ifdef HAVE_KEXIV2 0129 | HostSupportsMetadataProcessing 0130 #endif 0131 0132 ; 0133 } 0134 0135 ImageCollectionSelector* KipiInterface::imageCollectionSelector(QWidget* parent) 0136 { 0137 qDebug() << "Called by plugins"; 0138 0139 return (new KipiImageCollectionSelector(this, parent)); 0140 } 0141 0142 UploadWidget* KipiInterface::uploadWidget(QWidget* parent) 0143 { 0144 qDebug() << "Called by plugins"; 0145 0146 return (new KipiUploadWidget(this, parent)); 0147 } 0148 0149 void KipiInterface::addSelectedImages(const QList<QUrl>& images) 0150 { 0151 m_selectedImages.append(images); 0152 } 0153 0154 void KipiInterface::addSelectedImage(const QUrl& image) 0155 { 0156 m_selectedImages.append(image); 0157 } 0158 0159 void KipiInterface::addAlbums(const QList<QUrl>& albums) 0160 { 0161 for (QList<QUrl>::const_iterator it = albums.constBegin(); it!=albums.constEnd(); ++it) 0162 { 0163 addAlbum(*it); 0164 } 0165 } 0166 0167 void KipiInterface::addAlbum(const QUrl& album) 0168 { 0169 m_albums.append(album); 0170 0171 // TODO: recurse through sub-directories? 0172 } 0173 0174 void KipiInterface::addSelectedAlbums(const QList<QUrl>& albums) 0175 { 0176 for (QList<QUrl>::const_iterator it = albums.constBegin(); it!=albums.constEnd(); ++it) 0177 { 0178 addSelectedAlbum(*it); 0179 } 0180 } 0181 0182 void KipiInterface::addSelectedAlbum(const QUrl& album) 0183 { 0184 m_selectedAlbums.append(album); 0185 0186 // TODO: recurse through sub-directories? 0187 } 0188 0189 QVariant KipiInterface::hostSetting(const QString& settingName) 0190 { 0191 Q_UNUSED(settingName); 0192 return QVariant(); 0193 } 0194 0195 void KipiInterface::thumbnails(const QList<QUrl>& list, int) 0196 { 0197 for (const QUrl& url : list) 0198 { 0199 QIcon icon(url.url()); 0200 Q_EMIT gotThumbnail(url, icon.pixmap(256)); 0201 } 0202 } 0203 0204 bool KipiInterface::saveImage(const QUrl& url, const QString& format, 0205 const QByteArray& data, uint width, uint height, 0206 bool sixteenBit, bool hasAlpha, bool* cancel) 0207 { 0208 KIPIWriteImage writer; 0209 writer.setImageData(data, width, height, sixteenBit, hasAlpha); 0210 writer.setCancel(cancel); 0211 0212 if (format.toUpper() == QLatin1String("JPG") || 0213 format.toUpper() == QLatin1String("JPEG")) 0214 { 0215 return writer.write2JPEG(url.toLocalFile()); 0216 } 0217 0218 if (format.toUpper() == QLatin1String("TIF") || 0219 format.toUpper() == QLatin1String("TIFF")) 0220 { 0221 return writer.write2TIFF(url.toLocalFile()); 0222 } 0223 0224 if (format.toUpper() == QLatin1String("PNG")) 0225 { 0226 return writer.write2PNG(url.toLocalFile()); 0227 } 0228 0229 if (format.toUpper() == QLatin1String("PPM")) 0230 { 0231 return writer.write2PPM(url.toLocalFile()); 0232 } 0233 0234 return false; 0235 } 0236 0237 // --------------------------------------------------------------------------------------- 0238 0239 #ifdef HAVE_KEXIV2 0240 0241 class KipiMetadataProcessor : public KIPI::MetadataProcessor 0242 { 0243 public: 0244 0245 KipiMetadataProcessor() {}; 0246 ~KipiMetadataProcessor() override {}; 0247 0248 bool load(const QUrl& url) override 0249 { 0250 return m_meta.load(url.toLocalFile()); 0251 } 0252 0253 bool save(const QUrl& url, bool writeToFileOnly) override 0254 { 0255 if (writeToFileOnly) 0256 m_meta.setMetadataWritingMode((int) KExiv2Iface::KExiv2::WRITETOIMAGEONLY); 0257 0258 return m_meta.save(url.toLocalFile()); 0259 } 0260 0261 bool applyChanges() override 0262 { 0263 return m_meta.applyChanges(); 0264 } 0265 0266 QSize getPixelSize() override 0267 { 0268 return m_meta.getPixelSize(); 0269 } 0270 0271 bool setImageProgramId(const QString& program, const QString& version) override 0272 { 0273 return m_meta.setImageProgramId(program, version); 0274 } 0275 0276 QSize getImageDimensions() override 0277 { 0278 return m_meta.getImageDimensions(); 0279 } 0280 0281 bool setImageDimensions(const QSize& size) override 0282 { 0283 return m_meta.setImageDimensions(size); 0284 } 0285 0286 int getImageOrientation() override 0287 { 0288 return m_meta.getImageOrientation(); 0289 } 0290 0291 bool setImageOrientation(int orientation) override 0292 { 0293 return m_meta.setImageOrientation((KExiv2Iface::KExiv2::ImageOrientation)orientation); 0294 } 0295 0296 bool rotateExifQImage(QImage& img, int orientation) override 0297 { 0298 return m_meta.rotateExifQImage(img, (KExiv2Iface::KExiv2::ImageOrientation)orientation); 0299 } 0300 0301 QDateTime getImageDateTime() override 0302 { 0303 return m_meta.getImageDateTime(); 0304 } 0305 0306 bool setImageDateTime(const QDateTime& dt) override 0307 { 0308 return m_meta.setImageDateTime(dt); 0309 } 0310 0311 bool getImagePreview(QImage& img) override 0312 { 0313 return m_meta.getImagePreview(img); 0314 } 0315 0316 bool setImagePreview(const QImage& img) override 0317 { 0318 return m_meta.setImagePreview(img); 0319 } 0320 0321 bool hasExif() override 0322 { 0323 return m_meta.hasExif(); 0324 } 0325 0326 bool hasIptc() override 0327 { 0328 return m_meta.hasIptc(); 0329 } 0330 0331 bool hasXmp() override 0332 { 0333 return m_meta.hasXmp(); 0334 } 0335 0336 QByteArray getExif() override 0337 { 0338 return m_meta.getExifEncoded(); 0339 } 0340 0341 QByteArray getIptc() override 0342 { 0343 return m_meta.getIptc(); 0344 } 0345 0346 QByteArray getXmp() override 0347 { 0348 return m_meta.getXmp(); 0349 } 0350 0351 bool setExif(const QByteArray& data) override 0352 { 0353 return m_meta.setExif(data); 0354 } 0355 0356 bool setIptc(const QByteArray& data) override 0357 { 0358 return m_meta.setIptc(data); 0359 } 0360 0361 bool setXmp(const QByteArray& data) override 0362 { 0363 return m_meta.setXmp(data); 0364 } 0365 0366 bool registerXmpNameSpace(const QString& uri, const QString& prefix) override 0367 { 0368 return m_meta.registerXmpNameSpace(uri, prefix); 0369 } 0370 0371 bool supportXmp() override 0372 { 0373 return m_meta.supportXmp(); 0374 } 0375 0376 bool canWriteXmp(const QUrl& url) override 0377 { 0378 return m_meta.canWriteXmp(url.toLocalFile()); 0379 } 0380 0381 bool removeExifTags(const QStringList& tagFilters) override 0382 { 0383 KExiv2Iface::KExiv2::MetaDataMap m = m_meta.getExifTagsDataList(tagFilters); 0384 0385 if (m.isEmpty()) 0386 return false; 0387 0388 for (KExiv2Iface::KExiv2::MetaDataMap::iterator it = m.begin(); it != m.end(); ++it) 0389 { 0390 m_meta.removeExifTag(it.key().toLatin1().constData()); 0391 } 0392 0393 return true; 0394 } 0395 0396 bool removeIptcTags(const QStringList& tagFilters) override 0397 { 0398 KExiv2Iface::KExiv2::MetaDataMap m = m_meta.getIptcTagsDataList(tagFilters); 0399 0400 if (m.isEmpty()) 0401 return false; 0402 0403 for (KExiv2Iface::KExiv2::MetaDataMap::iterator it = m.begin(); it != m.end(); ++it) 0404 { 0405 m_meta.removeIptcTag(it.key().toLatin1().constData()); 0406 } 0407 0408 return true; 0409 } 0410 0411 bool removeXmpTags(const QStringList& tagFilters) override 0412 { 0413 KExiv2Iface::KExiv2::MetaDataMap m = m_meta.getXmpTagsDataList(tagFilters); 0414 0415 if (m.isEmpty()) 0416 return false; 0417 0418 for (KExiv2Iface::KExiv2::MetaDataMap::iterator it = m.begin(); it != m.end(); ++it) 0419 { 0420 m_meta.removeXmpTag(it.key().toLatin1().constData()); 0421 } 0422 0423 return true; 0424 } 0425 0426 bool getGPSInfo(double& alt, double& lat, double& lon) override 0427 { 0428 return m_meta.getGPSInfo(alt, lat, lon); 0429 } 0430 0431 bool setGPSInfo(const double alt, const double lat, const double lon) override 0432 { 0433 return m_meta.setGPSInfo(alt, lat, lon); 0434 } 0435 0436 bool removeGPSInfo() override 0437 { 0438 return m_meta.removeGPSInfo(); 0439 } 0440 0441 QString getExifTagString(const QString& tag) override 0442 { 0443 return m_meta.getExifTagString(tag.toLatin1().constData()); 0444 } 0445 0446 bool setExifTagString(const QString& tag, const QString& val) override 0447 { 0448 return m_meta.setExifTagString(tag.toLatin1().constData(), val); 0449 } 0450 0451 bool getExifTagRational(const QString& tag, long int& num, long int& den) override 0452 { 0453 return m_meta.getExifTagRational(tag.toLatin1().constData(), num, den); 0454 } 0455 0456 bool setExifTagRational(const QString& tag, long int num, long int den) override 0457 { 0458 return m_meta.setExifTagRational(tag.toLatin1().constData(), num, den); 0459 } 0460 0461 QString getXmpTagString(const QString& tag) override 0462 { 0463 return m_meta.getXmpTagString(tag.toLatin1().constData()); 0464 } 0465 0466 bool setXmpTagString(const QString& tag, const QString& val) override 0467 { 0468 return m_meta.setXmpTagString(tag.toLatin1().constData(), val); 0469 } 0470 0471 QStringList getXmpKeywords() override 0472 { 0473 return m_meta.getXmpKeywords(); 0474 } 0475 0476 bool setXmpKeywords(const QStringList& keywords) override 0477 { 0478 return m_meta.setXmpKeywords(keywords); 0479 } 0480 0481 QVariant getXmpTagVariant(const QString& tag) override 0482 { 0483 return m_meta.getXmpTagVariant(tag.toLatin1().constData()); 0484 } 0485 0486 private: 0487 0488 KExiv2Iface::KExiv2 m_meta; 0489 }; 0490 0491 MetadataProcessor* KipiInterface::createMetadataProcessor() const 0492 { 0493 return (new KipiMetadataProcessor); 0494 } 0495 0496 #else // HAVE_KEXIV2 0497 0498 MetadataProcessor* KipiInterface::createMetadataProcessor() const 0499 { 0500 qDebug() << "This interface was not compiled with libkexiv2 to support Metadata processing"; 0501 return 0; 0502 } 0503 0504 #endif // HAVE_KEXIV2 0505 0506 // --------------------------------------------------------------------------------------- 0507 0508 FileReadWriteLock* KipiInterface::createReadWriteLock(const QUrl&) const 0509 { 0510 return nullptr; // TODO 0511 } 0512 0513 } // namespace KXMLKipiCmd 0514 0515 #include "moc_kipiinterface.cpp"