musicwidgetplugin/src/musicwidget.cpp
changeset 61 3cd404d31176
parent 58 ed94e1e8390e
--- a/musicwidgetplugin/src/musicwidget.cpp	Fri Sep 17 08:28:52 2010 +0300
+++ b/musicwidgetplugin/src/musicwidget.cpp	Mon Oct 04 00:14:19 2010 +0300
@@ -15,9 +15,8 @@
 *
 */
 
-#include "musicwidget.h"
-
-#include <QtGui>
+// System includes
+#include <qgraphicslinearlayout.h>
 #include <hbpushbutton.h>
 #include <hblabel.h>
 #include <hbicon.h>
@@ -26,174 +25,95 @@
 #include <hbwidget.h>
 #include <hbframeitem.h>
 #include <hbframedrawer.h>
-#include <hbcolorscheme.h>
+#include <hbtranslator.h>
 
+// User includes
+#include "musicwidget.h"
 #include "musicwidgetdocumentloader.h"
 #include "mptrace.h"
 #include "mpenginefactory.h"
 #include "mpalbumcoverwidget.h"
+#include "mpplaybackdata.h"
+#include "mpapplicationmonitor.h"
 
 // Constants
 /** Docml */
-const QString MUSIC_WIDGET_DOCML = ":/gfx/music_widget.docml";
-
-/** File name suffix lists for push buttons */
-const QStringList PREV_BUTTON_SUFFIXES = (QStringList() << "_l" << "_c" << "_cr");
-const QStringList PLAY_BUTTON_SUFFIXES = (QStringList() << "_cl" << "_c" << "_cr");
-const QStringList NEXT_BUTTON_SUFFIXES = (QStringList() << "_cl" << "_c" << "_r");
-
-/**  Prefixes for 3 piece button background graphics */
-const QLatin1String PUSH_BUTTON_NORMAL("qtg_fr_hsbutton_normal");
-const QLatin1String PUSH_BUTTON_PRESSED ("qtg_fr_hsbutton_pressed");
-const QLatin1String PUSH_BUTTON_DISABLED ("qtg_fr_hsbutton_disabled");
-
-/**  Push button icon colors for each of the states (Normal, Pressed and Disabled) */
-const QLatin1String ICON_COLOR_NORMAL ("qtc_button_normal");
-const QLatin1String ICON_COLOR_PRESSED ("qtc_button_pressed");
-const QLatin1String ICON_COLOR_DISABLED ("qtc_button_disabled");
+const QString MUSIC_WIDGET_DOCML = ":/docml/music_widget.docml";
 
 /**  Play and Pause icons */
-const QLatin1String ICON_PLAY ("qtg_mono_play");
-const QLatin1String ICON_PAUSE ("qtg_mono_pause");
-/**  Music Player shortcut icon */
-const QLatin1String ICON_LARGE_MUSIC_PLAYER ("qtg_large_music");
-/**  Music Player shortcut icon */
-const QLatin1String ICON_FIRST_TIME_USE ("qtg_large_music_empty");
-const QLatin1String ICON_DEFAULT_ART ("qtg_large_album_art");
+const QLatin1String ICON_PLAY ( "qtg_mono_play" );
+const QLatin1String ICON_PAUSE ( "qtg_mono_pause" );
+
+/** Album art icon */
+const QLatin1String ICON_DEFAULT_ART ( "qtg_large_music_empty" );
 
 /**  HsWidget normal background */
-const QLatin1String WIDGET_BG_NORMAL ("qtg_fr_hswidget_normal");
+const QLatin1String WIDGET_BG_NORMAL ( "qtg_fr_hswidget_normal" );
 /**  Text background */
-const QLatin1String TEXT_BG_NORMAL ("qtg_fr_multimedia_trans");
+const QLatin1String TEXT_BG_NORMAL ( "qtg_fr_multimedia_trans" );
 /**  Separator : character and space between artist and song name */
-const QLatin1String SEPARATOR_TEXT (": ");
-/**  Temporary unknown artist */
-const QLatin1String TEMPORARY_UNKWNOWN_TEXT ("Unknown");
-/**  Localized unknown artist */
-const QLatin1String UNKWNOWN_TEXT ("txt_mus_other_unknown_1");
+const QLatin1String SEPARATOR_TEXT ( ": " );
 
-/**  Marquee width */
-const int MARQUEE_WIDTH = 170;
 /**  Infinite loop value for marquee */
 const int MARQUEE_LOOP_FOREVER = -1;
 
 /**  Now playing view with random play */
-const QLatin1String SERVICEREQ_FIRST_TIME_USE ("appto://10207C62?activityname=MusicNowPlayingView&launchtype=standalone&shuffle=yes");
+const QLatin1String SERVICEREQ_NOW_PLAYING_VIEW_SHUFFLE ( "appto://10207C62?activityname=MusicNowPlayingView&launchtype=standalone&shuffle=yes" );
 /**  Main view */
-const QLatin1String SERVICEREQ_MAIN_VIEW ("appto://10207C62?activityname=MusicMainView&launchtype=standalone");
+const QLatin1String SERVICEREQ_MAIN_VIEW ( "appto://10207C62?activityname=MusicMainView&launchtype=standalone" );
 /**  Now playing view */
-const QLatin1String SERVICEREQ_NOW_PLAYING_VIEW ("appto://10207C62?activityname=MusicNowPlayingView&launchtype=standalone");
+const QLatin1String SERVICEREQ_NOW_PLAYING_VIEW ( "appto://10207C62?activityname=MusicNowPlayingView&launchtype=standalone" );
+
+/**  DOCML object names */
+const QLatin1String DOCML_CONTAINER_WIDGET ( "containerWidget" );
+const QLatin1String DOCML_BG_ICON ( "widget_background_icon" );
+const QLatin1String DOCML_ALBUM_ART ( "album_art_image" );
+const QLatin1String DOCML_TEXT_BG ( "text_bg" );
+const QLatin1String DOCML_SCROLLING_TEXT ( "scrolling_text" );
+const QLatin1String DOCML_BUTTON_GROUP_CONTAINER ( "button_group_container" );
+const QLatin1String DOCML_PREV_BUTTON ( "btn_previous" );
+const QLatin1String DOCML_PLAY_BUTTON ( "btn_play" );
+const QLatin1String DOCML_NEXT_BUTTON ( "btn_next" );
 
