File indexing completed on 2025-01-05 04:25:41

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Leo Franchi <lfranchi@gmail.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 #define DEBUG_PREFIX "CurrentEngine"
0018 
0019 #include "CurrentEngine.h"
0020 
0021 #include "EngineController.h"
0022 #include "core/support/Debug.h"
0023 #include "core/capabilities/SourceInfoCapability.h"
0024 #include "core/collections/Collection.h"
0025 #include "core/collections/QueryMaker.h"
0026 #include "core/meta/support/MetaUtility.h"
0027 #include "core/meta/Statistics.h"
0028 #include "core/support/Amarok.h"
0029 #include "core-impl/collections/support/CollectionManager.h"
0030 #include "covermanager/CoverCache.h"
0031 
0032 #include <QDateTime>
0033 
0034 #include <KFormat>
0035 #include <KLocalizedString>
0036 
0037 
0038 CurrentEngine::CurrentEngine( QObject* parent )
0039     : QObject( parent )
0040     , m_lastQueryMaker( nullptr )
0041 {
0042     EngineController* engine = The::engineController();
0043 
0044     // Connect queued to reduce interface stuttering.
0045     connect( engine, &EngineController::trackPlaying,
0046              this, &CurrentEngine::slotTrackChanged, Qt::QueuedConnection );
0047     connect( engine, &EngineController::stopped,
0048              this, &CurrentEngine::stopped, Qt::QueuedConnection );
0049     connect( engine, &EngineController::trackMetadataChanged,
0050              this, &CurrentEngine::slotTrackMetadataChanged, Qt::QueuedConnection );
0051     connect( engine, &EngineController::albumMetadataChanged,
0052              this, &CurrentEngine::slotAlbumMetadataChanged, Qt::QueuedConnection );
0053 }
0054 
0055 CurrentEngine::~CurrentEngine()
0056 {
0057 }
0058 
0059 void
0060 CurrentEngine::slotAlbumMetadataChanged( const Meta::AlbumPtr &album )
0061 {
0062     DEBUG_BLOCK
0063 
0064     // disregard changes for other albums (BR: 306735)
0065     if( !m_currentTrack || m_currentTrack->album() != album )
0066         return;
0067 
0068     QPixmap cover;
0069 
0070     if( album )
0071         cover = The::coverCache()->getCover( album, 1 );
0072 
0073     if( m_cover.cacheKey() != cover.cacheKey() )
0074     {
0075         m_cover = cover;
0076         Q_EMIT albumChanged();
0077     }
0078 }
0079 
0080 void
0081 CurrentEngine::slotTrackMetadataChanged( Meta::TrackPtr track )
0082 {
0083     if( !track )
0084         return;
0085 
0086     update( track->album() );
0087     Q_EMIT trackChanged();
0088 }
0089 
0090 void
0091 CurrentEngine::slotTrackChanged(const Meta::TrackPtr &track)
0092 {
0093     DEBUG_BLOCK
0094 
0095     if( !track || track == m_currentTrack )
0096         return;
0097 
0098     m_currentTrack = track;
0099     slotTrackMetadataChanged( track );
0100 }
0101 
0102 
0103 void
0104 CurrentEngine::stopped()
0105 {
0106     m_currentTrack.clear();
0107     Q_EMIT trackChanged();
0108 
0109     m_cover = QPixmap();
0110 
0111     // Collect data for the recently added albums
0112     m_albums.clear();
0113     Q_EMIT albumChanged();
0114 
0115     Collections::QueryMaker *qm = CollectionManager::instance()->queryMaker();
0116     qm->setAutoDelete( true );
0117     qm->setQueryType( Collections::QueryMaker::Album );
0118     qm->excludeFilter( Meta::valAlbum, QString(), true, true );
0119     qm->orderBy( Meta::valCreateDate, true );
0120     qm->limitMaxResultSize( Amarok::config("Albums Applet").readEntry("RecentlyAdded", 5) );
0121 
0122     connect( qm, &Collections::QueryMaker::newAlbumsReady,
0123                 this, &CurrentEngine::resultReady, Qt::QueuedConnection );
0124 
0125     m_lastQueryMaker = qm;
0126     qm->run();
0127 }
0128 
0129 void
0130 CurrentEngine::update( Meta::AlbumPtr album )
0131 {
0132     m_lastQueryMaker = nullptr;
0133 
0134     if( !album )
0135         return;
0136 
0137     slotAlbumMetadataChanged( album );
0138 
0139     Meta::TrackPtr track = The::engineController()->currentTrack();
0140 
0141     if( !track )
0142         return;
0143 
0144     Meta::ArtistPtr artist = track->artist();
0145 
0146     // Prefer track artist to album artist BUG: 266682
0147     if( !artist )
0148         artist = album->albumArtist();
0149     
0150     if( artist && !artist->name().isEmpty() )
0151     {
0152         m_albums.clear();
0153 
0154         // -- search the collection for albums with the same artist
0155         Collections::QueryMaker *qm = CollectionManager::instance()->queryMaker();
0156         qm->setAutoDelete( true );
0157         qm->addFilter( Meta::valArtist, artist->name(), true, true );
0158         qm->setAlbumQueryMode( Collections::QueryMaker::AllAlbums );
0159         qm->setQueryType( Collections::QueryMaker::Album );
0160 
0161         connect( qm, &Collections::QueryMaker::newAlbumsReady,
0162                  this, &CurrentEngine::resultReady, Qt::QueuedConnection );
0163 
0164         m_lastQueryMaker = qm;
0165         qm->run();
0166     }
0167 }
0168 
0169 void
0170 CurrentEngine::resultReady( const Meta::AlbumList &albums )
0171 {
0172     if( sender() == m_lastQueryMaker )
0173         m_albums << albums;
0174 }
0175 
0176 QString
0177 CurrentEngine::artist() const
0178 {
0179     if( !m_currentTrack )
0180         return QString();
0181 
0182     return m_currentTrack->artist()->prettyName();
0183 }
0184 
0185 QString
0186 CurrentEngine::track() const
0187 {
0188     if( !m_currentTrack )
0189         return QString();
0190 
0191     return m_currentTrack->prettyName();
0192 }
0193 
0194 QString
0195 CurrentEngine::album() const
0196 {
0197     if( !m_currentTrack )
0198         return QString();
0199 
0200     return m_currentTrack->album()->prettyName();
0201 }
0202 
0203 int
0204 CurrentEngine::rating() const
0205 {
0206     if( !m_currentTrack )
0207         return 0;
0208 
0209     return m_currentTrack->statistics()->rating();
0210 }
0211 
0212 void
0213 CurrentEngine::setRating(int rating)
0214 {
0215     DEBUG_BLOCK
0216 
0217     debug() << "New rating:" << rating;
0218 
0219     if( !m_currentTrack )
0220         return;
0221 
0222     if( rating == m_currentTrack->statistics()->rating() )
0223         return;
0224 
0225     m_currentTrack->statistics()->setRating( rating );
0226     Q_EMIT trackChanged();
0227 }
0228 
0229 int
0230 CurrentEngine::score() const
0231 {
0232     if( !m_currentTrack )
0233         return 0;
0234 
0235     return m_currentTrack->statistics()->score();
0236 }
0237 
0238 int
0239 CurrentEngine::length() const
0240 {
0241     if( !m_currentTrack )
0242         return 0;
0243 
0244     return m_currentTrack->length();
0245 }
0246 
0247 QString
0248 CurrentEngine::lastPlayed() const
0249 {
0250     if( !m_currentTrack )
0251         return QString();
0252 
0253     auto lastPlayed = m_currentTrack->statistics()->lastPlayed();
0254     QString lastPlayedString;
0255     if( lastPlayed.isValid() )
0256         lastPlayedString = KFormat().formatRelativeDateTime( lastPlayed, QLocale::ShortFormat );
0257     else
0258         lastPlayedString = i18n( "Never" );
0259 
0260     return lastPlayedString;
0261 }
0262 
0263 int
0264 CurrentEngine::timesPlayed() const
0265 {
0266     if( !m_currentTrack )
0267         return 0;
0268 
0269     return m_currentTrack->statistics()->playCount();
0270 }