14 * Description: Music Player Query Manager. |
14 * Description: Music Player Query Manager. |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 #include "mpquerymanager.h" |
18 #include "mpquerymanager.h" |
19 #include <QDebug> |
|
20 #include <QObject> |
19 #include <QObject> |
21 #include <QNetworkAccessManager> |
20 #include <QNetworkAccessManager> |
22 #include <QNetworkDiskCache> |
21 #include <QNetworkDiskCache> |
23 #include <QNetworkProxyFactory> |
22 #include <QNetworkProxyFactory> |
24 #include <qmobilityglobal.h> |
23 #include <qmobilityglobal.h> |
25 #include <QNetworkSession> |
24 #include <QNetworkSession> |
26 #include <QDomElement> |
25 #include <QDomElement> |
27 #include <QList> |
26 #include <QList> |
28 #include <QFile> |
|
29 #include <QUrl> |
27 #include <QUrl> |
30 #include <QSslError> |
28 #include <QSslError> |
31 #include <QDir> |
|
32 #include <QCoreApplication> |
|
33 #include <XQSysInfo> |
29 #include <XQSysInfo> |
34 |
30 #include <QSignalMapper> |
35 #include <thumbnailmanager_qt.h> |
31 #include <QSettings> |
36 #include <thumbnaildata.h> |
|
37 #include <thumbnailobjectsource.h> |
|
38 |
32 |
39 #include "mptrace.h" |
33 #include "mptrace.h" |
40 |
34 |
41 const int KUndefined = -1; |
|
42 const int KRecommendationCount = 2; |
35 const int KRecommendationCount = 2; |
43 |
36 |
44 MpQueryManager::MpQueryManager() |
37 MpQueryManager::MpQueryManager() |
45 : mManager(0), |
38 : mManager(0), |
46 mAlbumArtDownloader(0), |
39 mAlbumArtDownloader(0), |
47 mThumbnailManager(0), |
|
48 mDefaultRecommendationAlbumArt("qtg_large_album_art"), |
40 mDefaultRecommendationAlbumArt("qtg_large_album_art"), |
49 mRequestType(NoRequest), |
41 mRequestType(NoRequest), |
50 mRecommendationCount(0) |
42 mRecommendationCount(0) |
51 |
43 { |
52 { |
44 TX_ENTRY |
53 TX_ENTRY |
|
54 |
|
55 QString privatePathQt( QCoreApplication::applicationDirPath() ); |
|
56 TX_LOG_ARGS( "Private path: " << privatePathQt ); |
|
57 QDir dir( privatePathQt ); |
|
58 QString newDir = "detailsview"; |
|
59 bool res = dir.mkdir( newDir ); |
|
60 TX_LOG_ARGS( "New dir creation result: " << res); |
|
61 |
|
62 // TODO: Instead of writing the album art to a file, |
|
63 // then using Thumbnail Manager to convert it, etc. |
|
64 // have you considered just loading it directly into QPixmap? |
|
65 // QPixmap provides a loadFromData() that can load from QByteArray. |
|
66 // This would not only make the availability of the album art immediate, |
|
67 // but also save a lot of cleanup in file system, thumbnail manager, etc. |
|
68 privatePathQt = privatePathQt + "/detailsview"; |
|
69 QString albumArt1( privatePathQt + "/albumOne.png" ); |
|
70 QString albumArt2( privatePathQt + "/albumTwo.png" ); |
|
71 mRecommendationAlbumArtsName << albumArt1 << albumArt2; |
|
72 TX_LOG_ARGS( "recommendation album art names: " << mRecommendationAlbumArtsName ); |
|
73 |
|
74 mManager = new QNetworkAccessManager( this ); |
45 mManager = new QNetworkAccessManager( this ); |
75 mAlbumArtDownloader = new QNetworkAccessManager( this ); // TODO: check if we can only use mManager |
46 // A second intance is necessary to reduce complexity. |
76 mThumbnailManager = new ThumbnailManager( this ); |
47 // Otherwise, we would have to shoot async events when we want to receive inspire me items' album art |
77 mThumbnailManager->setQualityPreference( ThumbnailManager::OptimizeForQuality ); |
48 // and that may not always work. |
78 mThumbnailManager->setThumbnailSize( ThumbnailManager::ThumbnailSmall ); |
49 mAlbumArtDownloader = new QNetworkAccessManager( this ); |
79 |
50 |
|
51 mDownloadSignalMapper = new QSignalMapper(this); |
80 TX_EXIT |
52 TX_EXIT |
81 } |
53 } |
82 |
54 |
83 MpQueryManager::~MpQueryManager() |
55 MpQueryManager::~MpQueryManager() |
84 { |
56 { |
113 } |
83 } |
114 mReplys.clear(); |
84 mReplys.clear(); |
115 TX_EXIT |
85 TX_EXIT |
116 } |
86 } |
117 |
87 |
118 |
|
119 void MpQueryManager::queryLocalMusicStore(QString artist,QString album,QString title) |
|
120 { |
|
121 TX_ENTRY |
|
122 mArtist=artist; |
|
123 mAlbum=album; |
|
124 mTitle=title; |
|
125 // TODO: country information handling, MCC |
|
126 QString queryURI("http://api.music.ovi.com/1.0/ru/?"); |
|
127 constructRequest( queryURI ); |
|
128 TX_LOG_ARGS( "queryURI : " << queryURI ); |
|
129 retrieveInformation( queryURI ); |
|
130 mRequestType = LocalStoreRequest; |
|
131 TX_EXIT |
|
132 } |
|
133 |
88 |
134 void MpQueryManager::queryInspireMeItems(QString artist,QString album,QString title) |
89 void MpQueryManager::queryInspireMeItems(QString artist,QString album,QString title) |
135 { |
90 { |
136 TX_ENTRY |
91 TX_ENTRY |
137 mArtist=artist; |
92 mArtist=artist; |
138 mAlbum=album; |
93 mAlbum=album; |
139 mTitle=title; |
94 mTitle=title; |
140 // start querying inspire me items |
95 // start querying inspire me items |
141 QString queryRecommendation("http://api.music.ovi.com/1.0/" + mMusicStore + "/releases/recommend/?"); |
96 QString queryRecommendation("http://api.music.ovi.com/1.0/" + mMusicStore + "/releases/recommend/?"); |
142 constructRequest( queryRecommendation ); |
97 constructRequest( queryRecommendation ); |
143 // TODO: Store the token to a cenrep key |
|
144 // TODO: Tokens change per new ovi api release. |
98 // TODO: Tokens change per new ovi api release. |
145 // Need to figure out a way to get them updated on the fly |
99 // Need to figure out a way to get them updated on the fly |
146 queryRecommendation.append("&Token=03574704-e3d1-4466-9691-e0b34c7abfff"); |
100 queryRecommendation.append("&Token=03574704-e3d1-4466-9691-e0b34c7abfff"); |
147 |
101 |
148 TX_LOG_ARGS( queryRecommendation ); |
102 TX_LOG_ARGS( queryRecommendation ); |
296 /*! |
242 /*! |
297 Slot to call when there is ssl error |
243 Slot to call when there is ssl error |
298 */ |
244 */ |
299 void MpQueryManager::retrieveInformationSslErrors( const QList<QSslError> &/*error*/ ) |
245 void MpQueryManager::retrieveInformationSslErrors( const QList<QSslError> &/*error*/ ) |
300 { |
246 { |
301 // TODO: agree on error handling |
|
302 TX_ENTRY_ARGS( "SSL error for retrieving Information" ); |
247 TX_ENTRY_ARGS( "SSL error for retrieving Information" ); |
303 disconnect( mManager, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( retrieveInformationFinished( QNetworkReply * ) ) ); |
248 disconnect( mManager, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( retrieveInformationFinished( QNetworkReply * ) ) ); |
304 signalError(); |
249 signalError(); |
305 TX_EXIT |
250 TX_EXIT |
306 } |
251 } |
307 |
252 |
308 /*! |
253 /*! |
309 Slot to call when downloading finished |
254 Slot to call when downloading finished |
310 */ |
255 */ |
311 void MpQueryManager::albumArtDownloaded( QNetworkReply* reply ) |
256 void MpQueryManager::albumArtDownloaded( int index ) |
312 { |
257 { |
313 TX_ENTRY_ARGS( "mDownloadedAlbumArts = " << mDownloadedAlbumArts ); |
258 TX_ENTRY_ARGS( "mDownloadedAlbumArts = " << mDownloadedAlbumArts << "index = " << index); |
314 TX_ENTRY_ARGS( "QNetworkReply obj " << reply); |
259 |
315 |
260 QNetworkReply* reply = qobject_cast<QNetworkReply*> ( qobject_cast<QSignalMapper*>( sender() )->mapping( index ) ); |
316 // It seems we get several finished signals for the same reply obj |
261 // It seems we get several finished signals for the same reply obj |
317 // do nothing if we get a second signal |
262 // do nothing if we get a second signal |
318 if( mReplys.indexOf(reply) == -1 ) { |
263 if( mReplys.indexOf(reply) == -1 ) { |
319 TX_LOG_ARGS("Warning: QNetworkReply AA request may have been processed in previous call: " << reply ); |
264 TX_LOG_ARGS("Warning: QNetworkReply AA request may have been processed in previous call: " << reply ); |
320 return; |
265 return; |
321 } |
266 } |
322 |
267 |
323 if ( reply->error() == QNetworkReply::NoError ) { |
268 if ( reply->error() == QNetworkReply::NoError ) { |
324 |
269 QPixmap albumart; |
325 QString fileName = mRecommendationAlbumArtsName.at( mDownloadedAlbumArts ); |
270 bool result = albumart.loadFromData( reply->readAll() ); |
326 QByteArray imageData = reply->readAll(); |
271 if ( result ) { |
327 bool ret = writeImageToFile( imageData, fileName ); |
272 mRecommendationAlbumArtsMap.insert( mRecommendationAlbumArtsLink.at( index ), HbIcon( QIcon( albumart ) ) ); |
328 |
273 |
329 // If file writing went OK, emit a signal with the real filename |
274 } else { |
330 // If it failed, use empty filename (since file was removed in any case) |
275 mRecommendationAlbumArtsMap.insert( mRecommendationAlbumArtsLink.at( index ), mDefaultRecommendationAlbumArt ); |
331 if ( ret ) { |
276 } |
332 // TODO: If album album arts come in different order than they have been asked, |
277 |
333 // then inspire me items will use swapped album arts. Correct |
|
334 setAlbumArtUri( mRecommendationAlbumArtsLink.at( mDownloadedAlbumArts), |
|
335 mRecommendationAlbumArtsName.at( mDownloadedAlbumArts ) ); |
|
336 } |
|
337 else { |
|
338 setAlbumArtUri(mRecommendationAlbumArtsLink.at( mDownloadedAlbumArts), ""); |
|
339 } |
|
340 ++mDownloadedAlbumArts; |
278 ++mDownloadedAlbumArts; |
341 mReplys.removeAll(reply); // remove it so that we wont process it again |
279 mReplys.removeAll(reply); // remove it so that we wont process it again |
342 reply->deleteLater(); // make sure reply is deleted, as we longer care about it |
280 reply->deleteLater(); // make sure reply is deleted, as we longer care about it |
343 } |
281 } |
344 else { |
282 else { |
345 TX_LOG_ARGS( "Error: Downloading album art failed! Will keep using the default AA" ); |
283 TX_LOG_ARGS( "Error: Downloading album art failed! Will keep using the default AA" ); |
346 } |
284 mRecommendationAlbumArtsMap.insert( mRecommendationAlbumArtsLink.at( index ), mDefaultRecommendationAlbumArt ); |
|
285 } |
|
286 mDownloadSignalMapper->removeMappings( reply ); |
347 |
287 |
348 if( mDownloadedAlbumArts == mRecommendationCount) { |
288 if( mDownloadedAlbumArts == mRecommendationCount) { |
349 // no need to be informed anymore |
289 // no need to be informed anymore |
350 mAlbumArtDownloader->disconnect(this); |
290 mDownloadSignalMapper->disconnect(this); |
351 } |
291 emit inspireMeItemAlbumArtReady(); |
352 |
292 } |
353 TX_EXIT |
293 |
354 } |
294 TX_EXIT |
355 |
295 } |
356 /*! |
296 |
357 Write the image data to a file with the given filename. |
|
358 If writing operation fails for any reason (e.g. OOD), |
|
359 returns false, otherwise true. |
|
360 */ |
|
361 bool MpQueryManager::writeImageToFile(const QByteArray &aImageData, const QString &aImageFileName ) |
|
362 { |
|
363 bool ret( false ); |
|
364 TX_ENTRY_ARGS( "imagefile: " << aImageFileName ); |
|
365 if ( aImageFileName.isEmpty() ) { |
|
366 TX_LOG_ARGS( "Only store two album arts" ); |
|
367 } |
|
368 else { |
|
369 QFile file( aImageFileName ); |
|
370 if ( !file.open( QIODevice::ReadWrite ) ) { |
|
371 TX_LOG_ARGS( "Unable to open file" ); |
|
372 } |
|
373 else { |
|
374 qint64 writtenBytes = file.write( aImageData ); |
|
375 // Verify file write status |
|
376 if ( writtenBytes < aImageData.size() ) { |
|
377 // If write succeeded only partially, or completely failed, |
|
378 // remove the file from filesystem to remove risk of corruption |
|
379 TX_LOG_ARGS( "Wrote only " << writtenBytes << " bytes, aborting operation!" ); |
|
380 file.close(); |
|
381 QFile::remove( mRecommendationAlbumArtsName.at( mDownloadedAlbumArts ) ); |
|
382 } |
|
383 else { |
|
384 // If write fully succeeded, flush contents |
|
385 TX_LOG_ARGS( "Wrote all the bytes (" << writtenBytes << "), flushing and closing!"); |
|
386 file.flush(); |
|
387 file.close(); |
|
388 ret = true; |
|
389 } |
|
390 } |
|
391 } |
|
392 TX_LOG_ARGS( "Returning with value: " << ret ); |
|
393 TX_EXIT |
|
394 return ret; |
|
395 } |
|
396 |
297 |
397 /*! |
298 /*! |
398 Get Atom response from Ovi server based on query |
299 Get Atom response from Ovi server based on query |
399 */ |
300 */ |
400 void MpQueryManager::retrieveInformation( const QString &urlEncoded ) |
301 void MpQueryManager::retrieveInformation( const QString &urlEncoded ) |
455 TX_LOG_ARGS( "Album art link: " << mRecommendationAlbumArtsLink.at(i) ); |
355 TX_LOG_ARGS( "Album art link: " << mRecommendationAlbumArtsLink.at(i) ); |
456 mRequestType = InspireMeItemsAlbumArtRequest; |
356 mRequestType = InspireMeItemsAlbumArtRequest; |
457 if ( mRecommendationAlbumArtsLink.at( i ).contains( "http", Qt::CaseInsensitive ) ) { |
357 if ( mRecommendationAlbumArtsLink.at( i ).contains( "http", Qt::CaseInsensitive ) ) { |
458 reply = mAlbumArtDownloader->get( QNetworkRequest( QUrl( mRecommendationAlbumArtsLink.at(i) ) ) ); |
358 reply = mAlbumArtDownloader->get( QNetworkRequest( QUrl( mRecommendationAlbumArtsLink.at(i) ) ) ); |
459 mReplys.append( reply ); |
359 mReplys.append( reply ); |
|
360 connect( reply, SIGNAL( finished() ), mDownloadSignalMapper, SLOT( map() ) ); |
|
361 mDownloadSignalMapper->setMapping( reply, i ); |
|
362 |
460 connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( retrieveInformationNetworkError( QNetworkReply::NetworkError ) ) ); |
363 connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( retrieveInformationNetworkError( QNetworkReply::NetworkError ) ) ); |
461 connect( reply, SIGNAL( sslErrors( QList<QSslError> ) ), this, SLOT( retrieveInformationSslErrors( QList<QSslError> ) ) ); |
364 connect( reply, SIGNAL( sslErrors( QList<QSslError> ) ), this, SLOT( retrieveInformationSslErrors( QList<QSslError> ) ) ); |
462 } |
365 } |
463 } |
366 } |
464 // we have queried for album arts for inspire me items. Now, time to wait for a response |
367 // we have queried for album arts for inspire me items. Now, time to wait for a response |
465 connect( mAlbumArtDownloader, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( albumArtDownloaded( QNetworkReply * ) ) ); |
368 connect( mDownloadSignalMapper, SIGNAL( mapped( int ) ), this, SLOT( albumArtDownloaded( int ) ) ); |
466 |
369 |
467 } |
370 } |
468 else if ( rootElement.attribute( "type" ) == "storeList" ) { |
371 else if ( rootElement.attribute( "type" ) == "storeList" ) { |
469 TX_LOG_ARGS( "Music Store List" ) |
372 TX_LOG_ARGS( "Music Store List" ) |
470 QDomElement entry = rootElement.firstChildElement( "workspace" ); |
373 QDomElement entry = rootElement.firstChildElement( "workspace" ); |
471 QString previousMusicStore = mMusicStore; |
374 QString previousMusicStore = mMusicStore; |
472 mMusicStore = entry.attribute( "countryCode" ); |
375 mMusicStore = entry.attribute( "countryCode" ); |
473 if(!mMusicStore.isEmpty()) { |
376 if( !mMusicStore.isEmpty() ) { |
474 bool musicStoreUpdated = (previousMusicStore != mMusicStore); |
377 bool musicStoreUpdated = ( previousMusicStore != mMusicStore ); |
475 TX_LOG_ARGS("Music Store" << mMusicStore ); |
378 TX_LOG_ARGS("Music Store" << mMusicStore ); |
476 emit localMusicStoreRetrieved(musicStoreUpdated); |
379 emit localMusicStoreRetrieved( musicStoreUpdated ); |
|
380 if( musicStoreUpdated ) { |
|
381 QSettings settings; |
|
382 TX_LOG_ARGS( "Storing music store value: " << mMusicStore ); |
|
383 settings.setValue( "LocalMusicStore", QVariant( mMusicStore ) ); |
|
384 } |
477 } |
385 } |
478 else { |
386 else { |
479 emit localMusicStoreRetrievalError(); |
387 emit localMusicStoreRetrievalError(); |
480 } |
388 } |
481 } |
389 } |
483 TX_LOG_ARGS( "Not supported response" ) |
391 TX_LOG_ARGS( "Not supported response" ) |
484 } |
392 } |
485 TX_EXIT |
393 TX_EXIT |
486 } |
394 } |
487 |
395 |
488 void MpQueryManager::clearThumbnails() |
|
489 { |
|
490 TX_ENTRY |
|
491 for(int i = 0; i < mThumbnailRequests.count(); ++i ) { |
|
492 mThumbnailManager->cancelRequest(mThumbnailRequests.at(i)); |
|
493 } |
|
494 mThumbnailRequests.clear(); |
|
495 for(int i = 0; i < mRecommendationAlbumArtsName.count(); ++i) { |
|
496 mThumbnailManager->deleteThumbnails(mRecommendationAlbumArtsName.at(i)); // async, returns immidiately |
|
497 } |
|
498 TX_EXIT |
|
499 } |
|
500 |
396 |
501 void MpQueryManager::reset() |
397 void MpQueryManager::reset() |
502 { |
398 { |
503 TX_ENTRY |
399 TX_ENTRY |
504 mManager->disconnect(this); |
400 mManager->disconnect(this); |
505 mAlbumArtDownloader->disconnect(this); |
401 mAlbumArtDownloader->disconnect(this); |
506 mThumbnailManager->disconnect(this); |
|
507 clearNetworkReplies(); |
402 clearNetworkReplies(); |
508 clearRecommendations(); |
403 clearRecommendations(); |
509 clearThumbnails(); |
|
510 mRecommendationAlbumArtsMap.clear(); |
404 mRecommendationAlbumArtsMap.clear(); |
511 TX_EXIT |
405 TX_EXIT |
512 } |
406 } |
513 |
407 |
514 /*! |
408 /*! |
519 TX_ENTRY_ARGS( "uri =" << uri) |
413 TX_ENTRY_ARGS( "uri =" << uri) |
520 |
414 |
521 QStringList keys; |
415 QStringList keys; |
522 keys << "artist" << "albumtitle" << "tracktitle" << "orderby"; |
416 keys << "artist" << "albumtitle" << "tracktitle" << "orderby"; |
523 |
417 |
524 // TODO: need to clarify which crition to use for sort, currently hard code to "relevancy" |
418 // "relevancy" is the selected sort order |
525 // order can be relevancy, alltimedownloads, streetreleasedate, sortname, recentdownloads |
419 // sort order types can be relevancy, alltimedownloads, streetreleasedate, sortname, recentdownloads |
526 QStringList values; |
420 QStringList values; |
527 values << mArtist << mAlbum << mTitle << QString("relevancy"); |
421 values << mArtist << mAlbum << mTitle << QString("relevancy"); |
528 TX_LOG_ARGS( "Artist: " << mArtist ); |
422 TX_LOG_ARGS( "Artist: " << mArtist ); |
529 TX_LOG_ARGS( "Album: " << mAlbum ); |
423 TX_LOG_ARGS( "Album: " << mAlbum ); |
530 TX_LOG_ARGS( "Title: " << mTitle ); |
424 TX_LOG_ARGS( "Title: " << mTitle ); |
556 } |
450 } |
557 TX_EXIT |
451 TX_EXIT |
558 return str.left( str.length() - 1 ); |
452 return str.left( str.length() - 1 ); |
559 } |
453 } |
560 |
454 |
561 /*! |
455 bool MpQueryManager::isLocalMusicStore() |
562 Sets recommendation album art |
456 { |
563 */ |
457 if( mMusicStore.isEmpty() ) { |
564 void MpQueryManager::setAlbumArtUri( const QString &albumArtUri, const QString &albumArtName ) |
458 QSettings settings; |
565 { |
459 QVariant settingsvariant = settings.value( "LocalMusicStore", "" ); |
566 // TODO: rename this function. Doing too many things |
460 mMusicStore = settingsvariant.toString(); |
567 TX_ENTRY_ARGS( "albumArtUri = " << albumArtUri ) |
461 TX_LOG_ARGS( "Got local music store from settings:" << mMusicStore ); |
568 TX_LOG_ARGS( "albumArtName = " << albumArtName ) |
462 } |
569 if ( !albumArtUri.isEmpty() && !albumArtName.isEmpty() ) { |
|
570 // TODO: this is no good to pass the address of the albumArtUri. It is an item in the list, which can cleaned |
|
571 int id = mThumbnailManager->getThumbnail( albumArtName, reinterpret_cast<void *>( const_cast<QString *>( &albumArtUri ) ) ); |
|
572 if ( id == KUndefined ) { |
|
573 // Request failed. Set default album art |
|
574 mRecommendationAlbumArtsMap.insert( albumArtUri, mDefaultRecommendationAlbumArt ); |
|
575 } |
|
576 else { |
|
577 // Async request went throu |
|
578 TX_LOG_ARGS("Request to thumbnail manager made. Id: " << id) |
|
579 mThumbnailRequests.append(id); |
|
580 mThumbnailManager->disconnect( this ); // to prevent multiple same connections with thumbnailmanager |
|
581 QObject::connect( mThumbnailManager, SIGNAL( thumbnailReady( QPixmap , void * , int , int ) ), |
|
582 this, SLOT( thumbnailReady( QPixmap , void * , int , int ) ) ); |
|
583 } |
|
584 } |
|
585 else { |
|
586 // No album art uri. Set default album art. |
|
587 mRecommendationAlbumArtsMap.insert( albumArtUri, mDefaultRecommendationAlbumArt ); |
|
588 } |
|
589 TX_EXIT |
|
590 } |
|
591 |
|
592 /*! |
|
593 Slot to handle the recommendation album art |
|
594 */ |
|
595 void MpQueryManager::thumbnailReady( |
|
596 const QPixmap pixmap, |
|
597 void *data, |
|
598 int id, |
|
599 int error ) |
|
600 { |
|
601 TX_ENTRY |
|
602 |
|
603 if( mThumbnailRequests.indexOf(id) == -1 ) { |
|
604 TX_LOG_ARGS("Warning: some old thumbnail request from previous song. Ignoring") |
|
605 return; |
|
606 } |
|
607 |
|
608 // TODO: Using data from array, which can be reset. There must be a safer way |
|
609 QString uri = *( reinterpret_cast<QString *>( data ) ); |
|
610 TX_LOG_ARGS( "Uri: " << uri ); |
|
611 |
|
612 if ( error == 0 ) { |
|
613 TX_LOG_ARGS( "album art link: " << uri ); |
|
614 mRecommendationAlbumArtsMap.insert( uri, HbIcon(QIcon(pixmap)) ); |
|
615 } |
|
616 else { |
|
617 mRecommendationAlbumArtsMap.insert( uri, mDefaultRecommendationAlbumArt ); |
|
618 } |
|
619 |
|
620 emit inspireMeItemAlbumArtReady(); |
|
621 TX_EXIT |
|
622 } |
|
623 |
|
624 bool MpQueryManager::isLocalMusicStore() const |
|
625 { |
|
626 TX_LOG_ARGS( "isLocalMusicStore = " << !mMusicStore.isEmpty() ) |
463 TX_LOG_ARGS( "isLocalMusicStore = " << !mMusicStore.isEmpty() ) |
627 return !mMusicStore.isEmpty(); |
464 return !mMusicStore.isEmpty(); |
628 } |
465 } |
629 |
466 |
630 HbIcon MpQueryManager::recommendedAlbumArt(int index) const |
467 HbIcon MpQueryManager::recommendedAlbumArt(int index) const |