-/**  DOCML object name for main widget */
-const QLatin1String DOCML_CONTAINER_WIDGET ("containerWidget");
-/**  DOCML object name for widget background */
-const QLatin1String DOCML_BG_ICON ("widget_background_icon");
-/**  DOCML object name for album art image */
-const QLatin1String DOCML_ALBUM_ART ("album_art_image");
-/**  DOCML object name for shortcut icon background */
-const QLatin1String DOCML_SHORTCUT_ICON_BG ("shortcut_icon_background");
-/**  DOCML object name for shortcut icon */
-const QLatin1String DOCML_SHORTCUT_ICON ("shortcut_icon");
-/**  DOCML object name for scrolling text background */
-const QLatin1String DOCML_TEXT_BG ("text_bg");
-/**  DOCML object name for scrolling text */
-const QLatin1String DOCML_SCROLLING_TEXT ("scrolling_text");
-/**  DOCML object name for button group container */
-const QLatin1String DOCML_BUTTON_GROUP_CONTAINER ("button_group_container");
-/**  DOCML object name for prev button */
-const QLatin1String DOCML_PREV_BUTTON ("btn_previous");
-/**  DOCML object name for play button */
-const QLatin1String DOCML_PLAY_BUTTON ("btn_play");
-/**  DOCML object name for next button */
-const QLatin1String DOCML_NEXT_BUTTON ("btn_next");
+/*!
+    \class MusicWidget
+    \brief Provides simple Music Player playback controls from the Home Screen.
+ */
 
