MythTV  master
mythuiwebbrowser.cpp
Go to the documentation of this file.
1 
7 #include "mythuiwebbrowser.h"
8 
9 // c++
10 #include <algorithm>
11 #include <chrono> // for milliseconds
12 #include <thread> // for sleep_for
13 
14 // qt
15 #include <QApplication>
16 #include <QWebFrame>
17 #include <QWebHistory>
18 #include <QPainter>
19 #include <QDir>
20 #include <QBuffer>
21 #include <QStyle>
22 #include <QKeyEvent>
23 #include <QDomDocument>
24 #include <QNetworkCookieJar>
25 #include <QNetworkConfiguration>
26 
27 // libmythbase
29 #include "libmythbase/mythdb.h"
30 #include "libmythbase/mythdirs.h"
33 
34 //libmythui
35 #include "mythpainter.h"
36 #include "mythimage.h"
37 #include "mythmainwindow.h"
38 #include "mythfontproperties.h"
39 #include "mythuihelper.h"
40 #include "mythdialogbox.h"
41 #include "mythprogressdialog.h"
42 #include "mythuiscrollbar.h"
43 
44 struct MimeType
45 {
46  QString m_mimeType;
47  QString m_extension;
48  bool m_isVideo;
49 };
50 
51 static const std::vector<MimeType> SupportedMimeTypes
52 {
53  { "audio/mpeg3", "mp3", false },
54  { "audio/x-mpeg-3", "mp3", false },
55  { "audio/mpeg", "mp2", false },
56  { "audio/x-mpeg", "mp2", false },
57  { "audio/ogg", "ogg", false },
58  { "audio/ogg", "oga", false },
59  { "audio/flac", "flac", false },
60  { "audio/x-ms-wma", "wma", false },
61  { "audio/wav", "wav", false },
62  { "audio/x-wav", "wav", false },
63  { "audio/ac3", "ac3", false },
64  { "audio/x-ac3", "ac3", false },
65  { "audio/x-oma", "oma", false },
66  { "audio/x-realaudio", "ra", false },
67  { "audio/dts", "dts", false },
68  { "audio/x-dts", "dts", false },
69  { "audio/aac", "aac", false },
70  { "audio/x-aac", "aac", false },
71  { "audio/m4a", "m4a", false },
72  { "audio/x-m4a", "m4a", false },
73  { "video/mpeg", "mpg", true },
74  { "video/mpeg", "mpeg", true },
75  { "video/x-ms-wmv", "wmv", true },
76  { "video/x-ms-wmv", "avi", true },
77  { "application/x-troff-msvideo", "avi", true },
78  { "video/avi", "avi", true },
79  { "video/msvideo", "avi", true },
80  { "video/x-msvideo", "avi", true }
81 };
82 
83 QNetworkReply* MythNetworkAccessManager::createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData)
84 {
85  QNetworkReply* reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
86  reply->ignoreSslErrors();
87  return reply;
88 }
89 
91 
92 static void DestroyNetworkAccessManager(void)
93 {
94  if (networkManager)
95  {
96  delete networkManager;
97  networkManager = nullptr;
98  }
99 }
100 
101 static QNetworkAccessManager *GetNetworkAccessManager(void)
102 {
103  if (networkManager)
104  return networkManager;
105 
107 // This next line prevents seg fault at program exit in
108 // QNetworkConfiguration::~QNetworkConfiguration()
109 // when destructor is called by DestroyNetworkAccessManager
110  networkManager->setConfiguration(networkManager->configuration());
111  LOG(VB_GENERAL, LOG_DEBUG, "Copying DLManager's Cookie Jar");
112  GetMythDownloadManager()->loadCookieJar(GetConfDir() + "/MythBrowser/cookiejar.txt");
113  networkManager->setCookieJar(GetMythDownloadManager()->copyCookieJar());
114 
116 
117  return networkManager;
118 }
119 
125 BrowserApi::BrowserApi(QObject *parent)
126  : QObject(parent)
127 {
128  gCoreContext->addListener(this);
129 }
130 
132 {
134 }
135 
136 void BrowserApi::setWebView(QWebView *view)
137 {
138  QWebPage *page = view->page();
139  m_frame = page->mainFrame();
140 
141  attachObject();
142  connect(m_frame, &QWebFrame::javaScriptWindowObjectCleared, this,
144 }
145 
147 {
148  m_frame->addToJavaScriptWindowObject(QString("MusicPlayer"), this);
149 }
150 
152 {
153  MythEvent me(QString("MUSIC_COMMAND %1 PLAY").arg(gCoreContext->GetHostName()));
154  gCoreContext->dispatch(me);
155 }
156 
158 {
159  MythEvent me(QString("MUSIC_COMMAND %1 STOP").arg(gCoreContext->GetHostName()));
160  gCoreContext->dispatch(me);
161 }
162 
164 {
165  MythEvent me(QString("MUSIC_COMMAND %1 PAUSE %1").arg(gCoreContext->GetHostName()));
166  gCoreContext->dispatch(me);
167 }
168 
169 void BrowserApi::SetVolume(int volumn)
170 {
171  MythEvent me(QString("MUSIC_COMMAND %1 SET_VOLUME %2")
172  .arg(gCoreContext->GetHostName()).arg(volumn));
173  gCoreContext->dispatch(me);
174 }
175 
177 {
178  m_gotAnswer = false;
179 
180  MythEvent me(QString("MUSIC_COMMAND %1 GET_VOLUME")
181  .arg(gCoreContext->GetHostName()));
182  gCoreContext->dispatch(me);
183 
184  QElapsedTimer timer;
185  timer.start();
186 
187  while (!timer.hasExpired(2000) && !m_gotAnswer)
188  {
189  QCoreApplication::processEvents();
190  std::this_thread::sleep_for(10ms);
191  }
192 
193  if (m_gotAnswer)
194  return m_answer.toInt();
195 
196  return -1;
197 }
198 
199 void BrowserApi::PlayFile(const QString& filename)
200 {
201  MythEvent me(QString("MUSIC_COMMAND %1 PLAY_FILE '%2'")
202  .arg(gCoreContext->GetHostName(), filename));
203  gCoreContext->dispatch(me);
204 }
205 
206 void BrowserApi::PlayTrack(int trackID)
207 {
208  MythEvent me(QString("MUSIC_COMMAND %1 PLAY_TRACK %2")
209  .arg(gCoreContext->GetHostName()).arg(trackID));
210  gCoreContext->dispatch(me);
211 }
212 
213 void BrowserApi::PlayURL(const QString& url)
214 {
215  MythEvent me(QString("MUSIC_COMMAND %1 PLAY_URL %2")
216  .arg(gCoreContext->GetHostName(), url));
217  gCoreContext->dispatch(me);
218 }
219 
221 {
222  m_gotAnswer = false;
223 
224  MythEvent me(QString("MUSIC_COMMAND %1 GET_METADATA")
225  .arg(gCoreContext->GetHostName()));
226  gCoreContext->dispatch(me);
227 
228  QElapsedTimer timer;
229  timer.start();
230 
231  while (!timer.hasExpired(2000) && !m_gotAnswer)
232  {
233  QCoreApplication::processEvents();
234  std::this_thread::sleep_for(10ms);
235  }
236 
237  if (m_gotAnswer)
238  return m_answer;
239 
240  return {"unknown"};
241 }
242 
243 void BrowserApi::customEvent(QEvent *e)
244 {
245  if (e->type() == MythEvent::kMythEventMessage)
246  {
247  auto *me = dynamic_cast<MythEvent *>(e);
248  if (me == nullptr)
249  return;
250 
251  const QString& message = me->Message();
252 
253  if (!message.startsWith("MUSIC_CONTROL"))
254  return;
255 
256  QStringList tokens = message.simplified().split(" ");
257 
258  if ((tokens.size() >= 4) && (tokens[1] == "ANSWER")
259  && (tokens[2] == gCoreContext->GetHostName()))
260  {
261  m_answer = tokens[3];
262 
263  for (int i = 4; i < tokens.size(); i++)
264  m_answer += QString(" ") + tokens[i];
265 
266  m_gotAnswer = true;
267  }
268  }
269 }
270 
271 MythWebPage::MythWebPage(QObject *parent)
272  : QWebPage(parent)
273 {
274  setNetworkAccessManager(GetNetworkAccessManager());
275 }
276 
278 {
279  LOG(VB_GENERAL, LOG_DEBUG, "Refreshing DLManager's Cookie Jar");
281  GetMythDownloadManager()->saveCookieJar(GetConfDir() + "/MythBrowser/cookiejar.txt");
282 }
283 
284 bool MythWebPage::supportsExtension(Extension extension) const
285 {
286  return extension == QWebPage::ErrorPageExtension;
287 }
288 
289 bool MythWebPage::extension(Extension extension, const ExtensionOption *option,
290  ExtensionReturn *output)
291 {
292  if (extension == QWebPage::ErrorPageExtension)
293  {
294  if (!option || !output)
295  return false;
296 
297  // Using static_cast yields the clang-tidy warning: do not use
298  // static_cast to downcast from a base to a derived class; use
299  // dynamic_cast instead. Using dynamic-cast yields the
300  // compiler error: 'QWebPage::ExtensionOption' is not
301  // polymorphic.
302  //
303  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
304  const auto *erroroption = static_cast<const ErrorPageExtensionOption *>(option);
305  ErrorPageExtensionReturn *erroroutput = nullptr;
306  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
307  erroroutput = static_cast<ErrorPageExtensionReturn *>(output);
308 
309  QString filename = "htmls/notfound.html";
310 
312  return false;
313 
314  QFile file(QLatin1String(qPrintable(filename)));
315  bool isOpened = file.open(QIODevice::ReadOnly);
316 
317  if (!isOpened)
318  return false;
319 
320  QString title = tr("Error loading page: %1").arg(erroroption->url.toString());
321  QString html = QString(QLatin1String(file.readAll()))
322  .arg(title,
323  erroroption->errorString,
324  erroroption->url.toString());
325 
326  QBuffer imageBuffer;
327  imageBuffer.open(QBuffer::ReadWrite);
328  QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning,
329  nullptr, nullptr);
330  QPixmap pixmap = icon.pixmap(QSize(32, 32));
331 
332  if (pixmap.save(&imageBuffer, "PNG"))
333  {
334  html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"),
335  QString(QLatin1String(imageBuffer.buffer().toBase64())));
336  }
337 
338  erroroutput->content = html.toUtf8();
339 
340  return true;
341  }
342 
343  return false;
344 }
345 
346 QString MythWebPage::userAgentForUrl(const QUrl &url) const
347 {
348  return QWebPage::userAgentForUrl(url).replace("Safari", "MythBrowser");
349 }
350 
356 MythWebView::MythWebView(QWidget *parent, MythUIWebBrowser *parentBrowser)
357  : QWebView(parent),
358  m_webpage(new MythWebPage(this)),
359  m_parentBrowser(parentBrowser),
360  m_api(new BrowserApi(this))
361 {
362  setPage(m_webpage);
363 
364  connect(page(), &QWebPage::unsupportedContent,
366 
367  connect(page(), &QWebPage::downloadRequested,
369 
370  page()->setForwardUnsupportedContent(true);
371 
372  m_api->setWebView(this);
373 }
374 
376 {
377  delete m_webpage;
378  delete m_api;
379 }
380 
385 const QString kgetType { QStringLiteral("\
386 function activeElement()\
387 {\
388  var type;\
389  type = document.activeElement.type;\
390  return type;\
391 }\
392 activeElement();") };
393 
394 void MythWebView::keyPressEvent(QKeyEvent *event)
395 {
396  // does an edit have focus?
398  .toString().toLower();
399  bool editHasFocus = (type == "text" || type == "textarea" ||
400  type == "password");
401 
402  // if the QWebView widget has focus then all keypresses from a regular
403  // keyboard get sent here first
404  if (editHasFocus || m_parentBrowser->IsInputToggled())
405  {
406  // input is toggled so pass all keypresses to the QWebView's handler
407  QWebView::keyPressEvent(event);
408  }
409  else
410  {
411  // we need to convert a few keypress events so the QWebView does the
412  // right thing
413  QStringList actions;
414  bool handled = false;
415  handled = GetMythMainWindow()->TranslateKeyPress("Browser", event,
416  actions);
417 
418  for (int i = 0; i < actions.size() && !handled; i++)
419  {
420  const QString& action = actions[i];
421  handled = true;
422 
423  if (action == "NEXTLINK")
424  {
425  QKeyEvent tabKey(event->type(), Qt::Key_Tab,
426  event->modifiers(), QString(),
427  event->isAutoRepeat(), event->count());
428  *event = tabKey;
429  QWebView::keyPressEvent(event);
430  return;
431  }
432  if (action == "PREVIOUSLINK")
433  {
434  QKeyEvent shiftTabKey(event->type(), Qt::Key_Tab,
435  event->modifiers() | Qt::ShiftModifier,
436  QString(),
437  event->isAutoRepeat(), event->count());
438  *event = shiftTabKey;
439  QWebView::keyPressEvent(event);
440  return;
441  }
442  if (action == "FOLLOWLINK")
443  {
444  QKeyEvent returnKey(event->type(), Qt::Key_Return,
445  event->modifiers(), QString(),
446  event->isAutoRepeat(), event->count());
447  *event = returnKey;
448  QWebView::keyPressEvent(event);
449  return;
450  }
451  }
452 
453  // pass the keyPress event to our main window handler so they get
454  // handled properly by the various mythui handlers
455  QCoreApplication::postEvent(GetMythMainWindow(), new QKeyEvent(*event));
456  }
457 }
458 
459 void MythWebView::handleUnsupportedContent(QNetworkReply *reply)
460 {
461  if (reply->error() == QNetworkReply::NoError)
462  {
463  stop();
464 
465  QVariant header = reply->header(QNetworkRequest::ContentTypeHeader);
466 
467  if (header != QVariant())
468  {
469  LOG(VB_GENERAL, LOG_ERR,
470  QString("MythWebView::handleUnsupportedContent - %1")
471  .arg(header.toString()));
472  }
473 
474  m_downloadReply = reply;
475  m_downloadRequest = reply->request();
476  m_downloadAndPlay = false;
478 
479  return;
480  }
481 }
482 
483 void MythWebView::handleDownloadRequested(const QNetworkRequest &request)
484 {
485  m_downloadReply = nullptr;
486  doDownloadRequested(request);
487 }
488 
489 void MythWebView::doDownloadRequested(const QNetworkRequest &request)
490 {
491  m_downloadRequest = request;
492 
493  // get the filename from the url if available
494  QFileInfo fi(request.url().path());
495  QString basename(fi.completeBaseName());
496  QString extension = fi.suffix().toLower();
497  QString mimetype = getReplyMimetype();
498 
499  // if we have a default filename use that
500  QString saveBaseName = basename;
501 
502  if (!m_parentBrowser->GetDefaultSaveFilename().isEmpty())
503  {
504  QFileInfo savefi(m_parentBrowser->GetDefaultSaveFilename());
505  saveBaseName = savefi.completeBaseName();
506  }
507 
508  // if the filename is still empty use a default name
509  if (saveBaseName.isEmpty())
510  saveBaseName = "unnamed_download";
511 
512  // if we don't have an extension from the filename get one from the mime type
513  if (extension.isEmpty())
514  extension = getExtensionForMimetype(mimetype);
515 
516  if (!extension.isEmpty())
517  extension = '.' + extension;
518 
519  QString saveFilename = QString("%1%2%3")
521  saveBaseName,
522  extension);
523 
524  // dont overwrite an existing file
525  if (QFile::exists(saveFilename))
526  {
527  int i = 1;
528 
529  do
530  {
531  saveFilename = QString("%1%2-%3%4")
533  saveBaseName,
534  QString::number(i++),
535  extension);
536  }
537  while (QFile::exists(saveFilename));
538  }
539 
540  // if we are downloading and then playing the file don't ask for the file name
541  if (m_downloadAndPlay)
542  {
543  doDownload(saveFilename);
544  }
545  else
546  {
547  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
548 
549  QString msg = tr("Enter filename to save file");
550  auto *input = new MythTextInputDialog(popupStack, msg, FilterNone,
551  false, saveFilename);
552 
553  if (input->Create())
554  {
555  input->SetReturnEvent(this, "filenamedialog");
556  popupStack->AddScreen(input);
557  }
558  else
559  {
560  delete input;
561  }
562  }
563 }
564 
565 void MythWebView::doDownload(const QString &saveFilename)
566 {
567  if (saveFilename.isEmpty())
568  return;
569 
570  openBusyPopup(tr("Downloading file. Please wait..."));
571 
572  // No need to make sure the path to saveFilename exists because
573  // MythDownloadManage takes care of that
575  saveFilename, this);
576 }
577 
578 void MythWebView::openBusyPopup(const QString &message)
579 {
580  if (m_busyPopup)
581  return;
582 
583  QString msg(tr("Downloading..."));
584 
585  if (!message.isEmpty())
586  msg = message;
587 
588  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
589  m_busyPopup = new MythUIBusyDialog(msg, popupStack, "downloadbusydialog");
590 
591  if (m_busyPopup->Create())
592  popupStack->AddScreen(m_busyPopup, false);
593 }
594 
596 {
597  if (m_busyPopup)
598  m_busyPopup->Close();
599 
600  m_busyPopup = nullptr;
601 }
602 
603 void MythWebView::customEvent(QEvent *event)
604 {
605  if (event->type() == DialogCompletionEvent::kEventType)
606  {
607  auto *dce = (DialogCompletionEvent *)(event);
608 
609  // make sure the user didn't ESCAPE out of the dialog
610  if (dce->GetResult() < 0)
611  return;
612 
613  QString resultid = dce->GetId();
614  QString resulttext = dce->GetResultText();
615 
616  if (resultid == "filenamedialog")
617  doDownload(resulttext);
618  else if (resultid == "downloadmenu")
619  {
620  if (resulttext == tr("Play the file"))
621  {
622  QFileInfo fi(m_downloadRequest.url().path());
623  QString extension = fi.suffix();
624  QString mimeType = getReplyMimetype();
625 
626  if (isMusicFile(extension, mimeType))
627  {
628  MythEvent me(QString("MUSIC_COMMAND %1 PLAY_URL %2")
629  .arg(gCoreContext->GetHostName(),
630  m_downloadRequest.url().toString()));
631  gCoreContext->dispatch(me);
632  }
633  else if (isVideoFile(extension, mimeType))
634  {
635  GetMythMainWindow()->HandleMedia("Internal",
636  m_downloadRequest.url().toString());
637  }
638  else
639  {
640  LOG(VB_GENERAL, LOG_ERR,
641  QString("MythWebView: Asked to play a file with "
642  "extension '%1' but don't know how")
643  .arg(extension));
644  }
645  }
646  else if (resulttext == tr("Download the file"))
647  {
649  }
650  else if (resulttext == tr("Download and play the file"))
651  {
652  m_downloadAndPlay = true;
654  }
655  }
656  }
657  else if (event->type() == MythEvent::kMythEventMessage)
658  {
659  auto *me = dynamic_cast<MythEvent *>(event);
660  if (me == nullptr)
661  return;
662 
663  QStringList tokens = me->Message().split(" ", Qt::SkipEmptyParts);
664  if (tokens.isEmpty())
665  return;
666 
667  if (tokens[0] == "DOWNLOAD_FILE")
668  {
669  QStringList args = me->ExtraDataList();
670 
671  if (tokens[1] == "UPDATE")
672  {
673  // could update a progressbar here
674  }
675  else if (tokens[1] == "FINISHED")
676  {
677  int fileSize = args[2].toInt();
678  int errorCode = args[4].toInt();
679  const QString& filename = args[1];
680 
681  closeBusyPopup();
682 
683  if ((errorCode != 0) || (fileSize == 0))
684  ShowOkPopup(tr("ERROR downloading file."));
685  else if (m_downloadAndPlay)
686  GetMythMainWindow()->HandleMedia("Internal", filename);
687 
688  MythEvent me2(QString("BROWSER_DOWNLOAD_FINISHED"), args);
689  gCoreContext->dispatch(me2);
690  }
691  }
692  }
693 }
694 
696 {
697  QFileInfo fi(m_downloadRequest.url().path());
698  QString extension = fi.suffix();
699  QString mimeType = getReplyMimetype();
700 
701  QString label = tr("What do you want to do with this file?");
702 
703  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
704 
705  auto *menu = new MythDialogBox(label, popupStack, "downloadmenu");
706 
707  if (!menu->Create())
708  {
709  delete menu;
710  return;
711  }
712 
713  menu->SetReturnEvent(this, "downloadmenu");
714 
715  if (isMusicFile(extension, mimeType))
716  menu->AddButton(tr("Play the file"));
717 
718  if (isVideoFile(extension, mimeType))
719  menu->AddButton(tr("Download and play the file"));
720 
721  menu->AddButton(tr("Download the file"));
722  menu->AddButton(tr("Cancel"));
723 
724  popupStack->AddScreen(menu);
725 }
726 
727 QString MythWebView::getExtensionForMimetype(const QString &mimetype)
728 {
729  if (mimetype.isEmpty())
730  return {""};
731 
732  auto it = std::find_if(SupportedMimeTypes.cbegin(), SupportedMimeTypes.cend(),
733  [mimetype] (const MimeType& entry) -> bool
734  { return mimetype == entry.m_mimeType; });
735  if (it != SupportedMimeTypes.cend())
736  return it->m_extension;
737  return {""};
738 }
739 
740 bool MythWebView::isMusicFile(const QString &extension, const QString &mimetype)
741 {
742  return std::any_of(SupportedMimeTypes.cbegin(), SupportedMimeTypes.cend(),
743  [extension, mimetype](const auto &entry){
744  if (entry.m_isVideo)
745  return false;
746  if (!mimetype.isEmpty() &&
747  mimetype == entry.m_mimeType)
748  return true;
749  if (!extension.isEmpty() &&
750  extension.toLower() == entry.m_extension)
751  return true;
752  return false; } );
753 }
754 
755 bool MythWebView::isVideoFile(const QString &extension, const QString &mimetype)
756 {
757  return std::any_of(SupportedMimeTypes.cbegin(), SupportedMimeTypes.cend(),
758  [extension, mimetype](const auto &entry) {
759  if (!entry.m_isVideo)
760  return false;
761  if (!mimetype.isEmpty() &&
762  mimetype == entry.m_mimeType)
763  return true;
764  if (!extension.isEmpty() &&
765  extension.toLower() == entry.m_extension)
766  return true;
767  return false; } );
768 }
769 
771 {
772  if (!m_downloadReply)
773  return {};
774 
775  QString mimeType;
776  QVariant header = m_downloadReply->header(QNetworkRequest::ContentTypeHeader);
777 
778  if (header != QVariant())
779  mimeType = header.toString();
780 
781  return mimeType;
782 }
783 
784 QWebView *MythWebView::createWindow(QWebPage::WebWindowType /* type */)
785 {
786  return (QWebView *) this;
787 }
788 
789 
829 MythUIWebBrowser::MythUIWebBrowser(MythUIType *parent, const QString &name)
830  : MythUIType(parent, name),
831  m_bgColor("White"), m_userCssFile(""),
832  m_defaultSaveDir(GetConfDir() + "/MythBrowser/"),
833  m_defaultSaveFilename(""),
834  m_lastMouseAction("")
835 {
836  SetCanTakeFocus(true);
837  m_scrollAnimation.setDuration(0);
838  m_lastUpdateTime.start();
839 }
840 
845 {
847 
848  Init();
849 }
850 
859 {
860  // only do the initialisation for widgets not being stored in the global object store
861  if (parent() == GetGlobalObjectStore())
862  return;
863 
864  if (m_initialized)
865  return;
866 
869  m_actualBrowserArea.translate(m_area.x(), m_area.y());
870 
871  if (!m_actualBrowserArea.isValid())
873 
874  m_browser = new MythWebView(GetMythMainWindow()->GetPaintWindow(), this);
875  m_browser->setPalette(QApplication::style()->standardPalette());
876  m_browser->setGeometry(m_actualBrowserArea);
877  m_browser->setFixedSize(m_actualBrowserArea.size());
879  m_browser->page()->setLinkDelegationPolicy(QWebPage::DontDelegateLinks);
880 
881  bool err = false;
882  UIUtilW::Assign(this, m_horizontalScrollbar, "horizscrollbar", &err);
883  UIUtilW::Assign(this, m_verticalScrollbar, "vertscrollbar", &err);
885  {
886  QWebFrame* frame = m_browser->page()->currentFrame();
887  frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
892  }
893 
895  {
896  QWebFrame* frame = m_browser->page()->currentFrame();
897  frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
902  }
903 
904  // if we have a valid css URL use that ...
905  if (!m_userCssFile.isEmpty())
906  {
907  QString filename = m_userCssFile;
908 
909  if (GetMythUI()->FindThemeFile(filename))
910  LoadUserStyleSheet(QUrl("file://" + filename));
911  }
912  else
913  {
914  // ...otherwise use the default one
915  QString filename = "htmls/mythbrowser.css";
916 
917  if (GetMythUI()->FindThemeFile(filename))
918  LoadUserStyleSheet(QUrl("file://" + filename));
919  }
920 
921  m_browser->winId();
922 
924 
925  connect(m_browser, &QWebView::loadStarted,
927  connect(m_browser, &QWebView::loadFinished,
929  connect(m_browser, &QWebView::loadProgress,
931  connect(m_browser, &QWebView::titleChanged,
933  connect(m_browser, &QWebView::iconChanged,
935  connect(m_browser, &QWebView::statusBarMessage,
937  connect(m_browser->page(), &QWebPage::linkHovered,
939  connect(m_browser, &QWebView::linkClicked,
941 
942  // find what screen we are on
943  m_parentScreen = nullptr;
944  QObject *parentObject = parent();
945 
946  while (parentObject)
947  {
948  m_parentScreen = qobject_cast<MythScreenType *>(parentObject);
949 
950  if (m_parentScreen)
951  break;
952 
953  parentObject = parentObject->parent();
954  }
955 
956  if (!m_parentScreen && parent() != GetGlobalObjectStore())
957  LOG(VB_GENERAL, LOG_ERR,
958  "MythUIWebBrowser: failed to find our parent screen");
959 
960  // connect to the topScreenChanged signals on each screen stack
961  for (int x = 0; x < GetMythMainWindow()->GetStackCount(); x++)
962  {
964 
965  if (stack)
966  connect(stack, &MythScreenStack::topScreenChanged,
968  }
969 
970  // set up the icon cache directory
971  QString path = GetConfDir();
972  QDir dir(path);
973 
974  if (!dir.exists())
975  dir.mkdir(path);
976 
977  path += "/MythBrowser";
978  dir.setPath(path);
979 
980  if (!dir.exists())
981  dir.mkdir(path);
982 
983  QWebSettings::setIconDatabasePath(path);
984 
985  if (gCoreContext->GetNumSetting("WebBrowserEnablePlugins", 1) == 1)
986  {
987  LOG(VB_GENERAL, LOG_INFO, "MythUIWebBrowser: enabling plugins");
988  QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,
989  true);
990  }
991  else
992  {
993  LOG(VB_GENERAL, LOG_INFO, "MythUIWebBrowser: disabling plugins");
994  QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,
995  false);
996  }
997 
998  if (!gCoreContext->GetBoolSetting("WebBrowserEnableJavascript",true))
999  {
1000  LOG(VB_GENERAL, LOG_INFO, "MythUIWebBrowser: disabling JavaScript");
1001  QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled, false);
1002  }
1003 
1004  QImage image = QImage(m_actualBrowserArea.size(), QImage::Format_ARGB32);
1006  m_image->Assign(image);
1007 
1009 
1010  m_zoom = gCoreContext->GetFloatSetting("WebBrowserZoomLevel", 1.0);
1011 
1012  SetZoom(m_zoom);
1013 
1014  if (!m_widgetUrl.isEmpty() && m_widgetUrl.isValid())
1016 
1017  m_initialized = true;
1018 }
1019 
1024 {
1025  if (m_browser)
1026  {
1027  m_browser->hide();
1028  m_browser->disconnect();
1029  m_browser->deleteLater();
1030  m_browser = nullptr;
1031  }
1032 
1033  if (m_image)
1034  {
1035  m_image->DecrRef();
1036  m_image = nullptr;
1037  }
1038 }
1039 
1044 void MythUIWebBrowser::LoadPage(const QUrl& url)
1045 {
1046  if (!m_browser)
1047  return;
1048 
1049  ResetScrollBars();
1050 
1051  m_browser->setUrl(url);
1052 }
1053 
1060 void MythUIWebBrowser::SetHtml(const QString &html, const QUrl &baseUrl)
1061 {
1062  if (!m_browser)
1063  return;
1064 
1065  ResetScrollBars();
1066 
1067  m_browser->setHtml(html, baseUrl);
1068 }
1069 
1075 {
1076  if (!m_browser)
1077  return;
1078 
1079  LOG(VB_GENERAL, LOG_INFO,
1080  "MythUIWebBrowser: Loading css from - " + url.toString());
1081 
1082  m_browser->page()->settings()->setUserStyleSheetUrl(url);
1083 }
1084 
1092 {
1093  if (!m_browser)
1094  return;
1095 
1096  color.setAlpha(255);
1097  QPalette palette = m_browser->page()->palette();
1098  palette.setBrush(QPalette::Window, QBrush(color));
1099  palette.setBrush(QPalette::Base, QBrush(color));
1100  m_browser->page()->setPalette(palette);
1101 
1102  UpdateBuffer();
1103 }
1104 
1116 {
1117  if (!m_browser)
1118  return;
1119 
1120  if (m_active == active)
1121  return;
1122 
1123  m_active = active;
1124  m_wasActive = active;
1125 
1126  if (m_active)
1127  {
1128  m_browser->setUpdatesEnabled(false);
1129  m_browser->setFocus();
1130  m_browser->show();
1131  m_browser->raise();
1132  if (QGuiApplication::platformName().contains("egl"))
1133  {
1134  m_browser->setParent(nullptr);
1135  m_browser->setFocus();
1136  m_browser->show();
1137  m_browser->raise();
1138  }
1139  m_browser->setUpdatesEnabled(true);
1140  }
1141  else
1142  {
1143  m_browser->clearFocus();
1144  m_browser->hide();
1145  if (QGuiApplication::platformName().contains("egl"))
1146  m_browser->setParent(GetMythMainWindow());
1147  UpdateBuffer();
1148  }
1149 }
1150 
1155 {
1156  SetZoom(m_zoom + 0.1);
1157 }
1158 
1163 {
1164  SetZoom(m_zoom - 0.1);
1165 }
1166 
1171 void MythUIWebBrowser::SetZoom(double zoom)
1172 {
1173  if (!m_browser)
1174  return;
1175 
1176  m_zoom = std::clamp(zoom, 0.3, 5.0);
1177  m_browser->setZoomFactor(m_zoom);
1178  ResetScrollBars();
1179  UpdateBuffer();
1180 
1181  slotStatusBarMessage(tr("Zoom: %1%").arg(m_zoom * 100));
1182 
1183  gCoreContext->SaveSetting("WebBrowserZoomLevel", QString("%1").arg(m_zoom));
1184 }
1185 
1186 void MythUIWebBrowser::SetDefaultSaveDirectory(const QString &saveDir)
1187 {
1188  if (!saveDir.isEmpty())
1189  m_defaultSaveDir = saveDir;
1190  else
1191  m_defaultSaveDir = GetConfDir() + "/MythBrowser/";
1192 }
1193 
1195 {
1196  if (!filename.isEmpty())
1198  else
1199  m_defaultSaveFilename.clear();
1200 }
1201 
1206 float MythUIWebBrowser::GetZoom(void) const
1207 {
1208  return m_zoom;
1209 }
1210 
1217 {
1218  if (!m_browser)
1219  return false;
1220 
1221  return m_browser->history()->canGoForward();
1222 }
1223 
1230 {
1231  if (!m_browser)
1232  return false;
1233 
1234  return m_browser->history()->canGoBack();
1235 }
1236 
1241 {
1242  if (!m_browser)
1243  return;
1244 
1245  m_browser->back();
1246 }
1247 
1252 {
1253  if (!m_browser)
1254  return;
1255 
1256  m_browser->forward();
1257 }
1258 
1264 {
1265  if (m_browser)
1266  {
1267  return QWebSettings::iconForUrl(m_browser->url());
1268  }
1269  return {};
1270 }
1271 
1277 {
1278  if (m_browser)
1279  {
1280  return m_browser->url();
1281  }
1282  return {};
1283 }
1284 
1290 {
1291  if (m_browser)
1292  return m_browser->title();
1293  return {""};
1294 }
1295 
1300 QVariant MythUIWebBrowser::evaluateJavaScript(const QString &scriptSource)
1301 {
1302  if (m_browser)
1303  {
1304  QWebFrame *frame = m_browser->page()->currentFrame();
1305  return frame->evaluateJavaScript(scriptSource);
1306  }
1307  return {};
1308 }
1309 
1310 void MythUIWebBrowser::Scroll(int dx, int dy)
1311 {
1312  if (!m_browser)
1313  return;
1314 
1315  QPoint startPos = m_browser->page()->currentFrame()->scrollPosition();
1316  QPoint endPos = startPos + QPoint(dx, dy);
1317 
1318  if (GetPainter()->SupportsAnimation() && m_scrollAnimation.duration() > 0)
1319  {
1320  // Previous scroll has been completed
1321  if (m_destinationScrollPos == startPos)
1322  m_scrollAnimation.setEasingCurve(QEasingCurve::InOutCubic);
1323  else
1324  m_scrollAnimation.setEasingCurve(QEasingCurve::OutCubic);
1325 
1326  m_destinationScrollPos = endPos;
1327  m_scrollAnimation.setStartValue(startPos);
1330  }
1331  else
1332  {
1333  m_destinationScrollPos = endPos;
1334  m_browser->page()->currentFrame()->setScrollPosition(endPos);
1335  UpdateBuffer();
1336  }
1337 }
1338 
1340 {
1341  ResetScrollBars();
1342  emit loadStarted();
1343 }
1344 
1346 {
1347  UpdateBuffer();
1348  emit loadFinished(ok);
1349 }
1350 
1352 {
1353  emit loadProgress(progress);
1354 }
1355 
1356 void MythUIWebBrowser::slotTitleChanged(const QString &title)
1357 {
1358  emit titleChanged(title);
1359 }
1360 
1362 {
1363  emit statusBarMessage(text);
1364 }
1365 
1367 {
1368  LoadPage(url);
1369 }
1370 
1372 {
1373  emit iconChanged();
1374 }
1375 
1377 {
1378  bool wasActive = (m_wasActive || m_active);
1379  SetActive(false);
1380  m_wasActive = wasActive;
1381 }
1382 
1384 {
1386  slotTopScreenChanged(nullptr);
1387 }
1388 
1390 {
1391  if (IsOnTopScreen())
1393  else
1394  {
1395  bool wasActive = (m_wasActive || m_active);
1396  SetActive(false);
1397  m_wasActive = wasActive;
1398  }
1399 }
1400 
1403 {
1404  if (!m_parentScreen)
1405  return false;
1406 
1407  for (int x = GetMythMainWindow()->GetStackCount() - 1; x >= 0; x--)
1408  {
1410 
1411  // ignore stacks with no screens on them
1412  if (!stack->GetTopScreen())
1413  continue;
1414 
1415  return (stack->GetTopScreen() == m_parentScreen);
1416  }
1417 
1418  return false;
1419 }
1420 
1421 
1423 {
1424  if (!m_browser)
1425  return;
1426 
1427  QPoint position = m_browser->page()->currentFrame()->scrollPosition();
1428  if (m_verticalScrollbar)
1429  {
1430  int maximum =
1431  m_browser->page()->currentFrame()->contentsSize().height() -
1432  m_actualBrowserArea.height();
1433  m_verticalScrollbar->SetMaximum(maximum);
1435  m_verticalScrollbar->SetSliderPosition(position.y());
1436  }
1437 
1439  {
1440  int maximum =
1441  m_browser->page()->currentFrame()->contentsSize().width() -
1442  m_actualBrowserArea.width();
1446  }
1447 }
1448 
1450 {
1451  UpdateScrollBars();
1452 
1453  if (!m_image || !m_browser)
1454  return;
1455 
1456  if (!m_active || (m_active && !m_browser->hasFocus()))
1457  {
1458  QPainter painter(m_image);
1459  m_browser->render(&painter);
1460  painter.end();
1461 
1462  m_image->SetChanged();
1463  Refresh();
1464  }
1465 }
1466 
1471 {
1472  if (!m_browser)
1473  return;
1474 
1475  if (m_scrollAnimation.IsActive() &&
1477  m_browser->page()->currentFrame()->scrollPosition())
1478  {
1480 
1481  QPoint scrollPosition = m_scrollAnimation.currentValue().toPoint();
1482  m_browser->page()->currentFrame()->setScrollPosition(scrollPosition);
1483 
1484  SetRedraw();
1485  UpdateBuffer();
1486  }
1487  else if (m_updateInterval && m_lastUpdateTime.hasExpired(m_updateInterval))
1488  {
1489  UpdateBuffer();
1490  m_lastUpdateTime.start();
1491  }
1492 
1494 }
1495 
1499 void MythUIWebBrowser::DrawSelf(MythPainter *p, int xoffset, int yoffset,
1500  int alphaMod, QRect clipRect)
1501 {
1502  if (!m_image || m_image->isNull() || !m_browser || m_browser->hasFocus())
1503  return;
1504 
1505  QRect area = m_actualBrowserArea;
1506  area.translate(xoffset, yoffset);
1507 
1508  p->SetClipRect(clipRect);
1509  p->DrawImage(area.x(), area.y(), m_image, alphaMod);
1510 }
1511 
1515 bool MythUIWebBrowser::keyPressEvent(QKeyEvent *event)
1516 {
1517  if (!m_browser)
1518  return false;
1519 
1520  QStringList actions;
1521  bool handled = false;
1522  handled = GetMythMainWindow()->TranslateKeyPress("Browser", event, actions);
1523 
1524  for (int i = 0; i < actions.size() && !handled; i++)
1525  {
1526  const QString& action = actions[i];
1527  handled = true;
1528 
1529  if (action == "TOGGLEINPUT")
1530  {
1532 
1533  if (m_inputToggled)
1534  slotStatusBarMessage(tr("Sending key presses to web page"));
1535  else
1536  slotStatusBarMessage(tr("Sending key presses to MythTV"));
1537 
1538  return true;
1539  }
1540 
1541  // if input is toggled all input goes to the web page
1542  if (m_inputToggled)
1543  {
1544  m_browser->keyPressEvent(event);
1545 
1546  return true;
1547  }
1548 
1549  QWebFrame *frame = m_browser->page()->currentFrame();
1550  if (action == "UP")
1551  {
1552  int pos = frame->scrollPosition().y();
1553 
1554  if (pos > 0)
1555  {
1556  Scroll(0, -m_actualBrowserArea.height() / 10);
1557  }
1558  else
1559  {
1560  handled = false;
1561  }
1562  }
1563  else if (action == "DOWN")
1564  {
1565  int pos = frame->scrollPosition().y();
1566  QSize maximum = frame->contentsSize() - m_actualBrowserArea.size();
1567 
1568  if (pos != maximum.height())
1569  {
1570  Scroll(0, m_actualBrowserArea.height() / 10);
1571  }
1572  else
1573  {
1574  handled = false;
1575  }
1576  }
1577  else if (action == "LEFT")
1578  {
1579  int pos = frame->scrollPosition().x();
1580 
1581  if (pos > 0)
1582  {
1583  Scroll(-m_actualBrowserArea.width() / 10, 0);
1584  }
1585  else
1586  {
1587  handled = false;
1588  }
1589  }
1590  else if (action == "RIGHT")
1591  {
1592  int pos = frame->scrollPosition().x();
1593  QSize maximum = frame->contentsSize() - m_actualBrowserArea.size();
1594 
1595  if (pos != maximum.width())
1596  {
1597  Scroll(m_actualBrowserArea.width() / 10, 0);
1598  }
1599  else
1600  {
1601  handled = false;
1602  }
1603  }
1604  else if (action == "PAGEUP")
1605  {
1606  Scroll(0, -m_actualBrowserArea.height());
1607  }
1608  else if (action == "PAGEDOWN")
1609  {
1610  Scroll(0, m_actualBrowserArea.height());
1611  }
1612  else if (action == "ZOOMIN")
1613  {
1614  ZoomIn();
1615  }
1616  else if (action == "ZOOMOUT")
1617  {
1618  ZoomOut();
1619  }
1620  else if (action == "MOUSEUP" || action == "MOUSEDOWN" ||
1621  action == "MOUSELEFT" || action == "MOUSERIGHT" ||
1622  action == "MOUSELEFTBUTTON")
1623  {
1625  }
1626  else if (action == "PAGELEFT")
1627  {
1628  Scroll(-m_actualBrowserArea.width(), 0);
1629  }
1630  else if (action == "PAGERIGHT")
1631  {
1632  Scroll(m_actualBrowserArea.width(), 0);
1633  }
1634  else if ((action == "NEXTLINK") ||
1635  (action == "PREVIOUSLINK") ||
1636  (action == "FOLLOWLINK"))
1637  {
1638  m_browser->keyPressEvent(event);
1639  }
1640  else if (action == "HISTORYBACK")
1641  {
1642  Back();
1643  }
1644  else if (action == "HISTORYFORWARD")
1645  {
1646  Forward();
1647  }
1648  else
1649  {
1650  handled = false;
1651  }
1652  }
1653 
1654  return handled;
1655 }
1656 
1658 {
1659  int step = 5;
1660 
1661  // speed up mouse movement if the same key is held down
1662  if (action == m_lastMouseAction &&
1663  m_lastMouseActionTime.isValid() &&
1664  !m_lastMouseActionTime.hasExpired(500))
1665  {
1666  m_lastMouseActionTime.start();
1667  m_mouseKeyCount++;
1668 
1669  if (m_mouseKeyCount > 5)
1670  step = 25;
1671  }
1672  else
1673  {
1675  m_lastMouseActionTime.start();
1676  m_mouseKeyCount = 1;
1677  }
1678 
1679  if (action == "MOUSEUP")
1680  {
1681  QPoint curPos = QCursor::pos();
1682  QCursor::setPos(curPos.x(), curPos.y() - step);
1683  }
1684  else if (action == "MOUSELEFT")
1685  {
1686  QPoint curPos = QCursor::pos();
1687  QCursor::setPos(curPos.x() - step, curPos.y());
1688  }
1689  else if (action == "MOUSERIGHT")
1690  {
1691  QPoint curPos = QCursor::pos();
1692  QCursor::setPos(curPos.x() + step, curPos.y());
1693  }
1694  else if (action == "MOUSEDOWN")
1695  {
1696  QPoint curPos = QCursor::pos();
1697  QCursor::setPos(curPos.x(), curPos.y() + step);
1698  }
1699  else if (action == "MOUSELEFTBUTTON")
1700  {
1701  QPoint curPos = QCursor::pos();
1702  QWidget *widget = QApplication::widgetAt(curPos);
1703 
1704  if (widget)
1705  {
1706  curPos = widget->mapFromGlobal(curPos);
1707 
1708  auto *me = new QMouseEvent(QEvent::MouseButtonPress, curPos,
1709  Qt::LeftButton, Qt::LeftButton,
1710  Qt::NoModifier);
1711  QCoreApplication::postEvent(widget, me);
1712 
1713  me = new QMouseEvent(QEvent::MouseButtonRelease, curPos,
1714  Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
1715  QCoreApplication::postEvent(widget, me);
1716  }
1717  }
1718 }
1719 
1721 {
1722  if (m_verticalScrollbar)
1723  {
1726  }
1727 
1729  {
1732  }
1733 }
1734 
1739  const QString &filename, QDomElement &element, bool showWarnings)
1740 {
1741  if (element.tagName() == "zoom")
1742  {
1743  QString zoom = getFirstText(element);
1744  m_zoom = zoom.toDouble();
1745  }
1746  else if (element.tagName() == "url")
1747  {
1748  m_widgetUrl.setUrl(getFirstText(element));
1749  }
1750  else if (element.tagName() == "userstylesheet")
1751  {
1752  m_userCssFile = getFirstText(element);
1753  }
1754  else if (element.tagName() == "updateinterval")
1755  {
1756  QString interval = getFirstText(element);
1757  m_updateInterval = interval.toInt();
1758  }
1759  else if (element.tagName() == "background")
1760  {
1761  m_bgColor = QColor(element.attribute("color", "#ffffff"));
1762  int alpha = element.attribute("alpha", "255").toInt();
1763  m_bgColor.setAlpha(alpha);
1764  }
1765  else if (element.tagName() == "browserarea")
1766  {
1767  m_browserArea = parseRect(element);
1768  }
1769  else if (element.tagName() == "scrollduration")
1770  {
1771  QString duration = getFirstText(element);
1772  m_scrollAnimation.setDuration(duration.toInt());
1773  }
1774  else if (element.tagName() == "acceptsfocus")
1775  {
1776  SetCanTakeFocus(parseBool(element));
1777  }
1778  else
1779  {
1780  return MythUIType::ParseElement(filename, element, showWarnings);
1781  }
1782 
1783  return true;
1784 }
1785 
1790 {
1791  auto *browser = dynamic_cast<MythUIWebBrowser *>(base);
1792  if (!browser)
1793  {
1794  LOG(VB_GENERAL, LOG_ERR, "ERROR, bad parsing");
1795  return;
1796  }
1797 
1798  MythUIType::CopyFrom(base);
1799 
1800  m_browserArea = browser->m_browserArea;
1801  m_zoom = browser->m_zoom;
1802  m_bgColor = browser->m_bgColor;
1803  m_widgetUrl = browser->m_widgetUrl;
1804  m_userCssFile = browser->m_userCssFile;
1805  m_updateInterval = browser->m_updateInterval;
1806  m_defaultSaveDir = browser->m_defaultSaveDir;
1807  m_defaultSaveFilename = browser->m_defaultSaveFilename;
1808  m_scrollAnimation.setDuration(browser->m_scrollAnimation.duration());
1809 }
1810 
1815 {
1816  auto *browser = new MythUIWebBrowser(parent, objectName());
1817  browser->CopyFrom(this);
1818 }
MythUIWebBrowser::SetActive
void SetActive(bool active)
Toggles the active state of the widget.
Definition: mythuiwebbrowser.cpp:1115
MythUIType::m_area
MythRect m_area
Definition: mythuitype.h:274
build_compdb.args
args
Definition: build_compdb.py:11
MythUIWebBrowser::CanGoForward
bool CanGoForward(void)
Can go forward in page history.
Definition: mythuiwebbrowser.cpp:1216
MythUIWebBrowser::Forward
void Forward(void)
Got forward in page history.
Definition: mythuiwebbrowser.cpp:1251
MimeType
Definition: mythuiwebbrowser.cpp:44
MythUIWebBrowser::m_mouseKeyCount
int m_mouseKeyCount
Definition: mythuiwebbrowser.h:243
MythUIWebBrowser::SetHtml
void SetHtml(const QString &html, const QUrl &baseUrl=QUrl())
Sets the content of the widget to the specified html.
Definition: mythuiwebbrowser.cpp:1060
MythWebPage
Definition: mythuiwebbrowser.h:69
MythEvent::kMythEventMessage
static const Type kMythEventMessage
Definition: mythevent.h:79
MythUIWebBrowser::m_zoom
qreal m_zoom
Definition: mythuiwebbrowser.h:234
MythWebPage::extension
bool extension(Extension extension, const ExtensionOption *option=nullptr, ExtensionReturn *output=nullptr) override
Definition: mythuiwebbrowser.cpp:289
MythUIWebBrowser::CreateCopy
void CreateCopy(MythUIType *parent) override
Copy the state of this widget to the one given, it must be of the same type.
Definition: mythuiwebbrowser.cpp:1814
mythdb.h
MythWebView::getReplyMimetype
QString getReplyMimetype(void)
Definition: mythuiwebbrowser.cpp:770
MythUIWebBrowser::slotScrollBarShowing
void slotScrollBarShowing(void)
Definition: mythuiwebbrowser.cpp:1376
MythUIWebBrowser::slotTitleChanged
void slotTitleChanged(const QString &title)
Definition: mythuiwebbrowser.cpp:1356
MythUIWebBrowser::GetDefaultSaveDirectory
QString GetDefaultSaveDirectory(void)
Definition: mythuiwebbrowser.h:171
MythUIWebBrowser::m_initialized
bool m_initialized
Definition: mythuiwebbrowser.h:230
MythWebPage::userAgentForUrl
QString userAgentForUrl(const QUrl &url) const override
Definition: mythuiwebbrowser.cpp:346
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:383
MythUIWebBrowser::UpdateBuffer
void UpdateBuffer(void)
Definition: mythuiwebbrowser.cpp:1449
MythWebView::closeBusyPopup
void closeBusyPopup(void)
Definition: mythuiwebbrowser.cpp:595
MythUIWebBrowser::IsInputToggled
bool IsInputToggled(void) const
returns true if all keypresses are to be passed to the web page
Definition: mythuiwebbrowser.h:159
MythUIWebBrowser::statusBarMessage
void statusBarMessage(const QString &text)
a pages title has changed
progress
bool progress
Definition: mythcommflag.cpp:69
BrowserApi::GetVolume
int GetVolume(void)
Definition: mythuiwebbrowser.cpp:176
MythUIWebBrowser::m_horizontalScrollbar
MythUIScrollBar * m_horizontalScrollbar
Definition: mythuiwebbrowser.h:246
MythUIWebBrowser::CanGoBack
bool CanGoBack(void)
Can we go backward in page history.
Definition: mythuiwebbrowser.cpp:1229
MythMainWindow::GetStackCount
int GetStackCount()
Definition: mythmainwindow.cpp:312
MythPainter::GetFormatImage
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
Definition: mythpainter.cpp:525
MythUIWebBrowser::m_browserArea
MythRect m_browserArea
Definition: mythuiwebbrowser.h:223
MythUIWebBrowser::loadProgress
void loadProgress(int progress)
a page has finished loading
MythUIBusyDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:32
MythUIWebBrowser::slotScrollBarHiding
void slotScrollBarHiding(void)
Definition: mythuiwebbrowser.cpp:1383
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythWebView
Subclass of QWebView.
Definition: mythuiwebbrowser.h:88
MythUIWebBrowser::m_userCssFile
QString m_userCssFile
Definition: mythuiwebbrowser.h:237
GetNetworkAccessManager
static QNetworkAccessManager * GetNetworkAccessManager(void)
Definition: mythuiwebbrowser.cpp:101
MythDownloadManager::queueDownload
void queueDownload(const QString &url, const QString &dest, QObject *caller, bool reload=false)
Adds a url to the download queue.
Definition: mythdownloadmanager.cpp:394
MythWebView::handleUnsupportedContent
void handleUnsupportedContent(QNetworkReply *reply)
Definition: mythuiwebbrowser.cpp:459
xbmcvfs.exists
bool exists(str path)
Definition: xbmcvfs.py:51
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
MythUIType::GetPainter
virtual MythPainter * GetPainter(void)
Definition: mythuitype.cpp:1417
MythWebView::m_parentBrowser
MythUIWebBrowser * m_parentBrowser
Definition: mythuiwebbrowser.h:118
MythUIWebBrowser::m_inputToggled
bool m_inputToggled
Definition: mythuiwebbrowser.h:241
MythUIType::SetCanTakeFocus
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
Definition: mythuitype.cpp:362
BrowserApi::m_gotAnswer
bool m_gotAnswer
Definition: mythuiwebbrowser.h:54
mythuiscrollbar.h
MythUIWebBrowser::SetDefaultSaveDirectory
void SetDefaultSaveDirectory(const QString &saveDir)
Definition: mythuiwebbrowser.cpp:1186
MythWebView::openBusyPopup
void openBusyPopup(const QString &message)
Definition: mythuiwebbrowser.cpp:578
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythWebView::showDownloadMenu
void showDownloadMenu(void)
Definition: mythuiwebbrowser.cpp:695
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
MythWebView::m_api
BrowserApi * m_api
Definition: mythuiwebbrowser.h:119
XMLParseBase::GetGlobalObjectStore
static MythUIType * GetGlobalObjectStore(void)
Definition: xmlparsebase.cpp:342
MimeType::m_isVideo
bool m_isVideo
Definition: mythuiwebbrowser.cpp:48
MythUIWebBrowser::CopyFrom
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
Definition: mythuiwebbrowser.cpp:1789
MythUIWebBrowser::slotLoadProgress
void slotLoadProgress(int progress)
Definition: mythuiwebbrowser.cpp:1351
MythUIWebBrowser::titleChanged
void titleChanged(const QString &title)
% of page loaded
build_compdb.file
file
Definition: build_compdb.py:55
mythdirs.h
BrowserApi::m_answer
QString m_answer
Definition: mythuiwebbrowser.h:55
MythWebView::doDownload
void doDownload(const QString &saveFilename)
Definition: mythuiwebbrowser.cpp:565
MythUIType::Pulse
virtual void Pulse(void)
Pulse is called 70 times a second to trigger a single frame of an animation.
Definition: mythuitype.cpp:456
mythprogressdialog.h
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythUIWebBrowser::m_defaultSaveDir
QString m_defaultSaveDir
Definition: mythuiwebbrowser.h:238
MythMainWindow::HandleMedia
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
Definition: mythmainwindow.cpp:1496
SupportedMimeTypes
static const std::vector< MimeType > SupportedMimeTypes
Definition: mythuiwebbrowser.cpp:52
MythWebPage::~MythWebPage
~MythWebPage() override
Definition: mythuiwebbrowser.cpp:277
MimeType::m_extension
QString m_extension
Definition: mythuiwebbrowser.cpp:47
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
BrowserApi::SetVolume
static void SetVolume(int volumn)
Definition: mythuiwebbrowser.cpp:169
BrowserApi::setWebView
void setWebView(QWebView *view)
Definition: mythuiwebbrowser.cpp:136
BrowserApi
Adds a JavaScript object.
Definition: mythuiwebbrowser.h:23
MythUIWebBrowser::GetZoom
float GetZoom(void) const
Get the current zoom level.
Definition: mythuiwebbrowser.cpp:1206
MythUIWebBrowser::LoadPage
void LoadPage(const QUrl &url)
Loads the specified url and displays it.
Definition: mythuiwebbrowser.cpp:1044
MythNetworkAccessManager
Definition: mythuiwebbrowser.h:58
MythUIWebBrowser::m_lastUpdateTime
QElapsedTimer m_lastUpdateTime
Definition: mythuiwebbrowser.h:231
MythUIWebBrowser::evaluateJavaScript
QVariant evaluateJavaScript(const QString &scriptSource)
Evaluates the JavaScript code in scriptSource.
Definition: mythuiwebbrowser.cpp:1300
MythUIWebBrowser::SetDefaultSaveFilename
void SetDefaultSaveFilename(const QString &filename)
Definition: mythuiwebbrowser.cpp:1194
mythfontproperties.h
MythWebView::createWindow
QWebView * createWindow(QWebPage::WebWindowType type) override
Definition: mythuiwebbrowser.cpp:784
mythlogging.h
MythUIWebBrowser::DrawSelf
void DrawSelf(MythPainter *p, int xoffset, int yoffset, int alphaMod, QRect clipRect) override
Definition: mythuiwebbrowser.cpp:1499
MythUIWebBrowser::ZoomOut
void ZoomOut(void)
Decrease the text size.
Definition: mythuiwebbrowser.cpp:1162
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
MythUIType::Refresh
void Refresh(void)
Definition: mythuitype.cpp:1051
MythUIAnimation::IsActive
bool IsActive() const
Definition: mythuianimation.h:60
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1111
hardwareprofile.config.p
p
Definition: config.py:33
MythUIWebBrowser::m_wasActive
bool m_wasActive
Definition: mythuiwebbrowser.h:229
MythWebView::isMusicFile
static bool isMusicFile(const QString &extension, const QString &mimetype)
Definition: mythuiwebbrowser.cpp:740
MythUIType::Showing
void Showing()
MythWebView::isVideoFile
static bool isVideoFile(const QString &extension, const QString &mimetype)
Definition: mythuiwebbrowser.cpp:755
MythUIWebBrowser::m_destinationScrollPos
QPoint m_destinationScrollPos
Definition: mythuiwebbrowser.h:249
MythUIWebBrowser::ZoomIn
void ZoomIn(void)
Increase the text size.
Definition: mythuiwebbrowser.cpp:1154
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
menu
static MythThemedMenu * menu
Definition: mythtv-setup.cpp:58
MythWebView::m_webpage
MythWebPage * m_webpage
Definition: mythuiwebbrowser.h:117
MythUIWebBrowser::GetIcon
QIcon GetIcon(void)
Gets the current page's fav icon.
Definition: mythuiwebbrowser.cpp:1263
MythScreenStack::topScreenChanged
void topScreenChanged(MythScreenType *screen)
MythUIWebBrowser::UpdateScrollBars
void UpdateScrollBars(void)
Definition: mythuiwebbrowser.cpp:1422
MythUIScrollBar::SetSliderPosition
void SetSliderPosition(int value)
Definition: mythuiscrollbar.cpp:73
MythUIWebBrowser::iconChanged
void iconChanged(void)
link hit test messages
MythWebView::getExtensionForMimetype
static QString getExtensionForMimetype(const QString &mimetype)
Definition: mythuiwebbrowser.cpp:727
MythUIWebBrowser::Finalize
void Finalize(void) override
Perform any post-xml parsing initialisation tasks.
Definition: mythuiwebbrowser.cpp:844
BrowserApi::Pause
static void Pause(void)
Definition: mythuiwebbrowser.cpp:163
XMLParseBase::getFirstText
static QString getFirstText(QDomElement &element)
Definition: xmlparsebase.cpp:52
MythUIWebBrowser::m_verticalScrollbar
MythUIScrollBar * m_verticalScrollbar
Definition: mythuiwebbrowser.h:247
MythUIWebBrowser::SetZoom
void SetZoom(double zoom)
Set the text size to specific size.
Definition: mythuiwebbrowser.cpp:1171
MythImage::DecrRef
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:52
MythUIWebBrowser::GetUrl
QUrl GetUrl(void)
Gets the current page's url.
Definition: mythuiwebbrowser.cpp:1276
BrowserApi::PlayTrack
static void PlayTrack(int trackID)
Definition: mythuiwebbrowser.cpp:206
MythRect::CalculateArea
void CalculateArea(QRect parentArea)
Definition: mythrect.cpp:64
BrowserApi::BrowserApi
BrowserApi(QObject *parent)
Definition: mythuiwebbrowser.cpp:125
BrowserApi::Stop
static void Stop(void)
Definition: mythuiwebbrowser.cpp:157
MythUIType::CopyFrom
virtual void CopyFrom(MythUIType *base)
Copy this widgets state from another.
Definition: mythuitype.cpp:1171
MythUIWebBrowser::slotLinkClicked
void slotLinkClicked(const QUrl &url)
Definition: mythuiwebbrowser.cpp:1366
MythUIBusyDialog
Definition: mythprogressdialog.h:36
MythUIWebBrowser::m_bgColor
QColor m_bgColor
Definition: mythuiwebbrowser.h:235
mythpainter.h
MythUIWebBrowser::Init
void Init(void)
Initializes the widget ready for use.
Definition: mythuiwebbrowser.cpp:858
BrowserApi::GetMetadata
QString GetMetadata(void)
Definition: mythuiwebbrowser.cpp:220
MythWebPage::MythWebPage
MythWebPage(QObject *parent=nullptr)
Definition: mythuiwebbrowser.cpp:271
MythUIWebBrowser::LoadUserStyleSheet
void LoadUserStyleSheet(const QUrl &url)
Sets the specified user style sheet.
Definition: mythuiwebbrowser.cpp:1074
XMLParseBase::parseRect
static MythRect parseRect(const QString &text, bool normalize=true)
Definition: xmlparsebase.cpp:132
MythImage::SetChanged
virtual void SetChanged(bool change=true)
Definition: mythimage.h:50
MythUIType::Hiding
void Hiding()
MythWebView::m_downloadAndPlay
bool m_downloadAndPlay
Definition: mythuiwebbrowser.h:123
MythWebPage::supportsExtension
bool supportsExtension(Extension extension) const override
Definition: mythuiwebbrowser.cpp:284
MythWebView::m_downloadReply
QNetworkReply * m_downloadReply
Definition: mythuiwebbrowser.h:121
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
clamp
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:204
MythUIWebBrowser::loadStarted
void loadStarted(void)
MythUIWebBrowser::slotStatusBarMessage
void slotStatusBarMessage(const QString &text)
Definition: mythuiwebbrowser.cpp:1361
MythUIWebBrowser::HandleMouseAction
void HandleMouseAction(const QString &action)
Definition: mythuiwebbrowser.cpp:1657
BrowserApi::~BrowserApi
~BrowserApi(void) override
Definition: mythuiwebbrowser.cpp:131
MythMainWindow::GetStackAt
MythScreenStack * GetStackAt(int Position)
Definition: mythmainwindow.cpp:330
MythUIWebBrowser::m_updateInterval
int m_updateInterval
Definition: mythuiwebbrowser.h:232
MythUIWebBrowser::m_defaultSaveFilename
QString m_defaultSaveFilename
Definition: mythuiwebbrowser.h:239
FilterNone
@ FilterNone
Definition: mythuitextedit.h:21
MythUIWebBrowser::GetTitle
QString GetTitle(void)
Gets the current page's title.
Definition: mythuiwebbrowser.cpp:1289
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:916
MythUIWebBrowser::slotTopScreenChanged
void slotTopScreenChanged(MythScreenType *screen)
Definition: mythuiwebbrowser.cpp:1389
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MythUIType::Hide
void Hide(void)
Definition: mythuitype.cpp:1139
MythUIType
The base class on which all widgets and screens are based.
Definition: mythuitype.h:85
MythUIWebBrowser::GetDefaultSaveFilename
QString GetDefaultSaveFilename(void)
Definition: mythuiwebbrowser.h:174
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:910
mythuihelper.h
MythUIWebBrowser::m_actualBrowserArea
MythRect m_actualBrowserArea
Definition: mythuiwebbrowser.h:224
MythUIScrollBar::SetPageStep
void SetPageStep(int value)
Definition: mythuiscrollbar.cpp:50
kgetType
const QString kgetType
Key event handler.
Definition: mythuiwebbrowser.cpp:385
MythUIWebBrowser::loadFinished
void loadFinished(bool ok)
a page is starting to load
mythimage.h
MythWebView::doDownloadRequested
void doDownloadRequested(const QNetworkRequest &request)
Definition: mythuiwebbrowser.cpp:489
MythDownloadManager::loadCookieJar
void loadCookieJar(const QString &filename)
Loads the cookie jar from a cookie file.
Definition: mythdownloadmanager.cpp:1644
MythUIThemeHelper::FindThemeFile
bool FindThemeFile(QString &Path)
Definition: mythuithemehelper.cpp:238
MythUIAnimation::IncrementCurrentTime
void IncrementCurrentTime(void)
Definition: mythuianimation.cpp:99
MythUIWebBrowser::ParseElement
bool ParseElement(const QString &filename, QDomElement &element, bool showWarnings) override
Parse the xml definition of this widget setting the state of the object accordingly.
Definition: mythuiwebbrowser.cpp:1738
mythcorecontext.h
networkManager
static MythNetworkAccessManager * networkManager
Definition: mythuiwebbrowser.cpp:90
MythUIWebBrowser::m_parentScreen
MythScreenType * m_parentScreen
Definition: mythuiwebbrowser.h:220
MythPainter
Definition: mythpainter.h:34
BrowserApi::m_frame
QWebFrame * m_frame
Definition: mythuiwebbrowser.h:52
MythWebView::customEvent
void customEvent(QEvent *e) override
Definition: mythuiwebbrowser.cpp:603
MythUIScrollBar::SetMaximum
void SetMaximum(int value)
Definition: mythuiscrollbar.cpp:62
BrowserApi::PlayURL
static void PlayURL(const QString &url)
Definition: mythuiwebbrowser.cpp:213
MythUIWebBrowser::slotLoadFinished
void slotLoadFinished(bool Ok)
Definition: mythuiwebbrowser.cpp:1345
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
MythUIWebBrowser::m_widgetUrl
QUrl m_widgetUrl
Definition: mythuiwebbrowser.h:236
MythUIWebBrowser::Back
void Back(void)
Got backward in page history.
Definition: mythuiwebbrowser.cpp:1240
MythUIWebBrowser::~MythUIWebBrowser
~MythUIWebBrowser() override
the classes destructor
Definition: mythuiwebbrowser.cpp:1023
MythNetworkAccessManager::createRequest
QNetworkReply * createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData=nullptr) override
Definition: mythuiwebbrowser.cpp:83
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:57
MythUIWebBrowser::Scroll
void Scroll(int dx, int dy)
Definition: mythuiwebbrowser.cpp:1310
MythUIWebBrowser::MythUIWebBrowser
MythUIWebBrowser(MythUIType *parent, const QString &name)
the classes constructor
Definition: mythuiwebbrowser.cpp:829
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythDownloadManager::refreshCookieJar
void refreshCookieJar(QNetworkCookieJar *jar)
Refresh the temporary cookie jar from another cookie jar.
Definition: mythdownloadmanager.cpp:1697
build_compdb.action
action
Definition: build_compdb.py:9
MimeType::m_mimeType
QString m_mimeType
Definition: mythuiwebbrowser.cpp:46
MythUIWebBrowser::m_scrollAnimation
MythUIAnimation m_scrollAnimation
Definition: mythuiwebbrowser.h:248
MythWebView::~MythWebView
~MythWebView(void) override
Definition: mythuiwebbrowser.cpp:375
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
MythUIWebBrowser::m_browser
MythWebView * m_browser
Definition: mythuiwebbrowser.h:222
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:842
MythUIWebBrowser::m_active
bool m_active
Definition: mythuiwebbrowser.h:228
MythDownloadManager::saveCookieJar
void saveCookieJar(const QString &filename)
Saves the cookie jar to a cookie file.
Definition: mythdownloadmanager.cpp:1656
MythUIWebBrowser::Pulse
void Pulse(void) override
Pulse is called 70 times a second to trigger a single frame of an animation.
Definition: mythuiwebbrowser.cpp:1470
MythWebView::m_busyPopup
MythUIBusyDialog * m_busyPopup
Definition: mythuiwebbrowser.h:122
MythThemedMenuState::Create
bool Create(void) override
Definition: myththemedmenu.cpp:34
MythUIWebBrowser::ResetScrollBars
void ResetScrollBars(void)
Definition: mythuiwebbrowser.cpp:1720
MythUIAnimation::Activate
void Activate(void)
Definition: mythuianimation.cpp:50
MythUIWebBrowser
Web browsing widget.
Definition: mythuiwebbrowser.h:132
BrowserApi::customEvent
void customEvent(QEvent *e) override
Definition: mythuiwebbrowser.cpp:243
MythCoreContext::GetFloatSetting
double GetFloatSetting(const QString &key, double defaultval=0.0)
Definition: mythcorecontext.cpp:923
MythTextInputDialog
Dialog prompting the user to enter a text string.
Definition: mythdialogbox.h:314
MythUIWebBrowser::m_lastMouseActionTime
QElapsedTimer m_lastMouseActionTime
Definition: mythuiwebbrowser.h:244
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:885
MythWebView::MythWebView
MythWebView(QWidget *parent, MythUIWebBrowser *parentBrowser)
Definition: mythuiwebbrowser.cpp:356
MythImage::Assign
void Assign(const QImage &img)
Definition: mythimage.cpp:77
DestroyNetworkAccessManager
static void DestroyNetworkAccessManager(void)
Definition: mythuiwebbrowser.cpp:92
MythUIWebBrowser::slotLoadStarted
void slotLoadStarted(void)
a file has been downloaded
Definition: mythuiwebbrowser.cpp:1339
MythWebView::keyPressEvent
void keyPressEvent(QKeyEvent *event) override
Definition: mythuiwebbrowser.cpp:394
mythdownloadmanager.h
MythUIType::ParseElement
virtual bool ParseElement(const QString &filename, QDomElement &element, bool showWarnings)
Parse the xml definition of this widget setting the state of the object accordingly.
Definition: mythuitype.cpp:1237
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:66
BrowserApi::Play
static void Play(void)
Definition: mythuiwebbrowser.cpp:151
mythuiwebbrowser.h
MythUIWebBrowser::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythuiwebbrowser.cpp:1515
build_compdb.filename
filename
Definition: build_compdb.py:21
MythWebView::handleDownloadRequested
void handleDownloadRequested(const QNetworkRequest &request)
Definition: mythuiwebbrowser.cpp:483
mythmainwindow.h
MythUIWebBrowser::IsOnTopScreen
bool IsOnTopScreen(void)
is our containing screen the top screen?
Definition: mythuiwebbrowser.cpp:1402
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
MythUIType::SetRedraw
void SetRedraw(void)
Definition: mythuitype.cpp:313
XMLParseBase::parseBool
static bool parseBool(const QString &text)
Definition: xmlparsebase.cpp:64
MythUIWebBrowser::SetBackgroundColor
void SetBackgroundColor(QColor color)
Sets the default background color.
Definition: mythuiwebbrowser.cpp:1091
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1727
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:566
output
#define output
Definition: synaesthesia.cpp:223
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
MythWebView::m_downloadRequest
QNetworkRequest m_downloadRequest
Definition: mythuiwebbrowser.h:120
MythUIWebBrowser::slotIconChanged
void slotIconChanged(void)
Definition: mythuiwebbrowser.cpp:1371
MythUIType::Finalize
virtual void Finalize(void)
Perform any post-xml parsing initialisation tasks.
Definition: mythuitype.cpp:1312
MythUIWebBrowser::m_lastMouseAction
QString m_lastMouseAction
Definition: mythuiwebbrowser.h:242
BrowserApi::attachObject
void attachObject()
Definition: mythuiwebbrowser.cpp:146
MythUIScrollBar::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuiscrollbar.cpp:15
MythUIWebBrowser::m_image
MythImage * m_image
Definition: mythuiwebbrowser.h:226
BrowserApi::PlayFile
static void PlayFile(const QString &filename)
Definition: mythuiwebbrowser.cpp:199
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:146
MythScreenStack::GetTopScreen
virtual MythScreenType * GetTopScreen(void) const
Definition: mythscreenstack.cpp:182