318 lines
9.4 KiB
C++
318 lines
9.4 KiB
C++
#ifndef STATUSPROVIDER_H
|
|
#define STATUSPROVIDER_H
|
|
|
|
#include "./notification.h"
|
|
|
|
#include <functional>
|
|
#include <vector>
|
|
|
|
namespace Media {
|
|
|
|
class MediaFileInfo;
|
|
|
|
class TAG_PARSER_EXPORT StatusProvider
|
|
{
|
|
// FIXME: make transferNotifications() public in next minor release and get rid of the friend class again
|
|
friend class MediaFileInfo;
|
|
|
|
public:
|
|
typedef std::function<void (StatusProvider &sender)> CallbackFunction;
|
|
typedef std::vector<CallbackFunction> CallbackVector;
|
|
typedef std::pair<int, CallbackFunction> CallbackPair;
|
|
|
|
const NotificationList ¬ifications() const;
|
|
bool hasNotifications() const;
|
|
bool hasCriticalNotifications() const;
|
|
NotificationType worstNotificationType() const;
|
|
const std::string ¤tStatus() const;
|
|
double currentPercentage() const;
|
|
size_t registerCallback(CallbackFunction callback);
|
|
void unregisterCallback(size_t id);
|
|
void unregisterAllCallbacks();
|
|
void forwardStatus(StatusProvider *other = nullptr);
|
|
StatusProvider *usedProvider();
|
|
void tryToAbort();
|
|
bool isAborted() const;
|
|
void invalidateStatus();
|
|
void invalidateNotifications();
|
|
void updateStatus(const std::string &status);
|
|
void updateStatus(const std::string &status, double percentage);
|
|
void updatePercentage(double percentage);
|
|
void addNotification(const Notification ¬ification);
|
|
void addNotification(NotificationType type, const std::string &message, const std::string &context);
|
|
//void addNotifications(const StatusProvider &from);
|
|
//void addNotifications(const std::string &higherContext, const StatusProvider &from);
|
|
//void addNotifications(const NotificationList ¬ifications);
|
|
|
|
protected:
|
|
StatusProvider();
|
|
|
|
private:
|
|
void invokeCallbacks();
|
|
void updateWorstNotificationType(NotificationType notificationType);
|
|
//void transferNotifications(StatusProvider &from);
|
|
|
|
StatusProvider *m_forward;
|
|
std::string m_status;
|
|
double m_percentage;
|
|
CallbackVector m_callbacks;
|
|
NotificationList m_notifications;
|
|
NotificationType m_worstNotificationType;
|
|
bool m_abort;
|
|
};
|
|
|
|
/*!
|
|
* \brief This method is meant to be called by the derived class to report updated status information.
|
|
*/
|
|
inline void StatusProvider::updateStatus(const std::string &status)
|
|
{
|
|
if(m_forward) {
|
|
m_forward->updateStatus(status);
|
|
return;
|
|
}
|
|
m_status = status;
|
|
invokeCallbacks();
|
|
}
|
|
|
|
/*!
|
|
* \brief This method is meant to be called by the derived class to report updated status information.
|
|
*
|
|
* The specified progress \a percentage should be a value between 0 and 1.
|
|
*/
|
|
inline void StatusProvider::updateStatus(const std::string &status, double percentage)
|
|
{
|
|
if(m_forward) {
|
|
m_forward->updateStatus(status, percentage);
|
|
return;
|
|
}
|
|
m_status = status;
|
|
m_percentage = percentage;
|
|
invokeCallbacks();
|
|
}
|
|
|
|
/*!
|
|
* \brief This method is meant to be called by the derived class to report updated progress percentage only.
|
|
*
|
|
* The specified \a percentage should be a value between 0 and 1.
|
|
*/
|
|
inline void StatusProvider::updatePercentage(double percentage)
|
|
{
|
|
if(m_forward) {
|
|
m_forward->updatePercentage(percentage);
|
|
return;
|
|
}
|
|
m_percentage = percentage;
|
|
invokeCallbacks();
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the provider which callback functions will be called when the status or the percentage is updated.
|
|
*
|
|
* The default is the current instance. This can be changed using the forwardStatus() method.
|
|
*/
|
|
inline StatusProvider *StatusProvider::usedProvider()
|
|
{
|
|
return m_forward ? m_forward->usedProvider() : this;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns notifications for the current object.
|
|
*/
|
|
inline const NotificationList &StatusProvider::notifications() const
|
|
{
|
|
return m_notifications;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns an indication whether there are notifications for the current object.
|
|
*/
|
|
inline bool StatusProvider::hasNotifications() const
|
|
{
|
|
return !m_notifications.empty();
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns an indication whether there are critical notifications for the current object.
|
|
*/
|
|
inline bool StatusProvider::hasCriticalNotifications() const
|
|
{
|
|
return m_worstNotificationType == NotificationType::Critical;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the worst notification type.
|
|
*/
|
|
inline NotificationType StatusProvider::worstNotificationType() const
|
|
{
|
|
return m_worstNotificationType;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns a status information for the current object.
|
|
*/
|
|
inline const std::string &StatusProvider::currentStatus() const
|
|
{
|
|
if(m_status.empty() && m_forward) {
|
|
return m_forward->currentStatus();
|
|
}
|
|
return m_status;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the progress percentage of the current object.
|
|
*/
|
|
inline double StatusProvider::currentPercentage() const
|
|
{
|
|
if(m_percentage == 0.0 && m_forward) {
|
|
return m_forward->currentPercentage();
|
|
}
|
|
return m_percentage;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns an indication whether the current operation should be aborted.
|
|
*
|
|
* This flag can be tested when implementing an operation that should be able to be
|
|
* aborted.
|
|
*/
|
|
inline bool StatusProvider::isAborted() const
|
|
{
|
|
return m_abort || (m_forward && m_forward->isAborted());
|
|
}
|
|
|
|
/*!
|
|
* \brief Unregisters a previously registered callback function whith the specified \a id.
|
|
* \param id Specifies the ID of the callback to be unregistered.
|
|
*
|
|
* \sa registerCallback()
|
|
*/
|
|
inline void StatusProvider::unregisterCallback(size_t id)
|
|
{
|
|
if(id < m_callbacks.size()) {
|
|
m_callbacks[id] = nullptr;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Unregisters all callback functions.
|
|
*
|
|
* \sa registerCallback()
|
|
*/
|
|
inline void StatusProvider::unregisterAllCallbacks()
|
|
{
|
|
m_callbacks.clear();
|
|
}
|
|
|
|
/*!
|
|
* \brief Forwards all status updates calls and notifications to the specified \a statusProvider.
|
|
*
|
|
* This basically forwards status information updates and notifications to the specified instance.
|
|
*
|
|
* \remarks
|
|
* - Any notifications will *not* be added to the current instance anymore. Instead the
|
|
* notifications will be added to the specified instance.
|
|
* - The callback methods assigned to the current instance will *not* be called
|
|
* to inform about status updates anymore. Instead the callback methods associated to
|
|
* the specified instance will be called.
|
|
* - The current instance is still passed as the sender when invoking callback methods.
|
|
* - The current instance is also considered as aborted if the specified provider is
|
|
* aborted - even if tryToAbort() has not been called on the current instance.
|
|
* - The current instance will return the status and percentage of the specified
|
|
* provider if it provides no own status or percentage.
|
|
* - Provide nullptr to revert to the default behaviour.
|
|
* - The methods invalidateStatus() and invalidateNotifications() are *not* forwarded.
|
|
* - The methods updateStatus() and updatePercentage() are *not* forwarded.
|
|
* - The method transferNotifications() is *not* forwarded.
|
|
* - Leads to endless recursion if \a statusProvider forwards (indirectly
|
|
* or directly) to the current instance. (So better prevent it.)
|
|
* - Set \a other to nullptr to restore the usual behaviour.
|
|
*/
|
|
inline void StatusProvider::forwardStatus(StatusProvider *other)
|
|
{
|
|
m_forward = other;
|
|
}
|
|
|
|
/*!
|
|
* \brief Commands the object to abort the current operation.
|
|
*
|
|
* If the object is currently not operating calling this method has no effect.
|
|
*
|
|
* The current operation might not be stopped immediately.
|
|
*/
|
|
inline void StatusProvider::tryToAbort()
|
|
{
|
|
m_abort = true;
|
|
}
|
|
|
|
/*!
|
|
* \brief Invalidates the current status.
|
|
*
|
|
* The status, the progress percentage and the "aborted"-flag will be wiped. It is
|
|
* recommend to call this method before performing an operation.
|
|
*
|
|
* This method is meant to be called by the derived class before performing operations
|
|
* to wipe possibly still present previous/obsolet status information.
|
|
*/
|
|
inline void StatusProvider::invalidateStatus()
|
|
{
|
|
m_status.clear();
|
|
m_percentage = 0.0;
|
|
m_abort = false;
|
|
}
|
|
|
|
/*!
|
|
* \brief Invalidates the object's notifications.
|
|
*
|
|
* All notifications will be wiped.
|
|
*/
|
|
inline void StatusProvider::invalidateNotifications()
|
|
{
|
|
m_notifications.clear();
|
|
m_worstNotificationType = NotificationType::None;
|
|
}
|
|
|
|
/*!
|
|
* \brief This method is internally called to invoke the registrated callbacks.
|
|
*/
|
|
inline void StatusProvider::invokeCallbacks()
|
|
{
|
|
for(std::function<void (StatusProvider &sender)> &callback : usedProvider()->m_callbacks) {
|
|
if(callback) {
|
|
callback(*this);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief This method is internally used to update the worst notification type.
|
|
*/
|
|
inline void StatusProvider::updateWorstNotificationType(NotificationType notificationType)
|
|
{
|
|
if(m_forward) {
|
|
m_forward->updateWorstNotificationType(notificationType);
|
|
return;
|
|
}
|
|
if(m_worstNotificationType < notificationType) {
|
|
m_worstNotificationType = notificationType;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Transfers all notifications from the specified status provider to the current instance.
|
|
* \remarks In constrast to the similar addNotifications() overload, this method does not copy the notifications. Instead
|
|
* the notifications are transfered. It also doesn't check whether \a from is the current instance and doesn't
|
|
* invoke callbacks.
|
|
* \deprecated This method should likely be removed after the status provider rework.
|
|
*/
|
|
/*inline void StatusProvider::transferNotifications(StatusProvider &from)
|
|
{
|
|
m_notifications.splice(m_notifications.end(), from.m_notifications);
|
|
m_worstNotificationType |= from.worstNotificationType();
|
|
}*/
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif // STATUSPROVIDER_H
|