-
-MusicWidget::MusicWidget(QGraphicsItem* parent, Qt::WindowFlags flags):
-    HbWidget(parent, flags),
-    mShortcutArea(0),
-    mSongDataBG(0),
-    mInformationSongName(0),
-    mMarqueeText(0),    
-    mPreviousPushButton(0),
-    mPlayPushButton(0),    
-    mNextPushButton(0),
-    mMusicPlayerNoSongData(1),
-    mMusicPlayerUpdating(0),
-    mMusicPlayerBlocked(0),
-    mAlbumArt(0),
-    mArtist(0),
-    mTitle(0),    
-    mMpEngine(0),
-    mMpPlaybackData(0)
+/*!
+ Constructs the Music Player home screen widget.
+ */
+MusicWidget::MusicWidget( QGraphicsItem* parent, Qt::WindowFlags flags ):
+    HbWidget( parent, flags ),
+    mSongDataBackground( 0 ),
+    mMarqueeText( 0 ),    
+    mPreviousPushButton( 0 ),
+    mPlayPushButton( 0 ),    
+    mNextPushButton( 0 ),
+    mMusicPlayerUpdating( false ),
+    mMusicPlayerBlocked( false ),
+    mMusicPlayerRunning( false ),
+    mAlbumArt( 0 ),
+    mMpEngine( 0 ),
+    mMpPlaybackData( 0 ),
+    mMpApplicationMonitor( 0 )
 {
-    TX_ENTRY
-    
-    // Setup UI
-    setupUi();
-    
-    // Connect to MP engine and playback data
-    mMpEngine = MpEngineFactory::createSharedEngine(MpCommon::KMusicPlayerUid, MpEngine::HomeScreen );
-    Q_ASSERT_X(mMpEngine, "music_widget", "no music player engine");
-    TX_LOG_ARGS("got mp engine")
-    
-    mMpPlaybackData = mMpEngine->playbackData();
-    Q_ASSERT_X(mMpPlaybackData, "music_widget", "no playback data");
-    TX_LOG_ARGS("got playback data")
-        
-    // Connect outgoing signals and slots
-    QObject::connect(mShortcutArea, SIGNAL(clicked()), this, SLOT(shortcutButton()));    
-    
-    // use signal mapper to indicate button identifiers to button event slots 
-    QSignalMapper* signalMapperPressed = new QSignalMapper( this ); 
-    signalMapperPressed->setMapping( mPreviousPushButton, EPrevious );
-    signalMapperPressed->setMapping( mPlayPushButton, EPlayPause);
-    signalMapperPressed->setMapping( mNextPushButton, ENext);
-
-    // need to use different signal mapper for pressed and released events, 
-    // both have same mappings but they are mapped to different slots
-    QSignalMapper* signalMapperReleased = new QSignalMapper( this );
-    signalMapperReleased->setMapping( mPreviousPushButton, EPrevious );
-    signalMapperReleased->setMapping( mPlayPushButton, EPlayPause);
-    signalMapperReleased->setMapping( mNextPushButton, ENext);
-        
-    // Connect button events to signal maps
-    QObject::connect(mPreviousPushButton, SIGNAL(pressed()), signalMapperPressed, SLOT (map()));
-    QObject::connect(mPreviousPushButton, SIGNAL(released()), signalMapperReleased, SLOT (map()));
-
-    QObject::connect(mPlayPushButton, SIGNAL(pressed()), signalMapperPressed, SLOT (map()));
-    QObject::connect(mPlayPushButton, SIGNAL(released()), signalMapperReleased, SLOT (map()));
-
-    QObject::connect(mNextPushButton, SIGNAL(pressed()), signalMapperPressed, SLOT (map()));
-    QObject::connect(mNextPushButton, SIGNAL(released()), signalMapperReleased, SLOT (map()));
-
-    // Connect mapper signals to self implemented slots
-    QObject::connect( signalMapperPressed, SIGNAL(mapped(int)), this, SLOT(mediaButtonPressed(int)));
-    QObject::connect( signalMapperReleased, SIGNAL(mapped(int)), this, SLOT(mediaButtonReleased(int)));
-
-    // Connect clicked events
-    QObject::connect(mPreviousPushButton, SIGNAL(clicked()), this, SLOT(prevSong()));
-    QObject::connect(mPlayPushButton, SIGNAL(clicked()), this, SLOT(playSong()));   
-    QObject::connect(mNextPushButton, SIGNAL(clicked()), this, SLOT(nextSong()));
-
-    // MpEngine
-    QObject::connect(mMpEngine, SIGNAL(libraryUpdateStarted()), this, SLOT(libraryUpdateStarted()));
-    QObject::connect(mMpEngine, SIGNAL(libraryUpdated()), this, SLOT(libraryUpdated()));
-    QObject::connect(mMpEngine, SIGNAL(usbBlocked(bool)), this, SLOT(usbBlocked(bool)));
-
-    //MpPlaybackData
-    QObject::connect(mMpPlaybackData, SIGNAL(albumArtReady()), this, SLOT(albumArtReady()));
-    QObject::connect(mMpPlaybackData, SIGNAL(playbackStateChanged()), this, SLOT(playbackStateChanged()));
-    QObject::connect(mMpPlaybackData, SIGNAL(playbackInfoChanged()), this, SLOT(playbackInfoChanged()));  
-    
-    // Initial data from Music Player get by onShow method call
-    TX_EXIT
+    TX_LOG
+    HbTranslator translator( QString( "musicwidgetplugin" ) );
 }
 
 /*!
-    Destructor
-*/
+ Destructor
+ */
 MusicWidget::~MusicWidget()
 {
+    TX_ENTRY
+    if ( mMpEngine ) {
+        MpEngineFactory::close();
+    }
+
+    delete mMpApplicationMonitor;
+    TX_EXIT
 }
 
 /*!
@@ -206,235 +126,66 @@
     // Use document loader to load the contents
     MusicWidgetDocumentLoader loader;
     bool ok = false;
-    loader.load( MUSIC_WIDGET_DOCML, &ok);
-    Q_ASSERT_X(ok, "music_widget", "invalid title docml file");
+    loader.load( MUSIC_WIDGET_DOCML, &ok );
+    Q_ASSERT_X( ok, "music_widget", "invalid title docml file" );
 
-    TX_LOG_ARGS("loaded docml")
+    TX_LOG_ARGS( "loaded docml" )
     
-    QGraphicsLinearLayout* mainLayout = new QGraphicsLinearLayout(Qt::Vertical, this);
-    QGraphicsWidget* container = loader.findWidget(DOCML_CONTAINER_WIDGET);
-    mainLayout->addItem(container);
+    QGraphicsLinearLayout* mainLayout = new QGraphicsLinearLayout( Qt::Vertical, this );
+    QGraphicsWidget* container = loader.findWidget( DOCML_CONTAINER_WIDGET );
+    mainLayout->addItem( container );
+    
     //Sets parent
     setLayout( mainLayout );
 
     // Load and set widget background
-    HbWidget *bgWidget = qobject_cast<HbWidget*> (loader.findWidget(DOCML_BG_ICON));
-    HbFrameItem *frameItem;
-    if (bgWidget)
-        {
-        HbFrameDrawer *drawer = new HbFrameDrawer(WIDGET_BG_NORMAL,
-            HbFrameDrawer::NinePieces);
-        frameItem = new HbFrameItem(drawer, bgWidget);
-        frameItem->setPreferredSize(bgWidget->preferredSize());
-        bgWidget->setZValue(1);
-        }
+    HbLabel *bgWidget = qobject_cast<HbLabel*> ( loader.findWidget( DOCML_BG_ICON ) );
+    HbFrameItem *frameItemWidgetBg = new HbFrameItem();
+    frameItemWidgetBg->frameDrawer().setFrameGraphicsName( WIDGET_BG_NORMAL );
+    frameItemWidgetBg->frameDrawer().setFrameType( HbFrameDrawer::NinePieces );
+    frameItemWidgetBg->frameDrawer().setFillWholeRect( true );
+    bgWidget->setBackgroundItem( frameItemWidgetBg );
 
     // Setup album art area
     QGraphicsWidget *tmpWidgetPtr;
-    tmpWidgetPtr = loader.findWidget(DOCML_ALBUM_ART);
-    mAlbumArt = qobject_cast<MpAlbumCoverWidget*>(tmpWidgetPtr);
+    tmpWidgetPtr = loader.findWidget( DOCML_ALBUM_ART );
+    mAlbumArt = qobject_cast<MpAlbumCoverWidget*>( tmpWidgetPtr );
     mAlbumArt->setEnabled( false );
     mAlbumArt->setDefaultIcon( HbIcon( ICON_DEFAULT_ART ) );
         
-    // Load shortcut background
-    HbWidget *shortcutAreaLayout = qobject_cast<HbWidget*> (loader.findWidget(DOCML_SHORTCUT_ICON_BG));
-    HbFrameItem *shortcutFrameItem;
-    if (shortcutAreaLayout) {
-        HbFrameDrawer *drawer = new HbFrameDrawer(WIDGET_BG_NORMAL,
-            HbFrameDrawer::NinePieces);
-        shortcutFrameItem = new HbFrameItem(drawer, shortcutAreaLayout);
-        shortcutFrameItem->setPreferredSize(shortcutAreaLayout->preferredSize());
-        shortcutAreaLayout->setZValue(3);
-        }
-
-    // Load shortcut widget and set background 
-    mShortcutArea = qobject_cast<HbPushButton*> (loader.findWidget(DOCML_SHORTCUT_ICON));
-    if ( mShortcutArea )
-        {
-        // icon needs to be put as a background so that it fills the whole button area
-        HbFrameDrawer* drawer = new HbFrameDrawer(ICON_LARGE_MUSIC_PLAYER, HbFrameDrawer::OnePiece);
-        mShortcutArea->setFrameBackground( drawer );
-        }
-
     // Set song data background
-    mSongDataBG = qobject_cast<HbWidget*> (loader.findWidget(DOCML_TEXT_BG));
-    HbFrameItem *scrollTextItem;
-    if (mSongDataBG) 
-        {
-        HbFrameDrawer *drawer = new HbFrameDrawer(TEXT_BG_NORMAL, 
-            HbFrameDrawer::NinePieces);
-        scrollTextItem = new HbFrameItem(drawer, mSongDataBG);
-        scrollTextItem->setPreferredSize(mSongDataBG->preferredSize());
-        mSongDataBG->setZValue(4);
-        mSongDataBG->hide(); // Hide initially...
-        }
+    mSongDataBackground = qobject_cast<HbLabel*> ( loader.findWidget( DOCML_TEXT_BG ) );
+    HbFrameItem *frameItemSongBg = new HbFrameItem();
+    frameItemSongBg->frameDrawer().setFrameGraphicsName( TEXT_BG_NORMAL );
+    frameItemSongBg->frameDrawer().setFrameType( HbFrameDrawer::NinePieces );
+    frameItemSongBg->frameDrawer().setFillWholeRect( true );
+    mSongDataBackground->setBackgroundItem( frameItemSongBg );
+    mSongDataBackground->hide();
 
     // Set scrolling song data
-    mInformationSongName = qobject_cast<HbLabel*> (loader.findWidget(DOCML_SCROLLING_TEXT));
-    if ( mInformationSongName )
-        {
-        // Setting primitive marquee item values from .css doesn't work well, set in code...
-        mMarqueeText = new HbMarqueeItem(mInformationSongName);
-        HbFontSpec fs(HbFontSpec::Secondary);
-        mMarqueeText->setFontSpec(fs);        
-        mMarqueeText->setTextColor(mInformationSongName->textColor());
-        mMarqueeText->setMinimumWidth(MARQUEE_WIDTH);
-        mMarqueeText->setLoopCount(MARQUEE_LOOP_FOREVER);
-        }
-    
-    HbWidget *buttonGroupContainer = qobject_cast<HbWidget*> (loader.findWidget(
-            DOCML_BUTTON_GROUP_CONTAINER));
-    if (buttonGroupContainer)
-        {
-        // Define push buttons in  state at this point, check the player status later and update buttons if needed
-        mPreviousPushButton = qobject_cast<HbPushButton*> (loader.findWidget(DOCML_PREV_BUTTON));
-        defineMediaButton( *mPreviousPushButton, PUSH_BUTTON_NORMAL, PREV_BUTTON_SUFFIXES, ICON_COLOR_NORMAL );
-        
-        mPlayPushButton = qobject_cast<HbPushButton*> (loader.findWidget(DOCML_PLAY_BUTTON));
-        defineMediaButton( *mPlayPushButton, PUSH_BUTTON_NORMAL, PLAY_BUTTON_SUFFIXES, ICON_COLOR_NORMAL );
-    
-        mNextPushButton = qobject_cast<HbPushButton*> (loader.findWidget(DOCML_NEXT_BUTTON));
-        defineMediaButton( *mNextPushButton, PUSH_BUTTON_NORMAL, NEXT_BUTTON_SUFFIXES, ICON_COLOR_NORMAL );
-        }
-    
+    mMarqueeText = qobject_cast<HbMarqueeItem*> ( loader.findWidget( DOCML_SCROLLING_TEXT ) );
+    mMarqueeText->setLoopCount( MARQUEE_LOOP_FOREVER );
+
+    // Get buttons
+    HbWidget *buttonGroupContainer = qobject_cast<HbWidget*> ( loader.findWidget(
+            DOCML_BUTTON_GROUP_CONTAINER ) );
+    if ( buttonGroupContainer ) {
+        // Define push buttons
+        mPreviousPushButton = qobject_cast<HbPushButton*> ( loader.findWidget( DOCML_PREV_BUTTON ) );
+        mPlayPushButton = qobject_cast<HbPushButton*> ( loader.findWidget( DOCML_PLAY_BUTTON ) );
+        mNextPushButton = qobject_cast<HbPushButton*> ( loader.findWidget( DOCML_NEXT_BUTTON ) );
+    }
+
     TX_EXIT
 }
 
 /*!
-    Makes the push button based on information aGraphicsId and aSuffix
- */
-void MusicWidget::defineMediaButton( HbPushButton& aTarget, QString aGraphicsId, QStringList aSuffix, QString aIconColor )
-    {
-    TX_ENTRY
-    
-    TX_LOG_ARGS("graphics id: " << aGraphicsId)
-    TX_LOG_ARGS("icon color: " << aIconColor)
-    
-    HbFrameDrawer* drawer;
-
-    // First check if the drawer is already created for this push button
-    if ( !aTarget.frameBackground()){
-        // Nope, create one now
-        drawer = new HbFrameDrawer(aGraphicsId, HbFrameDrawer::ThreePiecesHorizontal);
-        aTarget.setFrameBackground( drawer );
-        TX_LOG_ARGS("created drawer for button bg")
-        }
-    else {
-        // Frame drawer already created, only need to update frame graphics
-        drawer = aTarget.frameBackground();
-        drawer->setFrameGraphicsName( aGraphicsId );
-        TX_LOG_ARGS("using existing drawer for button bg")
-        }
-
-    // Set file name suffix list, so that drawer can load correct 3-piece graphic files 
-    drawer->setFileNameSuffixList( aSuffix );
-
-    // Update also the icon color
-    QColor color = HbColorScheme::color(aIconColor);
-    aTarget.icon().setColor( color );
-
-    // Lastly, check if the buttton is disabled
-    if ( aIconColor == ICON_COLOR_DISABLED )
-        {
-        aTarget.setEnabled(false);
-        TX_LOG_ARGS("button disabled")
-        }
-    else
-        {
-        aTarget.setEnabled(true);
-        TX_LOG_ARGS("button enabled")
-        }
-    
-    TX_EXIT
-    }
-
-/*!
-
- */
-void MusicWidget::mediaButtonEvent( MediaKeyIdentifier aMediaKeyId, QString aGraphicsId, QString aIconColor )
-    {
-    TX_ENTRY
-    
-    HbPushButton* target = NULL;
-    QStringList suffix;
-    
-    switch ( aMediaKeyId )
-        {
-        case EPrevious: {
-            TX_LOG_ARGS("previous")
-            target = mPreviousPushButton;
-            suffix = PREV_BUTTON_SUFFIXES;
-            break;
-            }
-        case EPlayPause: {
-            TX_LOG_ARGS("play/pause")
-            target = mPlayPushButton;
-            suffix = PLAY_BUTTON_SUFFIXES;
-            break;
-            }
-        case ENext: {
-            TX_LOG_ARGS("next")
-            target = mNextPushButton;
-            suffix = NEXT_BUTTON_SUFFIXES;
-            break;
-            }
-        default: {
-            // Do proper error handling.. should not be possible to get here ever tough
-            TX_LOG_ARGS("unknown button")
-            return;
-            }
-        }
-        
-    if ( target )
-    	{
-    	MusicWidget::defineMediaButton( *target, aGraphicsId, suffix, aIconColor );
-    	}
-    
-    TX_EXIT
-    }
-
-/*!
-   Emited from HbPushButton:pressed() signal, changes the button layout to 'Pressed'
- */
-void MusicWidget::mediaButtonPressed( int aMediaKeyId )
-    {
-    TX_LOG_ARGS("media key: " << aMediaKeyId )
-    mediaButtonEvent( (MediaKeyIdentifier)aMediaKeyId, PUSH_BUTTON_PRESSED, ICON_COLOR_PRESSED );
-    }
-
-/*!
-   Emited from HbPushButton:released() signal, changes the button layout to 'Normal'
- */
-void MusicWidget::mediaButtonReleased( int aMediaKeyId )
-    {
-    TX_LOG_ARGS("media key: " << aMediaKeyId )
-    mediaButtonEvent( (MediaKeyIdentifier)aMediaKeyId, PUSH_BUTTON_NORMAL, ICON_COLOR_NORMAL );
-    }
-
-/*!
-   Disables specified push button
- */
-void MusicWidget::mediaButtonDisabled( int aMediaKeyId )
-    {
-    TX_LOG_ARGS("media key: " << aMediaKeyId )
-    mediaButtonEvent( (MediaKeyIdentifier)aMediaKeyId, PUSH_BUTTON_DISABLED, ICON_COLOR_DISABLED );
-    }
-
-/*!
-   Disables specified push button
- */
-void MusicWidget::mediaButtonEnabled( int aMediaKeyId )
-    {
-    TX_LOG_ARGS("media key: " << aMediaKeyId )
-    mediaButtonEvent( (MediaKeyIdentifier)aMediaKeyId, PUSH_BUTTON_NORMAL, ICON_COLOR_NORMAL );
-    }
-
-/*!
  Manually update music widget state.
  */
 void MusicWidget::refreshData()
 { 
     TX_ENTRY
+    
     // Get current player state
     playbackStateChanged();
     
@@ -443,89 +194,64 @@
 
     // Get current album art
     albumArtReady();
+    
     TX_EXIT
 }
 
 /*!
- Launch music player...
+ Launch music player.
  */
