diff -r b95ddb5a0d10 -r eff9df3d9c98 mpengine/src/mpengine.cpp --- a/mpengine/src/mpengine.cpp Fri Jun 11 16:24:02 2010 +0100 +++ b/mpengine/src/mpengine.cpp Thu Jul 22 16:32:33 2010 +0100 @@ -15,21 +15,20 @@ * */ -#include -#include -#include -#include -#include -#include #include +#include #include "mpengine.h" #include "mpmpxharvesterframeworkwrapper.h" #include "mpmpxcollectionframeworkwrapper.h" #include "mpmpxplaybackframeworkwrapper.h" -#include "mpsongscanner.h" +#include "mpmpxdetailsframeworkwrapper.h" +#include "mpaudioeffectsframeworkwrapper.h" +#include "mpequalizerframeworkwrapper.h" #include "mpmediakeyhandler.h" #include "mptrace.h" +#include "mpsettingsmanager.h" +#include "mpsongscanner.h" /*! \class MpEngine @@ -46,87 +45,61 @@ */ /*! - \fn void scanStarted() - - This signal is emitted when scan operation is started. - - */ - -/*! - \fn void scanEnded() + \fn void libraryAboutToUpdate() - This signal is emitted when scan operation ends. - - */ - -/*! - \fn void scanCountChanged( int count ) - - This signal is emitted when scan count is updated. + This signal is emitted when a scan operation has been requested or + when MTP synchronization starts. */ /*! \fn void libraryUpdated() - This signal is emitted when MpSongScannerHelper ends scanning, - or USB-MTP Synchronization finishes. + This signal is emitted when library has changed. + + \sa handleScanEnded() + \sa handleDiskEvent() + \sa handleUsbMtpEndEvent() */ /*! - \fn void formatStarted() - - This signal is emitted when EMcMsgFormatStart is received from MPXCollectionUtility. - - */ - -/*! - \fn void formatEnded() + \fn void usbBlocked( bool blocked ) - This signal is emitted when EMcMsgFormatEnd is received from MPXCollectionUtility. - - */ - -/*! - \fn void diskRemoved() - - This signal is emitted when EMcMsgDiskRemoved is received from MPXCollectionUtility. + This signal is emitted to update the usb blocking state + due a previous usb event received. + + \sa handleUsbEvent() */ /*! - \fn void diskInserted() - - This signal is emitted when EMcMsgDiskInserted is received from MPXCollectionUtility. + \fn void unableToCotinueDueUSB() - */ - -/*! - \fn void usbMassStorageStarted() - - This signal is emitted when EMcMsgUSBMassStorageStart is received from MPXCollectionUtility. + This signal is emitted if usb blocking verification returns true. + + \sa verifyUsbBlocking() */ /*! - \fn void usbMassStorageEnded() + \fn void usbSynchronizationStarted() - This signal is emitted when EMcMsgUSBMassStorageEnd is received from MPXCollectionUtility. + This signal is emitted when usb is connected in MassStorage mode or MTP mode and synchronizing. */ /*! - \fn void usbMtpStarted() + \fn void usbSynchronizationFinished() - This signal is emitted when EMcMsgUSBMtpStart is received from MPXCollectionUtility. + This signal is emitted when usb in synchronizing state is disconnected. */ /*! - \fn void usbMtpEnded() + \fn void libraryRefreshNeeded() - This signal is emitted when EMcMsgUSBMtpEnd is received from MPXCollectionUtility. + This signal is emitted when usb in MassStorage mode is disconnected. */ @@ -154,6 +127,24 @@ */ /*! + \fn void aboutToAddSongs( int count ) + + Signal emitted up on a notification from MPX Collection wrapper, + when play list is prepared and about to be added. + \a count Indicates number of songs to be added. + + */ + +/*! + \fn void deleteStarted(TCollectionContext context, int Count) + + This signal is emitted when song delete operation has started. + \a context The context where delete operation is taking place. + \a Count Number of items to delete. + + */ + +/*! \fn void songsDeleted( bool success ) This signal is emitted when song delete operation is completed, it @@ -177,19 +168,36 @@ */ /*! + \fn void restorePathFailed() + + This signal is emitted when an the previous path cannot be restored + (i.e. no music in collection). + + */ + +/*! + \fn void containerContentsChanged() + + This signal is emitted when items are removed or inserted on the current + container. + + */ + +/*! Constructs music player engine. */ MpEngine::MpEngine() : mMpxHarvesterWrapper(0), mSongScanner(0), mMediaKeyHandler(0), - mUsbOutstandingNote(0), mMpxCollectionWrapper(0), mMpxPlaybackWrapper(0), - mMpTranslator(0), + mMpxDetailsWrapper(0), + mAudioEffectsWrapper(0), + mEqualizerWrapper(0), + mCurrentPresetIndex(KEqualizerPresetNone), mUsbBlockingState(USB_NotConnected), - mPreviousUsbState(USB_NotConnected), - mViewMode(MpCommon::DefaultView) + mPreviousUsbState(USB_NotConnected) { TX_LOG } @@ -200,42 +208,28 @@ MpEngine::~MpEngine() { TX_ENTRY + delete mMediaKeyHandler; + delete mMpxPlaybackWrapper; + delete mMpxDetailsWrapper; + delete mMpxHarvesterWrapper; + delete mMpxCollectionWrapper; + delete mAudioEffectsWrapper; + delete mEqualizerWrapper; + delete mSongScanner; TX_EXIT } /*! - Returns the singleton instance of music player engine. - */ -MpEngine * MpEngine::instance() -{ - static MpEngine instance; - return &instance; -} - -/*! Initialize engine */ -void MpEngine::initialize( MpCommon::MpViewMode viewMode, TUid hostUid ) +void MpEngine::initialize( TUid hostUid, EngineMode mode ) { TX_ENTRY - mViewMode = viewMode; mHostUid = hostUid; - - //Load musicplayer translator - 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 ); - } - - if( mViewMode == MpCommon::DefaultView || mViewMode == MpCommon::FetchView ){ + if( mode == StandAlone || mode == Fetch ){ // Harvesting Wrapper - mMpxHarvesterWrapper = new MpMpxHarvesterFrameworkWrapper( mViewMode, mHostUid ); + mMpxHarvesterWrapper = new MpMpxHarvesterFrameworkWrapper( mHostUid ); connect( mMpxHarvesterWrapper, SIGNAL( scanStarted() ), this, SLOT( handleScanStarted() ), Qt::QueuedConnection ); connect( mMpxHarvesterWrapper, SIGNAL( scanEnded(int, int) ), @@ -246,53 +240,65 @@ qRegisterMetaType("MpxUsbEvents"); connect( mMpxHarvesterWrapper, SIGNAL( usbEvent(MpxUsbEvents) ), this, SLOT( handleUsbEvent(MpxUsbEvents) ), Qt::QueuedConnection ); - mSongScanner = new MpSongScanner( mMpxHarvesterWrapper ); mMediaKeyHandler = new MpMediaKeyHandler(); + } + + if ( mode == StandAlone || mode == Fetch || mode == MediaBrowsing) { // Collection Wrapper - mMpxCollectionWrapper = new MpMpxCollectionFrameworkWrapper( mViewMode, mHostUid ); + mMpxCollectionWrapper = new MpMpxCollectionFrameworkWrapper( mHostUid ); + + //disabling these since fetch mode plays only one song at a time. + mMpxCollectionWrapper->setRepeatFeatureEnabled( mode != Fetch ); + mMpxCollectionWrapper->setShuffleFeatureEnabled( mode != Fetch ); + connect( mMpxCollectionWrapper, SIGNAL( collectionPlaylistOpened() ), this, SIGNAL( collectionPlaylistOpened() ), Qt::QueuedConnection ); + connect( mMpxCollectionWrapper, SIGNAL( aboutToAddSongs( int ) ), + this, SIGNAL( aboutToAddSongs( int ) ) ); connect( mMpxCollectionWrapper, SIGNAL( playlistSaved( bool ) ), this, SIGNAL( playlistSaved( bool ) ), Qt::QueuedConnection ); - connect( mMpxCollectionWrapper, SIGNAL( songsDeleted( bool ) ), - this, SIGNAL( songsDeleted( bool ) ), - Qt::QueuedConnection ); connect( mMpxCollectionWrapper, SIGNAL( playlistsRenamed( bool ) ), this, SIGNAL( playlistsRenamed( bool ) ), Qt::QueuedConnection ); connect( mMpxCollectionWrapper, SIGNAL( isolatedCollectionOpened( MpMpxCollectionData* ) ), this, SIGNAL( isolatedCollectionOpened( MpMpxCollectionData* ) ), Qt::QueuedConnection ); + connect( mMpxCollectionWrapper, SIGNAL( containerContentsChanged() ), + this, SIGNAL( containerContentsChanged() ), + Qt::QueuedConnection ); + connect( mMpxCollectionWrapper, SIGNAL( deleteStarted( TCollectionContext, int ) ), + this, SLOT( handleDeleteStarted( TCollectionContext, int ) ) ); + connect( mMpxCollectionWrapper, SIGNAL( songsDeleted( bool ) ), + this, SLOT( handleDeleteEnded( bool ) ), + Qt::QueuedConnection ); + connect( mMpxCollectionWrapper, SIGNAL( restorePathFailed() ), + this, SIGNAL( restorePathFailed() ), + Qt::QueuedConnection ); } - // Playback Wrapper - mMpxPlaybackWrapper = new MpMpxPlaybackFrameworkWrapper( mViewMode, mHostUid ); - - TX_EXIT -} + if( mode == StandAlone ){ + // Equalizer wrapper , this needs to be created before playback wrapper. + mEqualizerWrapper = new MpEqualizerFrameworkWrapper(); + connect( mEqualizerWrapper, SIGNAL( equalizerReady() ), + this, SLOT( handleEqualizerReady() ), Qt::QueuedConnection ); + } + + if ( mode == StandAlone || mode == Fetch || mode == Embedded ) { + // Playback Wrapper + mMpxPlaybackWrapper = new MpMpxPlaybackFrameworkWrapper( mHostUid ); + + // Details Wrapper + mMpxDetailsWrapper = new MpMpxDetailsFrameworkWrapper( mHostUid ); + } -/*! - Deinitialize wrappers - */ -void MpEngine::close( ) -{ - delete mMpTranslator; - mMpTranslator = 0; - delete mSongScanner; - mSongScanner = 0; - delete mMediaKeyHandler; - mMediaKeyHandler = 0; - delete mUsbOutstandingNote; - mUsbOutstandingNote = 0; - delete mMpxPlaybackWrapper; - mMpxPlaybackWrapper = 0; - delete mMpxHarvesterWrapper; - mMpxHarvesterWrapper = 0; - delete mMpxCollectionWrapper; - mMpxCollectionWrapper = 0; + if( mode == StandAlone ){ + // AudioEffects wrapper + mAudioEffectsWrapper = new MpAudioEffectsFrameworkWrapper(); + } + TX_EXIT } /*! @@ -306,18 +312,14 @@ Used to verify if an action can be executed depending on USB blocking state. If not, a notification note might be displayed. */ -bool MpEngine::verifyUsbBlocking( bool showMessage ) +bool MpEngine::verifyUsbBlocking( bool notify ) { TX_ENTRY bool result( false ); if ( mUsbBlockingState == USB_Connected ) { result = true; - if ( showMessage ) { - HbMessageBox *dialog = new HbMessageBox( HbMessageBox::MessageTypeInformation ); - dialog->setText( hbTrId( "txt_mus_info_usb_conn_in_progress" ) ); - dialog->setModal( true ); - setOutstandingPopup( dialog ); - mUsbOutstandingNote->show();; + if ( notify ) { + emit unableToCotinueDueUSB(); } } TX_EXIT @@ -336,15 +338,26 @@ } /*! + \ + Returs the current songScanner instance + */ +MpSongScanner *MpEngine::songScanner() +{ + return mSongScanner; +} +/*! Slot to be called to start Refresh library process. If scanning is already ongoing, this request is ignored. */ -void MpEngine::refreshLibrary() +void MpEngine::refreshLibrary( bool automaticRequest ) { TX_ENTRY if ( !verifyUsbBlocking( true ) ) { + if ( !mSongScanner ) { + mSongScanner = new MpSongScanner( mMpxHarvesterWrapper ); + } emit libraryAboutToUpdate(); - mSongScanner->scan(); + mSongScanner->scan( automaticRequest ); } TX_EXIT } @@ -390,7 +403,7 @@ break; case DiskInserted: if ( mUsbBlockingState == USB_NotConnected ) { - refreshLibrary(); + refreshLibrary( true ); } else if ( mUsbBlockingState == USB_Connected ) { emit libraryUpdated(); @@ -430,16 +443,6 @@ } /*! - Slot to be called when mUsbOutstandingNote is about to close. - */ -void MpEngine::handleOutstandingNoteClosing() -{ - TX_ENTRY - mUsbOutstandingNote = 0; - TX_EXIT -} - -/*! To be called when EMcMsgUSBMassStorageStart event is received. */ void MpEngine::handleUsbMassStorageStartEvent() @@ -449,9 +452,8 @@ changeUsbBlockingState( USB_Synchronizing ); emit usbBlocked(true); - - launchBlockingNote(); - + emit usbSynchronizationStarted(); + TX_EXIT } @@ -461,24 +463,13 @@ void MpEngine::handleUsbMassStorageEndEvent() { TX_ENTRY - mMediaKeyHandler->setEnabled(true); + mMediaKeyHandler->setEnabled(true); changeUsbBlockingState( USB_NotConnected ); emit usbBlocked(false); + emit usbSynchronizationFinished(); + emit libraryRefreshNeeded(); - HbAction *action; - HbMessageBox *promptRefresh = new HbMessageBox( HbMessageBox::MessageTypeQuestion ); - promptRefresh->setText( hbTrId( "txt_mus_info_music_may_need_to_be_refreshed" ) ); - promptRefresh->setTimeout( HbPopup::NoTimeout ); - promptRefresh->setModal( true ); - promptRefresh->clearActions(); - action = new HbAction( hbTrId( "txt_common_button_yes" ) ); - connect( action, SIGNAL( triggered() ), this, SLOT( refreshLibrary() ) ); - promptRefresh->addAction( action ); - action = new HbAction( hbTrId( "txt_common_button_no" ) ); - promptRefresh->addAction( action ); - setOutstandingPopup( promptRefresh ); - mUsbOutstandingNote->show(); TX_EXIT } @@ -496,7 +487,7 @@ //Cancel any ongoing operation. emit libraryAboutToUpdate(); - launchBlockingNote(); + emit usbSynchronizationStarted(); TX_EXIT } @@ -507,15 +498,13 @@ void MpEngine::handleUsbMtpEndEvent() { TX_ENTRY - mMediaKeyHandler->setEnabled(true); + mMediaKeyHandler->setEnabled(true); changeUsbBlockingState( USB_NotConnected ); emit usbBlocked(false); - - if ( mUsbOutstandingNote ) { - mUsbOutstandingNote->close(); - } + if ( mPreviousUsbState == USB_Synchronizing ) { + emit usbSynchronizationFinished(); emit libraryUpdated(); } TX_EXIT @@ -545,48 +534,6 @@ } /*! - Internal - Used to launch the usb blocking note - */ -void MpEngine::launchBlockingNote() -{ - TX_ENTRY - - HbProgressDialog *usbBlockingNote = new HbProgressDialog( HbProgressDialog::WaitDialog ); - usbBlockingNote->setModal( true ); - if ( usbBlockingNote->actions().count() ) { - //Hide cancel action. - usbBlockingNote->actions().at( 0 )->setVisible( false ); - } - usbBlockingNote->setDismissPolicy( HbPopup::NoDismiss ); - usbBlockingNote->setText( hbTrId( "txt_mus_info_usb_conn_in_progress" ) ); - setOutstandingPopup( usbBlockingNote ); - mUsbOutstandingNote->show(); - - TX_EXIT -} - -/*! - \internal - sets \a popup as the current outstanding popup and cancels any other active popup. - */ -void MpEngine::setOutstandingPopup( HbPopup *popup ) -{ - TX_ENTRY - //Close previous popup (Normally blocking usb note) - if ( mUsbOutstandingNote ) { - disconnect( mUsbOutstandingNote, SIGNAL( aboutToClose() ), this, SLOT( handleOutstandingNoteClosing() ) ); - mUsbOutstandingNote->close(); - } - - //Set new outstanding popup - popup->setAttribute( Qt::WA_DeleteOnClose ); - connect( popup, SIGNAL( aboutToClose() ), this, SLOT( handleOutstandingNoteClosing() ) ); - mUsbOutstandingNote = popup; - TX_EXIT -} - -/*! ------------------------------------------------------------------------------- Collection related ------------------------------------------------------------------------------- @@ -722,6 +669,22 @@ } /*! + Finds all songs beloging to the album specified by the \a index. + */ +void MpEngine::findAlbumSongs( int index ) +{ + mMpxCollectionWrapper->findAlbumSongs(index); +} + +/*! + Plays album with \a albumIndex starting with the songs with \a songIndex. + */ +void MpEngine::playAlbumSongs( int albumIndex, int songIndex, MpMpxCollectionData* collectionData ) +{ + mMpxCollectionWrapper->playAlbumSongs(albumIndex, songIndex, collectionData); +} + +/*! Returns pointer to MpMpxCollectionData, which is the collection data. */ MpMpxCollectionData *MpEngine::collectionData() @@ -750,12 +713,53 @@ } /*! + Slot to be called when song deleting starts. + */ +void MpEngine::handleDeleteStarted( TCollectionContext context, int count ) +{ + TX_ENTRY + mMediaKeyHandler->setEnabled( false ); + emit deleteStarted( context, count ); + TX_EXIT +} + +/*! + Slot to be called when song deleting ends. + */ +void MpEngine::handleDeleteEnded( bool success ) +{ + TX_ENTRY + mMediaKeyHandler->setEnabled(true); + emit songsDeleted( success ); + TX_EXIT +} + +/*! + Slot to be called when song deleting ends. + */ +void MpEngine::cancelCollectionRequest() +{ + TX_ENTRY + mMpxCollectionWrapper->cancelRequest(); + TX_EXIT +} + +/*! Returns pointer to MpPlaybackData, which is the playback data. */ MpPlaybackData *MpEngine::playbackData() { return mMpxPlaybackWrapper->playbackData(); } + +/*! + Requests playback of all songs with shuffle enabled + */ +void MpEngine::shuffleAll() +{ + mMpxCollectionWrapper->openShuffleAllSongsPath(); +} + /*! Slot to be called to request embedded playback of item with Uri aFilename */ @@ -790,7 +794,7 @@ } /*! - Slot to handle a skeep forward. + Slot to handle a skip forward. */ void MpEngine::skipForward() { @@ -798,7 +802,23 @@ } /*! - Slot to handle a skeep backwards. + Slot to handle seek forward. + */ +void MpEngine::startSeekForward() +{ + mMpxPlaybackWrapper->startSeekForward(); +} + +/*! + Slot to handle stop seeking. + */ +void MpEngine::stopSeeking() +{ + mMpxPlaybackWrapper->stopSeeking(); +} + +/*! + Slot to handle a skip backwards. */ void MpEngine::skipBackward() { @@ -806,6 +826,13 @@ } /*! + Slot to handle seek backwards. + */ +void MpEngine::startSeekBackward() +{ + mMpxPlaybackWrapper->startSeekBackward(); +} +/*! Slot to handle a request to change \a position. */ void MpEngine::setPosition( int position ) @@ -829,3 +856,161 @@ mMpxPlaybackWrapper->setRepeat( mode ); } +/*! + Returns pointer to MpSongData, which is the song data for detail's view. + */ +MpSongData *MpEngine::songData() +{ + return mMpxDetailsWrapper->songData(); +} + +/*! + Retrieve song informatioin + */ +void MpEngine::retrieveSong() +{ + TX_ENTRY + mMpxDetailsWrapper->retrieveSong(); + TX_EXIT +} + +/*! + Retrieve balance informatioin from audio effects + */ +int MpEngine::balance() +{ + return mAudioEffectsWrapper->balance(); +} + +/*! + Retrieve loudness informatioin from audio effects + */ +bool MpEngine::loudness() +{ + return mAudioEffectsWrapper->loudness(); +} + +/*! + Slot to handle a request to change \a balance in audio effects. + */ +void MpEngine::setBalance( int balance ) +{ + TX_ENTRY + + if ( mAudioEffectsWrapper->balance() != balance ) { + mAudioEffectsWrapper->setBalance( balance ); + mMpxPlaybackWrapper->setBalance( balance ); + } + + TX_EXIT +} + +/*! + Slot to handle a request to change loudness \a mode in audio effects. + */ +void MpEngine::setLoudness( bool mode ) +{ + TX_ENTRY + + if( mAudioEffectsWrapper->loudness() != mode ) { //do not set same value twice + mAudioEffectsWrapper->setLoudness( mode ); + mMpxPlaybackWrapper->applyAudioEffects(); + } + + TX_EXIT +} + +/*! + Apply the preset by giving \a presetIndex. The index is subtracted by 1 because + index 0 represent "Off" at UI level. + */ +void MpEngine::applyPreset( int presetIndex ) +{ + TX_ENTRY_ARGS( "presetIndex=" << presetIndex ); + + TInt presetKey = mEqualizerWrapper->getPresetNameKey( presetIndex - 1 ); + + if ( presetKey != KEqualizerPresetNone ) { + TX_LOG_ARGS( "Preset key in engine =" << presetKey ); + // Store in CenRep file + MpSettingsManager::setPreset( presetKey ); + // Notify playback framework of the change. + mMpxPlaybackWrapper->applyEqualizer(); + mCurrentPresetIndex = presetIndex; + } + else { + TX_LOG_ARGS("getPresetNameKey Error = " << KEqualizerPresetNone); + } + + TX_EXIT +} + +/*! + Disabling equalizer by setting the preset to -1 and apply it to + disable current preset. + */ +void MpEngine::disableEqualizer() +{ + TX_ENTRY + + mCurrentPresetIndex = KEqualizerPresetNone; + // Store in CenRep file + MpSettingsManager::setPreset( mCurrentPresetIndex ); + // Notify playback framework of the change. + mMpxPlaybackWrapper->applyEqualizer(); + + TX_EXIT +} + +/*! + Return current preset index (UI) + */ +int MpEngine::activePreset() +{ + TX_LOG_ARGS("mCurrentPresetIndex = " << mCurrentPresetIndex ); + + return mCurrentPresetIndex; +} + +/*! + Retrieve list of preset names from equalizer wrapper + */ +QStringList MpEngine::presetNames() +{ + return mEqualizerWrapper->presetNames(); +} + +/*! + Save data needed to later restore state (activity) + */ +void MpEngine::saveActivityData( QByteArray &data ) +{ + mMpxCollectionWrapper->savePath( data ); +} + +/*! + Restore state from activity data + */ +void MpEngine::loadActivityData( const QByteArray &data ) +{ + mMpxCollectionWrapper->restorePath( data ); +} + +/*! + Slot to handle equalizer ready signal from equalizer wrapper. + */ +void MpEngine::handleEqualizerReady() +{ + TX_ENTRY + + // Get preset id from cenrep + TInt presetKey( MpSettingsManager::preset() ); + + //Set the current preset index. 1 is added to index because index 0 represent "Off" at UI level. + mCurrentPresetIndex = mEqualizerWrapper->getPresetIndex( presetKey ); + mCurrentPresetIndex++; + emit equalizerReady(); + + TX_EXIT +} +