File indexing completed on 2024-05-12 04:19:37
0001 /* 0002 Gwenview: an image viewer 0003 Copyright 2007 Aurélien Gâteau <agateau@kde.org> 0004 0005 This program is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU General Public License 0007 as published by the Free Software Foundation; either version 2 0008 of the License, or (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0018 0019 */ 0020 #ifndef DOCUMENT_H 0021 #define DOCUMENT_H 0022 0023 #include <lib/gwenviewlib_export.h> 0024 0025 // STL 0026 #include <memory> 0027 0028 // Qt 0029 #include <QObject> 0030 #include <QSharedData> 0031 #include <QSize> 0032 0033 // Local 0034 #include <lib/cms/cmsprofile.h> 0035 #include <lib/mimetypeutils.h> 0036 0037 class QImage; 0038 class QRect; 0039 class QSvgRenderer; 0040 class QUndoStack; 0041 0042 class KJob; 0043 class QUrl; 0044 0045 namespace Exiv2 0046 { 0047 class Image; 0048 } 0049 0050 namespace Gwenview 0051 { 0052 class AbstractDocumentEditor; 0053 class AbstractDocumentImpl; 0054 class DocumentJob; 0055 class DocumentFactory; 0056 struct DocumentPrivate; 0057 class ImageMetaInfoModel; 0058 0059 /** 0060 * This class represents an image. 0061 * 0062 * It handles loading and saving the image, applying operations and maintaining 0063 * the document undo stack. 0064 * 0065 * It is capable of loading down sampled versions of an image using 0066 * prepareDownSampledImageForZoom() and downSampledImageForZoom(). Down sampled 0067 * images load much faster than the full image but you need to load the full 0068 * image to manipulate it (use startLoadingFullImage() to do so). 0069 * 0070 * To get a Document instance for url, ask for one with 0071 * DocumentFactory::instance()->load(url); 0072 */ 0073 class GWENVIEWLIB_EXPORT Document : public QObject, public QSharedData 0074 { 0075 Q_OBJECT 0076 public: 0077 /** 0078 * Document won't produce down sampled images for any zoom value higher than maxDownSampledZoom(). 0079 * 0080 * Note: We can't use the enum {} trick to declare this constant, that's 0081 * why it's defined as a static method 0082 */ 0083 static qreal maxDownSampledZoom(); 0084 0085 enum LoadingState { 0086 Loading, ///< Image is loading 0087 KindDetermined, ///< Image is still loading, but kind has been determined 0088 MetaInfoLoaded, ///< Image is still loading, but meta info has been loaded 0089 Loaded, ///< Full image has been loaded 0090 LoadingFailed, ///< Image loading has failed 0091 }; 0092 0093 using Ptr = QExplicitlySharedDataPointer<Document>; 0094 ~Document() override; 0095 0096 /** 0097 * Returns a message for the last error which happened 0098 */ 0099 QString errorString() const; 0100 0101 void reload(); 0102 0103 void startLoadingFullImage(); 0104 0105 /** 0106 * Prepare a version of the image down sampled to be a bit bigger than 0107 * size() * @a zoom. 0108 * Do not ask for a down sampled image for @a zoom >= to MaxDownSampledZoom. 0109 * 0110 * @return true if the image is ready, false if not. In this case the 0111 * downSampledImageReady() signal will be emitted. 0112 */ 0113 bool prepareDownSampledImageForZoom(qreal zoom); 0114 0115 LoadingState loadingState() const; 0116 0117 MimeTypeUtils::Kind kind() const; 0118 0119 bool isModified() const; 0120 0121 const QImage &image() const; 0122 0123 const QImage &downSampledImageForZoom(qreal zoom) const; 0124 0125 /** 0126 * Returns an implementation of AbstractDocumentEditor if this document can 0127 * be edited. 0128 */ 0129 AbstractDocumentEditor *editor(); 0130 0131 QUrl url() const; 0132 0133 DocumentJob *save(const QUrl &url, const QByteArray &format); 0134 0135 QByteArray format() const; 0136 0137 void waitUntilLoaded(); 0138 0139 QSize size() const; 0140 0141 int width() const 0142 { 0143 return size().width(); 0144 } 0145 0146 int height() const 0147 { 0148 return size().height(); 0149 } 0150 0151 bool hasAlphaChannel() const; 0152 0153 ImageMetaInfoModel *metaInfo() const; 0154 0155 QUndoStack *undoStack() const; 0156 0157 void setKeepRawData(bool); 0158 0159 bool keepRawData() const; 0160 0161 /** 0162 * Returns how much bytes the document is using 0163 */ 0164 int memoryUsage() const; 0165 0166 /** 0167 * Returns the compressed version of the document, if it is still 0168 * available. 0169 */ 0170 QByteArray rawData() const; 0171 0172 Cms::Profile::Ptr cmsProfile() const; 0173 0174 /** 0175 * Returns a QSvgRenderer which can be used to render this document if it is 0176 * an SVG image. Returns a NULL pointer otherwise. 0177 */ 0178 QSvgRenderer *svgRenderer() const; 0179 0180 /** 0181 * Returns true if the image can be edited. 0182 * You must ensure it has been fully loaded with startLoadingFullImage() first. 0183 */ 0184 bool isEditable() const; 0185 0186 /** 0187 * Returns true if the image is animated (eg: gif or mng format) 0188 */ 0189 bool isAnimated() const; 0190 0191 /** 0192 * Starts animation. Only sensible if isAnimated() returns true. 0193 */ 0194 void startAnimation(); 0195 0196 /** 0197 * Stops animation. Only sensible if isAnimated() returns true. 0198 */ 0199 void stopAnimation(); 0200 0201 void enqueueJob(DocumentJob *); 0202 0203 void imageOperationCompleted(); 0204 0205 /** 0206 * Returns true if there are queued tasks for this document. 0207 */ 0208 bool isBusy() const; 0209 0210 Q_SIGNALS: 0211 void downSampledImageReady(); 0212 void imageRectUpdated(const QRect &); 0213 void kindDetermined(const QUrl &); 0214 void metaInfoLoaded(const QUrl &); 0215 void loaded(const QUrl &); 0216 void loadingFailed(const QUrl &); 0217 void saved(const QUrl &oldUrl, const QUrl &newUrl); 0218 void modified(const QUrl &); 0219 void metaInfoUpdated(); 0220 void isAnimatedUpdated(); 0221 void busyChanged(const QUrl &, bool); 0222 void allTasksDone(); 0223 0224 private Q_SLOTS: 0225 void emitMetaInfoLoaded(); 0226 void emitLoaded(); 0227 void emitLoadingFailed(); 0228 void slotSaveResult(KJob *); 0229 void slotJobFinished(KJob *); 0230 0231 private: 0232 friend class AbstractDocumentImpl; 0233 friend class DocumentFactory; 0234 friend struct DocumentPrivate; 0235 friend class DownSamplingJob; 0236 0237 void setImageInternal(const QImage &); 0238 void setKind(MimeTypeUtils::Kind); 0239 void setFormat(const QByteArray &); 0240 void setSize(const QSize &); 0241 void setExiv2Image(std::unique_ptr<Exiv2::Image>); 0242 void setDownSampledImage(const QImage &, int invertedZoom); 0243 void switchToImpl(AbstractDocumentImpl *impl); 0244 void setErrorString(const QString &); 0245 void setCmsProfile(const Cms::Profile::Ptr &); 0246 0247 Document(const QUrl &); 0248 DocumentPrivate *const d; 0249 }; 0250 0251 } // namespace 0252 0253 #endif /* DOCUMENT_H */