-void MusicWidget::launchMusicPlayer(int launchMode)
+void MusicWidget::launchMusicPlayer( int launchMode )
 {  
     TX_ENTRY
-    //TODO: Detect if MusicPlayer is running or not properly, handle case where player not available?!
-    //TODO: Get service status from XQSettingManager
-    //TODO: Service status from signal:
-    //TODO: void statusChanged(const XQAiwInterfaceDescriptor& implementation,  ServiceStatus currentStatus);
-     
+    
     QUrl url;
-    XQAiwRequest* req;
-    
-    if ( launchMode == ELaunchFromPlay )
-        {
-        TX_LOG_ARGS("launch from play")
-        // Launch to now playing view, random play to be started!
-        url.setUrl(SERVICEREQ_FIRST_TIME_USE);        
-        }
-    else if (mMusicPlayerNoSongData)
-        {
-        TX_LOG_ARGS("to main view")
-        // Launch to main view
-        url.setUrl(SERVICEREQ_MAIN_VIEW);    
-        }
-    else
-        {
-        TX_LOG_ARGS("to now playing view")
-        // Launch to now playing view
-        url.setUrl(SERVICEREQ_NOW_PLAYING_VIEW);
-        }   
-    
-    req = mApplicationManager.create(url);    
-    if (req == NULL)
-        {
-        // No handlers for the URI
-        TX_LOG_ARGS("no req created")
-        return;
-        }
     
-    req->setBackground(false);
-    req->setSynchronous(false);
+    switch ( launchMode ) {
+        case ELaunchToMainView:
+            TX_LOG_ARGS( "to main view" )
+            // Launch to main view
+            url.setUrl( SERVICEREQ_MAIN_VIEW );    
+            break;
+        case ELaunchToNowPlayingView:
+            TX_LOG_ARGS( "to now playing view" )
+            // Launch to now playing view
+            url.setUrl( SERVICEREQ_NOW_PLAYING_VIEW );
+            break;
+        case ELaunchToNowPlayingViewWithShuffle:
+            TX_LOG_ARGS( "to now playing view with shuffle" )
+            // Launch to now playing view with shuffle
+            url.setUrl( SERVICEREQ_NOW_PLAYING_VIEW_SHUFFLE );        
+            break;
+        default:
+            //should never get here
+            TX_LOG_ARGS( "Error: invalid launchMode." )
+            return;
+    }
     
-    // Set function parameters
-   QList<QVariant> args;
-   args << url.toString();
-   req->setArguments(args);
+    XQAiwRequest* req;
+    req = mApplicationManager.create( url );    
+    if ( req ) {
+        req->setBackground( false );
+        req->setSynchronous( false );
+    
+        // Set function parameters
+        QList<QVariant> args;
+        args << url.toString();
+        req->setArguments( args );
 
-   // Send the request
-   bool res = req->send();
-   if  (!res) 
-   {
-       // Request failed. 
-      int error = req->lastError();
-      // Handle error
-      TX_LOG_ARGS("req send error: " << error)
-   }
-
-   delete req;
+        // Send the request
+        bool res = req->send();
+        if ( !res ) {
+            // Request failed. 
+            int error = req->lastError();
+            // Handle error
+            TX_LOG_ARGS( "req send error: " << error )
+        }
+        delete req;
+    }
    
-   TX_EXIT
-}
-
-/*!
-    Return bounding rect
-*/
-QRectF MusicWidget::boundingRect() const
-{
-    return childrenBoundingRect();
-}
-
-/*!
-    Return shape
-*/
-QPainterPath MusicWidget::shape() const
-{   
-    QPainterPath path;
-    path.addRect(boundingRect());
-    return path;
+    TX_EXIT
 }
 
 /*!
@@ -533,7 +259,33 @@
  */
 void MusicWidget::onInitialize()
 {
-    TX_LOG
+    TX_ENTRY
+
+    // Setup UI
+    setupUi();
+    
+    // Start Monitoring Music Player running status.
+    mMpApplicationMonitor = new MpApplicationMonitor();
+    
+    // Check if Music Player UI is up and running
+    mMusicPlayerRunning = mMpApplicationMonitor->isApplicationRunning();
+    
+    // Connect to MP engine and playback data
+    connectMusicPlayerEngine( mMusicPlayerRunning );
+
+    // Connect albumart click signal
+    QObject::connect( mAlbumArt, SIGNAL( clicked() ), this, SLOT( handleAlbumArtClicked() ) );    
+    
+    // Connect button clicked signals
+    QObject::connect( mPreviousPushButton, SIGNAL( clicked() ), this, SLOT( handlePrevButtonClicked() ) );
+    QObject::connect( mPlayPushButton, SIGNAL( clicked() ), this, SLOT( handlePlayButtonClicked() ) );   
+    QObject::connect( mNextPushButton, SIGNAL( clicked() ), this, SLOT( handleNextButtonClicked() ) );
+
+    // Connect Music Player observer signal
+    QObject::connect( mMpApplicationMonitor, SIGNAL( applicationStatusChanged( bool ) ), 
+                     this, SLOT ( applicationStatusChanged( bool ) ) );   
+    
+    TX_EXIT
 }
 
 /*!
@@ -541,8 +293,9 @@
  */
 void MusicWidget::onShow()
 {
-    TX_LOG
+    TX_ENTRY
     refreshData();
+    TX_EXIT
 }
 
 /*!
@@ -551,6 +304,9 @@
 void MusicWidget::onHide()
 {
     TX_LOG
+    if ( mMarqueeText->isAnimating() ) {
+        mMarqueeText->stopAnimation();
+    }
 }
 
 /*!
@@ -562,268 +318,340 @@
 }
 
 /*!
- Slot for shortcut button clicked.
+ Slot to handle when the album art area is clicked.
  */
