diff -r 3ec52facab4d -r 8192e5b5c935 mpviewplugins/mpcollectionviewplugin/src/mpcollectioncontainerartists.cpp --- 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 #include +#include + #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(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(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(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(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(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(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(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(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(); }