MythTV  0.26-pre
mythuiwebbrowser.cpp
Go to the documentation of this file.
00001 
00010 #include "mythuiwebbrowser.h"
00011 
00012 // qt
00013 #include <QApplication>
00014 #include <QWebFrame>
00015 #include <QWebHistory>
00016 #include <QPainter>
00017 #include <QDir>
00018 #include <QBuffer>
00019 #include <QStyle>
00020 #include <QKeyEvent>
00021 #include <QDomDocument>
00022 #include <QNetworkCookieJar>
00023 
00024 // myth
00025 #include "mythpainter.h"
00026 #include "mythimage.h"
00027 #include "mythmainwindow.h"
00028 #include "mythfontproperties.h"
00029 #include "mythlogging.h"
00030 #include "mythdb.h"
00031 #include "mythdirs.h"
00032 #include "mythuihelper.h"
00033 #include "mythcorecontext.h"
00034 #include "mythdownloadmanager.h"
00035 #include "mythdialogbox.h"
00036 #include "mythprogressdialog.h"
00037 #include "mythuiscrollbar.h"
00038 
00039 struct MimeType
00040 {
00041     QString mimeType;
00042     QString extension;
00043     bool    isVideo;
00044 };
00045 
00046 static MimeType SupportedMimeTypes[] =
00047 {
00048     { "audio/mpeg3",                 "mp3",   false },
00049     { "audio/x-mpeg-3",              "mp3",   false },
00050     { "audio/mpeg",                  "mp2",   false },
00051     { "audio/x-mpeg",                "mp2",   false },
00052     { "audio/ogg",                   "ogg",   false },
00053     { "audio/ogg",                   "oga",   false },
00054     { "audio/flac",                  "flac",  false },
00055     { "audio/x-ms-wma",              "wma",   false },
00056     { "audio/wav",                   "wav",   false },
00057     { "audio/x-wav",                 "wav",   false },
00058     { "audio/ac3",                   "ac3",   false },
00059     { "audio/x-ac3",                 "ac3",   false },
00060     { "audio/x-oma",                 "oma",   false },
00061     { "audio/x-realaudio",           "ra",    false },
00062     { "audio/dts",                   "dts",   false },
00063     { "audio/x-dts",                 "dts",   false },
00064     { "audio/aac",                   "aac",   false },
00065     { "audio/x-aac",                 "aac",   false },
00066     { "audio/m4a",                   "m4a",   false },
00067     { "audio/x-m4a",                 "m4a",   false },
00068     { "video/mpeg",                  "mpg",   true },
00069     { "video/mpeg",                  "mpeg",  true },
00070     { "video/x-ms-wmv",              "wmv",   true },
00071     { "video/x-ms-wmv",              "avi",   true },
00072     { "application/x-troff-msvideo", "avi",   true },
00073     { "video/avi",                   "avi",   true },
00074     { "video/msvideo",               "avi",   true },
00075     { "video/x-msvideo",             "avi",   true }
00076 };
00077 
00078 static int SupportedMimeTypesCount = sizeof(SupportedMimeTypes) /
00079                                         sizeof(SupportedMimeTypes[0]);
00080 
00081 static QNetworkAccessManager *networkManager = NULL;
00082 
00083 static void DestroyNetworkAccessManager(void)
00084 {
00085     if (networkManager)
00086     {
00087         MythDownloadManager *dlmgr = GetMythDownloadManager();
00088         if (dlmgr)
00089         {
00090             LOG(VB_GENERAL, LOG_DEBUG, "Refreshing DLManager's Cookie Jar");
00091             dlmgr->refreshCookieJar(networkManager->cookieJar());
00092         }
00093 
00094         delete networkManager;
00095         networkManager = NULL;
00096     }
00097 }
00098 
00099 static QNetworkAccessManager *GetNetworkAccessManager(void)
00100 {
00101     if (networkManager)
00102         return networkManager;
00103 
00104     networkManager = new QNetworkAccessManager();
00105     LOG(VB_GENERAL, LOG_DEBUG, "Copying DLManager's Cookie Jar");
00106     networkManager->setCookieJar(GetMythDownloadManager()->copyCookieJar());
00107 
00108     atexit(DestroyNetworkAccessManager);
00109 
00110     return networkManager;
00111 }
00112 
00118 BrowserApi::BrowserApi(QObject *parent) : QObject(parent)
00119 {
00120     gCoreContext->addListener(this);
00121 }
00122 
00123 BrowserApi::~BrowserApi(void)
00124 {
00125     gCoreContext->removeListener(this);
00126 }
00127 
00128 void BrowserApi::setWebView(QWebView *view)
00129 {
00130     QWebPage *page = view->page();
00131     m_frame = page->mainFrame();
00132 
00133     attachObject();
00134     connect(m_frame, SIGNAL(javaScriptWindowObjectCleared()), this,
00135             SLOT(attachObject()));
00136 }
00137 
00138 void BrowserApi::attachObject(void)
00139 {
00140     m_frame->addToJavaScriptWindowObject(QString("MusicPlayer"), this);
00141 }
00142 
00143 void BrowserApi::Play(void)
00144 {
00145     MythEvent me(QString("MUSIC_COMMAND %1 PLAY").arg(gCoreContext->GetHostName()));
00146     gCoreContext->dispatch(me);
00147 }
00148 
00149 void BrowserApi::Stop(void)
00150 {
00151     MythEvent me(QString("MUSIC_COMMAND %1 STOP").arg(gCoreContext->GetHostName()));
00152     gCoreContext->dispatch(me);
00153 }
00154 
00155 void BrowserApi::Pause(void)
00156 {
00157     MythEvent me(QString("MUSIC_COMMAND %1 PAUSE %1").arg(gCoreContext->GetHostName()));
00158     gCoreContext->dispatch(me);
00159 }
00160 
00161 void BrowserApi::SetVolume(int volumn)
00162 {
00163     MythEvent me(QString("MUSIC_COMMAND %1 SET_VOLUME %2")
00164                  .arg(gCoreContext->GetHostName()).arg(volumn));
00165     gCoreContext->dispatch(me);
00166 }
00167 
00168 int BrowserApi::GetVolume(void)
00169 {
00170     m_gotAnswer = false;
00171 
00172     MythEvent me(QString("MUSIC_COMMAND %1 GET_VOLUME")
00173                  .arg(gCoreContext->GetHostName()));
00174     gCoreContext->dispatch(me);
00175 
00176     QTime timer;
00177     timer.start();
00178 
00179     while (timer.elapsed() < 2000  && !m_gotAnswer)
00180     {
00181         qApp->processEvents();
00182         usleep(10000);
00183     }
00184 
00185     if (m_gotAnswer)
00186         return m_answer.toInt();
00187 
00188     return -1;
00189 }
00190 
00191 void BrowserApi::PlayFile(QString filename)
00192 {
00193     MythEvent me(QString("MUSIC_COMMAND %1 PLAY_FILE '%2'")
00194                  .arg(gCoreContext->GetHostName()).arg(filename));
00195     gCoreContext->dispatch(me);
00196 }
00197 
00198 void BrowserApi::PlayTrack(int trackID)
00199 {
00200     MythEvent me(QString("MUSIC_COMMAND %1 PLAY_TRACK %2")
00201                  .arg(gCoreContext->GetHostName()).arg(trackID));
00202     gCoreContext->dispatch(me);
00203 }
00204 
00205 void BrowserApi::PlayURL(QString url)
00206 {
00207     MythEvent me(QString("MUSIC_COMMAND %1 PLAY_URL %2")
00208                  .arg(gCoreContext->GetHostName()).arg(url));
00209     gCoreContext->dispatch(me);
00210 }
00211 
00212 QString BrowserApi::GetMetadata(void)
00213 {
00214     m_gotAnswer = false;
00215 
00216     MythEvent me(QString("MUSIC_COMMAND %1 GET_METADATA")
00217                  .arg(gCoreContext->GetHostName()));
00218     gCoreContext->dispatch(me);
00219 
00220     QTime timer;
00221     timer.start();
00222 
00223     while (timer.elapsed() < 2000  && !m_gotAnswer)
00224     {
00225         qApp->processEvents();
00226         usleep(10000);
00227     }
00228 
00229     if (m_gotAnswer)
00230         return m_answer;
00231 
00232     return QString("unknown");
00233 }
00234 
00235 void BrowserApi::customEvent(QEvent *e)
00236 {
00237     if ((MythEvent::Type)(e->type()) == MythEvent::MythEventMessage)
00238     {
00239         MythEvent *me = (MythEvent *)e;
00240         QString message = me->Message();
00241 
00242         if (message.left(13) != "MUSIC_CONTROL")
00243             return;
00244 
00245         QStringList tokens = message.simplified().split(" ");
00246 
00247         if ((tokens.size() >= 4) && (tokens[1] == "ANSWER")
00248             && (tokens[2] == gCoreContext->GetHostName()))
00249         {
00250             m_answer = tokens[3];
00251 
00252             for (int i = 4; i < tokens.size(); i++)
00253                 m_answer += QString(" ") + tokens[i];
00254 
00255             m_gotAnswer = true;
00256         }
00257     }
00258 }
00259 
00260 MythWebPage::MythWebPage(QObject *parent)
00261             : QWebPage(parent)
00262 {
00263     setNetworkAccessManager(GetNetworkAccessManager());
00264 }
00265 
00266 MythWebPage::~MythWebPage()
00267 {
00268     DestroyNetworkAccessManager();
00269 }
00270 
00271 bool MythWebPage::supportsExtension(Extension extension) const
00272 {
00273     if (extension == QWebPage::ErrorPageExtension)
00274         return true;
00275 
00276     return false;
00277 }
00278 
00279 bool MythWebPage::extension(Extension extension, const ExtensionOption *option,
00280                             ExtensionReturn *output)
00281 {
00282     if (extension == QWebPage::ErrorPageExtension)
00283     {
00284         ErrorPageExtensionOption *erroroption;
00285         erroroption = (ErrorPageExtensionOption *) option;
00286         ErrorPageExtensionReturn *erroroutput;
00287         erroroutput = (ErrorPageExtensionReturn *) output;
00288 
00289         if (!option || !output)
00290             return false;
00291 
00292         QString filename = "htmls/notfound.html";
00293 
00294         if (!GetMythUI()->FindThemeFile(filename))
00295             return false;
00296 
00297         QFile file(QLatin1String(qPrintable(filename)));
00298         bool isOpened = file.open(QIODevice::ReadOnly);
00299 
00300         if (!isOpened)
00301             return false;
00302 
00303         QString title = tr("Error loading page: %1").arg(erroroption->url.toString());
00304         QString html = QString(QLatin1String(file.readAll()))
00305                        .arg(title)
00306                        .arg(erroroption->errorString)
00307                        .arg(erroroption->url.toString());
00308 
00309         QBuffer imageBuffer;
00310         imageBuffer.open(QBuffer::ReadWrite);
00311         QIcon icon = qApp->style()->standardIcon(QStyle::SP_MessageBoxWarning,
00312                                                  0, 0);
00313         QPixmap pixmap = icon.pixmap(QSize(32, 32));
00314 
00315         if (pixmap.save(&imageBuffer, "PNG"))
00316         {
00317             html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"),
00318                          QString(QLatin1String(imageBuffer.buffer().toBase64())));
00319         }
00320 
00321         erroroutput->content = html.toUtf8();
00322 
00323         return true;
00324     }
00325 
00326     return false;
00327 }
00328 
00329 QString MythWebPage::userAgentForUrl(const QUrl &url) const
00330 {
00331     return QWebPage::userAgentForUrl(url).replace("Safari", "MythBrowser");
00332 }
00333 
00339 MythWebView::MythWebView(QWidget *parent, MythUIWebBrowser *parentBrowser)
00340             : QWebView(parent),
00341       m_webpage(new MythWebPage(this))
00342 {
00343     setPage(m_webpage);
00344 
00345     m_parentBrowser = parentBrowser;
00346     m_busyPopup = NULL;
00347 
00348     connect(page(), SIGNAL(unsupportedContent(QNetworkReply *)),
00349             this, SLOT(handleUnsupportedContent(QNetworkReply *)));
00350 
00351     connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)),
00352             this, SLOT(handleDownloadRequested(QNetworkRequest)));
00353 
00354     page()->setForwardUnsupportedContent(true);
00355 
00356     m_api = new BrowserApi(this);
00357     m_api->setWebView(this);
00358 
00359     m_downloadAndPlay = false;
00360     m_downloadReply = NULL;
00361 }
00362 
00363 MythWebView::~MythWebView(void)
00364 {
00365     delete m_webpage;
00366     delete m_api;
00367 }
00368 
00373 const char *kgetType = "\
00374 function activeElement()\
00375 {\
00376     var type;\
00377     type = document.activeElement.type;\
00378     return type;\
00379 }\
00380 activeElement();";
00381 
00382 void MythWebView::keyPressEvent(QKeyEvent *event)
00383 {
00384     // does an edit have focus?
00385     QString type = m_parentBrowser->evaluateJavaScript(QString(kgetType))
00386                                                     .toString().toLower();
00387     bool editHasFocus = (type == "text" || type == "textarea" ||
00388                          type == "password");
00389 
00390     // if the QWebView widget has focus then all keypresses from a regular
00391     // keyboard get sent here first
00392     if (editHasFocus || m_parentBrowser->IsInputToggled())
00393     {
00394         // input is toggled so pass all keypresses to the QWebView's handler
00395         QWebView::keyPressEvent(event);
00396     }
00397     else
00398     {
00399         // we need to convert a few keypress events so the QWebView does the
00400         // right thing
00401         QStringList actions;
00402         bool handled = false;
00403         handled = GetMythMainWindow()->TranslateKeyPress("Browser", event,
00404                                                          actions);
00405 
00406         for (int i = 0; i < actions.size() && !handled; i++)
00407         {
00408             QString action = actions[i];
00409             handled = true;
00410 
00411             if (action == "NEXTLINK")
00412             {
00413                 QKeyEvent tabKey(event->type(), Qt::Key_Tab,
00414                                  event->modifiers(), QString(),
00415                                  event->isAutoRepeat(), event->count());
00416                 *event = tabKey;
00417                 QWebView::keyPressEvent(event);
00418                 return;
00419             }
00420             else if (action == "PREVIOUSLINK")
00421             {
00422                 QKeyEvent shiftTabKey(event->type(), Qt::Key_Tab,
00423                                       event->modifiers() | Qt::ShiftModifier,
00424                                       QString(),
00425                                       event->isAutoRepeat(), event->count());
00426                 *event = shiftTabKey;
00427                 QWebView::keyPressEvent(event);
00428                 return;
00429             }
00430             else if (action == "FOLLOWLINK")
00431             {
00432                 QKeyEvent returnKey(event->type(), Qt::Key_Return,
00433                                     event->modifiers(), QString(),
00434                                     event->isAutoRepeat(), event->count());
00435                 *event = returnKey;
00436                 QWebView::keyPressEvent(event);
00437                 return;
00438             }
00439         }
00440 
00441         // pass the keyPress event to our main window handler so they get
00442         // handled properly by the various mythui handlers
00443         QCoreApplication::postEvent(GetMythMainWindow(), new QKeyEvent(*event));
00444     }
00445 }
00446 
00447 void MythWebView::wheelEvent(QWheelEvent *event)
00448 {
00449     event->accept();
00450     QCoreApplication::postEvent(GetMythMainWindow(), new QWheelEvent(*event));
00451 }
00452 
00453 void MythWebView::handleUnsupportedContent(QNetworkReply *reply)
00454 {
00455     if (reply->error() == QNetworkReply::NoError)
00456     {
00457         stop();
00458 
00459         QVariant header = reply->header(QNetworkRequest::ContentTypeHeader);
00460 
00461         if (header != QVariant())
00462             LOG(VB_GENERAL, LOG_ERR,
00463                 QString("MythWebView::handleUnsupportedContent - %1")
00464                 .arg(header.toString()));
00465 
00466         m_downloadReply = reply;
00467         m_downloadRequest = reply->request();
00468         m_downloadAndPlay = false;
00469         showDownloadMenu();
00470 
00471         return;
00472     }
00473 }
00474 
00475 void  MythWebView::handleDownloadRequested(const QNetworkRequest &request)
00476 {
00477     m_downloadReply = NULL;
00478     doDownloadRequested(request);
00479 }
00480 
00481 void  MythWebView::doDownloadRequested(const QNetworkRequest &request)
00482 {
00483     m_downloadRequest = request;
00484 
00485     // get the filename from the url if available
00486     QFileInfo fi(request.url().path());
00487     QString basename(fi.completeBaseName());
00488     QString extension = fi.suffix().toLower();
00489     QString mimetype = getReplyMimetype();
00490 
00491     // if we have a default filename use that
00492     QString saveBaseName = basename;
00493 
00494     if (!m_parentBrowser->GetDefaultSaveFilename().isEmpty())
00495     {
00496         QFileInfo savefi(m_parentBrowser->GetDefaultSaveFilename());
00497         saveBaseName = savefi.completeBaseName();
00498     }
00499 
00500     // if the filename is still empty use a default name
00501     if (saveBaseName.isEmpty())
00502         saveBaseName = "unnamed_download";
00503 
00504     // if we don't have an extension from the filename get one from the mime type
00505     if (extension.isEmpty())
00506         extension = getExtensionForMimetype(mimetype);
00507 
00508     if (!extension.isEmpty())
00509         extension = '.' + extension;
00510 
00511     QString saveFilename = QString("%1%2%3")
00512                                 .arg(m_parentBrowser->GetDefaultSaveDirectory())
00513                                 .arg(saveBaseName)
00514                                 .arg(extension);
00515 
00516     // dont overwrite an existing file
00517     if (QFile::exists(saveFilename))
00518     {
00519         int i = 1;
00520 
00521         do
00522         {
00523             saveFilename = QString("%1%2-%3%4")
00524                                 .arg(m_parentBrowser->GetDefaultSaveDirectory())
00525                                 .arg(saveBaseName)
00526                                 .arg(QString::number(i++))
00527                                 .arg(extension);
00528         }
00529         while (QFile::exists(saveFilename));
00530     }
00531 
00532     // if we are downloading and then playing the file don't ask for the file name
00533     if (m_downloadAndPlay)
00534     {
00535         doDownload(saveFilename);
00536     }
00537     else
00538     {
00539         MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00540 
00541         QString msg = tr("Enter filename to save file");
00542         MythTextInputDialog *input = new MythTextInputDialog(popupStack, msg,
00543                                                              FilterNone, false,
00544                                                              saveFilename);
00545 
00546         if (input->Create())
00547         {
00548             input->SetReturnEvent(this, "filenamedialog");
00549             popupStack->AddScreen(input);
00550         }
00551         else
00552             delete input;
00553     }
00554 }
00555 
00556 void MythWebView::doDownload(const QString &saveFilename)
00557 {
00558     if (saveFilename.isEmpty())
00559         return;
00560 
00561     openBusyPopup(QObject::tr("Downloading file. Please wait..."));
00562 
00563     // No need to make sure the path to saveFilename exists because
00564     // MythDownloadManage takes care of that
00565     GetMythDownloadManager()->queueDownload(m_downloadRequest.url().toString(),
00566                                             saveFilename, this);
00567 }
00568 
00569 void MythWebView::openBusyPopup(const QString &message)
00570 {
00571     if (m_busyPopup)
00572         return;
00573 
00574     QString msg(tr("Downloading..."));
00575 
00576     if (!message.isEmpty())
00577         msg = message;
00578 
00579     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00580     m_busyPopup = new MythUIBusyDialog(msg, popupStack, "downloadbusydialog");
00581 
00582     if (m_busyPopup->Create())
00583         popupStack->AddScreen(m_busyPopup, false);
00584 }
00585 
00586 void MythWebView::closeBusyPopup(void)
00587 {
00588     if (m_busyPopup)
00589         m_busyPopup->Close();
00590 
00591     m_busyPopup = NULL;
00592 }
00593 
00594 void MythWebView::customEvent(QEvent *event)
00595 {
00596     if (event->type() == DialogCompletionEvent::kEventType)
00597     {
00598         DialogCompletionEvent *dce = (DialogCompletionEvent *)(event);
00599 
00600         // make sure the user didn't ESCAPE out of the dialog
00601         if (dce->GetResult() < 0)
00602             return;
00603 
00604         QString resultid   = dce->GetId();
00605         QString resulttext = dce->GetResultText();
00606 
00607         if (resultid == "filenamedialog")
00608             doDownload(resulttext);
00609         else if (resultid == "downloadmenu")
00610         {
00611             if (resulttext == tr("Play the file"))
00612             {
00613                 QFileInfo fi(m_downloadRequest.url().path());
00614                 QString basename(fi.baseName());
00615                 QString extension = fi.suffix();
00616                 QString mimeType = getReplyMimetype();
00617 
00618                 if (isMusicFile(extension, mimeType))
00619                 {
00620                     MythEvent me(QString("MUSIC_COMMAND %1 PLAY_URL %2")
00621                                  .arg(gCoreContext->GetHostName())
00622                                  .arg(m_downloadRequest.url().toString()));
00623                     gCoreContext->dispatch(me);
00624                 }
00625                 else if (isVideoFile(extension, mimeType))
00626                     GetMythMainWindow()->HandleMedia("Internal",
00627                                             m_downloadRequest.url().toString());
00628                 else
00629                     LOG(VB_GENERAL, LOG_ERR,
00630                         QString("MythWebView: Asked to play a file with "
00631                                 "extension '%1' but don't know how")
00632                         .arg(extension));
00633             }
00634             else if (resulttext == tr("Download the file"))
00635             {
00636                 doDownloadRequested(m_downloadRequest);
00637             }
00638             else if (resulttext == tr("Download and play the file"))
00639             {
00640                 m_downloadAndPlay = true;
00641                 doDownloadRequested(m_downloadRequest);
00642             }
00643         }
00644     }
00645     else if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage)
00646     {
00647         MythEvent *me = (MythEvent *)event;
00648         QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts);
00649 
00650         if (tokens.isEmpty())
00651             return;
00652 
00653         if (tokens[0] == "DOWNLOAD_FILE")
00654         {
00655             QStringList args = me->ExtraDataList();
00656 
00657             if (tokens[1] == "UPDATE")
00658             {
00659                 // could update a progressbar here
00660             }
00661             else if (tokens[1] == "FINISHED")
00662             {
00663                 int fileSize  = args[2].toInt();
00664                 int errorCode = args[4].toInt();
00665                 QString filename = args[1];
00666 
00667                 closeBusyPopup();
00668 
00669                 if ((errorCode != 0) || (fileSize == 0))
00670                     ShowOkPopup(tr("ERROR downloading file."));
00671                 else if (m_downloadAndPlay)
00672                     GetMythMainWindow()->HandleMedia("Internal", filename);
00673 
00674                 MythEvent me(QString("BROWSER_DOWNLOAD_FINISHED"), args);
00675                 gCoreContext->dispatch(me);
00676             }
00677         }
00678     }
00679 }
00680 
00681 void MythWebView::showDownloadMenu(void)
00682 {
00683     QFileInfo fi(m_downloadRequest.url().path());
00684     QString basename(fi.baseName());
00685     QString extension = fi.suffix();
00686     QString mimeType = getReplyMimetype();
00687 
00688     QString label = tr("What do you want to do with this file?");
00689 
00690     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00691 
00692     MythDialogBox *menu = new MythDialogBox(label, popupStack, "downloadmenu");
00693 
00694     if (!menu->Create())
00695     {
00696         delete menu;
00697         return;
00698     }
00699 
00700     menu->SetReturnEvent(this, "downloadmenu");
00701 
00702     if (isMusicFile(extension, mimeType))
00703         menu->AddButton(tr("Play the file"));
00704 
00705     if (isVideoFile(extension, mimeType))
00706         menu->AddButton(tr("Download and play the file"));
00707 
00708     menu->AddButton(tr("Download the file"));
00709     menu->AddButton(tr("Cancel"));
00710 
00711     popupStack->AddScreen(menu);
00712 }
00713 
00714 QString MythWebView::getExtensionForMimetype(const QString &mimetype)
00715 {
00716     for (int x = 0; x < SupportedMimeTypesCount; x++)
00717     {
00718         if (!mimetype.isEmpty() && mimetype == SupportedMimeTypes[x].mimeType)
00719             return SupportedMimeTypes[x].extension;
00720     }
00721 
00722     return QString("");
00723 }
00724 
00725 bool MythWebView::isMusicFile(const QString &extension, const QString &mimetype)
00726 {
00727     for (int x = 0; x < SupportedMimeTypesCount; x++)
00728     {
00729         if (!SupportedMimeTypes[x].isVideo)
00730         {
00731             if (!mimetype.isEmpty() &&
00732                 mimetype == SupportedMimeTypes[x].mimeType)
00733                 return true;
00734 
00735             if (!extension.isEmpty() &&
00736                 extension.toLower() == SupportedMimeTypes[x].extension)
00737                 return true;
00738         }
00739     }
00740 
00741     return false;
00742 }
00743 
00744 bool MythWebView::isVideoFile(const QString &extension, const QString &mimetype)
00745 {
00746     for (int x = 0; x < SupportedMimeTypesCount; x++)
00747     {
00748         if (SupportedMimeTypes[x].isVideo)
00749         {
00750             if (!mimetype.isEmpty() &&
00751                 mimetype == SupportedMimeTypes[x].mimeType)
00752                 return true;
00753 
00754             if (!extension.isEmpty() &&
00755                 extension.toLower() == SupportedMimeTypes[x].extension)
00756                 return true;
00757         }
00758     }
00759 
00760     return false;
00761 }
00762 
00763 QString MythWebView::getReplyMimetype(void)
00764 {
00765     if (!m_downloadReply)
00766         return QString();
00767 
00768     QString mimeType;
00769     QVariant header = m_downloadReply->header(QNetworkRequest::ContentTypeHeader);
00770 
00771     if (header != QVariant())
00772         mimeType = header.toString();
00773 
00774     return mimeType;
00775 }
00776 
00777 QWebView *MythWebView::createWindow(QWebPage::WebWindowType type)
00778 {
00779     (void) type;
00780     return (QWebView *) this;
00781 }
00782 
00783 
00825 MythUIWebBrowser::MythUIWebBrowser(MythUIType *parent, const QString &name)
00826                  : MythUIType(parent, name),
00827       m_parentScreen(NULL),
00828       m_browser(NULL),       m_image(NULL),
00829       m_active(false),       m_wasActive(false),
00830       m_initialized(false),  m_lastUpdateTime(QTime()),
00831       m_updateInterval(0),   m_zoom(1.0),
00832       m_bgColor("White"),    m_widgetUrl(QUrl()), m_userCssFile(""),
00833       m_defaultSaveDir(GetConfDir() + "/MythBrowser/"),
00834       m_defaultSaveFilename(""),
00835       m_inputToggled(false), m_lastMouseAction(""),
00836       m_mouseKeyCount(0),    m_lastMouseActionTime(),
00837       m_horizontalScrollbar(NULL), m_verticalScrollbar(NULL)
00838 {
00839     SetCanTakeFocus(true);
00840     m_scrollAnimation.setDuration(0);
00841 }
00842 
00846 void MythUIWebBrowser::Finalize(void)
00847 {
00848     Init();
00849     MythUIType::Finalize();
00850 }
00851 
00859 void MythUIWebBrowser::Init(void)
00860 {
00861     if (m_initialized)
00862         return;
00863 
00864     if (!m_browserArea.isValid())
00865         m_browserArea = m_Area;
00866 
00867     m_browser = new MythWebView(GetMythMainWindow()->GetPaintWindow(), this);
00868     m_browser->setPalette(qApp->style()->standardPalette());
00869     m_browser->setGeometry(m_browserArea);
00870     m_browser->setFixedSize(m_browserArea.size());
00871     m_browser->move(m_browserArea.x(), m_browserArea.y());
00872     m_browser->page()->setLinkDelegationPolicy(QWebPage::DontDelegateLinks);
00873 
00874     bool err = false;
00875     UIUtilW::Assign(this, m_horizontalScrollbar, "horizscrollbar", &err);
00876     UIUtilW::Assign(this, m_verticalScrollbar, "vertscrollbar", &err);
00877     if (m_horizontalScrollbar)
00878     {
00879         QWebFrame* frame = m_browser->page()->currentFrame();
00880         frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
00881     }
00882 
00883     if (m_verticalScrollbar)
00884     {
00885         QWebFrame* frame = m_browser->page()->currentFrame();
00886         frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
00887     }
00888 
00889     // if we have a valid css URL use that ...
00890     if (!m_userCssFile.isEmpty())
00891     {
00892         QString filename = m_userCssFile;
00893 
00894         if (GetMythUI()->FindThemeFile(filename))
00895             LoadUserStyleSheet(QUrl("file://" + filename));
00896     }
00897     else
00898     {
00899         // ...otherwise use the default one
00900         QString filename = "htmls/mythbrowser.css";
00901 
00902         if (GetMythUI()->FindThemeFile(filename))
00903             LoadUserStyleSheet(QUrl("file://" + filename));
00904     }
00905 
00906     m_browser->winId();
00907 
00908     SetActive(m_active);
00909 
00910     connect(m_browser, SIGNAL(loadStarted()),
00911             this, SLOT(slotLoadStarted()));
00912     connect(m_browser, SIGNAL(loadFinished(bool)),
00913             this, SLOT(slotLoadFinished(bool)));
00914     connect(m_browser, SIGNAL(loadProgress(int)),
00915             this, SLOT(slotLoadProgress(int)));
00916     connect(m_browser, SIGNAL(titleChanged(const QString &)),
00917             this, SLOT(slotTitleChanged(const QString &)));
00918     connect(m_browser, SIGNAL(iconChanged(void)),
00919             this, SLOT(slotIconChanged(void)));
00920     connect(m_browser, SIGNAL(statusBarMessage(const QString &)),
00921             this, SLOT(slotStatusBarMessage(const QString &)));
00922     connect(m_browser->page(), SIGNAL(linkHovered(const QString &,
00923                                                   const QString &,
00924                                                   const QString &)),
00925             this, SLOT(slotStatusBarMessage(const QString &)));
00926     connect(m_browser, SIGNAL(linkClicked(const QUrl &)),
00927             this, SLOT(slotLinkClicked(const QUrl &)));
00928 
00929     // find what screen we are on
00930     m_parentScreen = NULL;
00931     QObject *parentObject = parent();
00932 
00933     while (parentObject)
00934     {
00935         m_parentScreen = dynamic_cast<MythScreenType *>(parentObject);
00936 
00937         if (m_parentScreen)
00938             break;
00939 
00940         parentObject = parentObject->parent();
00941     }
00942 
00943     if (!m_parentScreen)
00944         LOG(VB_GENERAL, LOG_ERR,
00945             "MythUIWebBrowser: failed to find our parent screen");
00946 
00947     // connect to the topScreenChanged signals on each screen stack
00948     for (int x = 0; x < GetMythMainWindow()->GetStackCount(); x++)
00949     {
00950         MythScreenStack *stack = GetMythMainWindow()->GetStackAt(x);
00951 
00952         if (stack)
00953             connect(stack, SIGNAL(topScreenChanged(MythScreenType *)),
00954                     this, SLOT(slotTopScreenChanged(MythScreenType *)));
00955     }
00956 
00957     // set up the icon cache directory
00958     QString path = GetConfDir();
00959     QDir dir(path);
00960 
00961     if (!dir.exists())
00962         dir.mkdir(path);
00963 
00964     path += "/MythBrowser";
00965     dir.setPath(path);
00966 
00967     if (!dir.exists())
00968         dir.mkdir(path);
00969 
00970     QWebSettings::setIconDatabasePath(path);
00971 
00972     if (gCoreContext->GetNumSetting("WebBrowserEnablePlugins", 1) == 1)
00973     {
00974         LOG(VB_GENERAL, LOG_INFO, "MythUIWebBrowser: enabling plugins");
00975         QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,
00976                                                      true);
00977     }
00978     else
00979     {
00980         LOG(VB_GENERAL, LOG_INFO, "MythUIWebBrowser: disabling plugins");
00981         QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,
00982                                                      false);
00983     }
00984 
00985     QImage image = QImage(m_browserArea.size(), QImage::Format_ARGB32);
00986     m_image = GetPainter()->GetFormatImage();
00987     m_image->Assign(image);
00988 
00989     SetBackgroundColor(m_bgColor);
00990     SetZoom(m_zoom);
00991 
00992     if (!m_widgetUrl.isEmpty() && m_widgetUrl.isValid())
00993         LoadPage(m_widgetUrl);
00994 
00995     m_initialized = true;
00996 }
00997 
01001 MythUIWebBrowser::~MythUIWebBrowser()
01002 {
01003     if (m_browser)
01004     {
01005         m_browser->hide();
01006         m_browser->disconnect();
01007         m_browser->deleteLater();
01008         m_browser = NULL;
01009     }
01010 
01011     if (m_image)
01012     {
01013         m_image->DownRef();
01014         m_image = NULL;
01015     }
01016 }
01017 
01022 void MythUIWebBrowser::LoadPage(QUrl url)
01023 {
01024     if (!m_browser)
01025         return;
01026 
01027     ResetScrollBars();
01028 
01029     m_browser->setUrl(url);
01030 }
01031 
01038 void MythUIWebBrowser::SetHtml(const QString &html, const QUrl &baseUrl)
01039 {
01040     if (!m_browser)
01041         return;
01042 
01043     ResetScrollBars();
01044 
01045     m_browser->setHtml(html, baseUrl);
01046 }
01047 
01052 void MythUIWebBrowser::LoadUserStyleSheet(QUrl url)
01053 {
01054     if (!m_browser)
01055         return;
01056 
01057     LOG(VB_GENERAL, LOG_INFO,
01058         "MythUIWebBrowser: Loading css from - " + url.toString());
01059 
01060     m_browser->page()->settings()->setUserStyleSheetUrl(url);
01061 }
01062 
01069 void MythUIWebBrowser::SetBackgroundColor(QColor color)
01070 {
01071     if (!m_browser)
01072         return;
01073 
01074     color.setAlpha(255);
01075     QPalette palette = m_browser->page()->palette();
01076     palette.setBrush(QPalette::Window, QBrush(color));
01077     palette.setBrush(QPalette::Base, QBrush(color));
01078     m_browser->page()->setPalette(palette);
01079 
01080     UpdateBuffer();
01081 }
01082 
01093 void MythUIWebBrowser::SetActive(bool active)
01094 {
01095     if (m_active == active)
01096         return;
01097 
01098     m_active = active;
01099     m_wasActive = active;
01100 
01101     if (m_active)
01102     {
01103         m_browser->setUpdatesEnabled(false);
01104         m_browser->setFocus();
01105         m_browser->show();
01106         m_browser->raise();
01107         m_browser->setUpdatesEnabled(true);
01108     }
01109     else
01110     {
01111         m_browser->clearFocus();
01112         m_browser->hide();
01113         UpdateBuffer();
01114     }
01115 }
01116 
01120 void MythUIWebBrowser::ZoomIn(void)
01121 {
01122     SetZoom(m_zoom + 0.1);
01123 }
01124 
01128 void MythUIWebBrowser::ZoomOut(void)
01129 {
01130     SetZoom(m_zoom - 0.1);
01131 }
01132 
01137 void MythUIWebBrowser::SetZoom(float zoom)
01138 {
01139     if (!m_browser)
01140         return;
01141 
01142     m_zoom = zoom;
01143     m_browser->setZoomFactor(m_zoom);
01144     ResetScrollBars();
01145     UpdateBuffer();
01146 }
01147 
01148 void MythUIWebBrowser::SetDefaultSaveDirectory(const QString &saveDir)
01149 {
01150     if (!saveDir.isEmpty())
01151         m_defaultSaveDir = saveDir;
01152     else
01153         m_defaultSaveDir = GetConfDir() + "/MythBrowser/";
01154 }
01155 
01156 void MythUIWebBrowser::SetDefaultSaveFilename(const QString &filename)
01157 {
01158     if (!filename.isEmpty())
01159         m_defaultSaveFilename = filename;
01160     else
01161         m_defaultSaveFilename.clear();
01162 }
01163 
01168 float MythUIWebBrowser::GetZoom(void)
01169 {
01170     return m_zoom;
01171 }
01172 
01178 bool MythUIWebBrowser::CanGoForward(void)
01179 {
01180     if (!m_browser)
01181         return false;
01182 
01183     return m_browser->history()->canGoForward();
01184 }
01185 
01191 bool MythUIWebBrowser::CanGoBack(void)
01192 {
01193     if (!m_browser)
01194         return false;
01195 
01196     return m_browser->history()->canGoBack();
01197 }
01198 
01202 void MythUIWebBrowser::Back(void)
01203 {
01204     if (!m_browser)
01205         return;
01206 
01207     m_browser->back();
01208 }
01209 
01213 void MythUIWebBrowser::Forward(void)
01214 {
01215     if (!m_browser)
01216         return;
01217 
01218     m_browser->forward();
01219 }
01220 
01225 QIcon MythUIWebBrowser::GetIcon(void)
01226 {
01227     if (m_browser)
01228     {
01229         return QWebSettings::iconForUrl(m_browser->url());
01230     }
01231     else
01232         return QIcon();
01233 }
01234 
01239 QUrl MythUIWebBrowser::GetUrl(void)
01240 {
01241     if (m_browser)
01242     {
01243         return m_browser->url();
01244     }
01245     else
01246         return QUrl();
01247 }
01248 
01253 QString MythUIWebBrowser::GetTitle(void)
01254 {
01255     if (m_browser)
01256         return m_browser->title();
01257     else
01258         return QString("");
01259 }
01260 
01265 QVariant MythUIWebBrowser::evaluateJavaScript(const QString &scriptSource)
01266 {
01267     if (m_browser)
01268     {
01269         QWebFrame *frame = m_browser->page()->currentFrame();
01270         return frame->evaluateJavaScript(scriptSource);
01271     }
01272     else
01273         return QVariant();
01274 }
01275 
01276 void MythUIWebBrowser::Scroll(int dx, int dy)
01277 {
01278     QPoint startPos = m_browser->page()->currentFrame()->scrollPosition();
01279     QPoint endPos = startPos + QPoint(dx, dy);
01280 
01281     if (GetPainter()->SupportsAnimation() && m_scrollAnimation.duration() > 0)
01282     {
01283         // Previous scroll has been completed
01284         if (m_destinationScrollPos == startPos)
01285             m_scrollAnimation.setEasingCurve(QEasingCurve::InOutCubic);
01286         else
01287             m_scrollAnimation.setEasingCurve(QEasingCurve::OutCubic);
01288 
01289         m_destinationScrollPos = endPos;
01290         m_scrollAnimation.setStartValue(startPos);
01291         m_scrollAnimation.setEndValue(m_destinationScrollPos);
01292         m_scrollAnimation.Activate();
01293     }
01294     else
01295     {
01296         m_destinationScrollPos = endPos;
01297         m_browser->page()->currentFrame()->setScrollPosition(endPos);
01298         UpdateBuffer();
01299     }
01300 }
01301 
01302 void MythUIWebBrowser::slotLoadStarted(void)
01303 {
01304     ResetScrollBars();
01305     emit loadStarted();
01306 }
01307 
01308 void MythUIWebBrowser::slotLoadFinished(bool ok)
01309 {
01310     UpdateBuffer();
01311     emit loadFinished(ok);
01312 }
01313 
01314 void MythUIWebBrowser::slotLoadProgress(int progress)
01315 {
01316     emit loadProgress(progress);
01317 }
01318 
01319 void MythUIWebBrowser::slotTitleChanged(const QString &title)
01320 {
01321     emit titleChanged(title);
01322 }
01323 
01324 void MythUIWebBrowser::slotStatusBarMessage(const QString &text)
01325 {
01326     emit statusBarMessage(text);
01327 }
01328 
01329 void MythUIWebBrowser::slotLinkClicked(const QUrl &url)
01330 {
01331     LoadPage(url);
01332 }
01333 
01334 void MythUIWebBrowser::slotIconChanged(void)
01335 {
01336     emit iconChanged();
01337 }
01338 
01339 void MythUIWebBrowser::slotTopScreenChanged(MythScreenType *screen)
01340 {
01341     (void) screen;
01342 
01343     if (!m_parentScreen)
01344         return;
01345 
01346     // is our containing screen the top screen?
01347     for (int x = GetMythMainWindow()->GetStackCount() - 1; x >= 0; x--)
01348     {
01349         MythScreenStack *stack = GetMythMainWindow()->GetStackAt(x);
01350 
01351         // ignore stacks with no screens on them
01352         if (!stack->GetTopScreen())
01353             continue;
01354 
01355         if (stack->GetTopScreen() == m_parentScreen)
01356         {
01357             SetActive(m_wasActive);
01358             break;
01359         }
01360         else
01361         {
01362             bool wasActive = (m_wasActive | m_active);
01363             SetActive(false);
01364             m_wasActive = wasActive;
01365             break;
01366         }
01367     }
01368 }
01369 
01370 
01371 void MythUIWebBrowser::UpdateScrollBars(void)
01372 {
01373     QPoint position = m_browser->page()->currentFrame()->scrollPosition();
01374     if (m_verticalScrollbar)
01375     {
01376         int maximum =
01377             m_browser->page()->currentFrame()->contentsSize().height() -
01378             m_browserArea.height();
01379         m_verticalScrollbar->SetMaximum(maximum);
01380         m_verticalScrollbar->SetPageStep(m_browserArea.height());
01381         m_verticalScrollbar->SetSliderPosition(position.y());
01382     }
01383 
01384     if (m_horizontalScrollbar)
01385     {
01386         int maximum =
01387             m_browser->page()->currentFrame()->contentsSize().width() -
01388             m_browserArea.width();
01389         m_horizontalScrollbar->SetMaximum(maximum);
01390         m_horizontalScrollbar->SetPageStep(m_browserArea.width());
01391         m_horizontalScrollbar->SetSliderPosition(position.x());
01392     }
01393 }
01394 
01395 void MythUIWebBrowser::UpdateBuffer(void)
01396 {
01397     UpdateScrollBars();
01398 
01399     if (!m_active || (m_active && !m_browser->hasFocus()))
01400     {
01401         QPainter painter(m_image);
01402         m_browser->render(&painter);
01403         painter.end();
01404 
01405         m_image->SetChanged();
01406         Refresh();
01407     }
01408 }
01409 
01413 void MythUIWebBrowser::Pulse(void)
01414 {
01415     if (m_scrollAnimation.IsActive() &&
01416         m_destinationScrollPos !=
01417         m_browser->page()->currentFrame()->scrollPosition())
01418     {
01419         m_scrollAnimation.IncrementCurrentTime();
01420 
01421         QPoint scrollPosition = m_scrollAnimation.currentValue().toPoint();
01422         m_browser->page()->currentFrame()->setScrollPosition(scrollPosition);
01423 
01424         SetRedraw();
01425         UpdateBuffer();
01426     }
01427     else if (m_updateInterval && m_lastUpdateTime.elapsed() > m_updateInterval)
01428     {
01429         UpdateBuffer();
01430         m_lastUpdateTime.start();
01431     }
01432 
01433     MythUIType::Pulse();
01434 }
01435 
01439 void MythUIWebBrowser::DrawSelf(MythPainter *p, int xoffset, int yoffset,
01440                                 int alphaMod, QRect clipRegion)
01441 {
01442     if (!m_image || m_image->isNull() || !m_browser || m_browser->hasFocus())
01443         return;
01444 
01445     QRect area = m_browserArea;
01446     area.translate(xoffset, yoffset);
01447 
01448     p->DrawImage(area.x(), area.y(), m_image, alphaMod);
01449 }
01450 
01454 bool MythUIWebBrowser::keyPressEvent(QKeyEvent *event)
01455 {
01456     QStringList actions;
01457     bool handled = false;
01458     handled = GetMythMainWindow()->TranslateKeyPress("Browser", event, actions);
01459 
01460     for (int i = 0; i < actions.size() && !handled; i++)
01461     {
01462         QString action = actions[i];
01463         handled = true;
01464 
01465         if (action == "TOGGLEINPUT")
01466         {
01467             m_inputToggled = !m_inputToggled;
01468             return true;
01469         }
01470 
01471         // if input is toggled all input goes to the web page
01472         if (m_inputToggled)
01473         {
01474             m_browser->keyPressEvent(event);
01475             return true;
01476         }
01477 
01478         QWebFrame *frame = m_browser->page()->currentFrame();
01479         if (action == "UP")
01480         {
01481             int pos = frame->scrollPosition().y();
01482 
01483             if (pos > 0)
01484             {
01485                 Scroll(0, -m_browserArea.height() / 10);
01486             }
01487             else
01488                 handled = false;
01489         }
01490         else if (action == "DOWN")
01491         {
01492             int pos = frame->scrollPosition().y();
01493             QSize maximum = frame->contentsSize() - m_browserArea.size();
01494 
01495             if (pos != maximum.height())
01496             {
01497                 Scroll(0, m_browserArea.height() / 10);
01498             }
01499             else
01500                 handled = false;
01501         }
01502         else if (action == "LEFT")
01503         {
01504             int pos = frame->scrollPosition().x();
01505 
01506             if (pos > 0)
01507             {
01508                 Scroll(-m_browserArea.width() / 10, 0);
01509             }
01510             else
01511                 handled = false;
01512         }
01513         else if (action == "RIGHT")
01514         {
01515             int pos = frame->scrollPosition().x();
01516             QSize maximum = frame->contentsSize() - m_browserArea.size();
01517 
01518             if (pos != maximum.width())
01519             {
01520                 Scroll(m_browserArea.width() / 10, 0);
01521             }
01522             else
01523                 handled = false;
01524         }
01525         else if (action == "PAGEUP")
01526         {
01527             Scroll(0, -m_browserArea.height());
01528         }
01529         else if (action == "PAGEDOWN")
01530         {
01531             Scroll(0, m_browserArea.height());
01532         }
01533         else if (action == "ZOOMIN")
01534         {
01535             ZoomIn();
01536         }
01537         else if (action == "ZOOMOUT")
01538         {
01539             ZoomOut();
01540         }
01541         else if (action == "MOUSEUP" || action == "MOUSEDOWN" ||
01542                  action == "MOUSELEFT" || action == "MOUSERIGHT" ||
01543                  action == "MOUSELEFTBUTTON")
01544         {
01545             HandleMouseAction(action);
01546         }
01547         else if (action == "PAGELEFT")
01548         {
01549             Scroll(-m_browserArea.width(), 0);
01550         }
01551         else if (action == "PAGERIGHT")
01552         {
01553             Scroll(m_browserArea.width(), 0);
01554         }
01555         else if (action == "NEXTLINK")
01556         {
01557             m_browser->keyPressEvent(event);
01558         }
01559         else if (action == "PREVIOUSLINK")
01560         {
01561             m_browser->keyPressEvent(event);
01562         }
01563         else if (action == "FOLLOWLINK")
01564         {
01565             m_browser->keyPressEvent(event);
01566         }
01567         else if (action == "HISTORYBACK")
01568         {
01569             Back();
01570         }
01571         else if (action == "HISTORYFORWARD")
01572         {
01573             Forward();
01574         }
01575         else
01576             handled = false;
01577     }
01578 
01579     return handled;
01580 }
01581 
01582 void MythUIWebBrowser::HandleMouseAction(const QString &action)
01583 {
01584     int step = 5;
01585 
01586     // speed up mouse movement if the same key is held down
01587     if (action == m_lastMouseAction &&
01588         m_lastMouseActionTime.msecsTo(QTime::currentTime()) < 500)
01589     {
01590         m_lastMouseActionTime = QTime::currentTime();
01591         m_mouseKeyCount++;
01592 
01593         if (m_mouseKeyCount > 5)
01594             step = 25;
01595     }
01596     else
01597     {
01598         m_lastMouseAction = action;
01599         m_lastMouseActionTime = QTime::currentTime();
01600         m_mouseKeyCount = 1;
01601     }
01602 
01603     if (action == "MOUSEUP")
01604     {
01605         QPoint curPos = QCursor::pos();
01606         QCursor::setPos(curPos.x(), curPos.y() - step);
01607     }
01608     else if (action == "MOUSELEFT")
01609     {
01610         QPoint curPos = QCursor::pos();
01611         QCursor::setPos(curPos.x() - step, curPos.y());
01612     }
01613     else if (action == "MOUSERIGHT")
01614     {
01615         QPoint curPos = QCursor::pos();
01616         QCursor::setPos(curPos.x() + step, curPos.y());
01617     }
01618     else if (action == "MOUSEDOWN")
01619     {
01620         QPoint curPos = QCursor::pos();
01621         QCursor::setPos(curPos.x(), curPos.y() + step);
01622     }
01623     else if (action == "MOUSELEFTBUTTON")
01624     {
01625         QPoint curPos = QCursor::pos();
01626         QWidget *widget = QApplication::widgetAt(curPos);
01627 
01628         if (widget)
01629         {
01630             curPos = widget->mapFromGlobal(curPos);
01631 
01632             QMouseEvent *me = new QMouseEvent(QEvent::MouseButtonPress, curPos,
01633                                               Qt::LeftButton, Qt::LeftButton,
01634                                               Qt::NoModifier);
01635             QCoreApplication::postEvent(widget, me);
01636 
01637             me = new QMouseEvent(QEvent::MouseButtonRelease, curPos,
01638                                  Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
01639             QCoreApplication::postEvent(widget, me);
01640         }
01641     }
01642 }
01643 
01644 void MythUIWebBrowser::ResetScrollBars()
01645 {
01646     if (m_verticalScrollbar)
01647     {
01648         m_verticalScrollbar->Reset();
01649         m_verticalScrollbar->Hide();
01650     }
01651 
01652     if (m_horizontalScrollbar)
01653     {
01654         m_horizontalScrollbar->Reset();
01655         m_horizontalScrollbar->Hide();
01656     }
01657 }
01658 
01662 bool MythUIWebBrowser::ParseElement(
01663     const QString &filename, QDomElement &element, bool showWarnings)
01664 {
01665     if (element.tagName() == "zoom")
01666     {
01667         QString zoom = getFirstText(element);
01668         m_zoom = zoom.toFloat();
01669     }
01670     else if (element.tagName() == "url")
01671     {
01672         m_widgetUrl.setUrl(getFirstText(element));
01673     }
01674     else if (element.tagName() == "userstylesheet")
01675     {
01676         m_userCssFile = getFirstText(element);
01677     }
01678     else if (element.tagName() == "updateinterval")
01679     {
01680         QString interval = getFirstText(element);
01681         m_updateInterval = interval.toInt();
01682     }
01683     else if (element.tagName() == "background")
01684     {
01685         m_bgColor = QColor(element.attribute("color", "#ffffff"));
01686         int alpha = element.attribute("alpha", "255").toInt();
01687         m_bgColor.setAlpha(alpha);
01688     }
01689     else if (element.tagName() == "browserarea")
01690     {
01691         m_browserArea = parseRect(element);
01692     }
01693     else if (element.tagName() == "scrollduration")
01694     {
01695         QString duration = getFirstText(element);
01696         m_scrollAnimation.setDuration(duration.toInt());
01697     }
01698     else
01699     {
01700         return MythUIType::ParseElement(filename, element, showWarnings);
01701     }
01702 
01703     return true;
01704 }
01705 
01709 void MythUIWebBrowser::CopyFrom(MythUIType *base)
01710 {
01711     MythUIWebBrowser *browser = dynamic_cast<MythUIWebBrowser *>(base);
01712 
01713     if (!browser)
01714     {
01715         LOG(VB_GENERAL, LOG_ERR, "ERROR, bad parsing");
01716         return;
01717     }
01718 
01719     MythUIType::CopyFrom(base);
01720 
01721     m_zoom = browser->m_zoom;
01722     m_bgColor = browser->m_bgColor;
01723     m_widgetUrl = browser->m_widgetUrl;
01724     m_userCssFile = browser->m_userCssFile;
01725     m_updateInterval = browser->m_updateInterval;
01726     m_defaultSaveDir = browser->m_defaultSaveDir;
01727     m_defaultSaveFilename = browser->m_defaultSaveFilename;
01728     m_scrollAnimation.setDuration(browser->m_scrollAnimation.duration());
01729 
01730     Init();
01731 }
01732 
01736 void MythUIWebBrowser::CreateCopy(MythUIType *parent)
01737 {
01738     MythUIWebBrowser *browser = new MythUIWebBrowser(parent, objectName());
01739     browser->CopyFrom(this);
01740 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends