1 /*******************************************************************************************************
2  DkProcess.h
3  Created on:	27.12.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 <QSharedPointer>
32 #include <QFutureWatcher>
33 #include <QFileInfo>
34 #include <QDir>
35 #include <QStringList>
36 #include <QUrl>
37 #pragma warning(pop)		// no warnings from includes - end
38 
39 #include "DkBatchInfo.h"
40 #include "DkManipulators.h"
41 
42 #pragma warning(disable: 4251)	// TODO: remove
43 
44 #ifndef DllCoreExport
45 #ifdef DK_CORE_DLL_EXPORT
46 #define DllCoreExport Q_DECL_EXPORT
47 #elif DK_DLL_IMPORT
48 #define DllCoreExport Q_DECL_IMPORT
49 #else
50 #define DllCoreExport Q_DECL_IMPORT
51 #endif
52 #endif
53 
54 // Qt defines
55 class QImage;
56 class QSettings;
57 
58 namespace nmc {
59 
60 // nomacs defines
61 class DkImageContainer;
62 class DkPluginContainer;
63 class DkBaseManipulator;
64 class DkMetaDataT;
65 
66 class DllCoreExport DkAbstractBatch {
67 
68 public:
DkAbstractBatch()69 	DkAbstractBatch() {};
70 
setProperties(...)71 	virtual void setProperties(...) {};
saveSettings(QSettings &)72 	virtual void saveSettings(QSettings&) const {};
loadSettings(QSettings &)73 	virtual void loadSettings(QSettings&) {};
74 	virtual bool compute(
75 		QSharedPointer<DkImageContainer> container,
76 		const DkSaveInfo& saveInfo,
77 		QStringList& logStrings,
78 		QVector<QSharedPointer<DkBatchInfo> >& batchInfos) const;
79 	virtual bool compute(QSharedPointer<DkImageContainer> container, QStringList& logStrings) const;
compute(QImage &,QStringList &)80 	virtual bool compute(QImage&, QStringList&) const { return true; };
isActive()81 	virtual bool isActive() const { return false; };
postLoad(const QVector<QSharedPointer<DkBatchInfo>> &)82 	virtual void postLoad(const QVector<QSharedPointer<DkBatchInfo> >&) const {};
83 
name()84 	virtual QString name() const {return "Abstract Batch";};
85 	QString settingsName() const;
86 
87 	static QSharedPointer<DkAbstractBatch> createFromName(const QString& settingsName);
88 
89 private:
90 	// ok, this is important:
91 	// we are using the abstract class to process specialized items
92 	// if we allow copy operations - we get slicing issues
93 	// so we just allow pointers to the batch processing functions.
94 	// but pointers result in threading issues - so we just use
95 	// QSharedPointers -> problem solved : )
96 	DkAbstractBatch(const DkAbstractBatch& o);
97 	DkAbstractBatch& operator=( const DkAbstractBatch& o);
98 
99 };
100 
101 #ifdef WITH_PLUGINS
102 class DllCoreExport DkPluginBatch : public DkAbstractBatch {
103 
104 public:
105 	DkPluginBatch();
106 
107 	virtual void saveSettings(QSettings& settings) const override;
108 	virtual void loadSettings(QSettings& settings) override;
109 
110 	virtual void preLoad();
111 	virtual void postLoad(const QVector<QSharedPointer<DkBatchInfo> >& batchInfo) const override;
112 	virtual void setProperties(const QStringList& pluginList);
113 	virtual bool compute(
114 		QSharedPointer<DkImageContainer> container,
115 		const DkSaveInfo& saveInfo,
116 		QStringList& logStrings,
117 		QVector<QSharedPointer<DkBatchInfo> >& batchInfos) const override;
118 	virtual QString name() const override;
119 	virtual bool isActive() const override;
120 	virtual QStringList pluginList() const;
121 
122 protected:
123 	void loadAllPlugins();
124 	void loadPlugin(const QString& pluginString, QSharedPointer<DkPluginContainer>& plugin, QString& runID) const;
125 
126 	QVector<QSharedPointer<DkPluginContainer> > mPlugins;
127 	QStringList mRunIDs;
128 	QStringList mPluginList;
129 };
130 #endif
131 
132 class DllCoreExport DkManipulatorBatch : public DkAbstractBatch {
133 
134 public:
135 	DkManipulatorBatch();
136 
137 	virtual void saveSettings(QSettings& settings) const override;
138 	virtual void loadSettings(QSettings& settings) override;
139 
140 	virtual void setProperties(const DkManipulatorManager& manager);
141 	virtual bool compute(
142 		QSharedPointer<DkImageContainer> container,
143 		QStringList& logStrings) const override;
144 	virtual QString name() const override;
145 	virtual bool isActive() const override;
146 
147 	DkManipulatorManager manager() const;
148 
149 protected:
150 	DkManipulatorManager mManager;
151 };
152 
153 class DllCoreExport DkBatchTransform : public DkAbstractBatch {
154 
155 public:
156 	DkBatchTransform();
157 
158 	enum ResizeMode {
159 		resize_mode_default,
160 		resize_mode_long_side,
161 		resize_mode_short_side,
162 		resize_mode_width,
163 		resize_mode_height,
164 
165 		resize_mode_end
166 	};
167 
168 	enum ResizeProperty {
169 		resize_prop_default,
170 		resize_prop_decrease_only,
171 		resize_prop_increase_only,
172 
173 		resize_prop_end
174 	};
175 
176 	virtual void saveSettings(QSettings& settings) const override;
177 	virtual void loadSettings(QSettings& settings) override;
178 
179 	virtual void setProperties(
180 		int angle,
181 		bool cropFromMetadata,
182 		QRect cropRect,
183 		float scaleFactor,
184 		const ResizeMode& mode = resize_mode_default,
185 		const ResizeProperty& prop = resize_prop_default,
186 		int iplMethod = 1/*DkImage::ipl_area*/,
187 		bool correctGamma = false
188 		);
189 
190 	virtual bool compute(QSharedPointer<DkImageContainer> container, QStringList& logStrings) const override;
191 	virtual QString name() const override;
192 	virtual bool isActive() const override;
193 
194 	int angle() const;
195 	bool cropMetatdata() const;
196 	bool cropFromRectangle() const;
197 	QRect cropRectangle() const;
198 
199 	// resize
200 	ResizeMode mode() const;
201 	ResizeProperty prop() const;
202 	int iplMethod() const;
203 	float scaleFactor() const;
204 	bool correctGamma() const;
205 
206 protected:
207 	bool prepareProperties(const QSize& imgSize, QSize& size, float& scaleFactor, QStringList& logStrings) const;
208 	bool isResizeActive() const;
209 	QString rectToString(const QRect& r) const;
210 	QRect stringToRect(const QString& s) const;
211 
212 	int mAngle = 0;
213 	bool mCropFromMetadata = false;
214 
215 	ResizeMode mResizeMode = resize_mode_default;
216 	ResizeProperty mResizeProperty = resize_prop_default;
217 	float mResizeScaleFactor = 1.0f;
218 	int mResizeIplMethod = 0;
219 	bool mResizeCorrectGamma = false;
220 
221 	QRect mCropRect;
222 };
223 
224 class DllCoreExport DkBatchProcess {
225 
226 public:
227 	DkBatchProcess(const DkSaveInfo& saveInfo = DkSaveInfo());
228 
229 	void setProcessChain(const QVector<QSharedPointer<DkAbstractBatch> > processes);
230 	bool compute();	// do the work
231 	QStringList getLog() const;
232 	bool hasFailed() const;
233 	bool wasProcessed() const;
234 	QString inputFile() const;
235 	QString outputFile() const;
236 
237 	QVector<QSharedPointer<DkBatchInfo> > batchInfo() const;
238 
239 protected:
240 	bool process();
241 	bool prepareDeleteExisting();
242 	bool deleteOrRestoreExisting();
243 	bool deleteOriginalFile();
244 	bool copyFile();
245 	bool renameFile();
246 	bool updateMetaData(DkMetaDataT* md);
247 
248 	DkSaveInfo mSaveInfo;
249 	int mFailure = 0;
250 	bool mIsProcessed = false;
251 
252 	QVector<QSharedPointer<DkBatchInfo> > mInfos;
253 	QVector<QSharedPointer<DkAbstractBatch> > mProcessFunctions;
254 	QStringList mLogStrings;
255 };
256 
257 class DllCoreExport DkBatchConfig {
258 
259 public:
DkBatchConfig()260 	DkBatchConfig() { };
261 	DkBatchConfig(const QStringList& fileList, const QString& outputDir, const QString& fileNamePattern);
262 
263 	virtual void saveSettings(QSettings& settings) const;
264 	virtual void loadSettings(QSettings& settings);
265 
266 	bool isOk() const;
267 
setFileList(const QStringList & fileList)268 	void setFileList(const QStringList& fileList) { mFileList = fileList; };
setOutputDir(const QString & outputDir)269 	void setOutputDir(const QString& outputDir) { mOutputDirPath = outputDir; };
setFileNamePattern(const QString & pattern)270 	void setFileNamePattern(const QString& pattern) { mFileNamePattern = pattern; };
setProcessFunctions(const QVector<QSharedPointer<DkAbstractBatch>> & processFunctions)271 	void setProcessFunctions(const QVector<QSharedPointer<DkAbstractBatch> >& processFunctions) { mProcessFunctions = processFunctions; };
setSaveInfo(const DkSaveInfo & saveInfo)272 	void setSaveInfo(const DkSaveInfo& saveInfo) { mSaveInfo = saveInfo; };
273 
getFileList()274 	QStringList getFileList() const { return mFileList; };
getOutputDirPath()275 	QString getOutputDirPath() const { return mOutputDirPath; };
getFileNamePattern()276 	QString getFileNamePattern() const { return mFileNamePattern; };
getProcessFunctions()277 	QVector<QSharedPointer<DkAbstractBatch> > getProcessFunctions() const { return mProcessFunctions; };
saveInfo()278 	DkSaveInfo saveInfo() const { return mSaveInfo; };
279 
280 protected:
281 
282 	DkSaveInfo mSaveInfo;
283 
284 	QStringList mFileList;
285 	QString mOutputDirPath;
286 	QString mFileNamePattern;
287 
288 	QVector<QSharedPointer<DkAbstractBatch> > mProcessFunctions;
289 };
290 
291 class DllCoreExport DkBatchProcessing : public QObject {
292 	Q_OBJECT
293 
294 public:
295 
296 	enum {
297 		batch_item_failed,
298 		batch_item_succeeded,
299 		batch_item_not_computed,
300 
301 		batch_item_end
302 	};
303 
304 	DkBatchProcessing(const DkBatchConfig& config = DkBatchConfig(), QWidget* parent = 0);
305 
306 	void compute();
307 	static bool computeItem(DkBatchProcess& item);
308 
309 	QStringList getLog() const;
310 	int getNumFailures() const;
311 	int getNumItems() const;
312 	int getNumProcessed() const;
313 
314 	bool isComputing() const;
315 	QList<int> getCurrentResults();
316 	QStringList getResultList() const;
317 	QString getBatchSummary(const DkBatchProcess& batch) const;
318 	void waitForFinished();
319 
320 	// getter, setter
setBatchConfig(const DkBatchConfig & config)321 	void setBatchConfig(const DkBatchConfig& config) { mBatchConfig = config; };
getBatchConfig()322 	DkBatchConfig getBatchConfig() const { return mBatchConfig; };
323 
324 	void postLoad();
325 
326 	static void computeBatch(const QString& settingsPath, const QString& logPath);
327 
328 public slots:
329 	// user interaction
330 	void cancel();
331 
332 signals:
333 	void progressValueChanged(int idx);
334 	void finished();
335 
336 protected:
337 	DkBatchConfig mBatchConfig;
338 	QVector<DkBatchProcess> mBatchItems;
339 	QList<int> mResList;
340 
341 	// threading
342 	QFutureWatcher<void> mBatchWatcher;
343 
344 	void init();
345 };
346 
347 class DllCoreExport DkBatchProfile {
348 
349 public:
350 	DkBatchProfile(const QString& profileDir = QString());
351 
352 	static DkBatchConfig loadProfile(const QString& profilePath);
353 	static bool saveProfile(const QString& profilePath, const DkBatchConfig& batchConfig);
354 	static QString defaultProfilePath();
355 	static QString profileNameToPath(const QString& profileName);
356 	static QString makeUserFriendly(const QString& profilePath);
357 	static QString extension();
358 
359 	QStringList profileNames();
360 
361 protected:
362 	QStringList index(const QString& profileDir) const;
363 
364 	QString mProfileDir;
365 	QStringList mProfilePaths;
366 	static QString ext;
367 };
368 
369 }