1 /*************************************************************************** 2 Copyright (C) 2003-2009 Robby Stephenson <robby@periapsis.org> 3 ***************************************************************************/ 4 5 /*************************************************************************** 6 * * 7 * This program is free software; you can redistribute it and/or * 8 * modify it under the terms of the GNU General Public License as * 9 * published by the Free Software Foundation; either version 2 of * 10 * the License or (at your option) version 3 or any later version * 11 * accepted by the membership of KDE e.V. (or its successor approved * 12 * by the membership of KDE e.V.), which shall act as a proxy * 13 * defined in Section 14 of version 3 of the license. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 22 * * 23 ***************************************************************************/ 24 25 #ifndef TELLICO_IMAGEFACTORY_H 26 #define TELLICO_IMAGEFACTORY_H 27 28 #include "../utils/stringset.h" 29 30 #include <QUrl> 31 #include <QObject> 32 #include <QColor> 33 #include <QHash> 34 #include <QPixmap> 35 36 #include <memory> 37 38 class KZip; 39 class KJob; 40 41 namespace Tellico { 42 namespace Data { 43 class Image; 44 class ImageInfo; 45 } 46 class ImageDirectory; 47 48 class StyleOptions { 49 public: 50 QString fontFamily; 51 int fontSize; 52 QColor baseColor; 53 QColor textColor; 54 QColor highlightedBaseColor; 55 QColor highlightedTextColor; 56 QString imgDir; 57 }; 58 59 /** 60 * @author Robby Stephenson 61 */ 62 class ImageFactory : public QObject { 63 Q_OBJECT 64 65 public: 66 enum CacheDir { 67 TempDir, 68 DataDir, 69 LocalDir, 70 ZipArchive 71 }; 72 73 /** 74 * setup some of the static members 75 */ 76 static void init(); 77 78 /** 79 * Returns the temporary directory where image files are saved 80 * 81 * @return The full path 82 */ 83 static QString tempDir(); 84 static QString dataDir(); 85 static QString localDir(); 86 static QString imageDir(); 87 static CacheDir cacheDir(); 88 89 /** 90 * Add an image, reading it from a URL, which is the case when adding a new image from the 91 * @ref ImageWidget. 92 * 93 * @param url The URL of the image, anything KIO can handle 94 * @param quiet If any error should not be reported. 95 * @return The image id, empty if null 96 */ 97 static QString addImage(const QUrl& url, bool quiet=false, 98 const QUrl& referrer = QUrl(), bool linkOnly=false); 99 /** 100 * Add an image, reading it from a regular QImage, which is the case when dragging and dropping 101 * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't 102 * 'know' what format it came from. 103 * 104 * @param image The qimage 105 * @param format The image format, probably "PNG" 106 * @return The image id, empty if null 107 */ 108 static QString addImage(const QImage& image, const QString& format); 109 static QString addImage(const QPixmap& image, const QString& format); 110 /** 111 * Add an image, reading it from data, which is the case when reading from the data file, and 112 * using the @p format and @p id as the image id. The image id is checked in the image cache 113 * image dict first, and then if it is not found, a new Image is constructed. The new image is 114 * inserted in the dict, and the image info is cached. 115 * 116 * @param data The image data 117 * @param format The image format, from Qt's output format list 118 * @param id The internal id of the image 119 * @return The image id, empty if null 120 */ 121 static QString addImage(const QByteArray& data, const QString& format, const QString& id); 122 123 static bool writeCachedImage(const QString& id, CacheDir dir, bool force = false); 124 static bool writeCachedImage(const QString& id, ImageDirectory* dir, bool force = false); 125 126 /** 127 * Returns an image reference given its id. If none is found, a null image 128 * is returned. 129 * 130 * @param id The image id 131 * @return The image reference 132 */ 133 static const Data::Image& imageById(const QString& id); 134 static bool hasLocalImage(const QString& id); 135 bool hasImageInMemory(const QString& id) const; 136 // just used for testing 137 bool hasNullImage(const QString& id) const; 138 /** 139 * Requests an image to be made available. Images already in the cache or available locally are 140 * considered to be instantly available. Otherwise, the id is assumed to be a URL and is downloaded 141 * The imageAvailable() signal is used to indicate completion and availability of the image. 142 * 143 * @param id The image id 144 */ 145 static void requestImageById(const QString& id); 146 static Data::ImageInfo imageInfo(const QString& id); 147 static void cacheImageInfo(const Data::ImageInfo& info); 148 static bool hasImageInfo(const QString& id); 149 // basically returns !imageById().isNull() 150 static bool validImage(const QString& id); 151 152 static QPixmap pixmap(const QString& id, int w, int h); 153 154 /** 155 * Clear the image cache and dict 156 * if deleteTempDirectory = true, then clean the temp dir and remove all temporary image files 157 */ 158 static void clean(bool deleteTempDirectory); 159 /** 160 * Creates the gradient images used in the entry view. 161 */ 162 static void createStyleImages(int collectionType, const StyleOptions& options = StyleOptions()); 163 164 static void removeImage(const QString& id_, bool deleteImage); 165 static StringSet imagesNotInCache(); 166 167 static QString localDirectory(const QUrl& url); 168 static void setLocalDirectory(const QUrl& url); 169 static void setZipArchive(std::unique_ptr<KZip> zip); 170 171 static ImageFactory* self(); 172 173 Q_SIGNALS: 174 void imageAvailable(const QString& id); 175 void imageLocationMismatch(); 176 177 private Q_SLOTS: 178 void slotImageJobResult(KJob* job); 179 180 private: 181 /** 182 * Add an image, reading it from a URL, which is the case when adding a new image from the 183 * @ref ImageWidget. 184 * 185 * @param url The URL of the image, anything KIO can handle 186 * @param quiet If any error should not be reported. 187 * @return The image 188 */ 189 const Data::Image& addImageImpl(const QUrl& url, bool quiet=false, 190 const QUrl& referrer = QUrl(), bool linkOnly = false); 191 void requestImageByUrlImpl(const QUrl& url, bool quiet=false, 192 const QUrl& referrer = QUrl(), bool linkOnly = false); 193 /** 194 * Add an image, reading it from a regular QImage, which is the case when dragging and dropping 195 * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't 196 * 'know' what format it came from. 197 * 198 * @param image The qimage 199 * @param format The image format, probably "PNG" 200 * @return The image 201 */ 202 const Data::Image& addImageImpl(const QImage& image, const QString& format); 203 /** 204 * Add an image, reading it from data, which is the case when reading from the data file. The 205 * @p id isn't strictly needed, since it can be reconstructed from the image data and format, but 206 * since it's already known, go ahead and use it. 207 * 208 * @param data The image data 209 * @param format The image format, from Qt's output format list 210 * @param id The internal id of the image 211 * @return The image 212 */ 213 const Data::Image& addImageImpl(const QByteArray& data, const QString& format, const QString& id); 214 215 const Data::Image& addCachedImageImpl(const QString& id, CacheDir dir); 216 217 static ImageFactory* factory; 218 219 static QHash<QString, Data::ImageInfo> s_imageInfoMap; 220 static StringSet s_imagesToRelease; 221 222 ImageFactory(); 223 ~ImageFactory(); 224 225 void releaseImages(); 226 void emitImageMismatch(); 227 228 class Private; 229 Private* const d; 230 }; 231 232 } // end namespace 233 234 #endif 235