|
MythTV
0.26-pre
|
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 }
1.7.6.1