Permalink
Browse files

MythUIWebBrowser: allow unsupported content to be downloaded or played.

This updates the web browser widget to ask if you want to download any files
that the browser doesn't know how to handle. You can also right click on an
image and download those as well. This is primarily for the music metadata
editor so you can do a search for a cover image for MythMusic to use.

Any audio files that are clicked and MythMusic can play will also ask if you
want to play them in the music player. Currently mp3 files play well but other
formats no so well but I do intend to look at improving that. There is support
to also play video files but this is currently disabled until the internal
player can better handle playing from an http url.
  • Loading branch information...
1 parent 46d70dc commit c1aebb3182606970140ec6fb847c59318f519d0b Paul Harrison committed Feb 24, 2011
Showing with 235 additions and 3 deletions.
  1. +216 −3 mythtv/libs/libmythui/mythuiwebbrowser.cpp
  2. +19 −0 mythtv/libs/libmythui/mythuiwebbrowser.h
View
219 mythtv/libs/libmythui/mythuiwebbrowser.cpp
@@ -30,7 +30,12 @@
#include "mythdirs.h"
#include "mythuihelper.h"
#include "mythcorecontext.h"
-#include "mythscreentype.h"
+#include "mythdownloadmanager.h"
+#include "mythdialogbox.h"
+#include "mythprogressdialog.h"
+
+#define MUSIC_EXTENSIONS "mp3,mp2,ogg,oga,flac,wma,wav,ac3,oma,omg,atp,ra,dts,aac,m4a,aa3,tta,mka,aiff,swa,wv"
+#define VIDEO_EXTENSIONS "mpeg,mpg,wmv,avi"
/**
* @class BrowserApi
@@ -182,10 +187,14 @@ MythWebView::MythWebView(QWidget *parent, MythUIWebBrowser *parentBrowser)
: QWebView(parent)
{
m_parentBrowser = parentBrowser;
+ m_busyPopup = NULL;
- connect(this->page(), SIGNAL(unsupportedContent(QNetworkReply *)),
+ connect(page(), SIGNAL(unsupportedContent(QNetworkReply *)),
this, SLOT(handleUnsupportedContent(QNetworkReply *)));
+ connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)),
+ this, SLOT(handleDownloadRequested(QNetworkRequest)));
+
page()->setForwardUnsupportedContent(true);
m_api = new BrowserApi(this);
@@ -259,6 +268,17 @@ void MythWebView::handleUnsupportedContent(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError)
{
+ QVariant header = reply->header(QNetworkRequest::ContentTypeHeader);
+
+ if (header != QVariant())
+ VERBOSE(VB_IMPORTANT, QString("MythWebView::handleUnsupportedContent - %1")
+ .arg(header.toString()));
+
+ m_downloadRequest = reply->request();
+ showDownloadMenu();
+
+ emit titleChanged(title());
+
return;
}
@@ -307,6 +327,189 @@ void MythWebView::handleUnsupportedContent(QNetworkReply *reply)
emit statusBarMessage(title);
}
+void MythWebView::handleDownloadRequested(const QNetworkRequest &request)
+{
+ QFileInfo fi(request.url().path());
+ QString basename(fi.baseName());
+ QString extension = fi.suffix();
+
+ m_downloadRequest = request;
+
+ QFileInfo savefi(m_parentBrowser->GetDefaultSaveDirectory());
+ QString saveBaseName(savefi.baseName());
+ if (saveBaseName.isEmpty())
+ saveBaseName = basename;
+ QString saveFilename = savefi.absolutePath() + '/' + saveBaseName + '.' + extension;
+
+ MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
+
+ QString msg = tr("Enter filename to save file");
+ MythTextInputDialog *input = new MythTextInputDialog(popupStack, msg, FilterNone, false, saveFilename);
+
+ if (input->Create())
+ {
+ input->SetReturnEvent(this, "filenamedialog");
+ popupStack->AddScreen(input);
+ }
+ else
+ delete input;
+}
+
+void MythWebView::doDownload(const QString &saveFilename)
+{
+ if (saveFilename.isEmpty())
+ return;
+
+ openBusyPopup(QObject::tr("Downloading file. Please wait..."));
+
+ GetMythDownloadManager()->queueDownload(m_downloadRequest.url().toString(), saveFilename, this);
+}
+
+void MythWebView::openBusyPopup(const QString &message)
+{
+ if (m_busyPopup)
+ return;
+
+ QString msg(tr("Downloading..."));
+ if (!message.isEmpty())
+ msg = message;
+
+ MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
+ m_busyPopup = new MythUIBusyDialog(msg, popupStack, "downloadbusydialog");
+
+ if (m_busyPopup->Create())
+ popupStack->AddScreen(m_busyPopup, false);
+}
+
+void MythWebView::closeBusyPopup(void)
+{
+ if (m_busyPopup)
+ m_busyPopup->Close();
+ m_busyPopup = NULL;
+}
+
+void MythWebView::customEvent(QEvent *event)
+{
+ if (event->type() == DialogCompletionEvent::kEventType)
+ {
+ DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
+
+ // make sure the user didn't ESCAPE out of the dialog
+ if (dce->GetResult() < 0)
+ return;
+
+ QString resultid = dce->GetId();
+ QString resulttext = dce->GetResultText();
+
+ if (resultid == "filenamedialog")
+ doDownload(resulttext);
+ else if (resultid == "downloadmenu")
+ {
+ if (resulttext == tr("Play the file"))
+ {
+ QFileInfo fi(m_downloadRequest.url().path());
+ QString basename(fi.baseName());
+ QString extension = fi.suffix();
+
+ if (isMusicFile(extension))
+ {
+ MythEvent me(QString("MUSIC_COMMAND %1 PLAY_URL %2")
+ .arg(gCoreContext->GetHostName()).arg(m_downloadRequest.url().toString()));
+ gCoreContext->dispatch(me);
+ }
+ else if (isVideoFile(extension))
+ {
+ //NOTE: before this will work internal_play_media() needs updating to support http: urls
+ GetMythMainWindow()->HandleMedia("Internal", m_downloadRequest.url().toString());
+ }
+ else
+ VERBOSE(VB_IMPORTANT, QString("MythWebView: Asked to play a file with extension '%1' but don't know how")
+ .arg(extension));
+ }
+ else if (resulttext == tr("Download the file"))
+ {
+ handleDownloadRequested(m_downloadRequest);
+ }
+ }
+ }
+ else if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage)
+ {
+ MythEvent *me = (MythEvent *)event;
+ QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts);
+
+ if (tokens.isEmpty())
+ return;
+
+ if (tokens[0] == "DOWNLOAD_FILE")
+ {
+ QStringList args = me->ExtraDataList();
+ if (tokens[1] == "UPDATE")
+ {
+ // could update a progressbar here
+ }
+ else if (tokens[1] == "FINISHED")
+ {
+ int fileSize = args[2].toInt();
+ int errorCode = args[4].toInt();
+
+ closeBusyPopup();
+
+ if ((errorCode != 0) || (fileSize == 0))
+ ShowOkPopup(tr("ERROR downloading file."));
+
+ MythEvent me(QString("BROWSER_DOWNLOAD_FINISHED"), args);
+ gCoreContext->dispatch(me);
+ }
+ }
+ }
+}
+
+void MythWebView::showDownloadMenu(void)
+{
+ QFileInfo fi(m_downloadRequest.url().path());
+ QString basename(fi.baseName());
+ QString extension = fi.suffix();
+
+ bool isPlayable = isMusicFile(extension) | isVideoFile(extension);
+
+ QString label = tr("What do you want to do with this file?");
+
+ MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
+
+ MythDialogBox *menu = new MythDialogBox(label, popupStack, "downloadmenu");
+
+ if (!menu->Create())
+ {
+ delete menu;
+ return;
+ }
+
+ menu->SetReturnEvent(this, "downloadmenu");
+
+ if (isPlayable)
+ menu->AddButton(tr("Play the file"));
+ menu->AddButton(tr("Download the file"));
+ menu->AddButton(tr("Cancel"));
+
+ popupStack->AddScreen(menu);
+}
+
+bool MythWebView::isMusicFile(const QString &extension)
+{
+ QStringList list = QString(MUSIC_EXTENSIONS).split(",");
+ return list.contains(extension, Qt::CaseInsensitive);
+}
+
+bool MythWebView::isVideoFile(const QString &extension)
+{
+ //the internal player is currently broken for all file formats
+ //so for the moment ignore all video files
+ return false;
+
+ QStringList list = QString(VIDEO_EXTENSIONS).split(",");
+ return list.contains(extension, Qt::CaseInsensitive);
+}
+
/**
* \class MythUIWebBrowser
* \brief Provide a web browser widget.
@@ -357,6 +560,7 @@ MythUIWebBrowser::MythUIWebBrowser(MythUIType *parent, const QString &name)
m_inputToggled(false), m_lastMouseAction(""),
m_mouseKeyCount(0), m_lastMouseActionTime()
{
+ m_defaultSaveDir = QDir::homePath() + "/";
SetCanTakeFocus(true);
}
@@ -475,7 +679,7 @@ void MythUIWebBrowser::Init(void)
QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,
false);
}
-
+
QImage image = QImage(m_Area.size(), QImage::Format_ARGB32);
m_image = GetPainter()->GetFormatImage();
m_image->Assign(image);
@@ -637,6 +841,14 @@ void MythUIWebBrowser::SetZoom(float zoom)
UpdateBuffer();
}
+void MythUIWebBrowser::SetDefaultSaveDirectory(const QString &saveDir)
+{
+ if (!saveDir.isEmpty())
+ m_defaultSaveDir = saveDir;
+ else
+ m_defaultSaveDir = QDir::homePath() + "/";
+}
+
/** \fn MythUIWebBrowser::GetZoom()
* \brief Get the current zoom level
* \return the zoom level
@@ -1134,6 +1346,7 @@ void MythUIWebBrowser::CopyFrom(MythUIType *base)
m_widgetUrl = browser->m_widgetUrl;
m_userCssFile = browser->m_userCssFile;
m_updateInterval = browser->m_updateInterval;
+ m_defaultSaveDir = browser->m_defaultSaveDir;
Init();
}
View
19 mythtv/libs/libmythui/mythuiwebbrowser.h
@@ -16,6 +16,7 @@
class MythUIWebBrowser;
+class MythUIBusyDialog;
class MythScreenType;
class BrowserApi : public QObject
@@ -62,12 +63,25 @@ class MythWebView : public QWebView
~MythWebView(void);
virtual void keyPressEvent(QKeyEvent *event);
+ virtual void customEvent(QEvent *e);
protected slots:
void handleUnsupportedContent(QNetworkReply *reply);
+ void handleDownloadRequested(const QNetworkRequest &request);
+
private:
+ void showDownloadMenu(void);
+ void doDownload(const QString &saveFilename);
+ void openBusyPopup(const QString &message);
+ void closeBusyPopup(void);
+
+ bool isMusicFile(const QString &extension);
+ bool isVideoFile(const QString &extension);
+
MythUIWebBrowser *m_parentBrowser;
BrowserApi *m_api;
+ QNetworkRequest m_downloadRequest;
+ MythUIBusyDialog *m_busyPopup;
};
/**
@@ -112,6 +126,9 @@ class MUI_PUBLIC MythUIWebBrowser : public MythUIType
QVariant evaluateJavaScript(const QString& scriptSource);
+ void SetDefaultSaveDirectory(const QString &saveDir);
+ QString GetDefaultSaveDirectory(void) { return m_defaultSaveDir; }
+
public slots:
void Back(void);
void Forward(void);
@@ -125,6 +142,7 @@ class MUI_PUBLIC MythUIWebBrowser : public MythUIType
void titleChanged(const QString &title); /// a pages title has changed
void statusBarMessage(const QString &text);/// link hit test messages
void iconChanged(void); /// a pages fav icon has changed
+ void fileDownloaded(QString filename); /// a file has been downloaded
protected slots:
void slotLoadStarted(void);
@@ -167,6 +185,7 @@ class MUI_PUBLIC MythUIWebBrowser : public MythUIType
QColor m_bgColor;
QUrl m_widgetUrl;
QString m_userCssFile;
+ QString m_defaultSaveDir;
bool m_inputToggled;
QString m_lastMouseAction;

0 comments on commit c1aebb3

Please sign in to comment.