|
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 container definition - Albums. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QtCore> |
|
19 |
|
20 #include <hbdocumentloader.h> |
|
21 #include <hblistview.h> |
|
22 #include <hbgroupbox.h> |
|
23 #include <hbindexfeedback.h> |
|
24 |
|
25 #include <hgmediawall.h> |
|
26 |
|
27 #include "mpcollectioncontaineralbums.h" |
|
28 #include "mpmpxcollectiondata.h" |
|
29 #include "mpcollectiondatamodel.h" |
|
30 #include "mpcollectiontbonelistdatamodel.h" |
|
31 #include "mptrace.h" |
|
32 #include "mpenginefactory.h" |
|
33 |
|
34 /*! |
|
35 \class MpCollectionContainerAlbums |
|
36 \brief Music Player collection container definition - Albums. |
|
37 |
|
38 'Albums' collection container implements the interface specified |
|
39 by MpCollectionContainer. It provides a layout and widgets for the |
|
40 'Albums' view. |
|
41 |
|
42 This container handles the following contexts: |
|
43 \li ECollectionContextAlbums |
|
44 \li ECollectionContextAlbumsTBone |
|
45 |
|
46 \sa MpCollectionContainer |
|
47 */ |
|
48 |
|
49 /*! |
|
50 Constructs the collection container. |
|
51 */ |
|
52 MpCollectionContainerAlbums::MpCollectionContainerAlbums( HbDocumentLoader *loader, QGraphicsItem *parent ) |
|
53 : MpCollectionListContainer(loader, parent), |
|
54 mTBone(0), |
|
55 mTBoneListModel(0), |
|
56 mCurrentAlbumIndex(0) |
|
57 { |
|
58 TX_LOG |
|
59 mCollectionContext = ECollectionContextAlbums; |
|
60 } |
|
61 |
|
62 /*! |
|
63 Destructs the collection container. |
|
64 */ |
|
65 MpCollectionContainerAlbums::~MpCollectionContainerAlbums() |
|
66 { |
|
67 TX_ENTRY |
|
68 delete mTBone; |
|
69 delete mList; |
|
70 delete mTBoneListModel; |
|
71 TX_EXIT |
|
72 } |
|
73 |
|
74 /*! |
|
75 Sets the data model for the container. |
|
76 */ |
|
77 void MpCollectionContainerAlbums::setDataModel( MpCollectionDataModel *dataModel ) |
|
78 { |
|
79 TX_ENTRY |
|
80 MpCollectionContainer::setDataModel(dataModel); |
|
81 if ( mCollectionContext == ECollectionContextAlbums ) { |
|
82 if ( mList ) { |
|
83 mList->setModel(dataModel); |
|
84 if ( mCollectionData->count() ) { |
|
85 mList->scrollTo( dataModel->index(mCurrentAlbumIndex, 0) ); |
|
86 } |
|
87 } |
|
88 } |
|
89 else if ( mCollectionContext == ECollectionContextAlbumsTBone ) { |
|
90 if ( mTBone ) { |
|
91 mTBone->setModel(dataModel); |
|
92 mTBone->scrollTo( dataModel->index(mCurrentAlbumIndex, 0) ); |
|
93 if ( mTBoneListModel == 0 ) { |
|
94 mTBoneListModel = new MpCollectionTBoneListDataModel(mCollectionData, MpEngineFactory::sharedEngine()->playbackData()); |
|
95 connect( mTBoneListModel, SIGNAL(albumDataChanged()), this, SLOT(albumDataChanged()) ); |
|
96 connect( mTBoneListModel, SIGNAL(albumDataAvailable()), this, SLOT(albumDataAvailable()) ); |
|
97 } |
|
98 mList->setModel(mTBoneListModel); |
|
99 if ( mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) { |
|
100 if ( mCollectionData->albumSongsCount() > 1 ) { |
|
101 emit shuffleEnabled(true); |
|
102 } |
|
103 else { |
|
104 emit shuffleEnabled(false); |
|
105 } |
|
106 } |
|
107 else { |
|
108 emit findAlbumSongs(mCurrentAlbumIndex); |
|
109 emit shuffleEnabled(false); |
|
110 } |
|
111 } |
|
112 } |
|
113 TX_EXIT |
|
114 } |
|
115 |
|
116 /*! |
|
117 Slot to be called when an item is selected by the user. |
|
118 */ |
|
119 void MpCollectionContainerAlbums::itemActivated( const QModelIndex &index ) |
|
120 { |
|
121 if ( mCollectionContext == ECollectionContextAlbums ) { |
|
122 mCurrentAlbumIndex = index.row(); |
|
123 TX_ENTRY_ARGS("mCurrentAlbumIndex=" << mCurrentAlbumIndex); |
|
124 MpCollectionListContainer::itemActivated(index); |
|
125 } |
|
126 else if ( mCollectionContext == ECollectionContextAlbumsTBone ) { |
|
127 int row = index.row(); |
|
128 TX_ENTRY_ARGS("index=" << row); |
|
129 if ( mViewMode == MpCommon::FetchView ) { |
|
130 MpCollectionListContainer::itemActivated(index); |
|
131 } |
|
132 else { |
|
133 emit playAlbumSongs(mCurrentAlbumIndex, row); |
|
134 } |
|
135 } |
|
136 TX_EXIT |
|
137 } |
|
138 |
|
139 /*! |
|
140 Slot to be called when scrolling ends in media wall and an album is centered. |
|
141 */ |
|
142 void MpCollectionContainerAlbums::albumCentered( const QModelIndex &index ) |
|
143 { |
|
144 TX_ENTRY |
|
145 if ( mCurrentAlbumIndex != index.row() ) { |
|
146 // Prevent reloading if user just moves the center album a little |
|
147 // and the same album re-centers. |
|
148 mCurrentAlbumIndex = index.row(); |
|
149 TX_LOG_ARGS("mCurrentAlbumIndex=" << mCurrentAlbumIndex); |
|
150 if ( mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) { |
|
151 if ( mCollectionData->albumSongsCount() > 1 ) { |
|
152 emit shuffleEnabled(true); |
|
153 } |
|
154 // Enable context menu |
|
155 mLongPressEnabled = true; |
|
156 } |
|
157 else { |
|
158 emit findAlbumSongs(mCurrentAlbumIndex); |
|
159 } |
|
160 } |
|
161 else { |
|
162 // Landed on the same album. Just update menu. |
|
163 if ( mCollectionData->albumSongsCount() > 1 ) { |
|
164 emit shuffleEnabled(true); |
|
165 } |
|
166 // Enable context menu |
|
167 mLongPressEnabled = true; |
|
168 } |
|
169 TX_EXIT |
|
170 } |
|
171 |
|
172 /*! |
|
173 Slot to be called data model has new data. |
|
174 Two cases: |
|
175 1) User deleted an album. |
|
176 2) User deleted last song in an album. |
|
177 */ |
|
178 void MpCollectionContainerAlbums::dataReloaded() |
|
179 { |
|
180 TX_ENTRY |
|
181 if ( mCollectionContext == ECollectionContextAlbumsTBone ) { |
|
182 if ( mCurrentAlbumIndex > 0 ) { |
|
183 --mCurrentAlbumIndex; |
|
184 } |
|
185 mTBone->scrollTo( mDataModel->index(mCurrentAlbumIndex, 0) ); |
|
186 if ( mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) { |
|
187 if ( mCollectionData->albumSongsCount() == 1 ) { |
|
188 emit shuffleEnabled(false); |
|
189 } |
|
190 } |
|
191 else { |
|
192 emit findAlbumSongs(mCurrentAlbumIndex); |
|
193 } |
|
194 } |
|
195 else { |
|
196 MpCollectionListContainer::dataReloaded(); |
|
197 } |
|
198 TX_EXIT |
|
199 } |
|
200 |
|
201 /*! |
|
202 Slot to be called data model has new data. |
|
203 User has deleted one of the songs from TBone list. |
|
204 */ |
|
205 void MpCollectionContainerAlbums::albumDataChanged() |
|
206 { |
|
207 TX_ENTRY |
|
208 emit findAlbumSongs(mCurrentAlbumIndex); |
|
209 emit shuffleEnabled(false); |
|
210 TX_EXIT |
|
211 } |
|
212 |
|
213 /*! |
|
214 Slot to be called TBone starts scrolling. |
|
215 */ |
|
216 void MpCollectionContainerAlbums::scrollingStarted() |
|
217 { |
|
218 TX_ENTRY |
|
219 // Disable shuffle action from the menu |
|
220 emit shuffleEnabled(false); |
|
221 // Disable context menu |
|
222 mLongPressEnabled = false; |
|
223 TX_EXIT |
|
224 } |
|
225 |
|
226 /*! |
|
227 Slot to be called album data is available. This is a result of findAlbumSongs signal. |
|
228 */ |
|
229 void MpCollectionContainerAlbums::albumDataAvailable() |
|
230 { |
|
231 TX_ENTRY |
|
232 int count = mCollectionData->albumSongsCount(); |
|
233 if ( count > 1 ) { |
|
234 emit shuffleEnabled(true); |
|
235 } |
|
236 // Enable context menu |
|
237 mLongPressEnabled = true; |
|
238 TX_EXIT |
|
239 } |
|
240 |
|
241 /*! |
|
242 Sets up the container by organizing widgets according to its layout. |
|
243 |
|
244 \reimp |
|
245 */ |
|
246 void MpCollectionContainerAlbums::setupContainer() |
|
247 { |
|
248 TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext); |
|
249 |
|
250 mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "showInfoBar"); |
|
251 |
|
252 if ( mCollectionData->count() ) { |
|
253 bool ok = false; |
|
254 QGraphicsWidget *widget; |
|
255 if ( mCollectionContext == ECollectionContextAlbums ) { |
|
256 mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "albums", &ok); |
|
257 if ( !ok ) { |
|
258 TX_LOG_ARGS("Error: invalid xml file."); |
|
259 Q_ASSERT_X(ok, "MpCollectionContainerAlbums::setupContainer", "invalid xml file"); |
|
260 } |
|
261 if ( !mList ) { |
|
262 widget = mDocumentLoader->findWidget(QString("albumsList")); |
|
263 mList = qobject_cast<HbListView*>(widget); |
|
264 mIndexFeedback->setItemView(mList); |
|
265 initializeList(); |
|
266 } |
|
267 if ( mTBone ) { |
|
268 delete mTBone; |
|
269 mTBone = 0; |
|
270 } |
|
271 |
|
272 mInfoBar->setHeading(hbTrId("txt_mus_subhead_albums_1l").arg(mCollectionData->count())); |
|
273 |
|
274 } |
|
275 else if ( mCollectionContext == ECollectionContextAlbumsTBone ) { |
|
276 if ( mViewMode == MpCommon::FetchView ) { |
|
277 mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "albumTBoneFetcher", &ok); |
|
278 if ( !ok ) { |
|
279 TX_LOG_ARGS("Error: invalid xml file."); |
|
280 Q_ASSERT_X(ok, "MpCollectionContainerAlbums::setupContainer", "invalid xml file"); |
|
281 } |
|
282 |
|
283 mInfoBar->setHeading(hbTrId("txt_mus_subtitle_select_song")); |
|
284 } |
|
285 else { |
|
286 mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "albumTBone", &ok); |
|
287 if ( !ok ) { |
|
288 TX_LOG_ARGS("Error: invalid xml file."); |
|
289 Q_ASSERT_X(ok, "MpCollectionContainerAlbums::setupContainer", "invalid xml file"); |
|
290 } |
|
291 |
|
292 mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "hideInfoBar"); |
|
293 |
|
294 } |
|
295 widget = mDocumentLoader->findWidget(QString("albumWall")); |
|
296 mTBone = qobject_cast<HgMediawall*>(widget); |
|
297 HbIcon defaultIcon( "qtg_large_album_art" ); |
|
298 defaultIcon.setSize(mTBone->itemSize()); |
|
299 mTBone->setDefaultImage( defaultIcon.pixmap().toImage() ); |
|
300 mTBone->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff ); |
|
301 mTBone->enableReflections(true); |
|
302 connect( mTBone, SIGNAL(scrollingStarted()), this, SLOT(scrollingStarted()) ); |
|
303 connect( mTBone, SIGNAL(animationAboutToEnd(QModelIndex)), this, SLOT(albumCentered(QModelIndex)) ); |
|
304 } |
|
305 } |
|
306 else { |
|
307 // Must delete widgets when last song is deleted and view is reloaded. |
|
308 if ( mTBone ) { |
|
309 delete mTBone; |
|
310 mTBone = 0; |
|
311 } |
|
312 |
|
313 mInfoBar->setHeading(hbTrId("txt_mus_subhead_albums_1l").arg(0)); |
|
314 |
|
315 // Call empty list from base class |
|
316 setupEmptyListContainer(); |
|
317 } |
|
318 TX_EXIT |
|
319 } |
|
320 |