File indexing completed on 2024-05-12 05:09:50

0001 /***************************************************************************
0002     Copyright (C) 2003-2009 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #ifndef TELLICO_IMAGEFACTORY_H
0026 #define TELLICO_IMAGEFACTORY_H
0027 
0028 #include "../utils/stringset.h"
0029 
0030 #include <QUrl>
0031 #include <QObject>
0032 #include <QColor>
0033 #include <QHash>
0034 #include <QPixmap>
0035 
0036 #include <memory>
0037 
0038 class KZip;
0039 class KJob;
0040 
0041 namespace Tellico {
0042   namespace Data {
0043     class Image;
0044     class ImageInfo;
0045   }
0046   class ImageDirectory;
0047 
0048 class StyleOptions {
0049 public:
0050   QString fontFamily;
0051   int fontSize;
0052   QColor baseColor;
0053   QColor textColor;
0054   QColor highlightedBaseColor;
0055   QColor highlightedTextColor;
0056   QColor linkColor;
0057   QString imgDir;
0058 };
0059 
0060 /**
0061  * @author Robby Stephenson
0062  */
0063 class ImageFactory : public QObject {
0064 Q_OBJECT
0065 
0066 public:
0067   enum CacheDir {
0068     TempDir,
0069     DataDir,
0070     LocalDir,
0071     ZipArchive
0072   };
0073 
0074   /**
0075    * setup some of the static members
0076    */
0077   static void init();
0078 
0079   /**
0080    * Returns the temporary directory where image files are saved
0081    *
0082    * @return The full path
0083    */
0084   static QString tempDir();
0085   static QString dataDir();
0086   static QString localDir();
0087   static QString imageDir();
0088   static CacheDir cacheDir();
0089 
0090   /**
0091    * Add an image, reading it from a URL, which is the case when adding a new image from the
0092    * @ref ImageWidget.
0093    *
0094    * @param url The URL of the image, anything KIO can handle
0095    * @param quiet If any error should not be reported.
0096    * @return The image id, empty if null
0097    */
0098   static QString addImage(const QUrl& url, bool quiet=false,
0099                           const QUrl& referrer = QUrl(), bool linkOnly=false);
0100   /**
0101    * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
0102    * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
0103    * 'know' what format it came from.
0104    *
0105    * @param image The qimage
0106    * @param format The image format, probably "PNG"
0107    * @return The image id, empty if null
0108    */
0109   static QString addImage(const QImage& image, const QString& format);
0110   static QString addImage(const QPixmap& image, const QString& format);
0111   /**
0112    * Add an image, reading it from data, which is the case when reading from the data file, and
0113    * using the @p format and @p id as the image id. The image id is checked in the image cache
0114    * image dict first, and then if it is not found, a new Image is constructed. The new image is
0115    * inserted in the dict, and the image info is cached.
0116    *
0117    * @param data The image data
0118    * @param format The image format, from Qt's output format list
0119    * @param id The internal id of the image
0120    * @return The image id, empty if null
0121    */
0122   static QString addImage(const QByteArray& data, const QString& format, const QString& id=QString());
0123 
0124   static bool writeCachedImage(const QString& id, CacheDir dir, bool force = false);
0125   static bool writeCachedImage(const QString& id, ImageDirectory* dir, bool force = false);
0126 
0127   /**
0128    * Returns an image reference given its id. If none is found, a null image
0129    * is returned.
0130    *
0131    * @param id The image id
0132    * @return The image reference
0133    */
0134   static const Data::Image& imageById(const QString& id);
0135   static bool hasLocalImage(const QString& id);
0136   bool hasImageInMemory(const QString& id) const;
0137   // just used for testing
0138   bool hasNullImage(const QString& id) const;
0139   /**
0140    * Requests an image to be made available. Images already in the cache or available locally are
0141    * considered to be instantly available. Otherwise, the id is assumed to be a URL and is downloaded
0142    * The imageAvailable() signal is used to indicate completion and availability of the image.
0143    *
0144    * @param id The image id
0145    */
0146   static void requestImageById(const QString& id);
0147   static Data::ImageInfo imageInfo(const QString& id);
0148   static void cacheImageInfo(const Data::ImageInfo& info);
0149   static bool hasImageInfo(const QString& id);
0150   // basically returns !imageById().isNull()
0151   static bool validImage(const QString& id);
0152 
0153   static QPixmap pixmap(const QString& id, int w, int h);
0154 
0155   /**
0156    * Clear the image cache and dict
0157    * if deleteTempDirectory = true, then clean the temp dir and remove all temporary image files
0158    */
0159   static void clean(bool deleteTempDirectory);
0160   /**
0161    * Creates the gradient images used in the entry view.
0162    */
0163   static void createStyleImages(int collectionType, const StyleOptions& options = StyleOptions());
0164 
0165   static void removeImage(const QString& id_, bool deleteImage);
0166   static StringSet imagesNotInCache();
0167 
0168   static QString localDirectory(const QUrl& url);
0169   static void setLocalDirectory(const QUrl& url);
0170   static void setZipArchive(std::unique_ptr<KZip> zip);
0171 
0172   static ImageFactory* self();
0173 
0174 Q_SIGNALS:
0175   void imageAvailable(const QString& id);
0176   void imageLocationMismatch();
0177 
0178 private Q_SLOTS:
0179   void slotImageJobResult(KJob* job);
0180 
0181 private:
0182   /**
0183    * Add an image, reading it from a URL, which is the case when adding a new image from the
0184    * @ref ImageWidget.
0185    *
0186    * @param url The URL of the image, anything KIO can handle
0187    * @param quiet If any error should not be reported.
0188    * @return The image
0189    */
0190   const Data::Image& addImageImpl(const QUrl& url, bool quiet=false,
0191                                   const QUrl& referrer = QUrl(), bool linkOnly = false);
0192   void requestImageByUrlImpl(const QUrl& url, bool quiet=false,
0193                              const QUrl& referrer = QUrl(), bool linkOnly = false);
0194   /**
0195    * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
0196    * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
0197    * 'know' what format it came from.
0198    *
0199    * @param image The qimage
0200    * @param format The image format, probably "PNG"
0201    * @return The image
0202    */
0203   const Data::Image& addImageImpl(const QImage& image, const QString& format);
0204   /**
0205    * Add an image, reading it from data, which is the case when reading from the data file. The
0206    * @p id isn't strictly needed, since it can be reconstructed from the image data and format, but
0207    * since it's already known, go ahead and use it.
0208    *
0209    * @param data The image data
0210    * @param format The image format, from Qt's output format list
0211    * @param id The internal id of the image
0212    * @return The image
0213    */
0214   const Data::Image& addImageImpl(const QByteArray& data, const QString& format, const QString& id);
0215 
0216   const Data::Image& addCachedImageImpl(const QString& id, CacheDir dir);
0217 
0218   static ImageFactory* factory;
0219 
0220   static QHash<QString, Data::ImageInfo> s_imageInfoMap;
0221   static StringSet s_imagesToRelease;
0222 
0223   ImageFactory();
0224   ~ImageFactory();
0225 
0226   void releaseImages();
0227   void emitImageMismatch();
0228 
0229   class Private;
0230   Private* const d;
0231 };
0232 
0233 } // end namespace
0234 
0235 #endif