mpviewplugins/mpcollectionviewplugin/src/mpcollectionview.cpp
changeset 19 4e84c994a771
child 20 82baf59ce8dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpviewplugins/mpcollectionviewplugin/src/mpcollectionview.cpp	Fri Mar 19 09:28:13 2010 +0200
@@ -0,0 +1,1231 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Music Player collection view.
+*
+*/
+
+// INCLUDE FILES
+#include <time.h>
+#include <cstdlib>
+#include <qtcore>
+
+#include <hbinstance.h>
+#include <hbapplication.h>
+#include <hbaction.h>
+#include <hbtoolbar.h>
+#include <hbmenu.h>
+#include <hbmessagebox.h>
+#include <hblistdialog.h>
+#include <hbinputdialog.h>
+#include <hblabel.h>
+
+#include "mpcollectionview.h"
+#include "mpcollectiondocumentloader.h"
+#include "mpcollectioncontainerfactory.h"
+#include "mpcollectioncontainer.h"
+#include "mpcollectiondatamodel.h"
+#include "mpcollectionsongscanner.h"
+#include "mpmpxframeworkwrapper.h"
+#include "mpmpxcollectiondata.h"
+#include "mpnowplayingwidget.h"
+#include "mpcommondefs.h"
+#include "mptrace.h"
+#include "mpsnapshotwidget.h"
+#include "mpsettingsmanager.h"
+
+
+const char*MUSIC_COLLECTION_DOCML = ":/docml/musiccollection.docml";
+const char*EFFECT_SELECT = ":/effects/select.fxml";
+const char*EFFECT_SELECT_END = ":/effects/select_end.fxml";
+
+const int KMainToolBarAll = 0;
+const int KMainToolBarArtists = 1;
+const int KMainToolBarPlaylists = 2;
+
+//const int KPlaylistToolBarAdd = 0;
+const int KPlaylistToolBarRemove = 1;
+const int KplaylistToolBarReorder = 2;
+
+
+
+/*!
+    \class MpCollectionView
+    \brief Music Player collection view.
+
+    Collection view provides access to music collection in the device.
+    This class owns the menu and the toolbar. In addition, it is
+    responsible for creating UI containers and the underlying engine
+    components and connecting them to work together.
+*/
+
+/*!
+    \fn void command( int command )
+
+    This signal is emitted when the view issues a \a command to the
+    application such as request to switch to a different view.
+ */
+
+/*!
+ Constructs the collection view.
+ */
+MpCollectionView::MpCollectionView()
+    : mCollectionContext(ECollectionContextUnknown),
+      mMpxWrapper(0),
+      mContainerFactory(0),
+      mCollectionContainer(0),
+      mCollectionDataModel(0),
+      mActivated(false),
+      mNowPlayingBanner(0),
+      mBannerAttached(false),
+      mEffectOnGoing(false),
+      mDocumentLoader(0),
+      mMainContainer(0),
+      mMainToolBar(0),
+      mPlaylistToolBar(0),
+      mSnapshot(0),
+      mSongScanner(0),
+      mScanning(false)
+{
+    TX_LOG
+}
+
+/*!
+ Destructs the collection view.
+ */
+MpCollectionView::~MpCollectionView()
+{
+    TX_ENTRY
+    delete mSongScanner;
+    delete mSnapshot;
+    delete mSoftKeyQuit;
+    delete mSoftKeyBack;
+
+    HbToolBar *toolBar = takeToolBar();
+    if ( mMainToolBar != toolBar && mPlaylistToolBar != toolBar ) {
+        delete toolBar;
+    }
+    if ( mMainToolBar) {
+        mMainToolBar->deleteLater();
+    }
+    if ( mPlaylistToolBar ) {
+        mPlaylistToolBar->deleteLater();
+    }
+    
+    delete mCollectionDataModel;
+    delete mCollectionContainer;
+    delete mContainerFactory;
+    delete mMpxWrapper;
+    delete mDocumentLoader;
+    TX_EXIT
+}
+
+/*!
+ Initializes the collection view. Allocates all resources needed by the view.
+ */
+void MpCollectionView::initializeView()
+{
+    TX_ENTRY
+
+    mWindow = mainWindow();
+
+    // Create softkey actions
+    mSoftKeyQuit = new HbAction(Hb::QuitAction, this);
+    connect( mSoftKeyQuit, SIGNAL(triggered()), this, SLOT(back()) );
+
+    mSoftKeyBack = new HbAction(Hb::BackAction, this);
+    connect( mSoftKeyBack, SIGNAL(triggered()), this, SLOT(back()) );
+
+    mMpxWrapper = new MpMpxFrameworkWrapper(mViewMode);
+    connect( mMpxWrapper, SIGNAL(collectionPlaylistOpened()), this, SLOT(startPlaybackView()) );
+    connect( mMpxWrapper, SIGNAL(playlistSaved(bool)), this, SLOT(playlistSaved(bool)), Qt::QueuedConnection );
+    connect( mMpxWrapper, SIGNAL(songsDeleted(bool)), this, SLOT(songsDeleted(bool)), Qt::QueuedConnection );
+    connect( mMpxWrapper, SIGNAL(playlistsRenamed(bool)), this, SLOT(playlistsRenamed(bool)), Qt::QueuedConnection );
+    mCollectionData = mMpxWrapper->collectionData();
+    connect( mCollectionData, SIGNAL(contextChanged(TCollectionContext)), this, SLOT(setContext(TCollectionContext)) );
+    mCollectionDataModel = new MpCollectionDataModel( mCollectionData );
+
+    mDocumentLoader = new MpCollectionDocumentLoader();
+    bool ok = false;
+    mDocumentLoader->load( MUSIC_COLLECTION_DOCML, &ok );
+    if ( ok ) {
+        QGraphicsWidget *widget;
+
+        widget = mDocumentLoader->findWidget(QString("nowPlaying"));
+        mNowPlayingBanner = qobject_cast<MpNowPlayingWidget*>(widget);
+
+        if ( mViewMode == MpCommon::FetchView ) {
+            // Banner is not needed since playback is stopped when returning
+            // from playback preview. Disable the banner from updating.
+            mNowPlayingBanner->setEnabled(false);
+        }
+        else {
+            connect( mNowPlayingBanner, SIGNAL(clicked()), this, SLOT(nowPlayingBannerActivated()) );
+            connect( mNowPlayingBanner, SIGNAL(playbackAttachmentChanged(bool)), this, SLOT(attachNowPlayingBanner(bool)) );
+            HbEffect::add( QString("banner"), EFFECT_SELECT, QString("chosen") );
+            HbEffect::add( QString("banner"), EFFECT_SELECT_END, QString("chosenEnd") );
+        }
+
+        widget = mDocumentLoader->findWidget(QString("mainContainer"));
+        mMainContainer = qobject_cast<HbWidget*>(widget);
+
+        setWidget(mMainContainer);
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_out_to_left.fxml"),
+                QString("slide_out_to_left") );
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_out_to_right.fxml"),
+                QString("slide_out_to_right") );
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_out_to_top.fxml"),
+                QString("slide_out_to_top") );
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_in_to_right_and_fade_in.fxml"),
+                QString("slide_in_to_right_and_fade_in") );
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_in_to_left_and_fade_in.fxml"),
+                QString("slide_in_to_left_and_fade_in") );
+
+        HbEffect::add(QString("container"),
+                QString(":/effects/slide_in_to_top_and_fade_in.fxml"),
+                QString("slide_in_to_top_and_fade_in") );
+    }
+    else {
+        TX_LOG_ARGS("Error: invalid xml file.");
+        Q_ASSERT_X(ok, "MpCollectionView::initializeView", "invalid xml file");
+    }
+
+    mContainerFactory = new MpCollectionContainerFactory(this, mDocumentLoader);
+
+    if ( MpSettingsManager::firstStartup() ) {
+        mSongScanner = new MpCollectionSongScanner(mMpxWrapper);
+        connect(mSongScanner, SIGNAL(scanEnded()), this, SLOT(handleScanningComplete()));
+        mScanning = true;
+        mSongScanner->scan();
+    }
+
+    TX_EXIT
+}
+
+/*!
+ Activates the collection view.
+ */
+void MpCollectionView::activateView()
+{
+    if ( mScanning ) {
+        return;
+    }
+    mActivated = true;
+    TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext);
+    if ( mCollectionContext == ECollectionContextUnknown ) {
+        // Open 'All Songs' by default
+        mMpxWrapper->openCollection( ECollectionContextAllSongs );
+    }
+    else {
+        // This true when returning from other views, e.g. playback view
+        setSoftkey();
+    }
+    TX_EXIT
+}
+
+/*!
+ Deactivates the collection view.
+ */
+void MpCollectionView::deactivateView()
+{
+    TX_ENTRY
+    clearSoftkey();
+    mActivated = false;
+    TX_EXIT
+}
+
+/*!
+ Loads the correct layout based on the \a orientation.
+ */
+void MpCollectionView::orientationChange( Qt::Orientation orientation )
+{
+    if ( mCollectionContainer ) {
+        mCollectionContainer->orientationChange(orientation);
+    }
+
+    if ( mBannerAttached ) {
+        if ( orientation == Qt::Vertical ) {
+            setBannerVisibility(true);
+        }
+        else {
+            setBannerVisibility(false);
+        }
+    }
+}
+
+/*!
+ Slot to be called when collection context is changed as a result of Open
+ operation.
+ */
+void MpCollectionView::setContext( TCollectionContext context )
+{
+    TX_ENTRY_ARGS("context=" << context);
+    if (mActivated) {
+        startContainerTransition(mCollectionContext, context);
+    }
+    mCollectionContext = context;
+    mCollectionContainer = mContainerFactory->createContainer(context);
+    mCollectionContainer->setViewMode(mViewMode);
+    mCollectionDataModel->refreshModel();
+    mCollectionContainer->setDataModel(mCollectionDataModel);
+
+    // Reset softkey and the menu
+    if (mActivated) {
+        clearSoftkey();
+        setSoftkey();
+    }
+    updateToolBar();
+    updateMenu();
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'All Songs' action is triggered from the toolbar.
+ */
+void MpCollectionView::openSongs()
+{
+    TX_ENTRY
+    mMpxWrapper->openCollection( ECollectionContextAllSongs );
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'Artists' action is triggered from the toolbar.
+ */
+void MpCollectionView::openArtists()
+{
+    TX_ENTRY
+    mMpxWrapper->openCollection( ECollectionContextArtistAlbums );
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'Playlists' action is triggered from the toolbar.
+ */
+void MpCollectionView::openPlaylists()
+{
+    TX_ENTRY
+    mMpxWrapper->openCollection( ECollectionContextPlaylists );
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'Genres' action is triggered from the toolbar.
+ */
+void MpCollectionView::openGenres()
+{
+    TX_ENTRY
+    mMpxWrapper->openCollection( ECollectionContextGenres );
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'Find' action is triggered from the toolbar.
+ */
+void MpCollectionView::find()
+{
+    // Todo
+    HbMessageBox messageBox("Not ready!", HbMessageBox::MessageTypeInformation);
+    messageBox.exec();
+    updateToolBar();
+}
+
+/*!
+ Slot to be called when 'Music Store' action is triggered from the toolbar.
+ */
+void MpCollectionView::openMusicStore()
+{
+    // Todo
+    HbMessageBox messageBox("Not ready!", HbMessageBox::MessageTypeInformation);
+    messageBox.exec();
+    updateToolBar();
+}
+
+/*!
+ Slot to be called when an item is selected by the user.
+ */
+void MpCollectionView::openIndex( int index )
+{
+    TX_ENTRY_ARGS("index=" << index);
+    bool doOpen = true;
+    if ( mViewMode == MpCommon::FetchView ) {
+        QString songUri;
+        switch ( mCollectionContext ) {
+            case ECollectionContextAllSongs:
+            case ECollectionContextAlbumSongs:
+            case ECollectionContextPlaylistSongs:
+            case ECollectionContextGenreSongs:
+                doOpen = false;
+                songUri = mCollectionData->itemData(index, MpMpxCollectionData::Uri);
+                emit songSelected(songUri);
+                break;
+            default:
+                break;
+        }
+    }
+    if ( doOpen ) {
+        mMpxWrapper->openCollectionItem( index );
+    }
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when back/quit softkey is pressed.
+ */
+void MpCollectionView::back()
+{
+    TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext);
+    bool doExit(false);
+    switch ( mCollectionContext ) {
+        case ECollectionContextAllSongs:
+        case ECollectionContextArtistAlbums:
+        case ECollectionContextPlaylists:
+        case ECollectionContextGenres:
+            // Exit from these levels.
+            doExit = true;
+            break;
+        case ECollectionContextAlbumSongs:
+        case ECollectionContextPlaylistSongs:
+        case ECollectionContextGenreSongs:
+            mMpxWrapper->back();
+            break;
+        default:
+            doExit = true;
+            break;
+    }
+
+    if ( doExit ) {
+	    if ( mViewMode == MpCommon::FetchView ) {
+            // Send an empty string to indicate that user has cancelled
+            // the fetch operation
+            emit songSelected("");
+        }
+        else {
+            emit command( MpCommon::Exit );
+        }
+    }
+    TX_EXIT
+}
+
+/*!
+ Slot to be called to exit.
+ */
+void MpCollectionView::exit()
+{
+    TX_ENTRY
+    emit command( MpCommon::Exit );
+    TX_EXIT
+}
+
+
+/*!
+ Slot to be called to activate playback view.
+ */
+void MpCollectionView::startPlaybackView()
+{
+    TX_LOG
+    emit command( MpCommon::ActivatePlaybackView );
+}
+
+/*!
+ Slot to be called when 'Now Playing Banner' state changes. If active, 'Now
+ Playing Banner' is attached/shown in the collection view.
+ */
+void MpCollectionView::attachNowPlayingBanner( bool active )
+{
+    TX_ENTRY
+    setBannerVisibility( active );
+    mBannerAttached = active;
+    updateMenu();
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when 'Now Playing Banner' is clicked by the user.
+ */
+void MpCollectionView::nowPlayingBannerActivated()
+{
+    if ( !mEffectOnGoing ) {
+        HbEffect::start(mNowPlayingBanner, QString("banner"), QString("chosen"), this, "nowPlayingBannerChosenFxComplete1");
+        mEffectOnGoing = true;
+    }
+}
+
+/*!
+ Slot for 'Now Playing Banner' effects part 1.
+ */
+void MpCollectionView::nowPlayingBannerChosenFxComplete1( const HbEffect::EffectStatus &status )
+{
+    Q_UNUSED(status);
+    HbEffect::start(mNowPlayingBanner, QString("banner"), QString("chosenEnd"), this, "nowPlayingBannerChosenFxComplete2");
+}
+
+/*!
+ Slot for 'Now Playing Banner' effects part 2. The end.
+ */
+void MpCollectionView::nowPlayingBannerChosenFxComplete2( const HbEffect::EffectStatus &status )
+{
+    Q_UNUSED(status);
+    mEffectOnGoing = false;
+    startPlaybackView();
+}
+
+/*!
+ Slot for container transition end.
+ */
+void MpCollectionView::containerTransitionComplete( const HbEffect::EffectStatus &status )
+{
+    Q_UNUSED(status);
+    qobject_cast<QGraphicsView *>(mWindow)->scene()->removeItem(mSnapshot);
+    delete mSnapshot;
+    mSnapshot = 0;
+}
+
+/*!
+ Slot to be called when 'Shuffle play all' is clicked by the user from the menu.
+ */
+void MpCollectionView::shufflePlayAll()
+{
+    mMpxWrapper->setShuffle(true);
+    MpSettingsManager::setShuffle(true);
+    int index = generateShuffleIndex();
+    openIndex(index);
+}
+
+
+/*!
+ Slot to be called when 'Refresh Library' is clicked by the user from the menu.
+ */
+void MpCollectionView::refreshLibrary()
+{
+    if ( !mSongScanner ) {
+        mSongScanner = new MpCollectionSongScanner(mMpxWrapper);
+        connect(mSongScanner, SIGNAL(scanEnded()), this, SLOT(handleScanningComplete()));
+    }
+    mScanning = true;
+    mSongScanner->scan();
+}
+
+/*!
+ Slot to be called when 'Add to playlist' is clicked by the user from the menu.
+ */
+void MpCollectionView::addToPlaylist()
+{
+    QModelIndexList SelectedModelIndexes;
+    bool ok;
+    SelectedModelIndexes = HbListDialog::getModelIndexes(QString(tr("Select songs:")), 
+            mCollectionDataModel,
+            &ok,
+            HbAbstractItemView::MultiSelection);
+                
+    if (ok && SelectedModelIndexes.count()) {
+        QList<int> selection;
+        for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) {
+            selection.append( SelectedModelIndexes.at(i).row() );
+        }
+    launchAddToPlaylistDialog(selection);
+    } 
+}
+
+/*!
+ Slot to be called when 'Delete' is clicked by the user from the menu.
+ */
+void MpCollectionView::deleteSongs()
+{
+    QModelIndexList SelectedModelIndexes;
+    bool ok;
+    SelectedModelIndexes = HbListDialog::getModelIndexes(QString(tr("Select songs:")), 
+            mCollectionDataModel,
+            &ok,
+            HbAbstractItemView::MultiSelection);
+                
+    if (ok && SelectedModelIndexes.count()) {
+        QList<int> selection;
+        for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) {
+            selection.append( SelectedModelIndexes.at(i).row() );
+        }
+    requestDelete(selection);
+    updateMenu();
+    }
+}
+
+/*!
+ Slot to be called when 'Rename Playlist' is clicked by the user from the menu.
+ */
+void MpCollectionView::renameCurrentPlaylistContainer()
+{
+    QString currentName;
+    currentName = mCollectionData->collectionTitle();
+    bool ok = false;
+    QString newName;
+    newName = HbInputDialog::getText(QString(tr("Enter name:")), currentName, &ok);
+    if ( ok && ( currentName != newName ) ) 
+    mMpxWrapper->renamePlaylist( newName );   
+}
+
+
+/*!
+ Slot to be called when 'Add to playlist' operation has completed.
+ */
+void MpCollectionView::playlistSaved( bool success )
+{
+    if (success && mCollectionContext == ECollectionContextPlaylists) {
+	      mMpxWrapper->reopenCollection();
+    }
+}
+
+/*!
+ Slot to be called when 'Delete' operation has completed.
+ */
+void MpCollectionView::songsDeleted( bool success )
+{
+    if ( success ) {
+        mMpxWrapper->reopenCollection();
+    }
+}
+/*!
+ Slot to be called when 'Rename' operation has completed.
+ */
+void MpCollectionView::playlistsRenamed( bool success )
+{
+    if ( success ) {
+        mMpxWrapper->reopenCollection();
+    }
+}
+
+/*!
+ Slot to be called when scan completes.
+ */
+void MpCollectionView::handleScanningComplete()
+{
+    TX_ENTRY
+    mScanning = false;
+    if ( mActivated ) {
+        mMpxWrapper->reopenCollection();
+    }
+    else {
+        activateView();
+    }
+    TX_EXIT
+}
+
+/*!
+ Slot to be called when an item is long pressed by the user.
+ */
+void MpCollectionView::openContextMenu( int index, const QPointF &coords )
+{
+    TX_ENTRY_ARGS("index=" << index);
+    switch ( mViewMode ) {
+        case MpCommon::DefaultView:
+            openDefaultViewContextMenu(index, coords);
+            break;
+        case MpCommon::FetchView:
+            openFetchViewContextMenu(index, coords);
+            break;
+        default:
+            break;
+    }
+    TX_EXIT
+}
+
+/*!
+ Default view context menu.
+ */
+void MpCollectionView::openDefaultViewContextMenu(int index, const QPointF &coords)
+{
+    HbMenu *contextMenu = 0;
+    HbAction *action;
+    switch (mCollectionContext) {
+        case ECollectionContextAllSongs:
+        case ECollectionContextAlbumSongs:
+            contextMenu = new HbMenu();
+            action = contextMenu->addAction(QString(tr("Add to playlist")));
+            action->setObjectName("add");
+            action = contextMenu->addAction(QString(tr("Delete")));
+            action->setObjectName("delete");
+            break;
+        case ECollectionContextArtistAlbums:
+            contextMenu = new HbMenu();
+            action = contextMenu->addAction(QString(tr("Add to playlist")));
+            action->setObjectName("add");
+            action = contextMenu->addAction(QString(tr("Delete")));
+            action->setObjectName("delete");
+            break;
+        case ECollectionContextPlaylists:
+            if ( !mCollectionData->isAutoPlaylist(index) ) {
+                contextMenu = new HbMenu();
+                action = contextMenu->addAction(QString(tr("Delete")));
+                action->setObjectName("delete");
+                action = contextMenu->addAction(QString(tr("Rename")));
+                action->setObjectName("rename playlist");
+            }
+            break;
+        case ECollectionContextPlaylistSongs:
+            if ( !mCollectionData->isAutoPlaylist() ) {
+                contextMenu = new HbMenu();
+                action = contextMenu->addAction(QString(tr("Remove")));
+                action->setObjectName("delete");
+            }
+            break;
+        default:
+            break;
+    }
+
+    if ( contextMenu ) {
+        HbAction *selectedAction = contextMenu->exec(coords);
+        if ( selectedAction ) {
+            QString objectName = selectedAction->objectName();
+            QList<int> selection;
+            selection.append(index);
+            if ( objectName == "add" ) {
+                launchAddToPlaylistDialog(selection);
+            }
+            else if ( objectName == "delete" ) {
+                requestDelete(selection);
+            }
+            else if ( objectName == "rename playlist" ) {
+                QString currentName;
+                currentName = mCollectionData->itemData(index, MpMpxCollectionData::Title);
+                bool ok = false;
+                QString newName;
+                newName = HbInputDialog::getText(QString(tr("Enter name:")), currentName, &ok);
+                if ( ok && ( currentName != newName ) ) {
+                    mMpxWrapper->renamePlaylist( newName, index );   
+                }
+            }
+        }
+    }
+    contextMenu->deleteLater();
+    TX_EXIT
+}
+
+/*!
+ Fetch view context menu
+ */
+void MpCollectionView::openFetchViewContextMenu( int index, const QPointF &coords )
+{
+    TX_ENTRY_ARGS("index=" << index);
+
+    HbMenu *contextMenu = 0;
+    switch ( mCollectionContext ) {
+        case ECollectionContextAllSongs:
+        case ECollectionContextAlbumSongs:
+        case ECollectionContextPlaylistSongs:
+        case ECollectionContextGenreSongs:
+            contextMenu = new HbMenu();
+            contextMenu->addAction(QString(tr("Play")));
+            break;
+        default:
+            break;
+    }
+
+    if ( contextMenu) {
+        if ( contextMenu->exec(coords) ) {
+            // Start the playback process. View will switch to playbackview.
+            mMpxWrapper->previewItem( index );
+        }
+    }
+    contextMenu->deleteLater();
+    TX_EXIT
+}
+
+/*!
+ \internal
+ Sets the main (default) toolbar for the view.
+ */
+void MpCollectionView::setMainToolBar()
+{
+    TX_ENTRY
+    if ( !mMainToolBar ) {
+        //Create the toolbar.
+        mMainToolBar = new HbToolBar();
+        mMainToolBar->setOrientation(Qt::Horizontal);
+        QActionGroup *actionsGroup = new QActionGroup( mMainToolBar );
+        HbAction *action;
+    
+        // All Songs
+        action = createToolBarAction(actionsGroup,
+                ":/icons/all_songs_on",
+                ":/icons/all_songs",
+                tr("All"));
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(openSongs()) );
+        mMainToolBar->addAction(action);
+    
+        // Artists
+        action = createToolBarAction(actionsGroup,
+                ":/icons/artists_on",
+                ":/icons/artists",
+                tr("Artists"));
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(openArtists()) );
+        mMainToolBar->addAction(action);
+    
+        // Playlists
+        action = createToolBarAction(actionsGroup,
+                ":/icons/playlists_on",
+                ":/icons/playlists",
+                tr("Playlists"));
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(openPlaylists()) );
+        mMainToolBar->addAction(action);
+    
+        // Genres
+        action = createToolBarAction(actionsGroup,
+                ":/icons/search_on",
+                ":/icons/search",
+                tr("Search"));
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(find()) );
+        mMainToolBar->addAction(action);
+    
+        if ( mViewMode != MpCommon::FetchView ) {
+            // Music Store
+            action = createToolBarAction(actionsGroup,
+                    ":/icons/ovi_on",
+                    ":/icons/ovi",
+                    tr("Ovi"));
+            connect( action, SIGNAL(triggered(bool)), this, SLOT(openMusicStore()) );
+            mMainToolBar->addAction(action);
+        }
+    }
+    HbAction* action = 0;
+    switch ( mCollectionContext ) {
+        case ECollectionContextAllSongs:
+            action = qobject_cast<HbAction*>(mMainToolBar->actions()[KMainToolBarAll]);
+            break;
+        case ECollectionContextArtistAlbums:
+        case ECollectionContextAlbumSongs:
+            action = qobject_cast<HbAction*>(mMainToolBar->actions()[KMainToolBarArtists]);
+            break;
+        case ECollectionContextPlaylists:
+        case ECollectionContextPlaylistSongs:
+            action = qobject_cast<HbAction*>(mMainToolBar->actions()[KMainToolBarPlaylists]);
+            break;
+    }
+    if ( action ) {
+        action->setChecked(true);
+    }
+    if ( toolBar() != mMainToolBar ) {
+        HbToolBar *tmpToolBar = takeToolBar();
+        if ( tmpToolBar && tmpToolBar->actions().empty() ) {
+            tmpToolBar->deleteLater();
+        }
+        setToolBar(mMainToolBar);
+    }
+    TX_EXIT
+}
+
+/*!
+ \internal
+ Sets the playlist toolbar for the view.
+ Used only on the playlist container.
+ */
+void MpCollectionView::setPlaylistToolBar()
+{
+    TX_ENTRY
+    if ( !mPlaylistToolBar ) {
+        mPlaylistToolBar = new HbToolBar();
+        mPlaylistToolBar->setOrientation(Qt::Horizontal);
+        HbAction *action;      
+        
+        action = new HbAction( tr("Add") );
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(notimplemented()) );
+        mPlaylistToolBar->addAction(action);
+        
+        action = new HbAction( tr("Remove") );
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(deleteSongs()));
+        mPlaylistToolBar->addAction(action);
+    
+        action = new HbAction( tr("Reorder") );
+        connect( action, SIGNAL(triggered(bool)), this, SLOT(notimplemented()) );
+        mPlaylistToolBar->addAction(action);
+    }
+ 
+    int items = mCollectionData->count();
+        
+    //no use for remove if there are no items.
+    mPlaylistToolBar->actions()[KPlaylistToolBarRemove]->setEnabled(items > 0); 
+     
+    //no use for reorder if there is no more than 1 item.
+    mPlaylistToolBar->actions()[KplaylistToolBarReorder]->setEnabled(items > 1);
+        
+    if ( toolBar() != mPlaylistToolBar ) {
+        HbToolBar *tmpToolBar = takeToolBar();
+        if (tmpToolBar && tmpToolBar->actions().empty ()) {
+            tmpToolBar->deleteLater();
+        }
+        setToolBar(mPlaylistToolBar);
+    }
+    TX_EXIT
+}
+
+/*!
+ \internal
+ Creates action associated with the action group for the toolbar.
+ */
+HbAction *MpCollectionView::createToolBarAction(
+    QActionGroup *actionsGroup,
+    const QString& iconOn,
+    const QString& iconOff,
+    const QString& toolTip )
+{
+    HbIcon actionIcon(iconOff);
+    // button pressed icon
+    actionIcon.setIconName(iconOn, QIcon::Normal, QIcon::On );
+
+    HbAction *action = new HbAction(actionsGroup);
+    action->setToolTip(toolTip);
+    action->setIcon(actionIcon);
+    action->setCheckable(true);
+    return action;
+}
+
+/*!
+ \internal
+ Updates the options menu according to current context.
+ */
+void MpCollectionView::updateMenu()
+{
+    TX_ENTRY
+    HbMenu* myMenu = new HbMenu();
+    if ( mViewMode == MpCommon::DefaultView ) {
+        bool items = mCollectionData->count() != 0;
+        if ( mBannerAttached ) {
+            connect( myMenu->addAction(tr("Go to Now Playing")), SIGNAL(triggered()), this, SLOT(startPlaybackView()) );
+        }
+        switch (mCollectionContext) {
+            case ECollectionContextAllSongs:
+                if (items) {
+                    connect( myMenu->addAction(tr("Shuffle play all")), SIGNAL(triggered()), this, SLOT(shufflePlayAll()) );
+                }
+                connect( myMenu->addAction(tr("Refresh library")), SIGNAL(triggered()), this, SLOT(refreshLibrary()) );
+                if (items) {
+                    connect( myMenu->addAction(tr("Add to playlist")), SIGNAL(triggered()), this, SLOT(addToPlaylist()), Qt::QueuedConnection );
+                }
+                connect( myMenu->addAction(tr("Exit")), SIGNAL(triggered()), this, SLOT(exit()) );
+                break;
+            case ECollectionContextArtistAlbums:
+                //connect( myMenu->addAction(tr("Add to playlist")), SIGNAL(triggered()), this, SLOT(addToPlaylist()), Qt::QueuedConnection );
+                // Todo: View as coverflow
+                break;
+            case ECollectionContextAlbumSongs:
+                if (items) {
+                    connect( myMenu->addAction(tr("Add to playlist")), SIGNAL(triggered()), this, SLOT(addToPlaylist()), Qt::QueuedConnection );
+                }
+                break;
+            case ECollectionContextPlaylists:
+                // Todo: Create new playlist
+                break;
+            case ECollectionContextPlaylistSongs:
+                if ( !mCollectionData->isAutoPlaylist() ) {
+                    connect( myMenu->addAction(tr("Rename playlist")), SIGNAL(triggered()), this, SLOT(renameCurrentPlaylistContainer()), Qt::QueuedConnection );
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    else if (mViewMode == MpCommon::FetchView ) {
+        if ( mCollectionContext == ECollectionContextAllSongs ) {
+            connect( myMenu->addAction(tr("Refresh library")), SIGNAL(triggered()), this, SLOT(refreshLibrary()) );
+        }
+    }
+
+    setMenu(myMenu);
+    TX_EXIT
+}
+
+/*!
+ \internal
+ Updates the Toolbar according to current context.
+ */
+void MpCollectionView::updateToolBar()
+{
+    TX_ENTRY
+
+    switch (mCollectionContext) {
+        case ECollectionContextPlaylistSongs:
+            if ( !mCollectionData->isAutoPlaylist() ) {
+                setPlaylistToolBar();
+            }
+            else if (!toolBar()->actions().empty()) {
+                takeToolBar();
+                setToolBar(new HbToolBar);
+            } 
+            break;
+        case ECollectionContextAlbumSongs:
+        case ECollectionContextGenreSongs:
+            if (!toolBar()->actions().empty()) {
+                takeToolBar();
+                setToolBar(new HbToolBar);
+            }
+            break;
+        default:
+            setMainToolBar();
+            break;
+    }
+    TX_EXIT
+}
+
+/*!
+ \internal
+ Updates the softkey according to current context.
+ */
+void MpCollectionView::setSoftkey()
+{
+    if ( mViewMode == MpCommon::FetchView ) {
+        // 'Back' is used in all views in fetch mode because we must
+        // appear as an embedded application.
+        mWindow->addSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyBack);
+    }
+    else {
+        switch ( mCollectionContext ) {
+            case ECollectionContextAllSongs:
+            case ECollectionContextArtistAlbums:
+            case ECollectionContextPlaylists:
+            case ECollectionContextGenres:
+                mWindow->addSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyQuit);
+                break;
+            default:
+                mWindow->addSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyBack);
+                break;
+        }
+    }
+}
+
+/*!
+ \internal
+ Clears the softkey set by this view. Restore to previous.
+ */
+void MpCollectionView::clearSoftkey()
+{
+    mWindow->removeSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyBack);
+    mWindow->removeSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyQuit);
+}
+
+/*!
+ \internal
+ Sets the Now Playing Banner visibility based on \a visible.
+ */
+void MpCollectionView::setBannerVisibility( bool visible )
+{
+    bool ok = false;
+    if ( visible && (hbInstance->allMainWindows()[0]->orientation() == Qt::Vertical)) {
+        mDocumentLoader->load(MUSIC_COLLECTION_DOCML, "showBanner", &ok);
+        mNowPlayingBanner->show();
+    }
+    else {
+        mDocumentLoader->load(MUSIC_COLLECTION_DOCML, "hideBanner", &ok);
+        mNowPlayingBanner->hide();
+    }
+
+    if ( !ok ) {
+        TX_LOG_ARGS("Error: invalid xml file.");
+        Q_ASSERT_X(ok, "MpCollectionView::setBannerVisibility", "invalid xml file");
+    }
+}
+
+/*!
+ \internal
+ Generates a random index for shuffle all.
+ */
+int MpCollectionView::generateShuffleIndex()
+{
+    int low = 0;
+    int high = mCollectionData->count();
+
+    time_t seconds;
+    time(&seconds);
+    srand((unsigned int) seconds);
+
+    int index = rand() % (high - low + 1) + low;
+    return index;
+}
+
+/*!
+ \internal
+ Launches the 'Add to playlist' dialog.
+ */
+void MpCollectionView::launchAddToPlaylistDialog( QList<int> selection )
+{
+    QString newPlaylistName;
+    int playlistIndex;
+    bool canceled = false;
+
+    forever {
+        QStringList list;
+        mMpxWrapper->findPlaylists(list);
+        if ( list.count()) {
+            HbListDialog dialog;
+            dialog.setStringItems(list);
+            dialog.setSelectionMode(HbAbstractItemView::SingleSelection);
+            dialog.setHeadingWidget(new HbLabel(QString(tr("Choose a playlist:"))));
+            dialog.setPrimaryAction(new HbAction(QString(tr("New"))));
+            dialog.setSecondaryAction(new HbAction(QString(tr("Cancel"))));
+            HbAction *selectedAction = dialog.exec();
+            if ( selectedAction == dialog.secondaryAction() ) {
+                // Cancel
+                break;
+            }
+            else if ( selectedAction != dialog.primaryAction()) {
+                // User selected existing playlist
+                playlistIndex = dialog.selectedItems().at(0);
+                mMpxWrapper->saveToPlaylist(playlistIndex, selection);
+                break;
+            }
+        }
+        else if (canceled) {
+            break;
+        }
+
+        // New - create a suggested name for the playlist
+        QString suggestedPlaylistName(tr("Playlist"));
+        int i = 0;
+        for (;
+             list.contains( QString( suggestedPlaylistName + "(" + QString::number(i) + ")" ) ) ;
+             i++ ) {};
+        suggestedPlaylistName += QString("(" + QString::number( i ) + ")");
+        // Loop until the user cancels or enters a valid name
+        forever {
+            QString suggestedText;
+            bool ok = false;
+            suggestedText = HbInputDialog::getText(QString(tr("Enter a name for the new playlist:")), suggestedPlaylistName, &ok);
+            if ( !ok ) {
+                canceled = true;
+                break;
+            }
+            if ( !list.contains(suggestedText) ) {
+            	  newPlaylistName = suggestedText;
+                mMpxWrapper->createPlaylist(newPlaylistName, selection);
+                return;
+            }
+        }
+    }
+}
+
+/*!
+ \internal
+ starts a transition of the main container with a decoy snapshot.
+ */
+void MpCollectionView::startContainerTransition(TCollectionContext contextFrom, TCollectionContext contextTo)
+{
+    if (!mSnapshot)
+      mSnapshot = new MpSnapshotWidget();
+    mSnapshot->capture(mWindow, mMainContainer );
+    mWindow->scene()->addItem(mSnapshot);
+
+
+    if ( ( contextFrom == ECollectionContextArtistAlbums && contextTo == ECollectionContextAlbumSongs ) ||
+            ( contextFrom == ECollectionContextPlaylists && contextTo == ECollectionContextPlaylistSongs ) ||
+            ( contextFrom == ECollectionContextGenres && contextTo == ECollectionContextGenreSongs ) ){
+        HbEffect::start(mSnapshot,
+                QString("container"),
+                QString("slide_out_to_left"));
+
+        HbEffect::start(mMainContainer,
+                QString("container"),
+                QString("slide_in_to_left_and_fade_in"),
+                this,
+                "containerTransitionComplete");
+    }
+    else if(( contextFrom == ECollectionContextAlbumSongs && contextTo == ECollectionContextArtistAlbums) ||
+            ( contextFrom == ECollectionContextPlaylistSongs && contextTo == ECollectionContextPlaylists) ||
+            ( contextFrom == ECollectionContextGenreSongs && contextTo == ECollectionContextGenres)) {
+        HbEffect::start(mSnapshot,
+                QString("container"),
+                QString("slide_out_to_right"));
+
+        HbEffect::start(mMainContainer,
+                QString("container"),
+                QString("slide_in_to_right_and_fade_in"),
+                this,
+                "containerTransitionComplete");
+    }
+    else {
+        HbEffect::start(mSnapshot,
+                QString("container"),
+                QString("slide_out_to_top"));
+
+        HbEffect::start(mMainContainer,
+                QString("container"),
+                QString("slide_in_to_top_and_fade_in"),
+                this,
+                "containerTransitionComplete");
+    }
+
+}
+
+/*!
+ \internal
+ request a delete operation always it has been confirmed.
+ */
+void MpCollectionView::requestDelete(QList<int> selection)
+{           
+    bool confirmation(false);
+    // Todo: Use HbMessageBox::question when time-out removed from it
+    HbMessageBox dialog(HbMessageBox::MessageTypeQuestion);
+    QString message;
+    HbAction *action;
+    
+    switch (mCollectionContext) {
+        case ECollectionContextAllSongs:
+        case ECollectionContextAlbumSongs:
+            message = QString(tr("Delete song?"));
+            dialog.setText(message);
+            dialog.setTimeout(HbPopup::NoTimeout);
+            action = dialog.exec();
+            if (action == dialog.primaryAction()) {
+                confirmation = true;
+            }
+            break;
+        case ECollectionContextArtistAlbums:
+            message = QString(tr("Delete album?"));
+            dialog.setText(message);
+            dialog.setTimeout(HbPopup::NoTimeout);
+            action = dialog.exec();
+            if (action == dialog.primaryAction()) {
+                confirmation = true;
+            }
+            break;
+        case ECollectionContextPlaylists:
+            message = QString(tr("Delete playlist?"));
+            dialog.setText(message);
+            dialog.setTimeout(HbPopup::NoTimeout);
+            action = dialog.exec();
+            if (action == dialog.primaryAction()) {
+                confirmation = true;
+            }
+            break;            
+        case ECollectionContextPlaylistSongs:
+        case ECollectionContextGenres:
+        case ECollectionContextGenreSongs:
+            confirmation = true;
+            break;
+        case ECollectionContextUnknown:
+        default:
+            // We shouldn't be here
+            TX_LOG_ARGS("Invalid Collection Context:" << mCollectionContext);
+            break;
+    }
+
+    if ( confirmation ) {
+        mMpxWrapper->deleteSongs(selection);
+    }    
+}