File indexing completed on 2024-05-05 16:54:08
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 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 "AmarokMimeData.h" 0018 0019 #include "core/collections/QueryMaker.h" 0020 #include "core/support/Debug.h" 0021 0022 #include <QCoreApplication> 0023 #include <QList> 0024 #include <QTimer> 0025 #include <QUrl> 0026 0027 const QString AmarokMimeData::TRACK_MIME = QStringLiteral("application/x-amarok-tracks"); 0028 const QString AmarokMimeData::PLAYLIST_MIME = QStringLiteral("application/x-amarok-playlists"); 0029 const QString AmarokMimeData::PLAYLISTBROWSERGROUP_MIME = QStringLiteral("application/x-amarok-playlistbrowsergroup"); 0030 const QString AmarokMimeData::PODCASTCHANNEL_MIME = QStringLiteral("application/x-amarok-podcastchannel"); 0031 const QString AmarokMimeData::PODCASTEPISODE_MIME = QStringLiteral("application/x-amarok-podcastepisode"); 0032 const QString AmarokMimeData::AMAROKURL_MIME = QStringLiteral("application/x-amarok-amarokurl"); 0033 const QString AmarokMimeData::BOOKMARKGROUP_MIME = QStringLiteral("application/x-amarok-bookmarkgroup"); 0034 0035 0036 class AmarokMimeData::Private 0037 { 0038 public: 0039 Private() : deleteQueryMakers( true ), completedQueries( 0 ) 0040 {} 0041 0042 ~Private() 0043 { 0044 if( deleteQueryMakers ) 0045 qDeleteAll( queryMakers ); 0046 } 0047 0048 Meta::TrackList tracks; 0049 Playlists::PlaylistList playlists; 0050 QStringList playlistGroups; 0051 Podcasts::PodcastChannelList m_podcastChannels; 0052 Podcasts::PodcastEpisodeList m_podcastEpisodes; 0053 QList<Collections::QueryMaker*> queryMakers; 0054 QMap<Collections::QueryMaker*, Meta::TrackList> trackMap; 0055 QMap<Collections::QueryMaker*, Playlists::PlaylistList> playlistMap; 0056 BookmarkList bookmarks; 0057 BookmarkGroupList bookmarkGroups; 0058 0059 bool deleteQueryMakers; 0060 int completedQueries; 0061 0062 }; 0063 0064 AmarokMimeData::AmarokMimeData() 0065 : QMimeData() 0066 , d( new Private() ) 0067 { 0068 //nothing to do 0069 } 0070 0071 AmarokMimeData::~AmarokMimeData() 0072 { 0073 delete d; 0074 } 0075 0076 QStringList 0077 AmarokMimeData::formats() const 0078 { 0079 QStringList formats( QMimeData::formats() ); 0080 if( !d->tracks.isEmpty() || !d->queryMakers.isEmpty() || !d->playlistGroups.isEmpty() || !d->bookmarks.isEmpty() || !d->bookmarkGroups.isEmpty() ) 0081 { 0082 formats.append( TRACK_MIME ); 0083 formats.append( PLAYLIST_MIME ); 0084 formats.append( PLAYLISTBROWSERGROUP_MIME ); 0085 formats.append( PODCASTCHANNEL_MIME ); 0086 formats.append( PODCASTEPISODE_MIME ); 0087 formats.append( BOOKMARKGROUP_MIME ); 0088 formats.append( AMAROKURL_MIME ); 0089 0090 if( !formats.contains( QStringLiteral("text/uri-list") ) ) 0091 formats.append( QStringLiteral("text/uri-list") ); 0092 if( !formats.contains( QStringLiteral("text/plain") ) ) 0093 formats.append( QStringLiteral("text/plain") ); 0094 } 0095 0096 return formats; 0097 } 0098 0099 bool 0100 AmarokMimeData::hasFormat( const QString &mimeType ) const 0101 { 0102 if( mimeType == TRACK_MIME ) 0103 return !d->tracks.isEmpty() || !d->queryMakers.isEmpty(); 0104 else if( mimeType == PLAYLIST_MIME ) 0105 return !d->playlists.isEmpty() || !d->queryMakers.isEmpty(); 0106 else if( mimeType == PLAYLISTBROWSERGROUP_MIME ) 0107 return !d->playlistGroups.isEmpty(); 0108 else if( mimeType == PODCASTCHANNEL_MIME ) 0109 return !d->m_podcastChannels.isEmpty(); 0110 else if( mimeType == PODCASTEPISODE_MIME ) 0111 return !d->m_podcastEpisodes.isEmpty(); 0112 else if( mimeType == BOOKMARKGROUP_MIME ) 0113 return !d->bookmarkGroups.isEmpty(); 0114 else if( mimeType == AMAROKURL_MIME ) 0115 return !d->bookmarks.isEmpty(); 0116 else if( mimeType == QLatin1String("text/uri-list") || mimeType == QLatin1String("text/plain") ) 0117 return !d->tracks.isEmpty() || !d->playlists.isEmpty() 0118 || !d->m_podcastChannels.isEmpty() || !d->m_podcastEpisodes.isEmpty() 0119 || !d->queryMakers.isEmpty(); 0120 else 0121 return QMimeData::hasFormat( mimeType ); 0122 } 0123 0124 Meta::TrackList 0125 AmarokMimeData::tracks() const 0126 { 0127 while( d->completedQueries < d->queryMakers.count() ) 0128 { 0129 QCoreApplication::instance()->processEvents( QEventLoop::ExcludeUserInputEvents ); 0130 } 0131 Meta::TrackList result = d->tracks; 0132 foreach( Collections::QueryMaker *qm, d->queryMakers ) 0133 { 0134 if( d->trackMap.contains( qm ) ) 0135 result << d->trackMap.value( qm ); 0136 } 0137 return result; 0138 } 0139 0140 void 0141 AmarokMimeData::setTracks( const Meta::TrackList &tracks ) 0142 { 0143 d->tracks = tracks; 0144 } 0145 0146 void 0147 AmarokMimeData::addTracks( const Meta::TrackList &tracks ) 0148 { 0149 d->tracks << tracks; 0150 } 0151 0152 void 0153 AmarokMimeData::getTrackListSignal() const 0154 { 0155 if( d->completedQueries < d->queryMakers.count() ) 0156 { 0157 QTimer::singleShot( 0, this, &AmarokMimeData::getTrackListSignal ); 0158 return; 0159 } 0160 else 0161 { 0162 Meta::TrackList result = d->tracks; 0163 foreach( Collections::QueryMaker *qm, d->queryMakers ) 0164 { 0165 if( d->trackMap.contains( qm ) ) 0166 result << d->trackMap.value( qm ); 0167 } 0168 Q_EMIT trackListSignal( result ); 0169 } 0170 } 0171 0172 Playlists::PlaylistList 0173 AmarokMimeData::playlists() const 0174 { 0175 while( d->completedQueries < d->queryMakers.count() ) 0176 { 0177 QCoreApplication::instance()->processEvents( QEventLoop::AllEvents ); 0178 } 0179 Playlists::PlaylistList result = d->playlists; 0180 return result; 0181 } 0182 0183 void 0184 AmarokMimeData::setPlaylists( const Playlists::PlaylistList &playlists ) 0185 { 0186 d->playlists = playlists; 0187 } 0188 0189 void 0190 AmarokMimeData::addPlaylists( const Playlists::PlaylistList &playlists ) 0191 { 0192 d->playlists << playlists; 0193 } 0194 0195 QStringList 0196 AmarokMimeData::playlistGroups() const 0197 { 0198 return d->playlistGroups; 0199 } 0200 0201 void 0202 AmarokMimeData::setPlaylistGroups( const QStringList &groups ) 0203 { 0204 d->playlistGroups = groups; 0205 } 0206 0207 void 0208 AmarokMimeData::addPlaylistGroup( const QString &group ) 0209 { 0210 d->playlistGroups << group; 0211 } 0212 0213 Podcasts::PodcastChannelList 0214 AmarokMimeData::podcastChannels() const 0215 { 0216 return d->m_podcastChannels; 0217 } 0218 0219 void 0220 AmarokMimeData::setPodcastChannels( const Podcasts::PodcastChannelList &channels ) 0221 { 0222 d->m_podcastChannels = channels; 0223 } 0224 0225 void 0226 AmarokMimeData::addPodcastChannels( const Podcasts::PodcastChannelList &channels ) 0227 { 0228 d->m_podcastChannels << channels; 0229 } 0230 0231 Podcasts::PodcastEpisodeList 0232 AmarokMimeData::podcastEpisodes() const 0233 { 0234 return d->m_podcastEpisodes; 0235 } 0236 0237 void 0238 AmarokMimeData::setPodcastEpisodes( const Podcasts::PodcastEpisodeList &episodes ) 0239 { 0240 d->m_podcastEpisodes = episodes; 0241 } 0242 0243 void 0244 AmarokMimeData::addPodcastEpisodes( const Podcasts::PodcastEpisodeList &episodes ) 0245 { 0246 d->m_podcastEpisodes << episodes; 0247 } 0248 0249 QList<Collections::QueryMaker*> 0250 AmarokMimeData::queryMakers() 0251 { 0252 d->deleteQueryMakers = false; 0253 return d->queryMakers; 0254 } 0255 0256 void 0257 AmarokMimeData::addQueryMaker( Collections::QueryMaker *queryMaker ) 0258 { 0259 d->queryMakers.append( queryMaker ); 0260 } 0261 0262 void 0263 AmarokMimeData::setQueryMakers( const QList<Collections::QueryMaker*> &queryMakers ) 0264 { 0265 d->queryMakers << queryMakers; 0266 } 0267 0268 BookmarkList AmarokMimeData::bookmarks() const 0269 { 0270 return d->bookmarks; 0271 } 0272 0273 void AmarokMimeData::setBookmarks( const BookmarkList &bookmarks ) 0274 { 0275 d->bookmarks = bookmarks; 0276 } 0277 0278 void AmarokMimeData::addBookmarks( const BookmarkList &bookmarks ) 0279 { 0280 d->bookmarks << bookmarks; 0281 } 0282 0283 BookmarkGroupList AmarokMimeData::bookmarkGroups() const 0284 { 0285 return d->bookmarkGroups; 0286 } 0287 0288 void AmarokMimeData::setBookmarkGroups( const BookmarkGroupList &groups ) 0289 { 0290 d->bookmarkGroups = groups; 0291 } 0292 0293 void AmarokMimeData::addBookmarkGroups( const BookmarkGroupList &groups ) 0294 { 0295 d->bookmarkGroups << groups; 0296 } 0297 0298 QVariant 0299 AmarokMimeData::retrieveData( const QString &mimeType, QVariant::Type type ) const 0300 { 0301 Meta::TrackList tracks = this->tracks(); 0302 Playlists::PlaylistList playlists = this->playlists(); 0303 Podcasts::PodcastChannelList channels = this->podcastChannels(); 0304 Podcasts::PodcastEpisodeList episodes = this->podcastEpisodes(); 0305 if( !tracks.isEmpty() ) 0306 { 0307 if( mimeType == QLatin1String("text/uri-list") && (type == QVariant::List || type == QVariant::ByteArray) ) 0308 { 0309 QList<QVariant> list; 0310 foreach( Meta::TrackPtr track, tracks ) 0311 { 0312 list.append( QVariant( QUrl( track->playableUrl() ) ) ); 0313 } 0314 foreach( Podcasts::PodcastEpisodePtr episode, episodes ) 0315 { 0316 list.append( QVariant( QUrl( episode->playableUrl() ) ) ); 0317 } 0318 foreach( Playlists::PlaylistPtr playlist, playlists ) 0319 { 0320 list.append( QVariant( QUrl( playlist->uidUrl() ) ) ); 0321 } 0322 foreach( Podcasts::PodcastChannelPtr channel, channels ) 0323 { 0324 list.append( QVariant( QUrl( channel->url() ) ) ); 0325 } 0326 return QVariant( list ); 0327 } 0328 if( mimeType == QLatin1String("text/plain") && (type == QVariant::String || type == QVariant::ByteArray) ) 0329 { 0330 QString result; 0331 foreach( Meta::TrackPtr track, tracks ) 0332 { 0333 if( !result.isEmpty() ) 0334 result += '\n'; 0335 result += track->artist()->prettyName(); 0336 result += QLatin1String(" - "); 0337 result += track->prettyName(); 0338 } 0339 foreach( Podcasts::PodcastEpisodePtr episode, episodes ) 0340 { 0341 if( !result.isEmpty() ) 0342 result += '\n'; 0343 result += episode->prettyName(); 0344 result += QLatin1String(" - "); 0345 result += episode->channel()->prettyName(); 0346 } 0347 foreach( Playlists::PlaylistPtr playlist, playlists ) 0348 { 0349 if( !result.isEmpty() ) 0350 result += '\n'; 0351 result += playlist->prettyName(); 0352 } 0353 foreach( Podcasts::PodcastChannelPtr channel, channels ) 0354 { 0355 if( !result.isEmpty() ) 0356 result += '\n'; 0357 result += channel->prettyName(); 0358 } 0359 return QVariant( result ); 0360 } 0361 } 0362 return QMimeData::retrieveData( mimeType, type ); 0363 } 0364 0365 void 0366 AmarokMimeData::startQueries() 0367 { 0368 foreach( Collections::QueryMaker *qm, d->queryMakers ) 0369 { 0370 qm->setQueryType( Collections::QueryMaker::Track ); 0371 connect( qm, &Collections::QueryMaker::newTracksReady, 0372 this, &AmarokMimeData::newResultReady, Qt::QueuedConnection ); 0373 connect( qm, &Collections::QueryMaker::queryDone, this, &AmarokMimeData::queryDone, Qt::QueuedConnection ); 0374 qm->run(); 0375 } 0376 } 0377 0378 void 0379 AmarokMimeData::newResultReady( const Meta::TrackList &tracks ) 0380 { 0381 Collections::QueryMaker *qm = dynamic_cast<Collections::QueryMaker*>( sender() ); 0382 if( qm ) 0383 { 0384 d->trackMap.insert( qm, tracks ); 0385 } 0386 else 0387 d->tracks << tracks; 0388 } 0389 0390 void 0391 AmarokMimeData::queryDone() 0392 { 0393 d->completedQueries++; 0394 } 0395 0396