|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Music Player collection data model. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QBrush> |
|
19 #include <QColor> |
|
20 |
|
21 #include <hbicon.h> |
|
22 |
|
23 #include "mpcollectiondatamodel.h" |
|
24 #include "mpcollectionalbumartmanager.h" |
|
25 #include "mpmpxcollectiondata.h" |
|
26 #include "mptrace.h" |
|
27 |
|
28 const int KInitCacheSize = 11; |
|
29 |
|
30 /*! |
|
31 \class MpCollectionDataModel |
|
32 \brief Music Player collection data model. |
|
33 |
|
34 Collection data model implements the interface specified by HbAbstractDataModel, |
|
35 which defines the standard interface that item models must use to be able to |
|
36 interoperate with other components in the model/view architecture. |
|
37 |
|
38 Every item of data that can be accessed via a model has an associated model |
|
39 index. |
|
40 |
|
41 Each item has a number of data elements associated with it and they can be |
|
42 retrieved by specifying a role (see Qt::ItemDataRole) to the model's data |
|
43 returned by itemData() function. |
|
44 |
|
45 \sa HbAbstractDataModel |
|
46 */ |
|
47 |
|
48 /*! |
|
49 Constructs the collection data model. |
|
50 */ |
|
51 MpCollectionDataModel::MpCollectionDataModel( MpMpxCollectionData *data, QObject *parent ) |
|
52 : QAbstractListModel(parent), |
|
53 mCollectionData(data), |
|
54 mRowCount(0), |
|
55 mCachingInProgress(false) |
|
56 { |
|
57 TX_ENTRY |
|
58 mAlbumArtManager = new MpCollectionAlbumArtManager(); |
|
59 connect( mAlbumArtManager, SIGNAL(albumArtReady(int)), this, SLOT(updateAlbumArt(int)) ); |
|
60 connect( mAlbumArtManager, SIGNAL(albumCacheReady()), this, SLOT(albumCacheReady()) ); |
|
61 TX_EXIT |
|
62 } |
|
63 |
|
64 /*! |
|
65 Destructs the collection data model. |
|
66 */ |
|
67 MpCollectionDataModel::~MpCollectionDataModel() |
|
68 { |
|
69 TX_ENTRY |
|
70 delete mAlbumArtManager; |
|
71 TX_EXIT |
|
72 } |
|
73 |
|
74 /*! |
|
75 Returns the number of rows under the given \a parent. |
|
76 |
|
77 View will request for the row count immediately after a model is set. |
|
78 To prevent it from reading data while caching the album art for the first |
|
79 screen, return row count as zero. |
|
80 |
|
81 \reimp |
|
82 */ |
|
83 int MpCollectionDataModel::rowCount( const QModelIndex &parent ) const |
|
84 { |
|
85 TX_LOG |
|
86 Q_UNUSED(parent); |
|
87 if ( mCachingInProgress ) { |
|
88 return 0; |
|
89 } |
|
90 else { |
|
91 return mRowCount; |
|
92 } |
|
93 } |
|
94 |
|
95 /*! |
|
96 Returns the data stored for the item referred to by the \a index. |
|
97 |
|
98 \reimp |
|
99 */ |
|
100 QVariant MpCollectionDataModel::data(const QModelIndex &index, int role) const |
|
101 { |
|
102 TX_ENTRY |
|
103 QVariant returnValue = QVariant(); |
|
104 if ( !index.isValid() ) { |
|
105 return returnValue; |
|
106 } |
|
107 |
|
108 int row = index.row(); |
|
109 TX_LOG_ARGS("index=" << row << ", role=" << role); |
|
110 TCollectionContext context = mCollectionData->context(); |
|
111 if ( role == Qt::DisplayRole ) { |
|
112 QStringList display; |
|
113 // Fetch the primary text, which is the title, if available. |
|
114 QString primaryText; |
|
115 primaryText = mCollectionData->itemData(row, MpMpxCollectionData::Title); |
|
116 if ( !primaryText.isEmpty() ) { |
|
117 display << primaryText; |
|
118 } |
|
119 else { |
|
120 display << QString( tr("Unknown") ); |
|
121 } |
|
122 |
|
123 // Fetch the secondary text, which depends on the current context, if available. |
|
124 QString secondaryText; |
|
125 switch ( context ) { |
|
126 case ECollectionContextAllSongs: |
|
127 case ECollectionContextArtistAlbums: |
|
128 case ECollectionContextPlaylistSongs: |
|
129 secondaryText = mCollectionData->itemData(row, MpMpxCollectionData::Artist); |
|
130 if ( !secondaryText.isEmpty() ) { |
|
131 display << secondaryText; |
|
132 } |
|
133 else { |
|
134 display << QString( tr("Unknown") ); |
|
135 } |
|
136 break; |
|
137 case ECollectionContextPlaylists: |
|
138 secondaryText = mCollectionData->itemData(row, MpMpxCollectionData::Count); |
|
139 if ( !secondaryText.isEmpty() ) { |
|
140 display << secondaryText; |
|
141 } |
|
142 break; |
|
143 } |
|
144 returnValue = display; |
|
145 } |
|
146 else if ( role == Qt::DecorationRole ) { |
|
147 switch ( context ) { |
|
148 case ECollectionContextArtistAlbums: |
|
149 bool defaultArt = true; |
|
150 QString albumArtUri = mCollectionData->itemData(row, MpMpxCollectionData::AlbumArtUri); |
|
151 if ( !albumArtUri.isEmpty() ) { |
|
152 HbIcon icon = mAlbumArtManager->albumArt(albumArtUri, row); |
|
153 if ( !icon.isNull() ) { |
|
154 returnValue = icon; |
|
155 defaultArt = false; |
|
156 } |
|
157 } |
|
158 if ( defaultArt ) { |
|
159 // No album art, use default album art |
|
160 HbIcon icon(QString(":/icons/default_album.png")); |
|
161 returnValue = icon; |
|
162 } |
|
163 break; |
|
164 } |
|
165 } |
|
166 TX_EXIT |
|
167 return returnValue; |
|
168 } |
|
169 |
|
170 /*! |
|
171 Must be called when data has changed and model needs to be refreshed |
|
172 to reflect the new data. |
|
173 */ |
|
174 void MpCollectionDataModel::refreshModel() |
|
175 { |
|
176 TX_ENTRY |
|
177 // Cancel all outstanding album art request first, then reset the model. |
|
178 mAlbumArtManager->cancel(); |
|
179 mRowCount = mCollectionData->count(); |
|
180 |
|
181 TCollectionContext context = mCollectionData->context(); |
|
182 if ( context == ECollectionContextArtistAlbums ) { |
|
183 // Before providing the new data to the view (list, grid, etc.), we want |
|
184 // to make sure that we have enough album arts for the first screen. |
|
185 if ( mRowCount > 0 ) { |
|
186 int initCount = ( mRowCount > KInitCacheSize ) ? KInitCacheSize : mRowCount; |
|
187 QStringList albumArtList; |
|
188 QString albumArtUri; |
|
189 for ( int i = 0; i < initCount; i++ ) { |
|
190 albumArtUri = mCollectionData->itemData(i, MpMpxCollectionData::AlbumArtUri); |
|
191 if ( !albumArtUri.isEmpty() ) { |
|
192 albumArtList << albumArtUri; |
|
193 } |
|
194 } |
|
195 mCachingInProgress = mAlbumArtManager->cacheAlbumArt(albumArtList); |
|
196 if ( !mCachingInProgress ) { |
|
197 reset(); |
|
198 } |
|
199 } |
|
200 else { |
|
201 reset(); |
|
202 } |
|
203 } |
|
204 else { |
|
205 reset(); |
|
206 } |
|
207 TX_EXIT |
|
208 } |
|
209 |
|
210 /*! |
|
211 Returns pointer to MpMpxCollectionData, which is the collection data. |
|
212 */ |
|
213 MpMpxCollectionData *MpCollectionDataModel::collectionData() |
|
214 { |
|
215 return mCollectionData; |
|
216 } |
|
217 |
|
218 /*! |
|
219 Slot to be called when album art for the \a index needs to be updated. |
|
220 */ |
|
221 void MpCollectionDataModel::updateAlbumArt( int index ) |
|
222 { |
|
223 TX_ENTRY_ARGS("index=" << index); |
|
224 if ( index > 0 && index < mRowCount ) { |
|
225 QModelIndex modelIndex = QAbstractItemModel::createIndex(index, 0); |
|
226 emit dataChanged(modelIndex, modelIndex); |
|
227 } |
|
228 TX_EXIT |
|
229 } |
|
230 |
|
231 /*! |
|
232 Slot to be called when album art cache is ready. |
|
233 */ |
|
234 void MpCollectionDataModel::albumCacheReady() |
|
235 { |
|
236 TX_ENTRY |
|
237 if ( mCachingInProgress ) { |
|
238 mCachingInProgress = false; |
|
239 reset(); |
|
240 } |
|
241 TX_EXIT |
|
242 } |