File indexing completed on 2024-05-05 04:48:15
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #ifndef AMAROK_LOGGER_H 0018 #define AMAROK_LOGGER_H 0019 0020 #include "core/amarokcore_export.h" 0021 0022 #include <QMetaMethod> 0023 #include <QMutex> 0024 #include <QObject> 0025 0026 #include <functional> 0027 0028 0029 class KJob; 0030 class QNetworkReply; 0031 struct ShortMessage; 0032 struct LongMessage; 0033 struct ProgressData; 0034 0035 namespace Amarok 0036 { 0037 /** 0038 * This class provides methods that allow backend components to notify the user. 0039 * Users of this class may not make assumptions about the kind of notifications that 0040 * will be sent to the user. 0041 * 0042 * The class name is up for discussion btw. 0043 */ 0044 class AMAROKCORE_EXPORT Logger 0045 { 0046 public: 0047 enum MessageType { Information, Warning, Error }; 0048 0049 Logger(); 0050 virtual ~Logger(); 0051 0052 /** 0053 * Informs the user about the progress of a job, i.e. a download job. 0054 * At the very least, the user is notified about the start and end of the job. 0055 * 0056 * @param job The job whose progress should be monitored 0057 * @param text An additional text that will be part of the notification 0058 * @param obj The object that will be called if the user cancels the job. If not set, the job will not be cancellable 0059 * @param slot The slot on the given object that will be called if the user cancels the job. No slot will be called if not set. 0060 * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender 0061 * @param type The Qt connection type to use for the connection to the receiving slot. Defaults to Qt::AutoConnection 0062 */ 0063 template<class Object = QObject, class Func = void (QObject::*)()> 0064 static void newProgressOperation( KJob *job, const QString &text, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection ) 0065 { 0066 if( !job ) 0067 return; 0068 0069 std::function<void ()> function = std::bind( slot, obj ); 0070 addProgressOperation( job, nullptr, nullptr, QMetaMethod(), QMetaMethod(), text, 100, obj, obj ? function : nullptr, type ); 0071 } 0072 0073 /** 0074 * Informs the user about the progress of a job, i.e. a download job. 0075 * At the very least, the user is notified about the start and end of the job. 0076 * 0077 * @param job The job whose progress should be monitored 0078 * @param text An additional text that will be part of the notification 0079 * @param obj The object that will be called if the user cancels the job. 0080 * @param slot The slot on the given object that will be called if the user cancels the job. 0081 * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender 0082 * @param type The Qt connection type to use for the connection to the receiving slot. 0083 * @param args Arguments given to the slot. 0084 */ 0085 template<class Object = QObject, class Func = void (QObject::*)(), class... FuncArgs> 0086 static void newProgressOperation( KJob *job, const QString &text, Object *obj, Func slot, Qt::ConnectionType type, FuncArgs... args ) 0087 { 0088 if( !job ) 0089 return; 0090 0091 std::function<void ()> function = std::bind( slot, obj, args... ); 0092 addProgressOperation( job, nullptr, nullptr, QMetaMethod(), QMetaMethod(), text, 100, obj, obj ? function : nullptr, type ); 0093 } 0094 0095 /** 0096 * Informs the user about the progress of a network request. 0097 * At the very least, the user is notified about the start and end of the request. 0098 * 0099 * @param reply The network reply object whose progress should be monitored 0100 * @param text An additional text that will be part of the notification 0101 * @param obj The object that will be called if the user cancels the network request. If not set, the progress will not be cancellable 0102 * @param slot The slot on the given object that will be called if the user cancels the network request. No slot will be called if not set. 0103 * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender 0104 * @param type The Qt connection type to use for the connection to the receiving slot. Defaults to Qt::AutoConnection 0105 */ 0106 template<class Object = QObject, class Func = void (QObject::*)()> 0107 static void newProgressOperation( QNetworkReply *reply, const QString &text, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection ) 0108 { 0109 if( !reply ) 0110 return; 0111 0112 std::function<void ()> function = std::bind( slot, obj ); 0113 addProgressOperation( nullptr, reply, nullptr, QMetaMethod(), QMetaMethod(), text, 100, obj, obj ? function : nullptr, type ); 0114 } 0115 0116 /** 0117 * Informs the user about the progress of a network request. 0118 * At the very least, the user is notified about the start and end of the request. 0119 * 0120 * @param reply The network reply object whose progress should be monitored 0121 * @param text An additional text that will be part of the notification 0122 * @param obj The object that will be called if the user cancels the network request. 0123 * @param slot The slot on the given object that will be called if the user cancels the network request. 0124 * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender 0125 * @param type The Qt connection type to use for the connection to the receiving slot. 0126 * @param args Arguments given to the slot. 0127 */ 0128 template<class Object = QObject, class Func = void (QObject::*)(), class... FuncArgs> 0129 static void newProgressOperation( QNetworkReply *reply, const QString &text, Object *obj, Func slot, Qt::ConnectionType type, FuncArgs... args ) 0130 { 0131 if( !reply ) 0132 return; 0133 0134 std::function<void ()> function = std::bind( slot, obj, args... ); 0135 addProgressOperation( nullptr, reply, nullptr, QMetaMethod(), QMetaMethod(), text, 100, obj, obj ? function : nullptr, type ); 0136 } 0137 0138 /** 0139 * Informs the user about the progress of a generic QObject 0140 * 0141 * @param sender The object sending the required signals. This sender must Q_EMIT signals 0142 * incrementProgress() and endProgressOperation() and optionally totalSteps(). 0143 * @param text An additional text that will be part of the notification 0144 * @param maximum The maximum value of the progress operation 0145 * @param obj The object that will be called if the user cancels the network request. If not 0146 * set, the progress will not be cancellable 0147 * @param slot The slot on the given object that will be called if the user cancels the 0148 * network request. No slot will be called if not set. 0149 * The signal will be emitted from the GUI thread. The receiver may not make assumptions 0150 * about the sender 0151 * @param type The Qt connection type to use for the connection to the receiving slot. 0152 * Defaults to Qt::AutoConnection 0153 */ 0154 template<class Sender, class Object = QObject, class Func = void (QObject::*)()> 0155 static typename std::enable_if<!std::is_convertible<Sender*, KJob*>::value && !std::is_convertible<Sender*, QNetworkReply*>::value && std::is_convertible<Sender*, QObject*>::value>::type 0156 newProgressOperation( Sender *sender, const QString &text, int maximum = 100, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection) 0157 { 0158 if( !sender ) 0159 return; 0160 0161 auto increment = QMetaMethod::fromSignal( &Sender::incrementProgress ); 0162 auto end = QMetaMethod::fromSignal( &Sender::endProgressOperation ); 0163 std::function<void ()> function = std::bind( slot, obj ); 0164 addProgressOperation( nullptr, nullptr, sender, increment, end, text, maximum, obj, obj ? function : nullptr, type ); 0165 } 0166 0167 /** 0168 * Informs the user about the progress of a generic QObject 0169 * 0170 * @param sender The object sending the required signals. This sender must Q_EMIT signals 0171 * incrementProgress() and endProgressOperation() and optionally totalSteps(). 0172 * @param text An additional text that will be part of the notification 0173 * @param maximum The maximum value of the progress operation 0174 * @param obj The object that will be called if the user cancels the network request. 0175 * @param slot The slot on the given object that will be called if the user cancels the 0176 * network request. 0177 * The signal will be emitted from the GUI thread. The receiver may not make assumptions 0178 * about the sender 0179 * @param type The Qt connection type to use for the connection to the receiving slot. 0180 * @param args Arguments given to the slot. 0181 */ 0182 template<class Sender, class Object = QObject, class Func = void (QObject::*)(), class... FuncArgs> 0183 static typename std::enable_if<!std::is_convertible<Sender*, KJob*>::value && !std::is_convertible<Sender*, QNetworkReply*>::value && std::is_convertible<Sender*, QObject*>::value>::type 0184 newProgressOperation( Sender *sender, const QString &text, int maximum, Object *obj, Func slot, Qt::ConnectionType type, FuncArgs... args ) 0185 { 0186 if( !sender ) 0187 return; 0188 0189 auto increment = QMetaMethod::fromSignal( &Sender::incrementProgress ); 0190 auto end = QMetaMethod::fromSignal( &Sender::endProgressOperation ); 0191 std::function<void ()> function = std::bind( slot, obj, args... ); 0192 addProgressOperation( nullptr, nullptr, sender, increment, end, text, maximum, obj, obj ? function : nullptr, type ); 0193 } 0194 0195 /** 0196 * Sends a notification to the user. 0197 * This method will send a notification containing the given text to the user. 0198 * 0199 * @param text The text that the notification will contain 0200 */ 0201 static void shortMessage( const QString &text ); 0202 0203 /** 0204 * Send a notification to the user with an additional context. 0205 * A notification will be send to the user containing the given text. Additionally, it will convey the context given by @p type. 0206 * @param text The text that the notification will contain 0207 * @param type The context of the notification 0208 */ 0209 static void longMessage( const QString &text, MessageType type = Information ); 0210 0211 protected: 0212 virtual void newProgressOperationImpl( KJob *job, const QString &text, QObject *context, const std::function<void ()> &function, Qt::ConnectionType type ) = 0; 0213 virtual void newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *context, const std::function<void ()> &function, Qt::ConnectionType type ) = 0; 0214 virtual void newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, const QString &text, 0215 int maximum, QObject *context, const std::function<void ()> &function, Qt::ConnectionType type ) = 0; 0216 virtual void longMessageImpl( const QString &text, MessageType type = Information ) = 0; 0217 virtual void shortMessageImpl( const QString &text ) = 0; 0218 0219 private: 0220 static void addProgressOperation(KJob *job = nullptr, QNetworkReply *reply = nullptr, QObject *sender = nullptr, QMetaMethod increment = QMetaMethod(), 0221 const QMetaMethod &end = QMetaMethod(), const QString &text = QString(), int maximum = 100, QObject *context = nullptr, 0222 const std::function<void ()> &function = nullptr, Qt::ConnectionType type = Qt::AutoConnection ); 0223 void loadExistingMessages(); 0224 0225 static QMutex s_mutex; 0226 static QList<Logger*> s_loggers; 0227 static QList<QString> s_shortMessageList; 0228 static QList<LongMessage> s_longMessageList; 0229 static QList<ProgressData> s_progressList; 0230 }; 0231 } 0232 0233 #endif