diff -r 4e84c994a771 -r 82baf59ce8dd mpviewplugins/mpdetailsviewplugin/src/mpdetailsview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpviewplugins/mpdetailsviewplugin/src/mpdetailsview.cpp Fri Apr 16 14:56:30 2010 +0300 @@ -0,0 +1,787 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Music Player details view. +* +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mpdetailsview.h" +#include "mpcommondefs.h" +#include "mpmpxdetailsframeworkwrapper.h" +#include "mpsongdata.h" +#include "mptrace.h" + +const int KUndefined = -1; +const int KRecommendationNum = 2; + +/*! + Constructor + */ +MpDetailsView::MpDetailsView() + : mSongData( 0 ), + mFrameworkWrapper( 0 ), + mActivated( false ), + mWindow( 0 ), + mSoftKeyBack( 0 ), + mSongText( NULL ), + mAlbumText( NULL ), + mArtistText( NULL ), + mAlbumArt( NULL ), + mDocumentLoader( NULL ), + mDownloadedAlbumArts( 0 ), + mAlbumArtsReadyCount( 0 ), + mMpTranslator( 0 ), + mCommonTranslator( 0 ) +{ + TX_ENTRY + bool widgetsOk = false; + HbMainWindow *mainWindow = hbInstance->allMainWindows()[0]; + mDocumentLoader = new HbDocumentLoader(); + + if ( mDocumentLoader ) { + mDocumentLoader->load( QString(":/detailsviewdocml/detailsview.docml"), &widgetsOk ); + } + if ( widgetsOk ) { + QGraphicsWidget *widget; + + widget = mDocumentLoader->findWidget( QString("content") ); + mContainer = qobject_cast(widget); + if ( mContainer ) { + setWidget( mContainer ); + } + + widget = mDocumentLoader->findWidget( QString("shareButton") ); + mShareButton = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("songText") ); + mSongText = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("artistText") ); + mArtistText = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("albumText") ); + mAlbumText = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("albumArt") ); + mAlbumArt = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("songDetailsGroupBox") ); + mSongDetailsGroupBox = qobject_cast(widget); + + widget = mDocumentLoader->findWidget( QString("inspireMeGroupBox") ); + mInspireMeGroupBox = qobject_cast(widget); + } + else { + TX_LOG_ARGS( "Error: invalid detailsview.docml" ); + } + TX_EXIT +} + +/*! + Destructs the details view. + */ +MpDetailsView::~MpDetailsView() +{ + TX_ENTRY + if ( mFrameworkWrapper ) { + delete mFrameworkWrapper; + } + if ( mSoftKeyBack ) { + delete mSoftKeyBack; + } + if ( mDocumentLoader ) { + delete mDocumentLoader; + } + if ( mManager ) { + mManager->deleteLater(); + } + if ( mDownloadManager ) { + mDownloadManager->deleteLater(); + } + if( mThumbnailManager ) { + delete mThumbnailManager; + } + delete mMpTranslator; + delete mCommonTranslator; + TX_EXIT +} + +/*! + Initializes the details view. Allocates all resources needed by the view. + */ +void MpDetailsView::initializeView() +{ + 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(); + mSoftKeyBack = new HbAction( Hb::BackAction, this ); + mFrameworkWrapper = new MpMpxDetailsFrameworkWrapper( ); + mSongData = mFrameworkWrapper->songData(); + + mCompositePixmap = QPixmap( 150, 150 ); + + mDetailList = new HbListWidget( mSongDetailsGroupBox ); + mButton = new HbPushButton( tr( "More recommendations" ) ); + mSongDetailsGroupBox->setCollapsable( true ); + mSongDetailsGroupBox->setHeading( tr("Song details") ); + mSongDetailsGroupBox->setContentWidget( mDetailList ); + mSongDetailsGroupBox->setCollapsed( true ); + + mLayout = new QGraphicsLinearLayout( Qt::Vertical ); + mInspireMe = new HbWidget( mInspireMeGroupBox ); + mInspireList = new HbListWidget(); + mInspireMeGroupBox->setCollapsable( true ); + mInspireMeGroupBox->setHeading( tr("Inspire me") ); + mInspireMeGroupBox->setContentWidget( mInspireMe ); + + + mManager = new QNetworkAccessManager( this ); + connect( mManager, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( retrieveInformationFinished( QNetworkReply * ) ) ); + + mDownloadManager = new QNetworkAccessManager( this ); + connect( mDownloadManager, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( DownloadFinished( QNetworkReply * ) ) ); + + mRecommendationAlbumArtsName << "C:\\Data\\albumOne.png" << "C:\\Data\\albumTwo.png"; + + mThumbnailManager = new ThumbnailManager( this ); + mThumbnailManager->setQualityPreference( ThumbnailManager::OptimizeForQuality ); + mThumbnailManager->setThumbnailSize( ThumbnailManager::ThumbnailSmall ); + QObject::connect( mThumbnailManager, SIGNAL( thumbnailReady( QPixmap , void * , int , int ) ), + this, SLOT( thumbnailReady( QPixmap , void * , int , int ) ) ); + mDefaultRecommendationAlbumArt = QPixmap( ":/detailsviewicons/defaultalbumart.png" ); + + setTitle( tr("Music") ); + // TODO: might need later + setupMenu(); + + connect( mSoftKeyBack, SIGNAL( triggered() ), this, SLOT( back() ) ); + connect( mShareButton, SIGNAL( clicked() ), this, SLOT( share() ) ); + connect( mSongData, SIGNAL( albumArtReady() ), this, SLOT( albumArtChanged() ) ); + connect( mSongData, SIGNAL( playbackInfoChanged() ), this, SLOT( playbackInfoChanged() ) ); + connect( mSongData, SIGNAL( songDetailInfoChanged() ), this, SLOT( songDetailInfoChanged() ) ); + connect( mSongDetailsGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( toggleInspireMeGroupBox( bool ) ) ); + connect( mInspireMeGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( toggleDetailsGroupBox( bool ) ) ); + TX_EXIT +} + +/*! + Activates the details view. + */ +void MpDetailsView::activateView() +{ + TX_ENTRY + setNavigationAction( mSoftKeyBack ); + mFrameworkWrapper->retrieveSong(); + + mActivated = true; + TX_EXIT +} + +/*! + Deactivates the details view. + */ +void MpDetailsView::deactivateView() +{ + TX_ENTRY + setNavigationAction( 0 ); + mActivated = false; + TX_EXIT +} + +/*! + Setup the menu. + */ +void MpDetailsView::setupMenu() +{ + TX_ENTRY + + TX_EXIT +} + +/*! + Slot to handle back command from softkey. + + \reimp + */ +void MpDetailsView::back() +{ + TX_ENTRY + emit command( MpCommon::ActivatePlaybackView ); + TX_EXIT +} + +/*! + Slot to be called when share button is clicked + */ +void MpDetailsView::share() +{ + TX_ENTRY + TX_EXIT +} + +/*! + Slot to handle Album art changed. + */ +void MpDetailsView::albumArtChanged( ) +{ + TX_ENTRY + QPixmap pixmap; + QIcon qicon; + mSongData->albumArt( pixmap ); + composeAlbumCover( pixmap ); + if ( !mCompositePixmap.isNull() ) + qicon = QIcon( mCompositePixmap ); + else + qicon = QIcon( pixmap ); + HbIcon icon( qicon ); + mAlbumArt->setIcon( icon ); + TX_EXIT +} + +void MpDetailsView::loadSharePlayer() +{ + TX_ENTRY + TX_EXIT +} + + +/*! + Slot to call when widget is loaded + */ +void MpDetailsView::webViewLoaded( bool ok ) +{ + TX_ENTRY + if ( ok ) { + TX_LOG_ARGS( "Loading web page successfully." ); + + } else { + TX_LOG_ARGS( "Loading web page failed!" ); + } + TX_EXIT +} + + +/*! + Compose the album art. + */ +void MpDetailsView::composeAlbumCover( QPixmap albumart ) +{ + TX_ENTRY + mCompositePixmap.fill( Qt::transparent ); + QPainter painter( &mCompositePixmap ); + painter.setCompositionMode( QPainter::CompositionMode_Clear ); + painter.setCompositionMode( QPainter::CompositionMode_SourceOver ); + painter.fillRect( mCompositePixmap.rect(), Qt::transparent ); + painter.drawPixmap( QRect( 0, 0, 150, 150 ), albumart ); + TX_EXIT +} + +/*! + Make a key & value pair string for querying + */ +QString MpDetailsView::keyValues( QStringList keys, QStringList values ) const +{ + TX_ENTRY + QString str; + if ( keys.length() != values.length() ) { + TX_LOG_ARGS( "Error: keys length is not equal to values length" ); + } else { + for ( int i = 0; i < keys.length(); i++ ) { + QString tValue = values.at( i ); + if ( 0 != tValue.length() ) + { + str += keys.at( i ) + "=" + values.at( i ) + "&"; + } + } + } + TX_EXIT + return str.left( str.length() - 1 ); +} + +/*! + Find the most suitable link based on Atom response from Ovi music server + */ +void MpDetailsView::handleParsedXML() +{ + TX_ENTRY + QDomElement rootElement = mDomDocument.documentElement(); + + if ( rootElement.attribute( "type" ) == tr( "search" ) ) { + TX_LOG_ARGS( "URI response" ) + QString result; + QDomElement entry = rootElement.firstChildElement( "entry" ); + while ( !entry.isNull() ) + { + if ( entry.attribute( "type" ) == tr( "musictrack" ) ) { + QDomElement link = entry.firstChildElement( "link" ); + while ( !link.isNull() ) + { + if ( link.attribute( "rel" ) == tr( "alternate" ) + && link.attribute( "type" ) == tr( "text/html" ) ) { + result = link.attribute( "href" ); + } + link = link.nextSiblingElement( "link" ); + } + } + entry = entry.nextSiblingElement( "entry" ); + } + + mSongData->setLink( result ); + } else if ( rootElement.attribute( "type" ) == tr( "recommendedTracks" ) ) { + TX_LOG_ARGS( "Recommendation response" ) + QDomElement entry = rootElement.firstChildElement( "entry" ); + QNetworkReply *reply; + int count = 0; + while ( !entry.isNull() && count < KRecommendationNum ) + { + if ( entry.attribute( "type" ) == tr( "musictrack" ) ) { + QDomElement link = entry.firstChildElement( "link" ); + while ( !link.isNull() ) + { + if ( link.attribute( "title" ) == tr( "albumart100" ) ) { + mRecommendationAlbumArtsLink.append( link.attribute( "href" ) ); + break; + } else { + link = link.nextSiblingElement( "link" ); + } + } + QDomElement metadata = entry.firstChildElement( "metadata" ); + mRecommendationSongs.append( metadata.firstChildElement( "name" ).text() ); + mRecommendationArtists.append( metadata.firstChildElement( "primaryartist" ).text() ); + count++; + } + entry = entry.nextSiblingElement( "entry" ); + } + + for (int i = 0; i < KRecommendationNum; i++ ) { + TX_LOG_ARGS( "song name: " << mRecommendationSongs.at(i) ); + TX_LOG_ARGS( "Artist name: " << mRecommendationArtists.at(i) ); + TX_LOG_ARGS( "Album art link: " << mRecommendationAlbumArtsLink.at(i) ); + + if ( mRecommendationAlbumArtsLink.at( i ).contains( "http", Qt::CaseInsensitive ) ) { + reply = mDownloadManager->get( QNetworkRequest( QUrl( mRecommendationAlbumArtsLink.at(i) ) ) ); + mReplys.append( reply ); + connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( retrieveInformationNetworkError( QNetworkReply::NetworkError ) ) ); + connect( reply, SIGNAL( sslErrors( QList ) ), this, SLOT( retrieveInformationSslErrors( QList ) ) ); + } + } + } else { + TX_LOG_ARGS( "Not supported response" ) + } + TX_EXIT +} + +/*! + Sets recommendation album art +*/ +void MpDetailsView::setAlbumArtUri( const QString &albumArtUri, const QString &albumArtName ) +{ + TX_ENTRY_ARGS( "albumArtUri = " << albumArtUri ) + TX_LOG_ARGS( "albumArtName = " << albumArtName ) + if ( !albumArtUri.isEmpty() ) { + int id = mThumbnailManager->getThumbnail( albumArtName, reinterpret_cast( const_cast( &albumArtUri ) ) ); + if ( id == KUndefined ) { + // Request failed. Set default album art. + mRecommendationAlbumArtsMap.insert( albumArtUri, mDefaultRecommendationAlbumArt ); + recommendationAlbumArtReady(); + } + } + else { + // No album art uri. Set default album art. + mRecommendationAlbumArtsMap.insert( albumArtUri, mDefaultRecommendationAlbumArt ); + recommendationAlbumArtReady(); + } + TX_EXIT +} + +/*! + Render inspireme groupbox after album arts downloaded + */ +void MpDetailsView::RenderInspireMeGroupBox() +{ + TX_ENTRY + for ( int i = 0; i < KRecommendationNum; i++ ) { + HbListWidgetItem *item = new HbListWidgetItem(); + HbIcon icon( QIcon( mRecommendationAlbumArtsMap.value( mRecommendationAlbumArtsLink.at( i ) ) ) ); + item->setIcon( icon ); + item->setText( mRecommendationSongs.at( i ) ); + item->setSecondaryText( mRecommendationArtists.at( i ) ); + + mInspireList->addItem( item ); + } + + // TODO: HbListWidget has some problem to return the correct height, hard code to 180 for now. + TX_LOG_ARGS( "height = " << mInspireList->geometry().height() ); + TX_LOG_ARGS( "height2 = " << mInspireList->size().height() ); + mInspireList->setMinimumHeight( 180 ); + mInspireList->setMaximumHeight( 180 ); + + mLayout->addItem( mInspireList ); + mButton->show(); + mLayout->addItem( mButton ); + mInspireMe->setLayout( mLayout ); + + TX_EXIT +} + +void MpDetailsView::recommendationAlbumArtReady() +{ + TX_ENTRY_ARGS( "mAlbumArtsReadyCount = " << mAlbumArtsReadyCount ) + mAlbumArtsReadyCount++; + if ( mAlbumArtsReadyCount == KRecommendationNum ) { + RenderInspireMeGroupBox(); + } + TX_EXIT +} + + +/*! + Slot to handle basic song information + */ +void MpDetailsView::playbackInfoChanged() +{ + TX_ENTRY + mSongText->setPlainText( mSongData->title() ); + mAlbumText->setPlainText( mSongData->album() ); + mArtistText->setPlainText( mSongData->artist() ); + + // Clear information & Remove album arts downloaded previously when song changes + TX_LOG_ARGS( "Reply count = " << mReplys.count() ); + for ( int i = 0; i < mReplys.count(); i++ ) { + QNetworkReply *reply = mReplys.at( i ); + if ( reply != NULL ) { + TX_LOG_ARGS( "Reply index : " << i ); + reply->close(); + delete reply; + reply = NULL; + } + } + mReplys.clear(); + + mDownloadedAlbumArts = 0; + mAlbumArtsReadyCount = 0; + mInspireList->clear(); + for ( int i = 0; i < KRecommendationNum; i++) { + mRecommendationSongs.clear(); + mRecommendationArtists.clear(); + mRecommendationAlbumArtsLink.clear(); + mRecommendationAlbumArtsMap.clear(); + + QFile file( mRecommendationAlbumArtsName.at( i ) ); + if ( file.exists() ) { + if ( file.remove() ) { + TX_LOG_ARGS( "File removed - " << file.fileName() ); + } + else { + TX_LOG_ARGS( "Cannot remove file - " << file.fileName() ); + } + } else { + TX_LOG_ARGS( "File doesn't exist - " << file.fileName() ); + } + } + mButton->hide(); + + // TODO: country information handling, MCC + QString queryURI("http://api.music.ovi.com/1.0/ru/?"); + constructRequest( queryURI ); + TX_LOG_ARGS( "queryURI : " << queryURI ); + retrieveInformation( queryURI ); + + QString queryRecommendation("http://api.music.ovi.com/1.0/gb/releases/recommend/?"); + constructRequest( queryRecommendation ); + TX_LOG_ARGS( "queryRecommendation : " << queryRecommendation ); + retrieveInformation( queryRecommendation ); + + loadSharePlayer(); + TX_EXIT +} + +/*! + Slot to handle detail song information + */ +void MpDetailsView::songDetailInfoChanged() +{ + TX_ENTRY + mDetailList->clear(); + + HbListWidgetItem *item = new HbListWidgetItem(); + item->setText( tr( "Track" ) ); + item->setSecondaryText( mSongData->albumTrack() ); + mDetailList->addItem( item ); + + item = new HbListWidgetItem(); + item->setText( tr( "Composer" ) ); + item->setSecondaryText( mSongData->composer() ); + mDetailList->addItem( item ); + + item = new HbListWidgetItem(); + item->setText( tr( "Year" ) ); + item->setSecondaryText( mSongData->year() ); + mDetailList->addItem( item ); + + item = new HbListWidgetItem(); + item->setText( tr( "Genre" ) ); + item->setSecondaryText( mSongData->genre() ); + mDetailList->addItem( item ); + + item = new HbListWidgetItem(); + item->setText( tr( "Comment" ) ); + item->setSecondaryText( mSongData->comment() ); + mDetailList->addItem( item ); + TX_EXIT +} + +/*! + Slot to handle details groupbox toggling + */ +void MpDetailsView::toggleDetailsGroupBox(bool /*state*/) +{ + TX_ENTRY + if ( !mInspireMeGroupBox->isCollapsed() ) { + mSongDetailsGroupBox->setCollapsed( true ); + } + TX_EXIT +} + +/*! + Slot to handle inspire me groupbox toggling + */ +void MpDetailsView::toggleInspireMeGroupBox(bool /*state*/) +{ + TX_ENTRY + if ( !mSongDetailsGroupBox->isCollapsed() ) { + mInspireMeGroupBox->setCollapsed( true ); + } + TX_EXIT +} + +/*! + Construct the query for fetching URI & recommendations + */ +void MpDetailsView::constructRequest( QString &uri ) +{ + TX_ENTRY_ARGS( "uri =" << uri) + + QStringList keys; + keys << tr("artist") << tr("albumtitle") << tr("tracktitle") << tr("orderby"); + + // TODO: need to clarify which crition to use for sort, currently hard code to "relevancy" + // order can be relevancy, alltimedownloads, streetreleasedate, sortname, recentdownloads + QStringList values; + values << mSongData->artist() << mSongData->album() + << mSongData->title() << QString(tr("relevancy")); + TX_LOG_ARGS( "Artist: " << mSongData->artist() ); + TX_LOG_ARGS( "Album: " << mSongData->album() ); + TX_LOG_ARGS( "Title: " << mSongData->title() ); + + uri += keyValues( keys, values ); + + QUrl url(uri); + uri = url.toEncoded(); + TX_EXIT +} + +/*! + Get Atom response from Ovi server based on query + */ +void MpDetailsView::retrieveInformation( const QString &urlEncoded ) +{ + TX_ENTRY_ARGS( "urlEconded = " << urlEncoded) + QNetworkReply *reply = mManager->get( QNetworkRequest( QUrl( urlEncoded ) ) ); + mReplys.append( reply ); + + connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( retrieveInformationNetworkError( QNetworkReply::NetworkError ) ) ); + connect( reply, SIGNAL( sslErrors( QList ) ), this, SLOT( retrieveInformationSslErrors( QList ) ) ); + TX_EXIT +} + + +/*! + Slot to call when getting response + */ +void MpDetailsView::retrieveInformationFinished( QNetworkReply* reply ) +{ + TX_ENTRY + QString errorStr; + int errorLine; + int errorColumn; + bool parsingSuccess; + + if ( reply->error() == QNetworkReply::NoError ) + { + parsingSuccess = mDomDocument.setContent( reply, true, &errorStr, &errorLine, &errorColumn ); + if ( parsingSuccess ) { + handleParsedXML(); //CodeScanner throws a warning mis-interpreting the trailing 'L' to be a leaving function. + } else { + // TODO: agree on error handling + TX_LOG_ARGS( "XML parsing error" ); + } + } + else + { + // TODO: agree on error handling + TX_LOG_ARGS( "Network error in retrieving Information" ); + } + TX_EXIT +} + +/*! + Slot to call when there is network error + */ +void MpDetailsView::retrieveInformationNetworkError( QNetworkReply::NetworkError /*error*/ ) +{ + // TODO: agree on error handling + TX_ENTRY_ARGS( "Network error for retrieving Information" ); + TX_EXIT +} + +/*! + Slot to call when there is ssl error + */ +void MpDetailsView::retrieveInformationSslErrors( const QList &/*error*/ ) +{ + // TODO: agree on error handling + TX_ENTRY_ARGS( "SSL error for retrieving Information" ); + TX_EXIT +} + +/*! + Slot to call when downloading finished + */ +void MpDetailsView::DownloadFinished( QNetworkReply* reply ) +{ + TX_ENTRY_ARGS( "mDownloadedAlbumArts = " << mDownloadedAlbumArts ); + if ( reply->error() == QNetworkReply::NoError ) + { + QString fileName = mRecommendationAlbumArtsName.at( mDownloadedAlbumArts ); + TX_LOG_ARGS( "File name: " << fileName ); + QFile file(fileName); + + if ( fileName.isEmpty() ) { + TX_LOG_ARGS( "Only store two album arts" ); + } else { + if ( !file.open( QIODevice::ReadWrite ) ) { + TX_LOG_ARGS( "Unable to open file" ); + } else { + file.write( reply->readAll() ); + file.flush(); + file.close(); + setAlbumArtUri( mRecommendationAlbumArtsLink.at( mDownloadedAlbumArts ), + mRecommendationAlbumArtsName.at( mDownloadedAlbumArts ) ); + } + } + } + else + { + TX_LOG_ARGS( "Downloading album art failed!" ); + } + + mDownloadedAlbumArts++; + TX_EXIT +} + +/*! + Slot to handle the recommendation album art +*/ +void MpDetailsView::thumbnailReady( + const QPixmap& pixmap, + void *data, + int /*id*/, + int error ) +{ + TX_ENTRY + QString uri = *( reinterpret_cast( data ) ); + TX_LOG_ARGS( "Uri: " << uri ); + + if ( error == 0 ) { + TX_LOG_ARGS( "album art link: " << uri ); + mRecommendationAlbumArtsMap.insert( uri, pixmap ); + recommendationAlbumArtReady(); + } + else { + mRecommendationAlbumArtsMap.insert( uri, mDefaultRecommendationAlbumArt ); + recommendationAlbumArtReady(); + } + + TX_EXIT +} + + +/*! + Slot to add context to javascript + */ +void MpDetailsView::addContext() +{ + TX_ENTRY + TX_EXIT +} + +/*! + Slot to close widget + */ +void MpDetailsView::close() +{ + TX_ENTRY + TX_EXIT +} +