File indexing completed on 2024-05-19 16:19:02

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   QString imgDir;
0057 };
0058 
0059 /**
0060  * @author Robby Stephenson
0061  */
0062 class ImageFactory : public QObject {
0063 Q_OBJECT
0064 
0065 public:
0066   enum CacheDir {
0067     TempDir,
0068     DataDir,
0069     LocalDir,
0070     ZipArchive
0071   };
0072 
0073   /**
0074    * setup some of the static members
0075    */
0076   static void init();
0077 
0078   /**
0079    * Returns the temporary directory where image files are saved
0080    *
0081    * @return The full path
0082    */
0083   static QString tempDir();
0084   static QString dataDir();
0085   static QString localDir();
0086   static QString imageDir();
0087   static CacheDir cacheDir();
0088 
0089   /**
0090    * Add an image, reading it from a URL, which is the case when adding a new image from the
0091    * @ref ImageWidget.
0092    *
0093    * @param url The URL of the image, anything KIO can handle
0094    * @param quiet If any error should not be reported.
0095    * @return The image id, empty if null
0096    */
0097   static QString addImage(const QUrl& url, bool quiet=false,
0098                           const QUrl& referrer = QUrl(), bool linkOnly=false);
0099   /**
0100    * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
0101    * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
0102    * 'know' what format it came from.
0103    *
0104    * @param image The qimage
0105    * @param format The image format, probably "PNG"
0106    * @return The image id, empty if null
0107    */
0108   static QString addImage(const QImage& image, const QString& format);
0109   static QString addImage(const QPixmap& image, const QString& format);
0110   /**
0111    * Add an image, reading it from data, which is the case when reading from the data file, and
0112    * using the @p format and @p id as the image id. The image id is checked in the image cache
0113    * image dict first, and then if it is not found, a new Image is constructed. The new image is
0114    * inserted in the dict, and the image info is cached.
0115    *
0116    * @param data The image data
0117    * @param format The image format, from Qt's output format list
0118    * @param id The internal id of the image
0119    * @return The image id, empty if null
0120    */
0121   static QString addImage(const QByteArray& data, const QString& format, const QString& id);
0122 
0123   static bool writeCachedImage(const QString& id, CacheDir dir, bool force = false);
0124   static bool writeCachedImage(const QString& id, ImageDirectory* dir, bool force = false);
0125 
0126   /**
0127    * Returns an image reference given its id. If none is found, a null image
0128    * is returned.
0129    *
0130    * @param id The image id
0131    * @return The image reference
0132    */
0133   static const Data::Image& imageById(const QString& id);
0134   static bool hasLocalImage(const QString& id);
0135   bool hasImageInMemory(const QString& id) const;
0136   // just used for testing
0137   bool hasNullImage(const QString& id) const;
0138   /**
0139    * Requests an image to be made available. Images already in the cache or available locally are
0140    * considered to be instantly available. Otherwise, the id is assumed to be a URL and is downloaded
0141    * The imageAvailable() signal is used to indicate completion and availability of the image.
0142    *
0143    * @param id The image id
0144    */
0145   static void requestImageById(const QString& id);
0146   static Data::ImageInfo imageInfo(const QString& id);
0147   static void cacheImageInfo(const Data::ImageInfo& info);
0148   static bool hasImageInfo(const QString& id);
0149   // basically returns !imageById().isNull()
0150   static bool validImage(const QString& id);
0151 
0152   static QPixmap pixmap(const QString& id, int w, int h);
0153 
0154   /**
0155    * Clear the image cache and dict
0156    * if deleteTempDirectory = true, then clean the temp dir and remove all temporary image files
0157    */
0158   static void clean(bool deleteTempDirectory);
0159   /**
0160    * Creates the gradient images used in the entry view.
0161    */
0162   static void createStyleImages(int collectionType, const StyleOptions& options = StyleOptions());
0163 
0164   static void removeImage(const QString& id_, bool deleteImage);
0165   static StringSet imagesNotInCache();
0166 
0167   static QString localDirectory(const QUrl& url);
0168   static void setLocalDirectory(const QUrl& url);
0169   static void setZipArchive(std::unique_ptr<KZip> zip);
0170 
0171   static ImageFactory* self();
0172 
0173 Q_SIGNALS:
0174   void imageAvailable(const QString& id);
0175   void imageLocationMismatch();
0176 
0177 private Q_SLOTS:
0178   void slotImageJobResult(KJob* job);
0179 
0180 private:
0181   /**
0182    * Add an image, reading it from a URL, which is the case when adding a new image from the
0183    * @ref ImageWidget.
0184    *
0185    * @param url The URL of the image, anything KIO can handle
0186    * @param quiet If any error should not be reported.
0187    * @return The image
0188    */
0189   const Data::Image& addImageImpl(const QUrl& url, bool quiet=false,
0190                                   const QUrl& referrer = QUrl(), bool linkOnly = false);
0191   void requestImageByUrlImpl(const QUrl& url, bool quiet=false,
0192                              const QUrl& referrer = QUrl(), bool linkOnly = false);
0193   /**
0194    * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
0195    * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
0196    * 'know' what format it came from.
0197    *
0198    * @param image The qimage
0199    * @param format The image format, probably "PNG"
0200    * @return The image
0201    */
0202   const Data::Image& addImageImpl(const QImage& image, const QString& format);
0203   /**
0204    * Add an image, reading it from data, which is the case when reading from the data file. The
0205    * @p id isn't strictly needed, since it can be reconstructed from the image data and format, but
0206    * since it's already known, go ahead and use it.
0207    *
0208    * @param data The image data
0209    * @param format The image format, from Qt's output format list
0210    * @param id The internal id of the image
0211    * @return The image
0212    */
0213   const Data::Image& addImageImpl(const QByteArray& data, const QString& format, const QString& id);
0214 
0215   const Data::Image& addCachedImageImpl(const QString& id, CacheDir dir);
0216 
0217   static ImageFactory* factory;
0218 
0219   static QHash<QString, Data::ImageInfo> s_imageInfoMap;
0220   static StringSet s_imagesToRelease;
0221 
0222   ImageFactory();
0223   ~ImageFactory();
0224 
0225   void releaseImages();
0226   void emitImageMismatch();
0227 
0228   class Private;
0229   Private* const d;
0230 };
0231 
0232 } // end namespace
0233 
0234 #endif