--- a/mpviewplugins/mpcollectionviewplugin/src/mpcollectioncontainerartists.cpp Fri May 14 15:49:53 2010 +0300
+++ b/mpviewplugins/mpcollectionviewplugin/src/mpcollectioncontainerartists.cpp Thu May 27 12:49:57 2010 +0300
@@ -22,8 +22,12 @@
#include <hbgroupbox.h>
#include <hbindexfeedback.h>
+#include <hgmediawall.h>
+
#include "mpcollectioncontainerartists.h"
#include "mpmpxcollectiondata.h"
+#include "mpcollectiondatamodel.h"
+#include "mpcollectiontbonelistdatamodel.h"
#include "mptrace.h"
/*!
@@ -37,8 +41,9 @@
This container handles the following contexts:
\li ECollectionContextArtists
\li ECollectionContextArtistAlbums
- \li ECollectionContextArtistSongs
-
+ \li ECollectionContextArtistAlbumsTBone
+ \li ECollectionContextArtistAllSongs
+
\sa MpCollectionContainer
*/
@@ -47,9 +52,14 @@
*/
MpCollectionContainerArtists::MpCollectionContainerArtists( HbDocumentLoader *loader, QGraphicsItem *parent )
: MpCollectionListContainer(loader, parent),
- mInfoBar(0)
+ mInfoBar(0),
+ mTBone(0),
+ mTBoneListModel(0),
+ mCurrentArtistIndex(0),
+ mCurrentAlbumIndex(0)
{
TX_LOG
+ mCollectionContext = ECollectionContextArtists;
}
/*!
@@ -59,7 +69,89 @@
{
TX_ENTRY
delete mInfoBar;
+ delete mTBone;
delete mList;
+ delete mTBoneListModel;
+ TX_EXIT
+}
+
+/*!
+ Sets the data model for the container.
+ */
+void MpCollectionContainerArtists::setDataModel( MpCollectionDataModel *dataModel )
+{
+ TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext);
+ MpCollectionContainer::setDataModel(dataModel);
+ int count = mCollectionData->count();
+ switch ( mCollectionContext ) {
+ case ECollectionContextArtists:
+ if ( mList ) {
+ mList->setModel(dataModel);
+ if ( count ) {
+ if ( mCurrentArtistIndex >= count ) {
+ // This can happen if the last item is deleted
+ mCurrentArtistIndex = count - 1;
+ }
+ mList->scrollTo( dataModel->index(mCurrentArtistIndex, 0) );
+ }
+ // Reset the current album index for navigation:
+ // ECollectionContextArtistAlbums -> ECollectionContextArtists
+ mCurrentAlbumIndex = 0;
+ }
+ break;
+ case ECollectionContextArtistAlbums:
+ if ( mList ) {
+ mList->setModel(dataModel);
+ if ( count ) {
+ if ( mCurrentAlbumIndex >= count ) {
+ // This can happen if the last item is deleted
+ mCurrentAlbumIndex = count - 1;
+ }
+ mList->scrollTo( dataModel->index(mCurrentAlbumIndex, 0) );
+ }
+ // Reset the album index offset for navigation:
+ // ECollectionContextArtistAlbumsTBone -> ECollectionContextArtistAlbums
+ mAlbumIndexOffset = 0;
+ }
+ break;
+ case ECollectionContextArtistAlbumsTBone:
+ if ( mTBone ) {
+ if ( count > 1 ) {
+ // Selected artist has more than 1 album and therefore the
+ // artist's "All songs" exist. Since we don't show artist's
+ // "All songs" in TBone, we need to set an offset.
+ mAlbumIndexOffset = 1;
+ }
+ else {
+ // Selected artist has exactly 1 album and therefore the
+ // artist's "All songs" doesn't exist.
+ mAlbumIndexOffset = 0;
+ }
+ if ( mCurrentAlbumIndex >= count ) {
+ // This can happen if the last item is deleted
+ mCurrentAlbumIndex = count - 1;
+ }
+ mTBone->setModel(dataModel);
+ mTBone->scrollTo( dataModel->index(mCurrentAlbumIndex - mAlbumIndexOffset, 0) );
+ if ( mTBoneListModel == 0 ) {
+ mTBoneListModel = new MpCollectionTBoneListDataModel(mCollectionData);
+ connect( mTBoneListModel, SIGNAL(albumDataChanged()), this, SLOT(albumDataChanged()) );
+ }
+ mList->setModel(mTBoneListModel);
+
+ if ( !mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) {
+ emit findAlbumSongs(mCurrentAlbumIndex);
+ }
+ }
+ break;
+ case ECollectionContextArtistAllSongs:
+ if ( mList ) {
+ mList->setModel(dataModel);
+ }
+ break;
+ default:
+ break;
+ }
TX_EXIT
}
@@ -69,21 +161,89 @@
void MpCollectionContainerArtists::itemActivated( const QModelIndex &index )
{
int row = index.row();
- TX_ENTRY_ARGS("index=" << row);
-
- if ( mCollectionContext == ECollectionContextArtists ) {
- mArtist = mCollectionData->itemData(row, MpMpxCollectionData::Title);
- if ( mArtist.isEmpty() ) {
- mArtist = hbTrId("txt_mus_subtitle_unknown");
+ TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext << "index=" << row);
+ switch ( mCollectionContext ) {
+ case ECollectionContextArtists:
+ mCurrentArtistIndex = row;
+ TX_LOG_ARGS("mCurrentArtistIndex=" << mCurrentArtistIndex);
+ MpCollectionListContainer::itemActivated(index);
+ break;
+ case ECollectionContextArtistAlbums:
+ mCurrentAlbumIndex = row;
+ TX_LOG_ARGS("mCurrentAlbumIndex=" << mCurrentAlbumIndex);
+ MpCollectionListContainer::itemActivated(index);
+ break;
+ case ECollectionContextArtistAlbumsTBone:
+ TX_LOG_ARGS("mCurrentAlbumIndex=" << mCurrentAlbumIndex);
+ if ( mViewMode == MpCommon::FetchView ) {
+ MpCollectionListContainer::itemActivated(index);
+ }
+ else {
+ emit playAlbumSongs(mCurrentAlbumIndex, row);
+ }
+ break;
+ case ECollectionContextArtistAllSongs:
+ MpCollectionListContainer::itemActivated(index);
+ break;
+ default:
+ break;
+ }
+ TX_EXIT
+}
+
+/*!
+ Slot to be called when scrolling ends in media wall and an album is centered.
+ */
+void MpCollectionContainerArtists::albumCentered()
+{
+ TX_ENTRY
+ int index = mTBone->currentIndex().row();
+ TX_LOG_ARGS("index=" << index);
+ index += mAlbumIndexOffset;
+ if ( mCurrentAlbumIndex != index ) {
+ // Prevent reloading if user just moves the center album a little
+ // and the same album re-centers.
+ mCurrentAlbumIndex = index;
+ TX_LOG_ARGS("mCurrentAlbumIndex=" << mCurrentAlbumIndex);
+ if ( !mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) {
+ emit findAlbumSongs(mCurrentAlbumIndex);
}
}
- else if ( mCollectionContext == ECollectionContextArtistAlbums ) {
- mAlbum = mCollectionData->itemData(row, MpMpxCollectionData::Title);
- if ( mAlbum.isEmpty() ) {
- mAlbum = hbTrId("txt_mus_dblist_val_unknown3");
+ TX_EXIT
+}
+
+/*!
+ Slot to be called data model has new data. This occurs after a delete operation is complete.
+ Two cases:
+ 1) User deleted an artist.
+ 2) User deleted last song in an album.
+ */
+void MpCollectionContainerArtists::dataReloaded()
+{
+ TX_ENTRY
+ if ( mCollectionContext == ECollectionContextArtistAlbumsTBone ) {
+ if ( mCurrentAlbumIndex > 0 ) {
+ --mCurrentAlbumIndex;
+ }
+ mTBone->scrollTo( mDataModel->index(mCurrentAlbumIndex - mAlbumIndexOffset, 0) );
+ if ( !mCollectionData->setCurrentAlbum(mCurrentAlbumIndex) ) {
+ emit findAlbumSongs(mCurrentAlbumIndex);
}
}
- MpCollectionListContainer::itemActivated(index);
+ else {
+ MpCollectionListContainer::dataReloaded();
+ }
+ TX_EXIT
+}
+
+/*!
+ Slot to be called data model has new data.
+ User has deleted one of the songs from TBone list.
+ */
+void MpCollectionContainerArtists::albumDataChanged()
+{
+ TX_ENTRY
+ emit findAlbumSongs(mCurrentAlbumIndex);
TX_EXIT
}
@@ -98,93 +258,114 @@
if ( mCollectionData->count() ) {
bool ok = false;
QGraphicsWidget *widget;
- if ( mCollectionContext == ECollectionContextArtists ) {
- mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artists", &ok);
- if ( !ok ) {
- TX_LOG_ARGS("Error: invalid xml file.");
- Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
- }
- if ( !mList ) {
- widget = mDocumentLoader->findWidget(QString("artistsList"));
- mList = qobject_cast<HbListView*>(widget);
- mIndexFeedback->setItemView(mList);
- initializeList();
- }
- if ( mInfoBar ) {
- delete mInfoBar;
- mInfoBar = 0;
- }
- }
- else if ( mCollectionContext == ECollectionContextArtistAlbums ) {
- mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistSongs", &ok);
- if ( !ok ) {
- TX_LOG_ARGS("Error: invalid xml file.");
- Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
- }
-
- widget = mDocumentLoader->findWidget(QString("artistSongsDetail"));
- mInfoBar = qobject_cast<HbGroupBox*>(widget);
-
- QString details;
- if ( mViewMode == MpCommon::FetchView ) {
- details = "Select a song";
- }
- else {
- details = mArtist;
- }
- mInfoBar->setHeading(details);
+ QString artist;
+ switch ( mCollectionContext ) {
+ case ECollectionContextArtists:
+ mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artists", &ok);
+ if ( !ok ) {
+ TX_LOG_ARGS("Error: invalid xml file.");
+ Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
+ }
+ if ( !mList ) {
+ widget = mDocumentLoader->findWidget(QString("artistsList"));
+ mList = qobject_cast<HbListView*>(widget);
+ mIndexFeedback->setItemView(mList);
+ initializeList();
+ }
+ if ( mInfoBar ) {
+ delete mInfoBar;
+ mInfoBar = 0;
+ }
+ if ( mTBone ) {
+ delete mTBone;
+ mTBone = 0;
+ }
+ break;
+ case ECollectionContextArtistAlbums:
+ mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistAlbums", &ok);
+ if ( !ok ) {
+ TX_LOG_ARGS("Error: invalid xml file.");
+ Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
+ }
+ widget = mDocumentLoader->findWidget(QString("artistDetail"));
+ mInfoBar = qobject_cast<HbGroupBox*>(widget);
+
+ artist = mCollectionData->collectionTitle();
+ if ( artist.isEmpty() ) {
+ artist = hbTrId("txt_mus_subtitle_unknown");
+ }
+ mInfoBar->setHeading(artist);
+ if ( mTBone ) {
+ delete mTBone;
+ mTBone = 0;
+ }
+ break;
+ case ECollectionContextArtistAlbumsTBone:
+ {
+ if ( mViewMode == MpCommon::FetchView ) {
+ mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistAlbumTBoneFetcher", &ok);
+ if ( !ok ) {
+ TX_LOG_ARGS("Error: invalid xml file.");
+ Q_ASSERT_X(ok, "MpCollectionContainerAlbums::setupContainer", "invalid xml file");
+ }
+ widget = mDocumentLoader->findWidget(QString("artistDetail"));
+ mInfoBar = qobject_cast<HbGroupBox*>(widget);
+ mInfoBar->setHeading( hbTrId("txt_mus_subtitle_select_a_song") );
+ }
+ else {
+ mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistAlbumTBone", &ok);
+ if ( !ok ) {
+ TX_LOG_ARGS("Error: invalid xml file.");
+ Q_ASSERT_X(ok, "MpCollectionContainerAlbums::setupContainer", "invalid xml file");
+ }
+ if ( mInfoBar ) {
+ delete mInfoBar;
+ mInfoBar = 0;
+ }
+ }
+ widget = mDocumentLoader->findWidget(QString("artistAlbumWall"));
+ mTBone = qobject_cast<HgMediawall*>(widget);
+ HbIcon defaultIcon( "qtg_large_music_album" );
+ defaultIcon.setSize(mTBone->itemSize());
+ mTBone->setDefaultImage( defaultIcon.pixmap().toImage() );
+ mTBone->setTitleFontSpec( HbFontSpec(HbFontSpec::Primary) );
+ mTBone->setDescriptionFontSpec( HbFontSpec(HbFontSpec::Secondary) );
+ mTBone->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff );
+ mTBone->enableReflections(true);
+ connect( mTBone, SIGNAL(scrollingEnded()), this, SLOT(albumCentered()) );
+ }
+ break;
+ case ECollectionContextArtistAllSongs:
+ // No need to load anything. Just reuse the section "artistAlbums" loaded
+ // in ECollectionContextArtistAlbums context.
+ if ( mViewMode == MpCommon::FetchView ) {
+ mInfoBar->setHeading( hbTrId("txt_mus_subtitle_select_a_song") );
+ }
+ else {
+ artist = mCollectionData->collectionTitle();
+ if ( artist.isEmpty() ) {
+ artist = hbTrId("txt_mus_subtitle_unknown_all");
+ }
+ else {
+ artist = hbTrId("txt_mus_subtitle_1_all").arg(artist);
+ }
+ mInfoBar->setHeading(artist);
+ }
+ break;
+ default:
+ break;
}
- else if ( mCollectionContext == ECollectionContextAlbumSongs ) {
- mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistSongs", &ok);
- if ( !ok ) {
- TX_LOG_ARGS("Error: invalid xml file.");
- Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
- }
-
- widget = mDocumentLoader->findWidget(QString("artistSongsDetail"));
- mInfoBar = qobject_cast<HbGroupBox*>(widget);
-
- QString details;
- if ( mViewMode == MpCommon::FetchView ) {
- details = "Select a song";
- }
- else {
- details = mArtist;
- details.append(" - ");
- details.append(mAlbum);
- }
- mInfoBar->setHeading(details);
- }
- else if ( mCollectionContext == ECollectionContextArtistSongs ) {
- mDocumentLoader->load(QString(":/docml/musiccollection.docml"), "artistSongs", &ok);
- if ( !ok ) {
- TX_LOG_ARGS("Error: invalid xml file.");
- Q_ASSERT_X(ok, "MpCollectionContainerArtists::setupContainer", "invalid xml file");
- }
-
- widget = mDocumentLoader->findWidget(QString("artistSongsDetail"));
- mInfoBar = qobject_cast<HbGroupBox*>(widget);
-
- QString details;
- if ( mViewMode == MpCommon::FetchView ) {
- details = "Select a song";
- }
- else if ( mArtist.isEmpty() ) {
- details = hbTrId("txt_mus_subtitle_unknown_all");
- }
- else{
- details = hbTrId( "txt_mus_subtitle_1_all" ).arg(mArtist);
-
- }
- mInfoBar->setHeading(details);
- }
- }
+ }
else {
+ // Must delete widgets when last song is deleted and view is reloaded.
if ( mInfoBar ) {
- // When last song in an album is deleted and album list is reloaded
delete mInfoBar;
mInfoBar = 0;
}
+ if ( mTBone ) {
+ delete mTBone;
+ mTBone = 0;
+ }
// Call empty list from base class
setupEmptyListContainer();
}