diff -r 4e84c994a771 -r 82baf59ce8dd mpviewplugins/mpcollectionviewplugin/src/mpcollectionview.cpp --- a/mpviewplugins/mpcollectionviewplugin/src/mpcollectionview.cpp Fri Mar 19 09:28:13 2010 +0200 +++ b/mpviewplugins/mpcollectionviewplugin/src/mpcollectionview.cpp Fri Apr 16 14:56:30 2010 +0300 @@ -29,13 +29,17 @@ #include #include #include +#include +#include +#include +#include #include "mpcollectionview.h" #include "mpcollectiondocumentloader.h" #include "mpcollectioncontainerfactory.h" #include "mpcollectioncontainer.h" #include "mpcollectiondatamodel.h" -#include "mpcollectionsongscanner.h" +#include "mpengine.h" #include "mpmpxframeworkwrapper.h" #include "mpmpxcollectiondata.h" #include "mpnowplayingwidget.h" @@ -57,8 +61,6 @@ const int KPlaylistToolBarRemove = 1; const int KplaylistToolBarReorder = 2; - - /*! \class MpCollectionView \brief Music Player collection view. @@ -80,22 +82,25 @@ 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) + : mCollectionContext( ECollectionContextUnknown ), + mMpxWrapper( 0 ), + mMpEngine( 0 ), + mContainerFactory( 0 ), + mCollectionContainer( 0 ), + mCollectionDataModel( 0 ), + mActivated( false ), + mNowPlayingBanner( 0 ), + mBannerAttached( false ), + mDocumentLoader( 0 ), + mMainContainer( 0 ), + mMainToolBar( 0 ), + mPlaylistToolBar( 0 ), + mSnapshot( 0 ), + mMpTranslator( 0 ), + mCommonTranslator( 0 ), + mActivationWaiting( false ), + mOutstandingPopup( 0 ), + mUsbBlocked( false ) { TX_LOG } @@ -106,7 +111,6 @@ MpCollectionView::~MpCollectionView() { TX_ENTRY - delete mSongScanner; delete mSnapshot; delete mSoftKeyQuit; delete mSoftKeyBack; @@ -115,18 +119,20 @@ if ( mMainToolBar != toolBar && mPlaylistToolBar != toolBar ) { delete toolBar; } - if ( mMainToolBar) { + if ( mMainToolBar ) { mMainToolBar->deleteLater(); } if ( mPlaylistToolBar ) { mPlaylistToolBar->deleteLater(); } - + delete mCollectionDataModel; delete mCollectionContainer; delete mContainerFactory; delete mMpxWrapper; delete mDocumentLoader; + delete mMpTranslator; + delete mCommonTranslator; TX_EXIT } @@ -137,22 +143,63 @@ { TX_ENTRY + //Load musicplayer and common translators + QString lang = QLocale::system().name(); + QString path = QString( "z:/resource/qt/translations/" ); + bool translatorLoaded = false; + + mMpTranslator = new QTranslator( this ); + translatorLoaded = mMpTranslator->load( path + "musicplayer_" + lang ); + TX_LOG_ARGS( "Loading translator ok=" << translatorLoaded ); + if ( translatorLoaded ) { + qApp->installTranslator( mMpTranslator ); + } + + mCommonTranslator = new QTranslator( this ); + translatorLoaded = mCommonTranslator->load( path + "common_" + lang ); + TX_LOG_ARGS( "Loading common translator ok=" << translatorLoaded ); + if ( translatorLoaded ) { + qApp->installTranslator( mCommonTranslator ); + } + mWindow = mainWindow(); // Create softkey actions - mSoftKeyQuit = new HbAction(Hb::QuitAction, this); - connect( mSoftKeyQuit, SIGNAL(triggered()), this, SLOT(back()) ); + 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()) ); + 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 ); + mMpxWrapper = new MpMpxFrameworkWrapper( mViewMode ); + connect( mMpxWrapper, + SIGNAL( collectionPlaylistOpened() ), + this, + SLOT( startPlaybackView() ), + Qt::QueuedConnection ); + 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 ); + connect( mMpxWrapper, + SIGNAL( isolatedCollectionOpened( MpMpxCollectionData* ) ), + this, + SLOT( handleIsolatedCollectionOpened( MpMpxCollectionData* ) ), + Qt::QueuedConnection ); + mCollectionData = mMpxWrapper->collectionData(); - connect( mCollectionData, SIGNAL(contextChanged(TCollectionContext)), this, SLOT(setContext(TCollectionContext)) ); + connect( mCollectionData, SIGNAL( contextChanged( TCollectionContext ) ), this, SLOT( setContext( TCollectionContext ) ) ); mCollectionDataModel = new MpCollectionDataModel( mCollectionData ); mDocumentLoader = new MpCollectionDocumentLoader(); @@ -161,62 +208,67 @@ if ( ok ) { QGraphicsWidget *widget; - widget = mDocumentLoader->findWidget(QString("nowPlaying")); - mNowPlayingBanner = qobject_cast(widget); + widget = mDocumentLoader->findWidget( QString( "nowPlaying" ) ); + mNowPlayingBanner = qobject_cast( 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); + 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") ); + connect( mNowPlayingBanner, SIGNAL( clicked() ), this, SLOT( startPlaybackView() ) ); + connect( mNowPlayingBanner, SIGNAL( playbackAttachmentChanged( bool ) ), this, SLOT( attachNowPlayingBanner( bool ) ) ); } - widget = mDocumentLoader->findWidget(QString("mainContainer")); - mMainContainer = qobject_cast(widget); + widget = mDocumentLoader->findWidget( QString( "mainContainer" ) ); + mMainContainer = qobject_cast( widget ); - setWidget(mMainContainer); + 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_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_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_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_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_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") ); + 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"); + TX_LOG_ARGS( "Error: invalid xml file." ); + Q_ASSERT_X( ok, "MpCollectionView::initializeView", "invalid xml file" ); } - mContainerFactory = new MpCollectionContainerFactory(this, mDocumentLoader); + mContainerFactory = new MpCollectionContainerFactory( this, mDocumentLoader ); + + mMpEngine = MpEngine::instance(); + connect( mMpEngine, SIGNAL( usbBlocked(bool) ), + this, SLOT( handleUsbBlocked(bool) ) ); + connect( mMpEngine, SIGNAL( libraryAboutToRefresh() ), + this, SLOT( handleLibraryAboutToUpdate() ) ); + connect( mMpEngine, SIGNAL( libraryRefreshed() ), + this, SLOT( handleLibraryUpdated() ) ); + mUsbBlocked = mMpEngine->verifyUsbBlocking(); if ( MpSettingsManager::firstStartup() ) { - mSongScanner = new MpCollectionSongScanner(mMpxWrapper); - connect(mSongScanner, SIGNAL(scanEnded()), this, SLOT(handleScanningComplete())); - mScanning = true; - mSongScanner->scan(); + mActivationWaiting = true; + mMpEngine->refreshLibrary(); } TX_EXIT @@ -227,11 +279,11 @@ */ void MpCollectionView::activateView() { - if ( mScanning ) { + if ( mActivationWaiting ) { return; } mActivated = true; - TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext); + TX_ENTRY_ARGS( "mCollectionContext=" << mCollectionContext ); if ( mCollectionContext == ECollectionContextUnknown ) { // Open 'All Songs' by default mMpxWrapper->openCollection( ECollectionContextAllSongs ); @@ -249,8 +301,32 @@ void MpCollectionView::deactivateView() { TX_ENTRY - clearSoftkey(); mActivated = false; + + if ( mOutstandingPopup ) { + mOutstandingPopup->close(); + } + menu()->close(); + + setNavigationAction( 0 ); + TX_EXIT +} + +/*! + Sets the default collection - AllSongs + */ +void MpCollectionView::setDefaultView() +{ + TX_ENTRY + if ( mCollectionContext != ECollectionContextAllSongs ) { + // Open 'All Songs' by default + mMpxWrapper->openCollection( ECollectionContextAllSongs ); + } + + if ( mBannerAttached ) { + setBannerVisibility( false ); + } + TX_EXIT } @@ -260,15 +336,15 @@ void MpCollectionView::orientationChange( Qt::Orientation orientation ) { if ( mCollectionContainer ) { - mCollectionContainer->orientationChange(orientation); + mCollectionContainer->orientationChange( orientation ); } if ( mBannerAttached ) { if ( orientation == Qt::Vertical ) { - setBannerVisibility(true); + setBannerVisibility( true ); } else { - setBannerVisibility(false); + setBannerVisibility( false ); } } } @@ -279,19 +355,18 @@ */ void MpCollectionView::setContext( TCollectionContext context ) { - TX_ENTRY_ARGS("context=" << context); - if (mActivated) { - startContainerTransition(mCollectionContext, context); + TX_ENTRY_ARGS( "context=" << context ); + if ( mActivated ) { + startContainerTransition( mCollectionContext, context ); } mCollectionContext = context; - mCollectionContainer = mContainerFactory->createContainer(context); - mCollectionContainer->setViewMode(mViewMode); + mCollectionContainer = mContainerFactory->createContainer( context ); + mCollectionContainer->setViewMode( mViewMode ); mCollectionDataModel->refreshModel(); - mCollectionContainer->setDataModel(mCollectionDataModel); + mCollectionContainer->setDataModel( mCollectionDataModel ); // Reset softkey and the menu - if (mActivated) { - clearSoftkey(); + if ( mActivated ) { setSoftkey(); } updateToolBar(); @@ -305,7 +380,9 @@ void MpCollectionView::openSongs() { TX_ENTRY - mMpxWrapper->openCollection( ECollectionContextAllSongs ); + if ( mCollectionContext != ECollectionContextAllSongs ) { + mMpxWrapper->openCollection( ECollectionContextAllSongs ); + } TX_EXIT } @@ -315,7 +392,9 @@ void MpCollectionView::openArtists() { TX_ENTRY - mMpxWrapper->openCollection( ECollectionContextArtistAlbums ); + if ( mCollectionContext != ECollectionContextAlbums ) { + mMpxWrapper->openCollection( ECollectionContextAlbums ); + } TX_EXIT } @@ -325,7 +404,9 @@ void MpCollectionView::openPlaylists() { TX_ENTRY - mMpxWrapper->openCollection( ECollectionContextPlaylists ); + if ( mCollectionContext != ECollectionContextPlaylists) { + mMpxWrapper->openCollection( ECollectionContextPlaylists ); + } TX_EXIT } @@ -335,7 +416,9 @@ void MpCollectionView::openGenres() { TX_ENTRY - mMpxWrapper->openCollection( ECollectionContextGenres ); + if ( mCollectionContext != ECollectionContextGenres ) { + mMpxWrapper->openCollection( ECollectionContextGenres ); + } TX_EXIT } @@ -345,7 +428,7 @@ void MpCollectionView::find() { // Todo - HbMessageBox messageBox("Not ready!", HbMessageBox::MessageTypeInformation); + HbMessageBox messageBox( "Not ready!", HbMessageBox::MessageTypeInformation ); messageBox.exec(); updateToolBar(); } @@ -356,7 +439,7 @@ void MpCollectionView::openMusicStore() { // Todo - HbMessageBox messageBox("Not ready!", HbMessageBox::MessageTypeInformation); + HbMessageBox messageBox( "Not ready!", HbMessageBox::MessageTypeInformation ); messageBox.exec(); updateToolBar(); } @@ -366,7 +449,7 @@ */ void MpCollectionView::openIndex( int index ) { - TX_ENTRY_ARGS("index=" << index); + TX_ENTRY_ARGS( "index=" << index ); bool doOpen = true; if ( mViewMode == MpCommon::FetchView ) { QString songUri; @@ -376,8 +459,8 @@ case ECollectionContextPlaylistSongs: case ECollectionContextGenreSongs: doOpen = false; - songUri = mCollectionData->itemData(index, MpMpxCollectionData::Uri); - emit songSelected(songUri); + songUri = mCollectionData->itemData( index, MpMpxCollectionData::Uri ); + emit songSelected( songUri ); break; default: break; @@ -394,11 +477,11 @@ */ void MpCollectionView::back() { - TX_ENTRY_ARGS("mCollectionContext=" << mCollectionContext); - bool doExit(false); + TX_ENTRY_ARGS( "mCollectionContext=" << mCollectionContext ); + bool doExit( false ); switch ( mCollectionContext ) { case ECollectionContextAllSongs: - case ECollectionContextArtistAlbums: + case ECollectionContextAlbums: case ECollectionContextPlaylists: case ECollectionContextGenres: // Exit from these levels. @@ -415,10 +498,10 @@ } if ( doExit ) { - if ( mViewMode == MpCommon::FetchView ) { + if ( mViewMode == MpCommon::FetchView ) { // Send an empty string to indicate that user has cancelled // the fetch operation - emit songSelected(""); + emit songSelected( "" ); } else { emit command( MpCommon::Exit ); @@ -461,42 +544,12 @@ } /*! - 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(mWindow)->scene()->removeItem(mSnapshot); + Q_UNUSED( status ); + qobject_cast( mWindow )->scene()->removeItem( mSnapshot ); delete mSnapshot; mSnapshot = 0; } @@ -506,10 +559,10 @@ */ void MpCollectionView::shufflePlayAll() { - mMpxWrapper->setShuffle(true); - MpSettingsManager::setShuffle(true); + mMpxWrapper->setShuffle( true ); + MpSettingsManager::setShuffle( true ); int index = generateShuffleIndex(); - openIndex(index); + openIndex( index ); } @@ -518,12 +571,9 @@ */ void MpCollectionView::refreshLibrary() { - if ( !mSongScanner ) { - mSongScanner = new MpCollectionSongScanner(mMpxWrapper); - connect(mSongScanner, SIGNAL(scanEnded()), this, SLOT(handleScanningComplete())); + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + mMpEngine->refreshLibrary(); } - mScanning = true; - mSongScanner->scan(); } /*! @@ -531,20 +581,21 @@ */ void MpCollectionView::addToPlaylist() { - QModelIndexList SelectedModelIndexes; - bool ok; - SelectedModelIndexes = HbListDialog::getModelIndexes(QString(tr("Select songs:")), - mCollectionDataModel, - &ok, - HbAbstractItemView::MultiSelection); - - if (ok && SelectedModelIndexes.count()) { - QList selection; - for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) { - selection.append( SelectedModelIndexes.at(i).row() ); + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + QModelIndexList SelectedModelIndexes; + bool ok; + SelectedModelIndexes = getModelIndexes( hbTrId( "txt_mus_title_select_songs" ), + mCollectionDataModel, + ok); + + if ( ok && SelectedModelIndexes.count() ) { + QList selection; + for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) { + selection.append( SelectedModelIndexes.at( i ).row() ); + } + launchAddToPlaylistDialog( selection ); } - launchAddToPlaylistDialog(selection); - } + } } /*! @@ -554,18 +605,17 @@ { QModelIndexList SelectedModelIndexes; bool ok; - SelectedModelIndexes = HbListDialog::getModelIndexes(QString(tr("Select songs:")), + SelectedModelIndexes = getModelIndexes( hbTrId( "txt_mus_title_select_songs" ), mCollectionDataModel, - &ok, - HbAbstractItemView::MultiSelection); - - if (ok && SelectedModelIndexes.count()) { + ok); + + if ( ok && SelectedModelIndexes.count() ) { QList selection; for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) { - selection.append( SelectedModelIndexes.at(i).row() ); + selection.append( SelectedModelIndexes.at( i ).row() ); } - requestDelete(selection); - updateMenu(); + requestDelete( selection ); + updateMenu(); } } @@ -574,13 +624,16 @@ */ 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 ); + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + QString currentName; + currentName = mCollectionData->collectionTitle(); + bool ok = false; + QString newName; + newName = getText( hbTrId( "txt_mus_dialog_enter_name" ), currentName, ok ); + if ( ok && ( currentName != newName ) && !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->renamePlaylist( newName ); + } + } } @@ -589,8 +642,10 @@ */ void MpCollectionView::playlistSaved( bool success ) { - if (success && mCollectionContext == ECollectionContextPlaylists) { - mMpxWrapper->reopenCollection(); + if ( success && + ( ECollectionContextPlaylists == mCollectionContext || + ECollectionContextPlaylistSongs == mCollectionContext ) ) { + mMpxWrapper->reopenCollection(); } } @@ -599,7 +654,8 @@ */ void MpCollectionView::songsDeleted( bool success ) { - if ( success ) { + // Update list if delete succeded or if delete interrupted by an USB MTP Event + if ( success || mMpEngine->verifyUsbBlocking( true ) ) { mMpxWrapper->reopenCollection(); } } @@ -614,19 +670,138 @@ } /*! - Slot to be called when scan completes. + Slot to be called to get ready for add to playlist using an isolated collection. */ -void MpCollectionView::handleScanningComplete() +void MpCollectionView::prepareToAddToPlaylist() +{ + TX_ENTRY + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + //We dismiss dialogs here since after open is complete we are triggering a dialog. + setOutstandingPopup( 0 ); + mMpxWrapper->openIsolatedCollection( ECollectionContextAllSongs ); + } + TX_EXIT +} + +/*! + Slot to be called when isolated collection is oppened. + */ +void MpCollectionView::handleIsolatedCollectionOpened( MpMpxCollectionData* collectionData ) { TX_ENTRY - mScanning = false; - if ( mActivated ) { - mMpxWrapper->reopenCollection(); + if ( mActivated && !mOutstandingPopup ) { + + if (ECollectionContextPlaylistSongs == mCollectionContext) { + addToCurrentPlaylist( collectionData ); + } + else if (ECollectionContextPlaylists == mCollectionContext) { + createNewPlaylist( collectionData ); + } + } + //Playlist is saved asynchronosly by the default collection, it is OK to release now. + mMpxWrapper->releaseIsolatedCollection(); + TX_EXIT +} + + +/*! + Slot to be called to add items to current playlist. + */ +void MpCollectionView::addToCurrentPlaylist( MpMpxCollectionData* collectionData ) +{ + MpCollectionDataModel *collectionDataModel; + collectionDataModel = new MpCollectionDataModel( collectionData ); + collectionDataModel->refreshModel(); + QModelIndexList SelectedModelIndexes; + bool ok; + SelectedModelIndexes = getModelIndexes( hbTrId( "txt_mus_title_select_songs" ), + collectionDataModel, + ok); + + if ( ok && SelectedModelIndexes.count() ) { + QList selection; + for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) { + selection.append( SelectedModelIndexes.at( i ).row() ); + } + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->saveToCurrentPlaylist( selection, collectionData ); + } } - else { - activateView(); + delete collectionDataModel; +} + +/*! + Slot to be called to add items to new playlist. + */ +void MpCollectionView::createNewPlaylist( MpMpxCollectionData* collectionData ) +{ + MpCollectionDataModel *collectionDataModel; + collectionDataModel = new MpCollectionDataModel( collectionData ); + collectionDataModel->refreshModel(); + + QString newPlaylistName; + bool ok; + QStringList playlists; + mMpxWrapper->findPlaylists( playlists ); + ok = queryNewPlaylistName(newPlaylistName , playlists); + if ( ok ) { + QModelIndexList SelectedModelIndexes; + SelectedModelIndexes = getModelIndexes( hbTrId( "txt_mus_title_select_songs" ), + collectionDataModel, + ok); + QList selection; + if ( ok && SelectedModelIndexes.count() ) { + for ( int i = 0; i < SelectedModelIndexes.size(); ++i ) { + selection.append( SelectedModelIndexes.at( i ).row() ); + } + } + //Creating Playlist even when there is no selection. + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->createPlaylist( newPlaylistName, selection, collectionData ); + } } - TX_EXIT + delete collectionDataModel; +} + +/*! + Slot to be called to arrange songs in a playlist. + */ +void MpCollectionView::arrangeSongs( ) +{ + HbListView *listView = new HbListView(); + listView->setItemRecycling(true); + listView->setScrollingStyle( HbListView::PanOrFlick ); + listView->setClampingStyle( HbListView::BounceBackClamping ); + HbScrollBar *scrollbar = listView->verticalScrollBar(); + scrollbar->show(); + scrollbar->setInteractive(true); + listView->setVerticalScrollBarPolicy(HbScrollArea::ScrollBarAsNeeded); + MpCollectionDataModel *model; + //Ownership of the model is passed to the listView as a child object. + model = new MpCollectionDataModel( mCollectionData, listView ); + model->refreshModel(); + connect( model, + SIGNAL( orderChanged( int, int, int, int ) ), + mMpxWrapper, + SLOT( reorderPlaylist( int, int, int, int ) ) ); + listView->setModel( model ); + listView->setArrangeMode( true ); + HbDialog *popup = new HbDialog(); + popup->setAttribute( Qt::WA_DeleteOnClose ); + popup->setDismissPolicy( HbPopup::NoDismiss ); + popup->setTimeout( HbPopup::NoTimeout ); + + HbLabel *label = new HbLabel( hbTrId( "txt_mus_title_arrange" ) ); + popup->setHeadingWidget( label ); + popup->setContentWidget( listView ); + popup->setPrimaryAction( new HbAction( hbTrId( "txt_common_button_ok" ), popup ) ); + popup->setModal( true ); + connect( popup, SIGNAL( aboutToClose() ), this, SLOT( outstandingPopupClosing() ) ); + //Reopen the collection so the ordinals get fixed on the view list, if we + //delete items the index will not match to the item on the collection. + connect( popup, SIGNAL( aboutToClose() ), mMpxWrapper, SLOT( reopenCollection() ) ); + setOutstandingPopup(popup); + popup->show(); } /*! @@ -634,13 +809,13 @@ */ void MpCollectionView::openContextMenu( int index, const QPointF &coords ) { - TX_ENTRY_ARGS("index=" << index); + TX_ENTRY_ARGS( "index=" << index ); switch ( mViewMode ) { case MpCommon::DefaultView: - openDefaultViewContextMenu(index, coords); + openDefaultViewContextMenu( index, coords ); break; case MpCommon::FetchView: - openFetchViewContextMenu(index, coords); + openFetchViewContextMenu( index, coords ); break; default: break; @@ -649,42 +824,112 @@ } /*! + Slot to be called when a dialog is about to close. + */ +void MpCollectionView::outstandingPopupClosing() +{ + HbPopup *popup = qobject_cast( sender() ); + if ( popup ) { + Q_ASSERT( popup != mOutstandingPopup ); + mOutstandingPopup = 0; + } +} + +/*! + Slot to be called when USB blocking status changes. + */ +void MpCollectionView::handleUsbBlocked( bool blocked ) +{ + TX_ENTRY_ARGS( "blocked=" << blocked ); + mUsbBlocked = blocked; + + // Hide/Show usb blocked options + updateMenu(); + if ( mCollectionContext == ECollectionContextPlaylistSongs ) { + updateToolBar(); + } + TX_EXIT +} + +/*! + Slot to be called when library is going to be updated. + */ +void MpCollectionView::handleLibraryAboutToUpdate() +{ + TX_ENTRY + + if ( mActivated ) { + if ( mOutstandingPopup ) { + mOutstandingPopup->close(); + } + menu()->close(); + } + TX_EXIT +} + +/*! + Slot to be called when refreshing completes or library has been updated. + */ +void MpCollectionView::handleLibraryUpdated() +{ + TX_ENTRY + if ( mActivationWaiting ) { + mActivationWaiting = false; + activateView(); + } + else { + //Update cache, even if collection is in background. + //Library refreshing could be triggered at any point due USB connect./disconnect. + mMpxWrapper->reopenCollection(); + } + TX_EXIT +} + +/*! Default view context menu. */ -void MpCollectionView::openDefaultViewContextMenu(int index, const QPointF &coords) +void MpCollectionView::openDefaultViewContextMenu( int index, const QPointF &coords ) { HbMenu *contextMenu = 0; HbAction *action; - switch (mCollectionContext) { + 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"); + if ( !mUsbBlocked ) { + action = contextMenu->addAction( hbTrId( "txt_mus_menu_add_to_playlist" ) ); + action->setObjectName( "add" ); + action = contextMenu->addAction( hbTrId( "txt_common_menu_delete" ) ); + action->setObjectName( "delete" ); + } break; - case ECollectionContextArtistAlbums: + case ECollectionContextAlbums: contextMenu = new HbMenu(); - action = contextMenu->addAction(QString(tr("Add to playlist"))); - action->setObjectName("add"); - action = contextMenu->addAction(QString(tr("Delete"))); - action->setObjectName("delete"); + if ( !mUsbBlocked ) { + action = contextMenu->addAction( hbTrId( "txt_mus_menu_add_to_playlist" ) ); + action->setObjectName( "add" ); + action = contextMenu->addAction( hbTrId( "txt_common_menu_delete" ) ); + action->setObjectName( "delete" ); + } break; case ECollectionContextPlaylists: - if ( !mCollectionData->isAutoPlaylist(index) ) { + 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"); + if ( !mUsbBlocked ) { + action = contextMenu->addAction( hbTrId( "txt_common_menu_delete" ) ); + action->setObjectName("delete"); + action = contextMenu->addAction( hbTrId( "txt_common_menu_rename_item" ) ); + action->setObjectName( "rename playlist" ); + } } break; case ECollectionContextPlaylistSongs: if ( !mCollectionData->isAutoPlaylist() ) { contextMenu = new HbMenu(); - action = contextMenu->addAction(QString(tr("Remove"))); - action->setObjectName("delete"); + if ( !mUsbBlocked ) { + action = contextMenu->addAction( hbTrId( "txt_common_menu_remove" ) ); + action->setObjectName( "delete" ); + } } break; default: @@ -692,23 +937,25 @@ } if ( contextMenu ) { - HbAction *selectedAction = contextMenu->exec(coords); - if ( selectedAction ) { + setOutstandingPopup( contextMenu ); + HbAction *selectedAction = mActivated ? contextMenu->exec( coords ) : 0; + setOutstandingPopup( 0 ); + if ( selectedAction && !mMpEngine->verifyUsbBlocking( true ) ) { QString objectName = selectedAction->objectName(); QList selection; - selection.append(index); + selection.append( index ); if ( objectName == "add" ) { - launchAddToPlaylistDialog(selection); + launchAddToPlaylistDialog( selection ); } else if ( objectName == "delete" ) { - requestDelete(selection); + requestDelete( selection ); } else if ( objectName == "rename playlist" ) { QString currentName; - currentName = mCollectionData->itemData(index, MpMpxCollectionData::Title); + currentName = mCollectionData->itemData( index, MpMpxCollectionData::Title ); bool ok = false; QString newName; - newName = HbInputDialog::getText(QString(tr("Enter name:")), currentName, &ok); + newName = getText( hbTrId("txt_mus_dialog_enter_name" ), currentName, ok ); if ( ok && ( currentName != newName ) ) { mMpxWrapper->renamePlaylist( newName, index ); } @@ -724,7 +971,7 @@ */ void MpCollectionView::openFetchViewContextMenu( int index, const QPointF &coords ) { - TX_ENTRY_ARGS("index=" << index); + TX_ENTRY_ARGS( "index=" << index ); HbMenu *contextMenu = 0; switch ( mCollectionContext ) { @@ -733,17 +980,19 @@ case ECollectionContextPlaylistSongs: case ECollectionContextGenreSongs: contextMenu = new HbMenu(); - contextMenu->addAction(QString(tr("Play"))); + contextMenu->addAction( hbTrId("txt_common_menu_play_music") ); break; default: break; } - if ( contextMenu) { - if ( contextMenu->exec(coords) ) { + if ( contextMenu ) { + setOutstandingPopup( contextMenu ); + if ( mActivated ? contextMenu->exec( coords ) : 0 ) { // Start the playback process. View will switch to playbackview. mMpxWrapper->previewItem( index ); } + setOutstandingPopup( 0 ); } contextMenu->deleteLater(); TX_EXIT @@ -751,7 +1000,7 @@ /*! \internal - Sets the main (default) toolbar for the view. + Sets the main ( default ) toolbar for the view. */ void MpCollectionView::setMainToolBar() { @@ -759,75 +1008,60 @@ if ( !mMainToolBar ) { //Create the toolbar. mMainToolBar = new HbToolBar(); - mMainToolBar->setOrientation(Qt::Horizontal); + 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); - + action = createToolBarAction( actionsGroup, "qtg_mono_songs_all" ); + connect( action, SIGNAL( triggered( bool ) ), this, SLOT( openSongs() ) ); + mMainToolBar->addAction( action ); + + // Albums + action = createToolBarAction( actionsGroup, "qtg_mono_artists_albums" ); + 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); - + action = createToolBarAction( actionsGroup, "qtg_mono_playlist" ); + 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); - + action = createToolBarAction( actionsGroup, "qtg_mono_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); + action = createToolBarAction(actionsGroup, "qtg_mono_ovistore" ); + connect( action, SIGNAL( triggered( bool ) ), this, SLOT( openMusicStore() ) ); + mMainToolBar->addAction( action ); } } HbAction* action = 0; switch ( mCollectionContext ) { case ECollectionContextAllSongs: - action = qobject_cast(mMainToolBar->actions()[KMainToolBarAll]); + action = qobject_cast( mMainToolBar->actions()[KMainToolBarAll] ); break; - case ECollectionContextArtistAlbums: + case ECollectionContextAlbums: case ECollectionContextAlbumSongs: - action = qobject_cast(mMainToolBar->actions()[KMainToolBarArtists]); + action = qobject_cast( mMainToolBar->actions()[KMainToolBarArtists] ); break; case ECollectionContextPlaylists: case ECollectionContextPlaylistSongs: - action = qobject_cast(mMainToolBar->actions()[KMainToolBarPlaylists]); + action = qobject_cast( mMainToolBar->actions()[KMainToolBarPlaylists] ); break; } if ( action ) { - action->setChecked(true); + action->setChecked( true ); } if ( toolBar() != mMainToolBar ) { HbToolBar *tmpToolBar = takeToolBar(); if ( tmpToolBar && tmpToolBar->actions().empty() ) { tmpToolBar->deleteLater(); } - setToolBar(mMainToolBar); + setToolBar( mMainToolBar ); } TX_EXIT } @@ -842,36 +1076,50 @@ 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); + mPlaylistToolBar->setOrientation( Qt::Horizontal ); + HbAction *action; + HbIcon *icon; + + action = new HbAction( this ); + icon = new HbIcon( "qtg_mono_plus" ); + action->setIcon( *icon ); + connect( action, SIGNAL( triggered( bool ) ), this, SLOT( prepareToAddToPlaylist() ) ); + mPlaylistToolBar->addAction( action ); + + action = new HbAction( this ); + icon = new HbIcon( "qtg_mono_minus" ); + action->setIcon( *icon); + connect( action, SIGNAL( triggered( bool ) ), this, SLOT( deleteSongs() ) ); + mPlaylistToolBar->addAction( action ); + + action = new HbAction( this ); + icon = new HbIcon( "qtg_mono_organize" ); + action->setIcon( *icon ); + connect( action, SIGNAL( triggered( bool ) ), this, SLOT( arrangeSongs() ) ); + 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 ( !mUsbBlocked ) { + int items = mCollectionData->count(); + + mPlaylistToolBar->setEnabled( true ); + + //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 ); + } + else { + mPlaylistToolBar->setEnabled( false ); + } + if ( toolBar() != mPlaylistToolBar ) { HbToolBar *tmpToolBar = takeToolBar(); - if (tmpToolBar && tmpToolBar->actions().empty ()) { + if ( tmpToolBar && tmpToolBar->actions().empty () ) { tmpToolBar->deleteLater(); } - setToolBar(mPlaylistToolBar); + setToolBar( mPlaylistToolBar ); } TX_EXIT } @@ -882,18 +1130,13 @@ */ HbAction *MpCollectionView::createToolBarAction( QActionGroup *actionsGroup, - const QString& iconOn, - const QString& iconOff, - const QString& toolTip ) + const QString& icon ) { - HbIcon actionIcon(iconOff); - // button pressed icon - actionIcon.setIconName(iconOn, QIcon::Normal, QIcon::On ); + HbIcon actionIcon( icon ); - HbAction *action = new HbAction(actionsGroup); - action->setToolTip(toolTip); - action->setIcon(actionIcon); - action->setCheckable(true); + HbAction *action = new HbAction( actionsGroup ); + action->setIcon( actionIcon ); + action->setCheckable( true ); return action; } @@ -907,48 +1150,52 @@ 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) { + switch ( mCollectionContext ) { case ECollectionContextAllSongs: - if (items) { - connect( myMenu->addAction(tr("Shuffle play all")), SIGNAL(triggered()), this, SLOT(shufflePlayAll()) ); + if (items ) { + connect( myMenu->addAction( hbTrId( "txt_mus_dblist_shuffle" ) ), 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 ); + if ( !mUsbBlocked ) { + if (items ) { + connect( myMenu->addAction( hbTrId( "txt_mus_opt_add_to_playlist" ) ), SIGNAL( triggered() ), this, SLOT( addToPlaylist() ) ); + } + connect( myMenu->addAction( hbTrId( "txt_mus_opt_refresh_library" ) ), SIGNAL( triggered() ), this, SLOT( refreshLibrary() ) ); } - connect( myMenu->addAction(tr("Exit")), SIGNAL(triggered()), this, SLOT(exit()) ); + connect( myMenu->addAction(hbTrId("txt_common_opt_exit")), SIGNAL(triggered()), this, SLOT(exit()) ); break; - case ECollectionContextArtistAlbums: - //connect( myMenu->addAction(tr("Add to playlist")), SIGNAL(triggered()), this, SLOT(addToPlaylist()), Qt::QueuedConnection ); + case ECollectionContextAlbums: + //connect( myMenu->addAction( hbTrId( "txt_mus_opt_add_to_playlist" ) ), SIGNAL( triggered() ), this, SLOT( addToPlaylist() ) ); // Todo: View as coverflow + if ( !mUsbBlocked ) { + connect( myMenu->addAction( hbTrId( "txt_mus_opt_refresh_library" ) ), SIGNAL( triggered() ), this, SLOT( refreshLibrary() ) ); + } break; case ECollectionContextAlbumSongs: - if (items) { - connect( myMenu->addAction(tr("Add to playlist")), SIGNAL(triggered()), this, SLOT(addToPlaylist()), Qt::QueuedConnection ); + if ( items && !mUsbBlocked ) { + connect( myMenu->addAction( hbTrId( "txt_mus_opt_add_to_playlist" ) ), SIGNAL( triggered() ), this, SLOT( addToPlaylist() ) ); } break; case ECollectionContextPlaylists: - // Todo: Create new playlist + if ( !mUsbBlocked ) { + connect( myMenu->addAction( hbTrId( "txt_mus_opt_new_playlist" ) ), SIGNAL( triggered() ), this, SLOT( prepareToAddToPlaylist() ) ); + } break; case ECollectionContextPlaylistSongs: - if ( !mCollectionData->isAutoPlaylist() ) { - connect( myMenu->addAction(tr("Rename playlist")), SIGNAL(triggered()), this, SLOT(renameCurrentPlaylistContainer()), Qt::QueuedConnection ); + if ( !mCollectionData->isAutoPlaylist() && !mUsbBlocked ) { + connect( myMenu->addAction( hbTrId( "txt_common_menu_rename_item" ) ), SIGNAL( triggered() ), this, SLOT( renameCurrentPlaylistContainer() ) ); } break; default: break; } } - else if (mViewMode == MpCommon::FetchView ) { - if ( mCollectionContext == ECollectionContextAllSongs ) { - connect( myMenu->addAction(tr("Refresh library")), SIGNAL(triggered()), this, SLOT(refreshLibrary()) ); + else if ( mViewMode == MpCommon::FetchView ) { + if ( mCollectionContext == ECollectionContextAllSongs && !mUsbBlocked ) { + connect( myMenu->addAction( hbTrId( "txt_mus_opt_refresh_library" ) ), SIGNAL( triggered() ), this, SLOT( refreshLibrary() ) ); } } - setMenu(myMenu); + setMenu( myMenu ); TX_EXIT } @@ -960,21 +1207,21 @@ { TX_ENTRY - switch (mCollectionContext) { + switch ( mCollectionContext ) { case ECollectionContextPlaylistSongs: if ( !mCollectionData->isAutoPlaylist() ) { setPlaylistToolBar(); } - else if (!toolBar()->actions().empty()) { + else if ( !toolBar()->actions().empty() ) { takeToolBar(); - setToolBar(new HbToolBar); - } + setToolBar( new HbToolBar ); + } break; case ECollectionContextAlbumSongs: case ECollectionContextGenreSongs: - if (!toolBar()->actions().empty()) { + if ( !toolBar()->actions().empty() ) { takeToolBar(); - setToolBar(new HbToolBar); + setToolBar( new HbToolBar ); } break; default: @@ -993,18 +1240,18 @@ 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); + setNavigationAction( mSoftKeyBack ); } else { switch ( mCollectionContext ) { case ECollectionContextAllSongs: - case ECollectionContextArtistAlbums: + case ECollectionContextAlbums: case ECollectionContextPlaylists: case ECollectionContextGenres: - mWindow->addSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyQuit); + setNavigationAction( mSoftKeyQuit ); break; default: - mWindow->addSoftKeyAction(Hb::SecondarySoftKey, mSoftKeyBack); + setNavigationAction( mSoftKeyBack ); break; } } @@ -1012,33 +1259,23 @@ /*! \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); + 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); + 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"); + TX_LOG_ARGS( "Error: invalid xml file." ); + Q_ASSERT_X( ok, "MpCollectionView::setBannerVisibility", "invalid xml file" ); } } @@ -1052,10 +1289,10 @@ int high = mCollectionData->count(); time_t seconds; - time(&seconds); - srand((unsigned int) seconds); + time( &seconds ); + srand( ( unsigned int ) seconds ); - int index = rand() % (high - low + 1) + low; + int index = rand() % ( high - low + 1 ) + low; return index; } @@ -1063,111 +1300,111 @@ \internal Launches the 'Add to playlist' dialog. */ -void MpCollectionView::launchAddToPlaylistDialog( QList selection ) +void MpCollectionView::launchAddToPlaylistDialog( QList &selection ) { + if (!mActivated) { + return; + } QString newPlaylistName; - int playlistIndex; - bool canceled = false; + QStringList playlists; + mMpxWrapper->findPlaylists( playlists ); + HbListDialog dialog; + dialog.setStringItems( playlists ); + dialog.setSelectionMode( HbAbstractItemView::SingleSelection ); + dialog.setHeadingWidget(new HbLabel( hbTrId( "txt_mus_title_select_playlist" ) ) ); + dialog.setPrimaryAction(new HbAction( hbTrId( "txt_mus_button_new" ) ) ); + dialog.setSecondaryAction(new HbAction( hbTrId( "txt_common_button_cancel" ) ) ); 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 + if ( playlists.count() ) { + //There are saved playlists, query for a saved playlist or new. + setOutstandingPopup( &dialog ); + HbAction *selectedAction = mActivated ? dialog.exec() : 0; + setOutstandingPopup( 0 ); + if ( selectedAction == dialog.primaryAction() ) { + //User selected pimaryAction "new", fall trough to new playlyst query. + } + else if ( dialog.selectedItems().count() ) {//this only works for SingleSelection + // User selected existing playlist, add songs and exit the loop. + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->saveToPlaylist( dialog.selectedItems().at( 0 ), selection ); + } break; } - else if ( selectedAction != dialog.primaryAction()) { - // User selected existing playlist - playlistIndex = dialog.selectedItems().at(0); - mMpxWrapper->saveToPlaylist(playlistIndex, selection); + else { + //Cancel was pressed or dialog was closed or never executed, exit the loop. break; } } - else if (canceled) { + //querying for a new playlist name. + if ( queryNewPlaylistName(newPlaylistName , playlists) ) { + // user selected a new playlist, save and exit the loop. + if ( !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->createPlaylist( newPlaylistName, selection ); + } 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; - } + else if (!playlists.count()) { + // user decided to not provide a new name and there are no saved playlists, exit the loop + break; } - } + // user decided to not provide a new name and there are saved playlists, back to the top. + } //forever } /*! \internal starts a transition of the main container with a decoy snapshot. */ -void MpCollectionView::startContainerTransition(TCollectionContext contextFrom, TCollectionContext contextTo) +void MpCollectionView::startContainerTransition( TCollectionContext contextFrom, TCollectionContext contextTo ) { - if (!mSnapshot) - mSnapshot = new MpSnapshotWidget(); - mSnapshot->capture(mWindow, mMainContainer ); - mWindow->scene()->addItem(mSnapshot); + if (contextFrom == contextTo) { + return; + } + + if ( !mSnapshot ) { + mSnapshot = new MpSnapshotWidget(); + } + mSnapshot->capture( mWindow, mMainContainer ); + mWindow->scene()->addItem( mSnapshot ); - if ( ( contextFrom == ECollectionContextArtistAlbums && contextTo == ECollectionContextAlbumSongs ) || + if ( ( contextFrom == ECollectionContextAlbums && contextTo == ECollectionContextAlbumSongs ) || ( contextFrom == ECollectionContextPlaylists && contextTo == ECollectionContextPlaylistSongs ) || - ( contextFrom == ECollectionContextGenres && contextTo == ECollectionContextGenreSongs ) ){ - HbEffect::start(mSnapshot, - QString("container"), - QString("slide_out_to_left")); + ( 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"), + HbEffect::start( mMainContainer, + QString( "container" ), + QString( "slide_in_to_left_and_fade_in" ), this, - "containerTransitionComplete"); + "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")); + else if( ( contextFrom == ECollectionContextAlbumSongs && contextTo == ECollectionContextAlbums ) || + ( 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"), + HbEffect::start( mMainContainer, + QString( "container" ), + QString( "slide_in_to_right_and_fade_in" ), this, - "containerTransitionComplete"); + "containerTransitionComplete" ); } else { - HbEffect::start(mSnapshot, - QString("container"), - QString("slide_out_to_top")); + HbEffect::start( mSnapshot, + QString( "container" ), + QString( "slide_out_to_top" ) ); - HbEffect::start(mMainContainer, - QString("container"), - QString("slide_in_to_top_and_fade_in"), + HbEffect::start( mMainContainer, + QString( "container" ), + QString( "slide_in_to_top_and_fade_in" ), this, - "containerTransitionComplete"); + "containerTransitionComplete" ); } } @@ -1176,43 +1413,50 @@ \internal request a delete operation always it has been confirmed. */ -void MpCollectionView::requestDelete(QList selection) -{ - bool confirmation(false); +void MpCollectionView::requestDelete( QList &selection ) +{ + bool confirmation( false ); // Todo: Use HbMessageBox::question when time-out removed from it - HbMessageBox dialog(HbMessageBox::MessageTypeQuestion); + HbMessageBox dialog( HbMessageBox::MessageTypeQuestion ); + QString message; - HbAction *action; - - switch (mCollectionContext) { + HbAction *action = 0; + + 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()) { + message = hbTrId( "txt_mus_delete_song" ); + dialog.setText( message ); + dialog.setTimeout( HbPopup::NoTimeout ); + setOutstandingPopup( &dialog ); + action = mActivated ? dialog.exec() : 0; + setOutstandingPopup( 0 ); + if ( action && 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()) { + case ECollectionContextAlbums: + message = hbTrId( "txt_mus_delete_album" ); + dialog.setText( message ); + dialog.setTimeout( HbPopup::NoTimeout ); + setOutstandingPopup( &dialog ); + action = mActivated ? dialog.exec() : 0; + setOutstandingPopup( 0 ); + if ( action && 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()) { + message = hbTrId( "txt_mus_delete_playlist" ); + dialog.setText( message ); + dialog.setTimeout( HbPopup::NoTimeout ); + setOutstandingPopup( &dialog ); + action = mActivated ? dialog.exec() : 0; + setOutstandingPopup( 0 ); + if ( action && action == dialog.primaryAction() ) { confirmation = true; } - break; + break; case ECollectionContextPlaylistSongs: case ECollectionContextGenres: case ECollectionContextGenreSongs: @@ -1221,11 +1465,114 @@ case ECollectionContextUnknown: default: // We shouldn't be here - TX_LOG_ARGS("Invalid Collection Context:" << mCollectionContext); + TX_LOG_ARGS( "Invalid Collection Context:" << mCollectionContext ); break; } - if ( confirmation ) { - mMpxWrapper->deleteSongs(selection); - } + if ( confirmation && !mMpEngine->verifyUsbBlocking( true ) ) { + mMpxWrapper->deleteSongs( selection ); + } +} + +/*! + \internal + Returns a list of itmes selected. + */ +QModelIndexList MpCollectionView::getModelIndexes( const QString &label, QAbstractItemModel* model, bool &ok ) +{ + QModelIndexList result; + + if ( !mActivated ) { + ok = false; + return result; + } + + HbListDialog *dlg = new HbListDialog(); + dlg->setHeadingWidget( new HbLabel( label ) ); + dlg->setSelectionMode( HbAbstractItemView::MultiSelection ); + dlg->setModel( model ); + setOutstandingPopup( dlg ); + HbAction* action = mActivated ? dlg->exec() : 0; + setOutstandingPopup( 0 ); + if( action == dlg->primaryAction() ){ //OK was pressed + ok = true; + result = dlg->selectedModelIndexes(); + } + else{ //Cancel was pressed or dialog was closed or never executed. + ok = false; + } + dlg->setModel( 0 ); + delete dlg; + return result; } + +/*! + \internal + Returns a string from user input. + */ +QString MpCollectionView::getText( const QString &label,const QString &text, + bool &ok ) +{ + + QString result; + + if ( !mActivated ) { + ok = false; + return result; + } + + HbInputDialog *dlg = new HbInputDialog(); + dlg->setPromptText( label ); + dlg->setInputMode( HbInputDialog::TextInput ); + dlg->setValue( text ); + setOutstandingPopup( dlg ); + HbAction* action = mActivated ? dlg->exec() : 0; + setOutstandingPopup( 0 ); + if( action == dlg->primaryAction() ) { //OK was pressed + ok = true; + result = dlg->value().toString(); + } else { //Cancel was pressed or dialog was closed or never executed. + ok = false; + } + delete dlg; + return result; +} + +/*! + \internal + sets \a popup as the current outstanding popup and cancels any otstanding popup. + */ +void MpCollectionView::setOutstandingPopup( HbPopup *popup ) +{ + if ( mOutstandingPopup ) { + mOutstandingPopup->close(); + } + mOutstandingPopup = popup; +} + +/*! + \internal + sets \a newPlaylistName with imput name from the user, uses \a playlists to + generate a suggested playlist name, retrns true if the user confirmed the query. + */ +bool MpCollectionView::queryNewPlaylistName(QString &newPlaylistName , const QStringList &playlists ) +{ + bool ret= false; + if (!mActivated) { + return ret; + } + int i = 0; + for ( ; + playlists.contains( hbTrId( "txt_mus_dialog_enter_name_entry_playlist_l1" ).arg( i ) ) ; + i++ ) {}; + QString suggestedPlaylistName = hbTrId( "txt_mus_dialog_enter_name_entry_playlist_l1" ).arg( i ); + QString suggestedText; + bool ok = false; + suggestedText = getText( hbTrId("txt_mus_dialog_enter_name" ), suggestedPlaylistName, ok); + if ( ok ) { + newPlaylistName = suggestedText; + ret = true; + } + return ret; +} +