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 }