1 /*******************************************************************************************************
2  DkImageContainer.h
3  Created on:	21.02.2014
4 
5  nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
6 
7  Copyright (C) 2011-2014 Markus Diem <markus@nomacs.org>
8  Copyright (C) 2011-2014 Stefan Fiel <stefan@nomacs.org>
9  Copyright (C) 2011-2014 Florian Kleber <florian@nomacs.org>
10 
11  This file is part of nomacs.
12 
13  nomacs is free software: you can redistribute it and/or modify
14  it under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  nomacs is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 
26  *******************************************************************************************************/
27 
28 #pragma once
29 
30 #pragma warning(push, 0)	// no warnings from includes - begin
31 #include <QFutureWatcher>
32 #include <QTimer>
33 #include <QSharedPointer>
34 #pragma warning(pop)		// no warnings from includes - end
35 
36 #pragma warning(disable: 4251)	// TODO: remove
37 
38 #ifndef DllCoreExport
39 #ifdef DK_CORE_DLL_EXPORT
40 #define DllCoreExport Q_DECL_EXPORT
41 #elif DK_DLL_IMPORT
42 #define DllCoreExport Q_DECL_IMPORT
43 #else
44 #define DllCoreExport Q_DECL_IMPORT
45 #endif
46 #endif
47 
48 #include "DkThumbs.h"
49 
50 namespace nmc {
51 
52 // nomacs defines
53 class DkBasicLoader;
54 class DkMetaDataT;
55 class DkZipContainer;
56 class FileDownloader;
57 class DkRotatingRect;
58 
59 class DllCoreExport DkImageContainer {
60 
61 public:
62 	enum {
63 		loading_canceled = -3,
64 		loading = -2,
65 		exists_not = -1,
66 		not_loaded,
67 		loaded,
68 	};
69 
70 	DkImageContainer(const QString& filePath);
71 	virtual ~DkImageContainer();
72 	bool operator==(const DkImageContainer& ric) const;
73 	bool operator< (const DkImageContainer& o) const;
74 	bool operator<= (const DkImageContainer& o) const;
75 	bool operator> (const DkImageContainer& o) const;
76 	bool operator>= (const DkImageContainer& o) const;
77 
78 	QImage image();
79 	QImage imageScaledToHeight(int height);
80 	QImage imageScaledToWidth(int width);
81 
82 	bool hasImage() const;
83 	bool hasSvg() const;
84 	bool hasMovie() const;
85 
86 	int getLoadState() const;
87 	QFileInfo fileInfo() const;
88 	QString filePath() const;
89 	QString dirPath() const;
90 	QString fileName() const;
91 	bool isFromZip();
92 	bool isEdited() const;
93 	bool isSelected() const;
94 	void setEdited(bool edited);
95 	QString getTitleAttribute() const;
96 	float getMemoryUsage() const;
97 	float getFileSize() const;
98 
99 	virtual QSharedPointer<DkBasicLoader> getLoader();
100 	virtual QSharedPointer<DkMetaDataT> getMetaData();
101 	virtual QSharedPointer<DkThumbNailT> getThumb();
102 	virtual QSharedPointer<QByteArray> getFileBuffer();
103 #ifdef WITH_QUAZIP
104 	QSharedPointer<DkZipContainer> getZipData();
105 #endif
106 #ifdef Q_OS_WIN
107 	std::wstring getFileNameWStr() const;
108 #endif
109 
110 	bool exists();
111 	bool setPageIdx(int skipIdx);
112 
113 	QSharedPointer<QByteArray> loadFileToBuffer(const QString& filePath);
114 	bool loadImage();
115 	void setImage(const QImage& img, const QString& editName);
116 	void setImage(const QImage& img, const QString& editName, const QString& filePath);
117 	bool saveImage(const QString& filePath, const QImage saveImg, int compression = -1);
118 	bool saveImage(const QString& filePath, int compression = -1);
119 	void saveMetaData();
120 	virtual void clear();
121 	virtual void undo();
122 	virtual void redo();
123 	virtual void setHistoryIndex(int idx);
124 	void cropImage(const DkRotatingRect & rect, const QColor & col, bool cropToMetadata);
125 	DkRotatingRect cropRect();
126 
127 protected:
128 	QSharedPointer<DkBasicLoader> loadImageIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, const QSharedPointer<QByteArray> fileBuffer);
129 	void saveMetaDataIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, QSharedPointer<QByteArray> fileBuffer = QSharedPointer<QByteArray>());
130 	QString saveImageIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, QImage saveImg, int compression);
131 	void setFilePath(const QString& filePath);
132 	void init();
133 
134 	QSharedPointer<QByteArray> mFileBuffer;
135 	QSharedPointer<DkBasicLoader> mLoader;
136 	QSharedPointer<DkThumbNailT> mThumb;
137 
138 	int mLoadState	= not_loaded;
139 	bool mEdited	= false;
140 	bool mSelected	= false;
141 
142 	QFileInfo mFileInfo;
143 	QVector<QImage> scaledImages;
144 
145 #ifdef WITH_QUAZIP
146 	QSharedPointer<DkZipContainer> mZipData;
147 #endif
148 #ifdef Q_OS_WIN
149 	std::wstring mFileNameStr;	// speeds up sorting of filenames on windows
150 #endif
151 
152 private:
153 	QString mFilePath;
154 
155 };
156 
157 bool imageContainerLessThan(const DkImageContainer& l, const DkImageContainer& r);
158 bool imageContainerLessThanPtr(const QSharedPointer<DkImageContainer> l, const QSharedPointer<DkImageContainer> r);
159 
160 class DllCoreExport DkImageContainerT : public QObject, public DkImageContainer {
161 	Q_OBJECT
162 
163 public:
164 	DkImageContainerT(const QString& filePath);
165 	virtual ~DkImageContainerT();
166 
167 	void fetchFile();
168 	void cancel();
169 	void clear() override;
170 	void receiveUpdates(QObject* obj, bool connectSignals = true);
171 	void downloadFile(const QUrl& url);
172 
173 	bool loadImageThreaded(bool force = false);
174 	bool saveImageThreaded(const QString& filePath, const QImage saveImg, int compression = -1);
175 	bool saveImageThreaded(const QString& filePath, int compression = -1);
176 	void saveMetaDataThreaded();
177 	bool isFileDownloaded() const;
178 
179 	virtual QSharedPointer<DkBasicLoader> getLoader() override;
180 	virtual QSharedPointer<DkThumbNailT> getThumb() override;
181 	static QSharedPointer<DkImageContainerT> fromImageContainer(QSharedPointer<DkImageContainer> imgC);
182 
183 	virtual void undo() override;
184 	virtual void redo() override;
185 	virtual void setHistoryIndex(int idx) override;
186 
187 signals:
188 	void fileLoadedSignal(bool loaded = true) const;
189 	void fileSavedSignal(const QString& fileInfo, bool saved = true, bool loadToTab = true) const;
190 	void showInfoSignal(const QString& msg, int time = 3000, int position = 0) const;
191 	void errorDialogSignal(const QString& msg) const;
192 	void thumbLoadedSignal(bool loaded = true) const;
193 	void imageUpdatedSignal() const;
194 
195 public slots:
196 	void checkForFileUpdates();
197 
198 protected slots:
199 	void bufferLoaded();
200 	void imageLoaded();
201 	void savingFinished();
202 	void loadingFinished();
203 	void fileDownloaded(const QString& filePath);
204 
205 protected:
206 	void fetchImage();
207 
208 	QSharedPointer<QByteArray> loadFileToBuffer(const QString& filePath);
209 	QSharedPointer<DkBasicLoader> loadImageIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, const QSharedPointer<QByteArray> fileBuffer);
210 	QString saveImageIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, QImage saveImg, int compression);
211 	void saveMetaDataIntern(const QString& filePath, QSharedPointer<DkBasicLoader> loader, QSharedPointer<QByteArray> fileBuffer);
212 
213 	QFutureWatcher<QSharedPointer<QByteArray> > mBufferWatcher;
214 	QFutureWatcher<QSharedPointer<DkBasicLoader> > mImageWatcher;
215 	QFutureWatcher<QString> mSaveImageWatcher;
216 	QFutureWatcher<bool> mSaveMetaDataWatcher;
217 
218 	QSharedPointer<FileDownloader> mFileDownloader;
219 
220 	enum UpdateStates {
221 		update_idle,
222 		update_pending,
223 		update_loading,
224 
225 		update_end
226 	};
227 
228 	int mWaitForUpdate = false;
229 
230 	bool mFetchingImage = false;
231 	bool mFetchingBuffer = false;
232 	bool mDownloaded = false;
233 
234 	QTimer mFileUpdateTimer;
235 };
236 
237 }
238