File indexing completed on 2024-05-05 04:33:15
0001 /* 0002 SPDX-FileCopyrightText: 2004-2018 Gilles Caulier <caulier dot gilles at gmail dot com> 0003 SPDX-FileCopyrightText: 2006-2012 Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0004 SPDX-FileCopyrightText: 2004-2005 Renchi Raju <renchi dot raju at gmail dot com> 0005 SPDX-FileCopyrightText: 2004-2005 Jesper K. Pedersen <blackie at kde dot org> 0006 SPDX-FileCopyrightText: 2004-2005 Aurelien Gateau <aurelien dot gateau at free dot fr> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #ifndef KIPI_INTERFACE_H 0012 #define KIPI_INTERFACE_H 0013 0014 // Std includes 0015 0016 #include <memory> 0017 0018 // Qt includes 0019 0020 #include <QFlags> 0021 #include <QObject> 0022 #include <QVariant> 0023 #include <QList> 0024 #include <QUrl> 0025 #include <QByteArray> 0026 #include <QImage> 0027 0028 // Local includes 0029 0030 #include "libkipi_export.h" 0031 0032 class QPixmap; 0033 class QWidget; 0034 class QAbstractItemModel; 0035 0036 /** 0037 * @namespace KIPI 0038 * 0039 * The namespace for all KIPI classes. 0040 */ 0041 0042 namespace KIPI 0043 { 0044 0045 class ImageCollection; 0046 class ImageCollectionSelector; 0047 class ImageInfo; 0048 class ImageInfoShared; 0049 class UploadWidget; 0050 0051 /*! 0052 @enum KIPI::Features 0053 Not all host applications support the full subset of features that KIPI 0054 allows access to. Thus before a plugin expect a decant value for the comment, 0055 it should check whether KIPI::CollectionsHaveComments are set. It does so 0056 using KIPI::Interface::hasFeature(). 0057 */ 0058 enum Features 0059 { 0060 CollectionsHaveComments = 1 << 0, /** This feature specifies that albums have descriptions associated to them. */ 0061 ImagesHasComments = 1 << 1, /** This feature specifies that images in the host application has descriptions associated to them. */ 0062 ImagesHasTime = 1 << 2, /** This feature specifies that images has a date associated with it, which the host application can display and set. */ 0063 HostSupportsDateRanges = 1 << 3, /** This feature specifies whether the host application supports that the user can specify a date range for images, like 1998-2000. */ 0064 HostAcceptNewImages = 1 << 4, /** This feature specifies that the host application do accept new images. Use \ref ImageCollection::uploadUrl to find the 0065 location to place the image, and \ref Interface::addImage() to tell the host application about the new image. */ 0066 ImagesHasTitlesWritable = 1 << 5, /** This feature specifies whether the plugin can change the title for images. */ 0067 CollectionsHaveCategory = 1 << 6, /** This feature specifies that collections are category associated to them ('travels', 'friends', 'monuments', etc.). */ 0068 CollectionsHaveCreationDate = 1 << 7, /** This feature specifies that collections are a creation date associated to them. */ 0069 HostSupportsProgressBar = 1 << 8, /** This feature specifies whether the host application has a progress manager available to report progress information from plugins. */ 0070 HostSupportsTags = 1 << 9, /** This feature specifies whether the host application supports keywords for images. */ 0071 HostSupportsRating = 1 << 10, /** This feature specifies whether the host application supports rating values for images. */ 0072 HostSupportsThumbnails = 1 << 11, /** This feature specifies that host application can provide image thumbnails. */ 0073 HostSupportsReadWriteLock = 1 << 12, /** This feature specifies that host application has mechanism to lock/unlock items to prevent concurrent operations. */ 0074 HostSupportsPickLabel = 1 << 13, /** This feature specifies whether the host application supports pick label values for images, used for photograph workflow. */ 0075 HostSupportsColorLabel = 1 << 14, /** This feature specifies whether the host application supports color label values for images, used to sort item with color flag. */ 0076 HostSupportsItemReservation = 1 << 15, /** This feature specifies whether the host application supports item reservation. */ 0077 HostSupportsPreviews = 1 << 16, /** This feature specifies that host application can provide image preview. */ 0078 HostSupportsRawProcessing = 1 << 17, /** This feature specifies that host application can process Raw files. */ 0079 HostSupportsMetadataProcessing = 1 << 18, /** This feature specifies that host application can process Metadata from files. */ 0080 HostSupportsSaveImages = 1 << 19 /** This feature specifies that host application can save image files. */ 0081 }; 0082 0083 // NOTE: When a new item is add to Features, please don't forget to patch Interface::hasFeature(). 0084 0085 /** 0086 * The EditHint enum. 0087 */ 0088 enum EditHint 0089 { 0090 UndefinedEditHint = 0, 0091 /** The image data (pixels) have been edited 0092 */ 0093 HintPixelContentChanged = 1 << 0, 0094 /** Metadata have been edited 0095 */ 0096 HintMetadataChanged = 1 << 1, 0097 /** All changes done (typically, to the metadata) are also communicated via image attributes. 0098 * In other words, if the host updates its internal storage from attribute changes 0099 * and ignores changes on disk, it already has all information. 0100 */ 0101 HintChangeReflectedByAttributes 0102 = 1 << 2, 0103 /** The operation indicated as "about to be done" has been aborted / did not result in a change. 0104 */ 0105 HintEditAborted = 1 << 3, 0106 0107 /** Short name, implies that only metadata changed, and all metadata changes are communicated via attributes. 0108 */ 0109 HintMetadataOnlyChange = HintMetadataChanged | HintChangeReflectedByAttributes 0110 }; 0111 /** 0112 * Stores a combination of #EditHint values. 0113 */ 0114 Q_DECLARE_FLAGS(EditHints, EditHint) 0115 0116 // --------------------------------------------------------------------------------------------------------------- 0117 0118 /** 0119 * @class FileReadWriteLock interface.h <KIPI/Interface> 0120 * 0121 * A Kipi FileReadWriteLock refers to application-wide reading/writing 0122 * to a file on disk; it is created with Interface::createReadWriteLock() for a URL. 0123 * All semantics are identical to a recursive QReadWriteLock. 0124 * You must unlock as often as you locked. 0125 * 0126 * @note Locking will incur a mutex wait if the file is not free. 0127 * Therefore, calling the lock methods, especially lockForWrite, 0128 * from the UI thread shall be done with care, or rather avoided. 0129 * 0130 * Note that you must not keep a lock for a longer time, but only for the imminent 0131 * low-level reading or writing on disk. 0132 * 0133 * See Interface::reserveForAction() API for longer lasting reservation which 0134 * do not incur waits. 0135 * 0136 * It is strongly recommended to use the FileReadLocker or FileWriteLocker 0137 * convenience locks instead of creating and locking a FileReadWriteLock directly. 0138 */ 0139 class LIBKIPI_EXPORT FileReadWriteLock 0140 { 0141 public: 0142 0143 virtual ~FileReadWriteLock() {} 0144 virtual void lockForRead() = 0; 0145 virtual void lockForWrite() = 0; 0146 virtual bool tryLockForRead() = 0; 0147 virtual bool tryLockForRead(int timeout) = 0; 0148 virtual bool tryLockForWrite() = 0; 0149 virtual bool tryLockForWrite(int timeout) = 0; 0150 virtual void unlock() = 0; 0151 }; 0152 0153 // --------------------------------------------------------------------------------------------------------------- 0154 0155 /** 0156 * @class MetadataProcessor interface.h <KIPI/Interface> 0157 * 0158 * A Kipi MetadataProcessor refers to application-wide to process file metadata 0159 * about Exif/Iptc/Xmp management; it is created with Interface::createMetadataProcessor(). 0160 * You can use libkexiv2 to re-implement this class as it's implemented in tests/common/kipiinterface.cpp. 0161 */ 0162 class LIBKIPI_EXPORT MetadataProcessor : public QObject 0163 { 0164 public: 0165 0166 /** Image orientation values from Exif tag. 0167 */ 0168 enum ExifOrientation 0169 { 0170 UNSPECIFIED = 0, 0171 NORMAL = 1, 0172 HFLIP = 2, 0173 ROT_180 = 3, 0174 VFLIP = 4, 0175 ROT_90_HFLIP = 5, 0176 ROT_90 = 6, 0177 ROT_90_VFLIP = 7, 0178 ROT_270 = 8 0179 }; 0180 0181 public: 0182 0183 MetadataProcessor() {}; 0184 ~MetadataProcessor() override {}; 0185 0186 virtual bool load(const QUrl& url) = 0; 0187 virtual bool applyChanges() = 0; 0188 0189 /** @note @p writeToFileOnly force to write metadata only in file without to manage XMP sidecar file 0190 */ 0191 virtual bool save(const QUrl& url, bool writeToFileOnly=false) = 0; 0192 0193 virtual QSize getPixelSize() = 0; 0194 0195 virtual bool setImageProgramId(const QString& program, const QString& version) = 0; 0196 0197 virtual QSize getImageDimensions() = 0; 0198 virtual bool setImageDimensions(const QSize& size) = 0; 0199 0200 /** @note orientation is standard value from Exif orientation tag. See ExifOrientation values. 0201 */ 0202 virtual int getImageOrientation() = 0; 0203 virtual bool setImageOrientation(int orientation) = 0; 0204 virtual bool rotateExifQImage(QImage& img, int orientation) = 0; 0205 0206 virtual QDateTime getImageDateTime() = 0; 0207 virtual bool setImageDateTime(const QDateTime& dt) = 0; 0208 0209 virtual bool getImagePreview(QImage& img) = 0; 0210 virtual bool setImagePreview(const QImage& img) = 0; 0211 0212 virtual bool hasExif() = 0; 0213 virtual bool hasIptc() = 0; 0214 virtual bool hasXmp() = 0; 0215 0216 virtual QByteArray getExif() = 0; 0217 virtual QByteArray getIptc() = 0; 0218 virtual QByteArray getXmp() = 0; 0219 0220 virtual bool setExif(const QByteArray& data) = 0; 0221 virtual bool setIptc(const QByteArray& data) = 0; 0222 virtual bool setXmp(const QByteArray& data) = 0; 0223 0224 virtual bool registerXmpNameSpace(const QString& uri, const QString& prefix) = 0; 0225 0226 virtual bool supportXmp() = 0; 0227 virtual bool canWriteXmp(const QUrl& url) = 0; 0228 0229 virtual bool removeExifTags(const QStringList& tagFilters) = 0; 0230 virtual bool removeIptcTags(const QStringList& tagFilters) = 0; 0231 virtual bool removeXmpTags(const QStringList& tagFilters) = 0; 0232 0233 virtual bool getGPSInfo(double& altitude, double& latitude, double& longitude) = 0; 0234 virtual bool setGPSInfo(const double altitude, const double latitude, const double longitude) = 0; 0235 virtual bool removeGPSInfo() = 0; 0236 0237 virtual QString getExifTagString(const QString& tag) = 0; 0238 virtual bool setExifTagString(const QString& tag, const QString& val) = 0; 0239 0240 virtual bool getExifTagRational(const QString& tag, long int& num, long int& den) = 0; 0241 virtual bool setExifTagRational(const QString& tag, long int num, long int den) = 0; 0242 0243 virtual QString getXmpTagString(const QString& tag) = 0; 0244 virtual bool setXmpTagString(const QString& tag, const QString& val) = 0; 0245 0246 virtual QStringList getXmpKeywords() = 0; 0247 virtual bool setXmpKeywords(const QStringList& keywords) = 0; 0248 0249 virtual QVariant getXmpTagVariant(const QString& tag) = 0; 0250 }; 0251 0252 // --------------------------------------------------------------------------------------------------------------- 0253 0254 /** 0255 * @class Interface interface.h <KIPI/Interface> 0256 * 0257 * The Interface class. 0258 */ 0259 class LIBKIPI_EXPORT Interface : public QObject 0260 { 0261 Q_OBJECT 0262 0263 public: 0264 0265 explicit Interface(QObject* const parent, const QString& name=QString()); 0266 ~Interface() override; 0267 0268 /** 0269 * Tells whether the host application under which the plugin currently executes a given feature. 0270 * See KIPI::Features for details on the individual features. 0271 */ 0272 bool hasFeature(Features feature) const; 0273 0274 /** 0275 * Returns list of all images in current album. 0276 * If there are no current album, the returned 0277 * KIPI::ImageCollection::isValid() will return @c false. 0278 */ 0279 virtual ImageCollection currentAlbum() = 0; 0280 0281 /** 0282 * Current selection in a thumbnail view for example. 0283 * If there are no current selection, the returned 0284 * KIPI::ImageCollection::isValid() will return @c false. 0285 */ 0286 virtual ImageCollection currentSelection() = 0; 0287 0288 /** 0289 * Returns a list of albums. 0290 */ 0291 virtual QList<ImageCollection> allAlbums() = 0; 0292 0293 /** 0294 * Returns the image info container for item pointed by @p url. 0295 */ 0296 virtual ImageInfo info(const QUrl& url) = 0; 0297 0298 /** 0299 * Tells to host application that a new image has been made available to it. 0300 * Returns @c true if the host application did accept the new image, otherwise @p err will be filled with 0301 * an error description. 0302 */ 0303 virtual bool addImage(const QUrl&, QString& err); 0304 0305 /** 0306 * Tells to host application that a new image has been removed. 0307 */ 0308 virtual void delImage(const QUrl&); 0309 0310 /** 0311 * Tells to host application that the following images has changed on disk 0312 */ 0313 virtual void refreshImages(const QList<QUrl>&); 0314 0315 /** 0316 * Tells to host application to render immediatly a preview image for one item. 0317 * This method re-implemented in host application and be thread safe. 0318 */ 0319 virtual QImage preview(const QUrl& url); 0320 0321 /** 0322 * Tell to host application to save image at a URL in specific format (JPG, PNG, TIF, etc). 0323 * Pixels image data must be in ARGB, with image size (width,height). 0324 * Pixels can be in sixteen bits per color per pixels and can have an alpha channel. 0325 * If @p cancel flag is passed it permit to cancel save operation. 0326 * This method re-implemented in host application must be thread safe. 0327 */ 0328 virtual bool saveImage(const QUrl& url, const QString& format, 0329 const QByteArray& data, uint width, uint height, 0330 bool sixteenBit, bool hasAlpha, 0331 bool* cancel = nullptr); 0332 0333 /** 0334 * Tells to host application to render a preview image for one item. 0335 * A resizement to a specific size will be generated if preview is largest than. 0336 * Use a positive @p resizedTo value in this case, else -1. Aspect ratio is preserved while rendering. 0337 * This asynchronous method must be re-implemented in host application. 0338 * Use gotPreview() signal to take preview. 0339 */ 0340 virtual void preview(const QUrl& url, int resizedTo); 0341 0342 /** 0343 * Tells to host application to render a thumbnail for one item. This asynchronous method must be 0344 * re-implemented in host application. Use gotThumbnail() signal to take thumb. 0345 */ 0346 virtual void thumbnail(const QUrl& url, int size); 0347 0348 /** 0349 * Ask to Kipi host application to render thumbnails for a list of images. This asynchronous method must be 0350 * re-implemented in host application. Use gotThumbnail() signal to take thumbs. 0351 */ 0352 virtual void thumbnails(const QList<QUrl>& list, int size); 0353 0354 /** 0355 Ask to Kipi host application to prepare progress manager for a new entry. This method must return from host 0356 a string identification about progress item created. This id will be used later to change in host progress item 0357 value and text. @p title is text used to name progress item in host application. 0358 Set @p canBeCanceled to @c true if you want that progress item provide a cancel button to close process from kipi host. 0359 Use progressCanceled() signal to manage feedback from kipi host when cancel button is pressed. 0360 Set @p hasThumb to @c true if you want that progress item support small thumbnail near progress bar. 0361 Use progresssThumbnailChanged() to change thumbnail in kipi host and progressValueChanged() to advance progress 0362 bar in percent. Use progressStatusChanged() to change description string of progress item. 0363 To close progress item in kipi host, for example when all is done in plugin, use progressCompleted() method. 0364 If you Host do not re-implement this method, value returned is a null string. 0365 You must re-implement this method if your host support HostSupportsProgressBar feature. 0366 */ 0367 virtual QString progressScheduled(const QString& title, bool canBeCanceled, bool hasThumb) const; 0368 0369 /** 0370 * To manage progress state from plugin to host application. 0371 * @param id identification string of process item returned from host by progressScheduled() method. 0372 */ 0373 virtual void progressValueChanged(const QString& id, float percent); 0374 virtual void progressStatusChanged(const QString& id, const QString& status); 0375 virtual void progressThumbnailChanged(const QString& id, const QPixmap& thumb); 0376 virtual void progressCompleted(const QString& id); 0377 0378 /** Returns RAW file extensions managed by host application, separated by blank spaces, (ex: "NEF CR2 ARW PEF"). 0379 */ 0380 virtual QString rawFiles(); 0381 0382 virtual ImageCollectionSelector* imageCollectionSelector(QWidget* parent)=0; 0383 virtual UploadWidget* uploadWidget(QWidget* parent)=0; 0384 virtual QAbstractItemModel* getTagTree() const; 0385 0386 /** 0387 * Supported if HostSupportsItemReservation 0388 * 0389 * If an item is scheduled in a plugin for an action which will edit the object, 0390 * call this method. If the user tries to subject the reserved item to another operation, 0391 * possibly conflicting, a warning message or other action may be taken. 0392 * 0393 * Give the URL of the item and a QObject which acts as the holder of the reservation. 0394 * The object must not be null, and the reservation will be cancelled when the object is deleted. 0395 * 0396 * @param descriptionOfAction a user-presentable string describing the action for which 0397 * the reservation was made 0398 * 0399 * @returns @c true if a reservation was made, or false if a reservation could not be made. 0400 */ 0401 virtual bool reserveForAction(const QUrl& url, QObject* const reservingObject, 0402 const QString& descriptionOfAction) const; 0403 /** 0404 * Supported if HostSupportsItemReservation 0405 * 0406 * Clears a reservation made previously with reserveForAction() for the given @p reservingObject. 0407 * You must clear any reservation you made, or, alternatively, delete the reserving object. 0408 */ 0409 virtual void clearReservation(const QUrl& url, QObject* const reservingObject); 0410 0411 /** 0412 * Supported if HostSupportsItemReservation 0413 * 0414 * Returns if the item is reserved. You can pass a pointer to a QString; if the return value 0415 * is @c true, the string will be set to the @p descriptionOfAction set with reserveForAction(). 0416 */ 0417 virtual bool itemIsReserved(const QUrl& url, QString* const descriptionOfAction = nullptr) const; 0418 0419 /** 0420 * Supported if HostSupportsReadWriteLock 0421 * Creates a ReadWriteLock for the given URL. 0422 * You must unlock the FileReadWriteLock as often as you locked. 0423 * Deleting the object does not unlock it. 0424 * The implementation from KIPI host application must be thread-safe. 0425 * 0426 */ 0427 virtual FileReadWriteLock* createReadWriteLock(const QUrl& url) const; 0428 0429 /** 0430 * Supported if HostSupportsMetadataProcessing. 0431 * Creates an instance of MetadataProcessor dedicated to manage file metadata. 0432 * The implementation from KIPI host application must be thread-safe. 0433 * 0434 */ 0435 virtual MetadataProcessor* createMetadataProcessor() const; 0436 0437 /** 0438 * Supported if HostSupportsEditHints 0439 * 0440 * Before an edit operation starts when it has finished, specify a hint for it. 0441 * Change hints are optional and may allow optimizations. 0442 * 0443 * When aboutToEdit() has been called, editingFinished() must be called afterwards. 0444 * It is strongly recommended to use the EditHintScope instead of these methods. 0445 */ 0446 virtual void aboutToEdit(const QUrl& url, EditHints hints); 0447 virtual void editingFinished(const QUrl& url, EditHints hints); 0448 0449 /** 0450 * Returns a string version of libkipi release ID. 0451 */ 0452 static QString version(); 0453 0454 /** 0455 * Return a list of supported image MIME types by Qt image reader. 0456 * @param readWrite query Qt to list MIME types in read mode (@c false), or in write mode (@c true). 0457 */ 0458 static QStringList supportedImageMimeTypes(bool readWrite=false); 0459 0460 Q_SIGNALS: 0461 0462 /** 0463 * Emit when item selection has changed from host application user interface. 0464 * @param hasSelection set @c true if items are select or not in collection. 0465 */ 0466 void selectionChanged(bool hasSelection); 0467 0468 /** 0469 * Emit when current album selection as changed from host application user interface. 0470 * @param hasSelection @c true if album are select or not in collection. 0471 */ 0472 void currentAlbumChanged(bool hasSelection); 0473 0474 /** Emit when host application has rendered item thumbnail. See asynchronous thumbnail() and thumbnails() 0475 * methods for details. 0476 */ 0477 void gotThumbnail(const QUrl&, const QPixmap&); 0478 0479 /** Emit when host application has rendered item preview image. See asynchronous preview() methods for details. 0480 */ 0481 void gotPreview(const QUrl&, const QImage&); 0482 0483 /** 0484 * This signal is emit from kipi host when a progress item is canceled. id is identification string of progress item. 0485 */ 0486 void progressCanceled(const QString& id); 0487 0488 /** 0489 * Supported if HostSupportsItemReservation 0490 * 0491 * Emitted from reservedForAction() and clearReservation(), respectively. 0492 * */ 0493 void reservedForAction(const QUrl& url, const QString& descriptionOfAction); 0494 void reservationCleared(const QUrl& url); 0495 0496 protected: 0497 0498 /** 0499 * Return a bitwise or of the KIPI::Features that thus application support. 0500 */ 0501 virtual int features() const = 0; 0502 0503 private: 0504 0505 bool hasFeature(const QString& feature) const; 0506 0507 private: 0508 0509 friend class PluginLoader; 0510 }; 0511 0512 // --------------------------------------------------------------------------------------------------------------- 0513 0514 /** 0515 * @class FileReadLocker interface.h <KIPI/Interface> 0516 * 0517 * Convenience classes creating a FileReadWriteLock and locking it for you. 0518 * It is strongly recommended to use FileReadWriteLock only through these 0519 * classes, created on the stack, as unlocking will be done automatically for you. 0520 * 0521 * The API is modelled according to the QReadLocker/QWriteLocker classes. 0522 * 0523 * @note Operations are no-ops and fileReadWriteLock() is a nullptr if not HostSupportsReadWriteLock. 0524 */ 0525 class LIBKIPI_EXPORT FileReadLocker 0526 { 0527 public: 0528 0529 FileReadLocker(Interface* const iface, const QUrl& url); 0530 FileReadLocker(ImageInfoShared* const info); 0531 ~FileReadLocker(); 0532 0533 FileReadWriteLock* fileReadWriteLock() const; 0534 void unlock(); 0535 void relock(); 0536 0537 private: 0538 0539 FileReadWriteLock* const d; 0540 }; 0541 0542 // --------------------------------------------------------------------------------------------------------------- 0543 0544 /** 0545 * @class FileWriteLocker interface.h <KIPI/Interface> 0546 * 0547 * The FileWriteLocker class. 0548 */ 0549 class LIBKIPI_EXPORT FileWriteLocker 0550 { 0551 public: 0552 0553 FileWriteLocker(Interface* const iface, const QUrl& url); 0554 FileWriteLocker(ImageInfoShared* const info); 0555 ~FileWriteLocker(); 0556 0557 FileReadWriteLock* fileReadWriteLock() const; 0558 void unlock(); 0559 void relock(); 0560 0561 private: 0562 0563 FileReadWriteLock* const d; 0564 }; 0565 0566 // --------------------------------------------------------------------------------------------------------------- 0567 0568 /** 0569 * @class EditHintScope interface.h <KIPI/Interface> 0570 * 0571 * The EditHintScope class. 0572 */ 0573 class LIBKIPI_EXPORT EditHintScope 0574 { 0575 public: 0576 0577 EditHintScope(Interface* const iface, const QUrl& url, EditHints hints); 0578 ~EditHintScope(); 0579 0580 void changeAborted(); 0581 0582 private: 0583 0584 class Private; 0585 std::unique_ptr<Private> const d; 0586 }; 0587 0588 } // namespace KIPI 0589 0590 Q_DECLARE_OPERATORS_FOR_FLAGS(KIPI::EditHints) 0591 0592 #endif /* KIPI_INTERFACE_H */