--- a/mpviewplugins/mpdetailsviewplugin/src/mpdetailssharedialog.cpp Fri May 14 18:54:37 2010 -0500
+++ b/mpviewplugins/mpdetailsviewplugin/src/mpdetailssharedialog.cpp Fri May 28 19:46:01 2010 -0500
@@ -1,3 +1,20 @@
+/*
+* 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: Implementation for share player.
+*
+*/
+
#ifdef SHARE_FUNC_ENABLED
#include "mpdetailssharedialog.h"
@@ -11,12 +28,19 @@
#include <QWebFrame>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
+#include <QNetworkReply>
#include <QDesktopServices>
#include <QNetworkProxyFactory>
+#include <QTimer>
#include <hbmessagebox.h>
#include <QFile>
#include <QTextStream>
+#include <qsysteminfo.h>
+#include <hbmainwindow.h>
+#include <hbstyleloader.h>
+#include <hbprogressdialog.h>
+QTM_USE_NAMESPACE
// SHARE_INDEX_FILE defines where the index.html file is loaded from.
#define SHARE_INDEX_URL "qrc:///shareview/index.html"
@@ -27,11 +51,9 @@
// For R&D testing, index.html may be loaded from E: drive.
// User must manually place index.html in the correct location.
// If the RND file does not exist, then SHARE_INDEX_URL will be used.
-#define RND_SHARE_INDEX_URL "file:///e:/index.html"
-#define RND_SHARE_INDEX_FILE "e:\\index.html"
-#define RND_OVI_LOGIN_FILE "e:\\ovicredentials.txt"
-#define RND_DEFAULT_USER "hipsu"
-#define RND_DEFAULT_PASS "hipsupass"
+#define RND_SHARE_INDEX_URL "file:///f:/index.html"
+#define RND_SHARE_INDEX_FILE "f:\\index.html"
+#define RND_OVI_LOGIN_FILE "f:\\ovicredentials.txt"
#endif
#else
// Assume Windows target.
@@ -41,27 +63,73 @@
#endif
-// For allowing local caching of javascript files loaded by popup
+// Default language in case QSystemInfo does not work.
+#define DEFAULT_LANGUAGE "en-US"
+
+// Default error message.
+#define ERROR_MESSAGE "An error occured. Sharing is not currently available"
+
+
+/*!
+ MpNetworkAccessManager allows local caching of publishing player files
+ in order to minimize network traffic.
+ The files will be cached to the private directory of the application,
+ i.e. in the music player's case, this is C:\Private\10207C62\Cache.
+ */
class MpNetworkAccessManager : public QNetworkAccessManager
{
public:
- MpNetworkAccessManager() { };
+ MpNetworkAccessManager( QObject* parent = 0 )
+ : QNetworkAccessManager( parent )
+ {
+ proxyFactory()->setUseSystemConfiguration( true );
+ QNetworkDiskCache* diskCache = new QNetworkDiskCache( this );
+ QString location = QDesktopServices::storageLocation( QDesktopServices::CacheLocation );
+ diskCache->setCacheDirectory( location );
+ setCache( diskCache );
+ }
private:
- QNetworkReply *createRequest( Operation op,
- const QNetworkRequest &request,
- QIODevice *outgoingData = 0 )
+ QNetworkReply* createRequest( Operation op,
+ const QNetworkRequest &request,
+ QIODevice* outgoingData = 0 )
{
TX_ENTRY
+ TX_LOG_ARGS( "share: createRequest URL=" << request.url().toString() )
+
QVariant val = request.attribute( QNetworkRequest::CacheLoadControlAttribute );
- qDebug() << "request cachecontrol - " << val.typeName() << val.toInt();
// Change the cache load control attrbute!
QNetworkRequest req = request;
req.setAttribute( QNetworkRequest::CacheLoadControlAttribute,
- QVariant( QNetworkRequest::PreferCache ) ); // was PreferNetwork
+ QVariant( QNetworkRequest::PreferCache ) );
+ QNetworkReply* result = QNetworkAccessManager::createRequest( op, req, outgoingData );
TX_EXIT
- return QNetworkAccessManager::createRequest( op, req, outgoingData );
+ return result;
+ }
+};
+
+/*!
+ MpShareWebView derives from QGraphicsWebView in order to override it's
+ contextMenuEvent method to prevent the background context menu from
+ being displayed when user makes long click in the web view.
+ */
+class MpShareWebView : public QGraphicsWebView
+{
+public:
+ MpShareWebView( QGraphicsItem * parent = 0 )
+ : QGraphicsWebView( parent )
+ {
+ settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
+ settings()->setAttribute( QWebSettings::LocalStorageDatabaseEnabled, true );
+ settings()->enablePersistentStorage();
+ }
+
+protected:
+ void contextMenuEvent( QGraphicsSceneContextMenuEvent* /*ev*/ ) // Override QGraphicsWebView::contextMenuEvent
+ {
+ // Fix to prevent "Stop" and "Reload" buttons in page background.
+ // Do not respond to the contextMenuEvent.
}
};
@@ -71,11 +139,22 @@
*/
MpDetailsShareDialog::MpDetailsShareDialog()
: mShareWebView( 0 ),
- mShareNetAccMan( 0 )
+ mShareNetAccMan( 0 ),
+ mProgressbar ( 0 ),
+ mIsInitialized( false )
{
+ // DeleteOnClose attribute prevents crash when user presses Cancel
+ // before publishing player is fully loaded.
+ setAttribute( Qt::WA_DeleteOnClose, true );
}
-void MpDetailsShareDialog::initialize( MpSongData* aSongData )
+/*!
+ Initialize the share dialog.
+ When fully initialized we set our mIsInitialized flag to true.
+ Our isInitialized() method can be called to determine whether
+ initialization was successful.
+ */
+void MpDetailsShareDialog::initialize( MpSongData* aSongData, const QString& aUnknownTr )
{
TX_ENTRY
if ( !initUser() )
@@ -83,7 +162,8 @@
emit closeShareDialog();
return;
}
- initShareData( aSongData );
+ initShareData( aSongData, aUnknownTr );
+ initLanguage();
initNetworkAccessManager();
initWebView();
initSignalSlots();
@@ -109,68 +189,136 @@
TX_LOG_ARGS( "share: Use QRC index.html file " << SHARE_INDEX_URL )
mShareWebView->load( QUrl( SHARE_INDEX_URL ) );
}
+
+ // Flag that the dialog is now fully initialized.
+ mIsInitialized = true;
+
+ // Show progress dialog in .3 second if loading not finished.
+ QTimer::singleShot(300, this, SLOT(showProgressDialog()));
+
TX_EXIT
}
-
/*!
Destructor.
*/
MpDetailsShareDialog::~MpDetailsShareDialog()
{
TX_ENTRY
+ if ( mShareData.songData() )
+ {
+ // Ensure that we remove the temporary album art file when we close the dialog.
+ // TODO this should be removed when base64 issue is solved.
+ TX_LOG_ARGS( "share: remove album art file" )
+ mShareData.songData()->removeAlbumArtFile();
+ }
logoutPlayer();
- delete mShareNetAccMan;
+ // Probably mShareNetAccMan should not be deleted but qt documentation
+ // does not indicate whether QWebPage takes ownership of the object or not.
+ // See http://doc.qt.nokia.com/4.6/qwebpage.html
+ //delete mShareNetAccMan;
TX_EXIT
}
-void MpDetailsShareDialog::initShareData( MpSongData* aSongData )
+/*!
+ Initialize share data.
+ */
+void MpDetailsShareDialog::initShareData( MpSongData* aSongData, const QString& aUnknownTr )
{
TX_ENTRY
// Set information for the share data.
mShareData.setOwner( this );
mShareData.setSongData( aSongData );
- // TODO need localized error message.
- mShareData.setErrorMessage( "An error occured. Sharing is not currently available" );
- // TODO need language setting.
- mShareData.setLanguage( "en" );
+ mShareData.setErrorMessage( tr( ERROR_MESSAGE ) );
+ mShareData.setUnknownTr( aUnknownTr );
TX_EXIT
}
+/*!
+ Initialize language.
+ Language string is formatted like "en-US", where "en" is the ISO-639-1 language code,
+ and "US" is the ISO-3166-1 country code.
+ We use the QT Mobility API (systeminfo) to obtain the settings from the device.
+ In the event that we cannot construct the QSystemInfo variable then we will fallback
+ to some DEFAULT_LANGUAGE setting.
+ */
+void MpDetailsShareDialog::initLanguage()
+{
+ TX_ENTRY
+ // Set language string, example "en-US".
+ QString language;
+ QSystemInfo* sysInfo = new QSystemInfo( this );
+ if ( sysInfo )
+ {
+ language += sysInfo->currentLanguage(); // ISO-639-1 language code.
+ language += "-";
+ language += sysInfo->currentCountryCode(); // ISO-3166-1 country code.
+ delete sysInfo;
+ }
+ else
+ {
+ // Fallback to the default language.
+ language = DEFAULT_LANGUAGE;
+ }
+ TX_LOG_ARGS( "share: language '" << language << "'" )
+ mShareData.setLanguage( language );
+ TX_EXIT
+}
+
+/*!
+ Initialize network access manager.
+ */
void MpDetailsShareDialog::initNetworkAccessManager()
{
TX_ENTRY
- // Make our own network access manager to allow JS retrieval from local cache,
+ // Make our own network access manager to allow file retrieval from local cache,
// since configuration for the default network access manager seems to be
// to always redownload from network.
- mShareNetAccMan = new MpNetworkAccessManager();
- mShareNetAccMan->proxyFactory()->setUseSystemConfiguration( true );
- QNetworkDiskCache* diskCache = new QNetworkDiskCache( this );
- QString location = QDesktopServices::storageLocation( QDesktopServices::CacheLocation );
- diskCache->setCacheDirectory( location );
- mShareNetAccMan->setCache( diskCache );
+ if ( !mShareNetAccMan )
+ {
+ TX_LOG_ARGS( "share: construct network access manager" )
+ mShareNetAccMan = new MpNetworkAccessManager( this );
+ }
TX_EXIT
}
+/*!
+ Initialize the web view.
+ */
void MpDetailsShareDialog::initWebView()
{
TX_ENTRY
- mShareWebView = new QGraphicsWebView();
- mShareWebView->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
- mShareWebView->settings()->setAttribute( QWebSettings::LocalStorageDatabaseEnabled, true );
- mShareWebView->settings()->enablePersistentStorage();
- mShareWebView->page()->setNetworkAccessManager( mShareNetAccMan );
- setContentWidget( mShareWebView );
+ if ( !mShareWebView )
+ {
+ TX_LOG_ARGS( "share: construct share web view" )
+ mShareWebView = new MpShareWebView( this );
+ mShareWebView->page()->setNetworkAccessManager( mShareNetAccMan );
+ mShareWebView->page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ mShareWebView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
+ setContentWidget( mShareWebView );
+ addContext();
+ mProgressbar = new HbProgressDialog(HbProgressDialog::WaitDialog);
+ mProgressbar->setText(tr("Loading"));
+ }
TX_EXIT
}
+/*!
+ Initialize signals and slots.
+ */
void MpDetailsShareDialog::initSignalSlots()
{
TX_ENTRY
+ // Connect various signals to slots for networking.
+ connect( mShareNetAccMan, SIGNAL( sslErrors( QNetworkReply*, const QList< QSslError >& ) ),
+ this, SLOT( handleRequestSSLErrors( QNetworkReply*, const QList< QSslError >& ) ) );
+ connect( mShareNetAccMan, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( handleRequestFinished( QNetworkReply* ) ) );
+
// Connect various signals to slots for interface to webview.
connect( mShareWebView, SIGNAL( loadFinished( bool ) ), SLOT( onIndexLoad( bool ) ) );
connect( mShareWebView->page()->mainFrame(), SIGNAL( javaScriptWindowObjectCleared() ), this, SLOT( addContext() ) );
connect( mShareWebView->page(), SIGNAL( windowCloseRequested() ), this, SIGNAL( closeShareDialog() ) );
+ connect( mProgressbar, SIGNAL(cancelled()), this, SIGNAL( closeShareDialog() ) );
TX_EXIT
}
@@ -186,10 +334,9 @@
QFile file( RND_OVI_LOGIN_FILE );
if ( !file.open( QFile::ReadOnly ) )
{
-// errorHandler( "share", QString( RND_OVI_LOGIN_FILE ) + " missing" );
- mShareData.setUsername( RND_DEFAULT_USER );
- mShareData.setPassword( RND_DEFAULT_PASS );
- result = true;
+ // There must be e:ovicredentials.txt in the filesystem but don't show error dialog
+ // otherwise it will appear as soon as detailsview is created.
+ result = false;
}
else
{
@@ -217,12 +364,46 @@
}
/*!
+ Returns true if the dialog has been fully initialized.
+ */
+bool MpDetailsShareDialog::isInitialized() const
+{
+ return mIsInitialized;
+}
+
+/*!
+ Attempt to cache the publishing player files from internet
+ to improve user experience for first-time use.
+ If the files are already in the cache and have not expired,
+ then this should not do anything.
+ */
+void MpDetailsShareDialog::cachePublishingPlayerFiles()
+{
+ TX_ENTRY
+ // We need the network access manager, so make sure it is initialized.
+ if ( !mShareNetAccMan )
+ {
+ initNetworkAccessManager();
+ }
+ // Attempt to get the required publishing player files from the net in advance.
+ // We don't listen to any signal that the download succeeded or failed
+ // since we will let it silently fail at this stage.
+ // These URLs are also included in index.html resource, and the two must
+ // be kept the same.
+ mShareNetAccMan->get( QNetworkRequest( QUrl(
+ "http://hf.ci.wipsl.com/PleiXXPTsup/noheva-be/css/ovi.player.share.ui.css" ) ) );
+ mShareNetAccMan->get( QNetworkRequest( QUrl(
+ "http://hf.ci.wipsl.com/PleiXXPTsup/noheva-be/js/publishplayer.js" ) ) );
+ TX_EXIT
+}
+
+/*!
Release resources from share player.
*/
void MpDetailsShareDialog::logoutPlayer()
{
TX_ENTRY
- if (mShareWebView)
+ if ( mShareWebView )
{
mShareWebView->page()->mainFrame()->evaluateJavaScript( "music.teardown();" );
}
@@ -235,7 +416,7 @@
void MpDetailsShareDialog::addContext()
{
TX_ENTRY
- if (mShareWebView)
+ if ( mShareWebView )
{
mShareWebView->page()->mainFrame()->addToJavaScriptWindowObject( "context", &mShareData );
}
@@ -248,9 +429,10 @@
void MpDetailsShareDialog::updateSharedData()
{
TX_ENTRY
- if (mShareWebView)
+ if ( mShareWebView )
{
- mShareWebView->page()->mainFrame()->evaluateJavaScript( "music.updateContextArea();" );
+ // We don't need to call updateContextArea when the track URL has been updated.
+ //mShareWebView->page()->mainFrame()->evaluateJavaScript( "music.updateContextArea();" );
mShareWebView->page()->mainFrame()->evaluateJavaScript( "music.updateMetadata();" );
}
TX_EXIT
@@ -287,12 +469,23 @@
/*!
Slot to call for displaying an error message to the user.
*/
-void MpDetailsShareDialog::errorHandler( QString error, QString message )
+void MpDetailsShareDialog::errorHandler( QString aError, QString aMessage )
{
TX_ENTRY
- TX_LOG_ARGS( "share: errorHandler: " << error << ": " << message )
- HbMessageBox::warning( error + ": " + message ); // For week16 hbwidgets
-// HbMessageBox::launchWarningMessageBox( error + ": " + message ); // For week12 hbwidgets
+ // If error argument ends with "_SUCCESS", then this should be an info message.
+ // If error argument ends with "_FAILED" or something else, then this should be a warning message.
+ TX_LOG_ARGS( "share: errorHandler: " << aError << ": " << aMessage )
+ if ( aError.endsWith( "_SUCCESS" ) )
+ {
+ // TODO this method seems to be deprecated?
+ HbMessageBox::information( tr( "%1" ).arg( aError ) + ": " + tr( "%1" ).arg( aMessage ) ); // For week16 hbwidgets
+ }
+ else
+ {
+ // TODO this method seems to be deprecated?
+ HbMessageBox::warning( tr( "%1" ).arg( aError ) + ": " + tr( "%1" ).arg( aMessage ) ); // For week16 hbwidgets
+ // HbMessageBox::launchWarningMessageBox( tr( "%1" ).arg( aError ) + ": " + tr( "%1" ).arg( message ) ); // For week12 hbwidgets
+ }
TX_EXIT
}
@@ -321,4 +514,55 @@
TX_EXIT
}
+/*!
+ Slot to show the publishing window after html elements are created in javascript.
+ */
+void MpDetailsShareDialog::showWindow()
+{
+ TX_ENTRY
+ if (mProgressbar)
+ mProgressbar->close();
+ show();
+ TX_EXIT
+}
+
+/*!
+ Slot to show progress dialog if the publishing window is not loaded in .3 sec.
+ */
+void MpDetailsShareDialog::showProgressDialog()
+{
+ TX_ENTRY
+ if (!isVisible())
+ mProgressbar->show();
+ TX_EXIT
+}
+
+/*!
+ Slot to SSL errors in network request. We will ignore any errors.
+ */
+void MpDetailsShareDialog::handleRequestSSLErrors( QNetworkReply* aReply, const QList< QSslError >& aErrors )
+{
+ TX_ENTRY
+ aReply->ignoreSslErrors();
+ for( int i = 0; i < aErrors.count(); i++ )
+ {
+ TX_LOG_ARGS( "SSL error " << aErrors.at( i ).errorString() );
+ }
+ TX_EXIT
+}
+
+/*!
+ Slot to handle network request completion.
+ */
+void MpDetailsShareDialog::handleRequestFinished( QNetworkReply* aReply )
+{
+ TX_ENTRY
+ if ( aReply->error() != QNetworkReply::NoError )
+ {
+ TX_LOG_ARGS( "Network request error " << aReply->error() << aReply->errorString() );
+ // TODO what to do now?
+ }
+ TX_EXIT
+}
+
#endif // SHARE_FUNC_ENABLED