-void MusicWidget::shortcutButton()
+void MusicWidget::handleAlbumArtClicked()
 {
-    TX_LOG
-    launchMusicPlayer(ELaunchFromShortcut);
+    TX_ENTRY
+    if ( getPlaybackState() == MpPlaybackData::NotPlaying ) {
+        launchMusicPlayer( ELaunchToMainView );
+    }
+    else {
+        launchMusicPlayer( ELaunchToNowPlayingView );
+    }
+    TX_EXIT
 }
 
 /*!
  Slot for previous button clicked.
  */
-void MusicWidget::prevSong()
+void MusicWidget::handlePrevButtonClicked()
 { 
-    TX_LOG
-    mMpEngine->skipBackward();
+    TX_ENTRY
+    if ( mMpEngine ) {
+        mMpEngine->skipBackward();
+    }
+    TX_EXIT
 }
 
 /*!
  Slot for play button clicked. Handles both Play and Pause!
  */
-void MusicWidget::playSong()
+void MusicWidget::handlePlayButtonClicked()
 {
     TX_ENTRY
-    if (mMusicPlayerNoSongData && mMpPlaybackData->playbackState() != MpPlaybackData::Playing )
-        {
+    // If nothing to play, start music player in playback view.
+    if ( getPlaybackState() == MpPlaybackData::NotPlaying ) {
         //Signal music player to start playing all songs with random
-        launchMusicPlayer(ELaunchFromPlay);
+        launchMusicPlayer( ELaunchToNowPlayingViewWithShuffle );
+    }
+    else {
+        // send play/pause command.
+        if ( mMpEngine ) {
+            mMpEngine->playPause();
         }
-
-    mMpEngine->playPause();
+    }
     TX_EXIT
 }
+
 /*!
  Slot for next button clicked.
  */
-void MusicWidget::nextSong()
+void MusicWidget::handleNextButtonClicked()
 {
-    TX_LOG
-    mMpEngine->skipForward();
+    TX_ENTRY
+    if ( mMpEngine ) {
+        mMpEngine->skipForward();
+    }
+    TX_EXIT
 }
 
 /*!
-
+ Slot to handle when the music player running status changed.
  */
-bool MusicWidget::eventFilter(QObject *target, QEvent *event)
- {
-    // pass the event on to the parent class
-    return HbWidget::eventFilter(target, event);    
+void MusicWidget::applicationStatusChanged( bool isRunning )
+{
+    TX_ENTRY_ARGS( "running " << isRunning );
+
+    // Connect/disconnect engine base on music player running state.
+    if ( mMusicPlayerRunning != isRunning ) {
+        TX_LOG_ARGS("running state changed");
+        mMusicPlayerRunning = isRunning;
+        connectMusicPlayerEngine( isRunning );
+        // refresh data if musicplayer is on, otherwise clear data
+        if ( isRunning ) {
+            refreshData();
+        }
+        else {
+            clearData();
+        }
+    }
+    
+    TX_EXIT
 }
 
 /*!
- MpEngine related
+ Library started refreshing.
  */
 void MusicWidget::libraryUpdateStarted()
 {
-    TX_LOG
+    TX_ENTRY
     //Refresh Library start
     mMusicPlayerUpdating = true;
     
     // Update button enabled/disabled state
-    toggleButtons();
+    updateButtons();
+    TX_EXIT
 }
 
 /*!
- MpEngine related
+ Library is finished refreshing.
  */
 void MusicWidget::libraryUpdated()
 {
-    TX_LOG
+    TX_ENTRY
     //Refresh Library done
     mMusicPlayerUpdating = false;
     
     // Update button enabled/disabled state
-    toggleButtons();
+    updateButtons();
+    TX_EXIT
 }
 
 /*!
- MpEngine related
+ USB blocking state has changed.
  */
 void MusicWidget::usbBlocked( bool blocked )
 {
-    TX_LOG_ARGS("blocked: " << blocked)
-    //Blocked state
-    //Mass storage mode
-    //Media transfer mode
-    //Ovi Suite mode
-    //Insert memory card
-    
+    TX_ENTRY_ARGS( "blocked: " << blocked )
     mMusicPlayerBlocked = blocked;
     
     // Update button enabled/disabled state
-    toggleButtons();
+    updateButtons();
+    TX_EXIT
 }
 
 /*!
- MpPlaybackData related
+ The album art has changed.
  */
 void MusicWidget::albumArtReady()
 {   
     TX_ENTRY
     HbIcon icon;
     
-    if ( mMpPlaybackData->playbackState() == MpPlaybackData::NotPlaying )
-        {
-        TX_LOG_ARGS("1st time album art")
-        icon = HbIcon(ICON_FIRST_TIME_USE);    
+    if ( getPlaybackState() == MpPlaybackData::NotPlaying ) {
+        TX_LOG_ARGS( "default album art" )
+        icon = HbIcon( ICON_DEFAULT_ART );    
+    }
+    else {
+        TX_LOG_ARGS( "playback data album art" )
+        if ( mMpPlaybackData ) {
+            mMpPlaybackData->albumArt( icon );
         }
-    else
-        {
-        TX_LOG_ARGS("playback data album art")
-        mMpPlaybackData->albumArt( icon );
-        }
+    }
     
     mAlbumArt->setIcon( icon );
     mAlbumArt->setEnabled( true );
+    TX_EXIT
+}
+
+/*!
+ Playback state has changed.
+ */
+void MusicWidget::playbackStateChanged()
+{
+    TX_ENTRY
+    
+    if ( getPlaybackState() == MpPlaybackData::Playing ) {
+        TX_LOG_ARGS( "pause icon" )
+        mPlayPushButton->setIcon( HbIcon( ICON_PAUSE ) );
+    }
+    else {
+        TX_LOG_ARGS( "play icon" )
+        mPlayPushButton->setIcon( HbIcon( ICON_PLAY ) );
+    }
+
+    // Update button enabled/disabled state
+    updateButtons();
     
     TX_EXIT
 }
 
-void MusicWidget::playbackStateChanged()
-{
+/*!
+ Song data has changed.
+ */
+void MusicWidget::playbackInfoChanged()
+{ 
     TX_ENTRY
-    // Set play/pause icon and start/stop marquee.   
-    QString iconName;
+    
+    QString songData;
+    QString artist;
+    QString title;
     
-    int state = mMpPlaybackData->playbackState();
-    
-    TX_LOG_ARGS("state: " << state)
+    if ( mMpPlaybackData ) {
+        artist = mMpPlaybackData->artist();
+        title = mMpPlaybackData->title();
+    }
     
-    switch (state)
-        {
-        case MpPlaybackData::Playing:
-            {
-            TX_LOG_ARGS("pause icon, start marquee")
-            iconName.append(ICON_PAUSE);
+    if ( !title.length() ) {
+        artist.clear();
+        title.clear();
+        // Initialize marquee with something (space), to ensure text updates to display as well.
+        songData = " ";
+        TX_LOG_ARGS( "no song data" )
+    }
+    else {
+        if ( !artist.length() ) {
+            //Show localized "Unknown" if there is no artist name
+            songData.append( hbTrId( "txt_muwidget_other_unknown_1" ).arg( title ) );
+        }
+        else {
+            songData.append( artist );
+            songData.append( SEPARATOR_TEXT );
+            songData.append( title );
+        }
+        TX_LOG_ARGS( "song data received" )
+    }    
+    
+    mMarqueeText->setText( songData );
+    TX_LOG_ARGS( "marquee text: " << songData )
+
+    // Display song data if it exist.
+    if ( title.length() ) {
+        if ( !mSongDataBackground->isVisible() ) {
+            mSongDataBackground->show();
+        }
+        if ( !mMarqueeText->isAnimating() ) {
             mMarqueeText->startAnimation();
-            break;
-            }
-        case MpPlaybackData::Paused:
-        case MpPlaybackData::Stopped:
-        case MpPlaybackData::NotPlaying:       
-            {
-            TX_LOG_ARGS("play icon, stop marquee")
-            iconName.append(ICON_PLAY);
+        }
+    }
+    else {
+        if ( mSongDataBackground->isVisible() ) {
+            mSongDataBackground->hide();
+        }
+        if ( mMarqueeText->isAnimating() ) {
             mMarqueeText->stopAnimation();
-            break;
-            }
         }
-
-    HbIcon iconPlayPause(iconName);
-    mPlayPushButton->setIcon(iconPlayPause);
+    }
     
     TX_EXIT
 }
 
 /*!
- MpPlaybackData related
+ Update buttons to disabled/enabled as required.
  */
-void MusicWidget::playbackInfoChanged()
+void MusicWidget::updateButtons()
 { 
     TX_ENTRY
-    // Initialize maqruee with something (space), to ensure
-    // text updates to display as well.
-    QString songData;
     
-    mArtist = mMpPlaybackData->artist();
-    mTitle = mMpPlaybackData->title();
-    
-    if ( !mTitle.length() )
-        {
-        mArtist.clear();
-        mTitle.clear();
-        songData = " ";
-
-        //1st time launch
-        mMusicPlayerNoSongData = true;
-        
-        TX_LOG_ARGS("no song data")
-        }
-    else
-        {
-        if ( !mArtist.length() )
-            {
-            //Show localized "Unknown" if there is no artist name
-            
-            //TODO: Widget needs own localization?!?!
-            //mArtist.append( hbTrId(UNKWNOWN_TEXT) );
-
-            //TODO: Remove temporary unknown string when localization resolved.
-            mArtist.append( TEMPORARY_UNKWNOWN_TEXT );
-            }
-        
-        songData.append(mArtist);
-        songData.append(SEPARATOR_TEXT);
-        songData.append(mTitle);
-        
-        mMusicPlayerNoSongData = false;
-        
-        TX_LOG_ARGS("song data received")
-        }    
-    
-    mMarqueeText->setText(songData);
-    TX_LOG_ARGS("marquee text: " << songData)
-
-    // Show dark BG to songdata only if there is songdata...
-    if ( mMusicPlayerNoSongData && mSongDataBG->isVisible() )
-        {
-        TX_LOG_ARGS("hide marquee bg")
-        mSongDataBG->hide();
-        }
-    else if ( !mMusicPlayerNoSongData && !mSongDataBG->isVisible() )
-        {
-        TX_LOG_ARGS("show marquee bg")
-        mSongDataBG->show();  
-        }
-    
-    // Update button enabled/disabled state
-    toggleButtons();
+    // All buttons disabled if updating or usb blocked
+    if ( mMusicPlayerUpdating || mMusicPlayerBlocked ) {
+        TX_LOG_ARGS( "refreshing" )
+        mPreviousPushButton->setEnabled( false );
+        mPlayPushButton->setEnabled( false );
+        mNextPushButton->setEnabled( false );
+    }
+    // Only play button enabled if there is no song data
+    else if ( getPlaybackState() == MpPlaybackData::NotPlaying ) {
+        TX_LOG_ARGS( "no song data" )
+        mPreviousPushButton->setEnabled( false );
+        mPlayPushButton->setEnabled( true );
+        mNextPushButton->setEnabled( false );
+    }
+    // Enable all buttons if there is song data
+    else {
+        TX_LOG_ARGS( "enable all buttons" )
+        mPreviousPushButton->setEnabled( true );
+        mPlayPushButton->setEnabled( true );
+        mNextPushButton->setEnabled( true );
+    }
     
     TX_EXIT
 }
 
 /*!
- Toggle buttons to disabled/enabled as required.
+ Connect/disconnect Music Player engine and playback data
  */
-void MusicWidget::toggleButtons()
-{ 
+void MusicWidget::connectMusicPlayerEngine( bool connect )
+{
     TX_ENTRY
-    // All buttons disabled if updating
-    if ( mMusicPlayerUpdating )
-        {
-        TX_LOG_ARGS("updating")
-        mediaButtonDisabled( EPlayPause );
-        mediaButtonDisabled( EPrevious );
-        mediaButtonDisabled( ENext );
-        }
+
+    if ( mMpEngine ) {
+        MpEngineFactory::close();
+        mMpEngine = 0;
+        mMpPlaybackData = 0;
+        mMusicPlayerUpdating = false;
+        mMusicPlayerBlocked = false;
+    }
     
-    // All buttons disabled if blocked
-    else if ( mMusicPlayerBlocked )
-        {
-        TX_LOG_ARGS("blocked")
-        mediaButtonDisabled( EPlayPause );
-        mediaButtonDisabled( EPrevious );
-        mediaButtonDisabled( ENext );
-        }    
+    if ( connect ) {
+        // Connect to MP engine and playback data
+        mMpEngine = MpEngineFactory::createSharedEngine( MpCommon::KMusicPlayerUid, MpEngine::HomeScreen );
+        Q_ASSERT_X( mMpEngine, "music_widget", "no music player engine" );
+        TX_LOG_ARGS( "got mp engine" )
+    
+        mMpPlaybackData = mMpEngine->playbackData();
+        Q_ASSERT_X( mMpPlaybackData, "music_widget", "no playback data" );
+        TX_LOG_ARGS( "got playback data" )
     
-    // Only play button enabled if there is no song data, 1st time use
-    else if ( mMusicPlayerNoSongData )
-        {
-        TX_LOG_ARGS("no song data")
-        mediaButtonEnabled( EPlayPause );
-        mediaButtonDisabled( EPrevious );
-        mediaButtonDisabled( ENext );
-        }
+        // MpEngine
+        QObject::connect( mMpEngine, SIGNAL( libraryUpdateStarted() ), this, SLOT( libraryUpdateStarted() ) );
+        QObject::connect( mMpEngine, SIGNAL( libraryUpdated() ), this, SLOT( libraryUpdated() ) );
+        QObject::connect( mMpEngine, SIGNAL( usbBlocked( bool ) ), this, SLOT( usbBlocked( bool ) ) );
+
+        //MpPlaybackData
+        QObject::connect( mMpPlaybackData, SIGNAL( albumArtReady() ), this, SLOT( albumArtReady() ) );
+        QObject::connect( mMpPlaybackData, SIGNAL( playbackStateChanged() ), this, SLOT( playbackStateChanged() ) );
+        QObject::connect( mMpPlaybackData, SIGNAL( playbackInfoChanged() ), this, SLOT( playbackInfoChanged() ) );
+    }
     
-    // Enable all buttons if there is song data
-    else
-        {
-        TX_LOG_ARGS("enable all buttons")
-        mediaButtonEnabled( EPlayPause );      
-        mediaButtonEnabled( EPrevious );
-        mediaButtonEnabled( ENext );      
-        }
     TX_EXIT
 }
+
+/*!
+ Get the playback state
+ */
+int MusicWidget::getPlaybackState()
+{
+    TX_ENTRY
+    int state;
+    if ( mMpPlaybackData ) {
+        state = mMpPlaybackData->playbackState();
+    }
+    else {
+        state = MpPlaybackData::NotPlaying;
+    }
+    TX_EXIT_ARGS( "playback state = " << state );
+    return state;
+}
+
+/*!
+ Clear the song data
+ */
+void MusicWidget::clearData()
+{
+    TX_ENTRY
+    // set play button to PLAY icon.
+    mPlayPushButton->setIcon( HbIcon( ICON_PLAY ) );
+    updateButtons();
+    
+    // remove song data.
+    mMarqueeText->setText( QString( " " ) );
+    mMarqueeText->stopAnimation();
+    mSongDataBackground->hide();
+    
+    // set default album art
+    mAlbumArt->setIcon( HbIcon( ICON_DEFAULT_ART ) );
+    mAlbumArt->setEnabled( true );
+    TX_EXIT
+}