File indexing completed on 2024-05-19 04:49:28
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 #include "Logger.h" 0018 0019 #include <QNetworkReply> 0020 #include <QPointer> 0021 #include <QTimer> 0022 0023 #include <KJob> 0024 0025 0026 // Durations for which messages are being saved. 0027 #define SHORT_MESSAGE_DURATION 10000 0028 #define LONG_MESSAGE_DURATION 10000 0029 0030 struct LongMessage 0031 { 0032 QString text; 0033 Amarok::Logger::MessageType type; 0034 }; 0035 0036 struct ProgressData 0037 { 0038 QPointer<QObject> sender; 0039 QMetaMethod increment; 0040 QMetaMethod end; 0041 QPointer<KJob> job; 0042 QPointer<QNetworkReply> reply; 0043 QString text; 0044 int maximum; 0045 QPointer<QObject> cancelObject; 0046 std::function<void ()> function; 0047 Qt::ConnectionType type; 0048 0049 bool operator==( const ProgressData &other ) 0050 { 0051 return sender == other.sender && 0052 job == other.job && 0053 reply == other.reply && 0054 increment == other.increment && 0055 end == other.end && 0056 text == other.text && 0057 maximum == other.maximum && 0058 cancelObject == other.cancelObject && 0059 function.target_type() == other.function.target_type() && 0060 type == other.type; 0061 } 0062 }; 0063 0064 QMutex Amarok::Logger::s_mutex; 0065 QList<Amarok::Logger*> Amarok::Logger::s_loggers; 0066 QList<QString> Amarok::Logger::s_shortMessageList; 0067 QList<LongMessage> Amarok::Logger::s_longMessageList; 0068 QList<ProgressData> Amarok::Logger::s_progressList; 0069 0070 Amarok::Logger::Logger() 0071 { 0072 QMutexLocker locker( &s_mutex ); 0073 s_loggers << this; 0074 0075 QTimer::singleShot( 0, [this] () { this->loadExistingMessages(); } ); 0076 } 0077 0078 Amarok::Logger::~Logger() 0079 { 0080 QMutexLocker locker( &s_mutex ); 0081 s_loggers.removeAll( this ); 0082 } 0083 0084 void Amarok::Logger::addProgressOperation( KJob* job, QNetworkReply* reply, QObject* sender, QMetaMethod increment, const QMetaMethod& end, 0085 const QString& text, int maximum, QObject* context, const std::function<void ()>& function, Qt::ConnectionType type ) 0086 { 0087 ProgressData data; 0088 data.sender = sender; 0089 data.job = job; 0090 data.reply = reply; 0091 data.increment = increment; 0092 data.end = end; 0093 data.text = text; 0094 data.maximum = maximum; 0095 data.cancelObject = context; 0096 data.function = function; 0097 data.type = type; 0098 0099 QMutexLocker locker( &s_mutex ); 0100 s_progressList << data; 0101 0102 auto removeFunction = [data] () { 0103 QMutexLocker locker( &s_mutex ); 0104 s_progressList.removeAll( data ); 0105 }; 0106 0107 if( job ) 0108 { 0109 QObject::connect( job, &QObject::destroyed, removeFunction ); 0110 for( const auto &logger : s_loggers ) 0111 logger->newProgressOperationImpl( job, text, context, function, type ); 0112 } 0113 else if( reply ) 0114 { 0115 QObject::connect( reply, &QObject::destroyed, removeFunction ); 0116 for( const auto &logger : s_loggers ) 0117 logger->newProgressOperationImpl( reply, text, context, function, type ); 0118 } 0119 else if( sender ) 0120 { 0121 QObject::connect( sender, &QObject::destroyed, removeFunction ); 0122 for( const auto &logger : s_loggers ) 0123 logger->newProgressOperationImpl( sender, increment, end, text, maximum, context, function, type ); 0124 } 0125 } 0126 0127 void Amarok::Logger::shortMessage( const QString& text ) 0128 { 0129 if( text.isEmpty() ) 0130 return; 0131 0132 QMutexLocker locker( &s_mutex ); 0133 s_shortMessageList << text; 0134 0135 for( const auto &logger : s_loggers ) 0136 logger->shortMessageImpl( text ); 0137 0138 auto removeFunction = [text] () { 0139 QMutexLocker locker( &s_mutex ); 0140 s_shortMessageList.removeAll( text ); 0141 }; 0142 0143 QTimer::singleShot( SHORT_MESSAGE_DURATION, removeFunction ); 0144 } 0145 0146 void Amarok::Logger::longMessage( const QString& text, Amarok::Logger::MessageType type ) 0147 { 0148 if( text.isEmpty() ) 0149 return; 0150 0151 LongMessage message; 0152 message.text = text; 0153 message.type = type; 0154 QMutexLocker locker( &s_mutex ); 0155 s_longMessageList << message; 0156 0157 for( const auto &logger : s_loggers ) 0158 logger->longMessageImpl( text, type ); 0159 0160 auto removeFunction = [text] () { 0161 QMutexLocker locker( &s_mutex ); 0162 s_shortMessageList.removeAll( text ); 0163 }; 0164 0165 QTimer::singleShot( LONG_MESSAGE_DURATION, removeFunction ); 0166 } 0167 0168 void Amarok::Logger::loadExistingMessages() 0169 { 0170 QMutexLocker locker( &s_mutex ); 0171 for( const auto &data : s_progressList ) 0172 { 0173 if( data.job ) 0174 newProgressOperationImpl( data.job, data.text, data.cancelObject, data.function, data.type ); 0175 else if( data.reply ) 0176 newProgressOperationImpl( data.reply, data.text, data.cancelObject, data.function, data.type ); 0177 else if( data.sender ) 0178 newProgressOperationImpl( data.sender, data.increment, data.end, data.text, data.maximum, data.cancelObject, data.function, data.type ); 0179 } 0180 0181 for( const auto &data : s_shortMessageList ) 0182 shortMessageImpl( data ); 0183 0184 for( const auto &data : s_longMessageList ) 0185 longMessageImpl( data.text, data.type ); 0186 }