Skip to content

Commit

Permalink
MythUIWebBrowser: allow unsupported content to be downloaded or played.
Browse files Browse the repository at this point in the history
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
Paul Harrison committed Feb 24, 2011
1 parent 46d70dc commit c1aebb3
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 3 deletions.
219 changes: 216 additions & 3 deletions mythtv/libs/libmythui/mythuiwebbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
Expand Down
19 changes: 19 additions & 0 deletions mythtv/libs/libmythui/mythuiwebbrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@


class MythUIWebBrowser;
class MythUIBusyDialog;
class MythScreenType;

class BrowserApi : public QObject
Expand Down Expand Up @@ -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;
};

/**
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c1aebb3

Please sign in to comment.