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 }