You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/threadimageio/loadsavethread.h

185 lines
6.0 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-12-17
* Description : image file IO threaded interface.
*
* Copyright (C) 2005-2006 by Marcel Wiesweg <marcel.wiesweg@gmx.de>
* Copyright (C) 2005-2006 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
* either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
#ifndef LOAD_SAVE_THREAD_H
#define LOAD_SAVE_THREAD_H
// TQt includes.
#include <tqthread.h>
#include <tqobject.h>
#include <tqmutex.h>
#include <tqptrlist.h>
#include <tqdatetime.h>
#include <tqwaitcondition.h>
// Digikam includes.
#include "dimg.h"
#include "digikam_export.h"
#include "loadingdescription.h"
namespace Digikam
{
class LoadSaveThreadPriv;
class LoadSaveTask;
class DIGIKAM_EXPORT LoadSaveThread : public TQObject, public TQThread
{
TQ_OBJECT
public:
enum NotificationPolicy
{
/** Always send notification, unless the last event is still in the event queue */
NotificationPolicyDirect,
/**
* Always wait for a certain amount of time after the last event sent.
* In particular, the first event will be sent only after waiting for this time span.
* (Or no event will be sent, when the loading has finished before)
* This is the default.
*/
NotificationPolicyTimeLimited
};
// used by SharedLoadSaveThread only
enum AccessMode
{
// image will only be used for reading
AccessModeRead,
// image data will possibly be changed
AccessModeReadWrite
};
LoadSaveThread();
/**
* Destructor:
* The thread will execute all pending tasks and wait for this upon destruction
*/
~LoadSaveThread();
/** Append a task to load the given file to the task list */
void load(LoadingDescription description);
/** Append a task to save the image to the task list */
void save(DImg &image, const TQString& filePath, const TQString &format);
void setNotificationPolicy(NotificationPolicy notificationPolicy);
bool isShuttingDown();
/**
* Utility to make sure that an image is rotated according to exif tag.
* Detects if an image has previously already been rotated: You can
* call this method more than one time on the same image.
* Returns true if the image has actually been rotated or flipped.
* Returns false if a rotation was not needed.
*/
static bool exifRotate(DImg &image, const TQString& filePath);
signals:
/** This signal is emitted when the loading process begins. */
void signalImageStartedLoading(const LoadingDescription &loadingDescription);
/**
* This signal is emitted whenever new progress info is available
* and the notification policy allows emitting the signal.
* No progress info will be sent for preloaded images (ManagedLoadSaveThread).
*/
void signalLoadingProgress(const LoadingDescription &loadingDescription, float progress);
/**
* This signal is emitted when the loading process has finished.
* If the process failed, img is null.
*/
void signalImageLoaded(const LoadingDescription &loadingDescription, const DImg& img);
/**
* This signal is emitted if
* - you are doing shared loading (SharedLoadSaveThread)
* - you started a loading operation with a LoadingDescription for
* a reduced version of the image
* - another thread started a loading operation for a more complete version
* You may want to cancel the current operation and start with the given loadingDescription
*/
void signalMoreCompleteLoadingAvailable(const LoadingDescription &oldLoadingDescription,
const LoadingDescription &newLoadingDescription);
void signalImageStartedSaving(const TQString& filePath);
void signalSavingProgress(const TQString& filePath, float progress);
void signalImageSaved(const TQString& filePath, bool success);
public:
void imageStartedLoading(const LoadingDescription &loadingDescription)
{ emit signalImageStartedLoading(loadingDescription); };
void loadingProgress(const LoadingDescription &loadingDescription, float progress)
{ emit signalLoadingProgress(loadingDescription, progress); };
void imageLoaded(const LoadingDescription &loadingDescription, const DImg& img)
{ emit signalImageLoaded(loadingDescription, img); };
void moreCompleteLoadingAvailable(const LoadingDescription &oldLoadingDescription,
const LoadingDescription &newLoadingDescription)
{ emit signalMoreCompleteLoadingAvailable(oldLoadingDescription, newLoadingDescription); }
void imageStartedSaving(const TQString& filePath)
{ emit signalImageStartedSaving(filePath); };
void savingProgress(const TQString& filePath, float progress)
{ emit signalSavingProgress(filePath, progress); };
void imageSaved(const TQString& filePath, bool success)
{ emit signalImageSaved(filePath, success); };
virtual bool querySendNotifyEvent();
virtual void taskHasFinished();
protected:
virtual void run();
virtual void customEvent(TQCustomEvent *event);
TQMutex m_mutex;
TQWaitCondition m_condVar;
TQPtrList<LoadSaveTask> m_todo;
LoadSaveTask *m_currentTask;
NotificationPolicy m_notificationPolicy;
private:
LoadSaveThreadPriv* d;
};
} // namespace Digikam
#endif // LOAD_SAVE_THREAD_H