MythTV  master
nettree.cpp
Go to the documentation of this file.
1 // qt
2 #include <QString>
3 #include <QFileInfo>
4 #include <QtAlgorithms>
5 
6 // myth
7 #include <mythdb.h>
8 #include <mythcontext.h>
9 #include <mythdirs.h>
10 #include <mythsystemlegacy.h>
11 #include <mythprogressdialog.h>
12 #include <rssparse.h>
13 #include <netutils.h>
14 #include <mythrssmanager.h>
15 #include <netgrabbermanager.h>
16 #include <mythcoreutil.h>
17 #include <metadata/videoutils.h>
18 #include <mythuiimage.h>
19 #include <mythuitext.h>
20 #include <mythscreenstack.h>
21 #include <mythmainwindow.h>
22 #include <mythsorthelper.h>
23 
24 // mythnetvision
25 #include "treeeditor.h"
26 #include "nettree.h"
27 #include "rsseditor.h"
28 #include "netcommon.h"
29 
30 class GrabberScript;
31 
32 const QString NetTree::RSSNode = tr("RSS Feeds");
33 const QString NetTree::SearchNode = tr("Searches");
34 const QString NetTree::DownloadNode = tr("Downloaded Files");
35 
36 namespace
37 {
38  MythGenericTree *GetNodePtrFromButton(MythUIButtonListItem *item)
39  {
40  if (item)
41  return item->GetData().value<MythGenericTree *>();
42 
43  return nullptr;
44  }
45 }
46 
48  : NetBase(parent, name),
49  m_gdt(new GrabberDownloadThread(this)), m_type(type)
50 {
51  connect(m_gdt, SIGNAL(finished()), SLOT(DoTreeRefresh()));
53  "mythNetTree.updateFreq", 6);
55  "mythnetvision.rssBackgroundFetch", false);
57  "mythnetvision.backgroundFetch", false);
58 }
59 
61 {
62  QString windowName = "gallery";
63 
64  switch (m_type)
65  {
66  case DLG_GALLERY:
67  windowName = "gallery";
68  break;
69  case DLG_BROWSER:
70  windowName = "browser";
71  break;
72  case DLG_TREE:
73  windowName = "tree";
74  break;
75  case DLG_DEFAULT:
76  default:
77  break;
78  }
79 
80  if (!LoadWindowFromXML("netvision-ui.xml", windowName, this))
81  return false;
82 
83  bool err = false;
84  if (m_type == DLG_TREE)
85  UIUtilE::Assign(this, m_siteMap, "videos", &err);
86  else
87  UIUtilE::Assign(this, m_siteButtonList, "videos", &err);
88 
89  UIUtilW::Assign(this, m_noSites, "nosites");
90 
91  UIUtilW::Assign(this, m_thumbImage, "preview");
92 
93  UIUtilW::Assign(this, m_downloadable, "downloadable");
94 
95  m_siteGeneric = new MythGenericTree("site root", 0, false);
97 
98  if (err)
99  {
100  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen '" + windowName + "'");
101  return false;
102  }
103 
104  BuildFocusList();
105 
107 
108  if (m_type == DLG_TREE)
109  {
111 
112  connect(m_siteMap, SIGNAL(itemClicked(MythUIButtonListItem *)),
113  SLOT(StreamWebVideo(void)));
114  connect(m_siteMap, SIGNAL(itemSelected(MythUIButtonListItem *)),
115  SLOT(SlotItemChanged(void)));
116  connect(m_siteMap, SIGNAL(nodeChanged(MythGenericTree *)),
117  SLOT(SlotItemChanged(void)));
118  }
119  else
120  {
122 
123  connect(m_siteButtonList, SIGNAL(itemClicked(MythUIButtonListItem *)),
125  connect(m_siteButtonList, SIGNAL(itemSelected(MythUIButtonListItem *)),
126  SLOT(SlotItemChanged(void)));
127  }
128 
129  return true;
130 }
131 
133 {
136 
137  FillTree();
138 }
139 
141 {
142  if (!node)
143  return;
144 
145  m_currentNode = node;
146 }
147 
149 {
150  delete m_siteGeneric;
151  m_siteGeneric = nullptr;
152 
153  delete m_gdt;
154  m_gdt = nullptr;
155 
156  m_rssList.clear();
157 
158  qDeleteAll(m_videos);
159  m_videos.clear();
160 }
161 
163 {
164  if (m_type == DLG_TREE)
166  else
167  {
169 
170  if (!m_currentNode)
172 
173  if (!m_currentNode)
174  return;
175 
177 
178  typedef QList<MythGenericTree *> MGTreeChildList;
179  MGTreeChildList *lchildren = m_currentNode->getAllChildren();
180 
181  for (MGTreeChildList::const_iterator p = lchildren->begin();
182  p != lchildren->end(); ++p)
183  {
184  if (*p != nullptr)
185  {
186  MythUIButtonListItem *item =
187  new MythUIButtonListItem(m_siteButtonList, QString(), nullptr,
189 
190  item->SetData(qVariantFromValue(*p));
191 
192  UpdateItem(item);
193 
194  if (*p == selectedNode)
196  }
197  }
198 
199  SlotItemChanged();
200  }
201 
202  if (m_siteGeneric->childCount() == 0 && m_noSites)
203  m_noSites->SetVisible(true);
204  else if (m_noSites)
205  m_noSites->SetVisible(false);
206 
207  if (m_siteGeneric->childCount() == 0)
208  RunTreeEditor();
209 }
210 
212 {
213  if (!item)
214  return;
215 
216  MythGenericTree *node = GetNodePtrFromButton(item);
217 
218  if (!node)
219  return;
220 
221  RSSSite *site = node->GetData().value<RSSSite *>();
222  ResultItem *video = node->GetData().value<ResultItem *>();
223 
224  int nodeInt = node->getInt();
225 
226  if (nodeInt == kSubFolder)
227  {
228  item->SetText(QString("%1").arg(node->visibleChildCount()),
229  "childcount");
230  item->DisplayState("subfolder", "nodetype");
231  item->SetText(node->GetText(), "title");
232  item->SetText(node->GetText());
233  item->SetImage(node->GetData().toString());
234  }
235  else if (nodeInt == kUpFolder)
236  {
237  item->DisplayState("upfolder", "nodetype");
238  item->SetText(node->GetText(), "title");
239  item->SetText(node->GetText());
240  }
241 
242  if (site)
243  {
244  item->SetText(site->GetTitle());
245  item->SetText(site->GetDescription(), "description");
246  item->SetText(site->GetURL(), "url");
247  item->SetImage(site->GetImage());
248  }
249  else if (video)
250  {
251  item->SetText(video->GetTitle());
252 
253  InfoMap metadataMap;
254  video->toMap(metadataMap);
255  item->SetTextFromMap(metadataMap);
256 
257  int pos;
258  if (m_type == DLG_TREE)
259  pos = 0;
260  else
261  pos = m_siteButtonList->GetItemPos(item);
262 
263  QString dlfile = video->GetThumbnail();
264  if (dlfile.contains("%SHAREDIR%"))
265  dlfile.replace("%SHAREDIR%", GetShareDir());
266  else
267  dlfile = getDownloadFilename(video->GetTitle(),
268  video->GetThumbnail());
269 
270  if (QFile::exists(dlfile))
271  item->SetImage(dlfile);
272  else if (video->GetThumbnail().startsWith("http"))
273  m_imageDownload->addThumb(video->GetTitle(), video->GetThumbnail(),
274  qVariantFromValue<uint>(pos));
275  }
276  else
277  {
278  item->SetText(node->GetText());
279  if (!node->GetData().toString().isEmpty())
280  {
281  QString tpath = node->GetData().toString();
282  if (tpath.startsWith("http://"))
283  {
284  uint pos;
285  if (m_type == DLG_TREE)
286  pos = 0;
287  else
288  pos = m_siteButtonList->GetItemPos(item);
289 
290  QString dlfile = GetThumbnailFilename(tpath,
291  node->GetText());
292  if (QFile::exists(dlfile))
293  item->SetImage(dlfile);
294  else
295  m_imageDownload->addThumb(node->GetText(), tpath,
296  qVariantFromValue<uint>(pos));
297  }
298  else if (tpath != "0")
299  {
300  QString filename = node->GetData().toString();
301  if (filename.contains("%SHAREDIR%"))
302  filename.replace("%SHAREDIR%", GetShareDir());
303  item->SetImage(filename);
304  }
305  }
306  }
307 }
308 
310 {
311  MythGenericTree *node = GetNodePtrFromButton(item);
312  if (!node)
313  return;
314 
315  int nodeInt = node->getInt();
316 
317  switch (nodeInt)
318  {
319  case kSubFolder:
320  HandleDirSelect(node);
321  break;
322  case kUpFolder:
323  GoBack();
324  break;
325  default:
326  {
327  StreamWebVideo();
328  }
329  }
330  SlotItemChanged();
331 }
332 
334 {
337 
338  SetCurrentNode(node);
339  LoadData();
340 }
341 
343 {
344  bool handled = false;
345 
348 
350  {
352  if (lparent)
353  {
354  SetCurrentNode(lparent);
355  handled = true;
356  }
357  }
358 
359  LoadData();
360 
361  return handled;
362 }
363 
364 bool NetTree::keyPressEvent(QKeyEvent *event)
365 {
366  if (GetFocusWidget()->keyPressEvent(event))
367  return true;
368 
369  QStringList actions;
370  bool handled = GetMythMainWindow()->TranslateKeyPress("Internet Video",
371  event, actions);
372 
373  for (int i = 0; i < actions.size() && !handled; i++)
374  {
375  QString action = actions[i];
376  handled = true;
377 
378  if (action == "MENU")
379  {
380  ShowMenu();
381  }
382  else if (action == "ESCAPE")
383  {
384  if (m_type != DLG_TREE
385  && !GetMythMainWindow()->IsExitingToMain()
387  handled = GoBack();
388  else
389  handled = false;
390  }
391  else
392  handled = false;
393  }
394 
395  if (!handled && MythScreenType::keyPressEvent(event))
396  handled = true;
397 
398  return handled;
399 }
400 
402 {
403  QString label = tr("Playback/Download Options");
404 
405  MythMenu *menu = new MythMenu(label, this, "options");
406 
407  ResultItem *item = nullptr;
408  if (m_type == DLG_TREE)
409  {
411 
412  if (node)
413  item = node->GetData().value<ResultItem *>();
414  }
415  else
416  {
417  MythGenericTree *node =
418  GetNodePtrFromButton(m_siteButtonList->GetItemCurrent());
419 
420  if (node)
421  item = node->GetData().value<ResultItem *>();
422  }
423 
424  if (item)
425  {
426  if (item->GetDownloadable())
427  menu->AddItem(tr("Stream Video"), SLOT(StreamWebVideo()));
428  menu->AddItem(tr("Open Web Link"), SLOT(ShowWebVideo()));
429 
430  if (item->GetDownloadable())
431  menu->AddItem(tr("Save This Video"), SLOT(DoDownloadAndPlay()));
432  }
433 
434  menu->AddItem(tr("Scan/Manage Subscriptions"), nullptr, CreateShowManageMenu());
435  menu->AddItem(tr("Change View"), nullptr, CreateShowViewMenu());
436 
437  MythDialogBox *menuPopup =
438  new MythDialogBox(menu, m_popupStack, "mythnettreemenupopup");
439 
440  if (menuPopup->Create())
441  m_popupStack->AddScreen(menuPopup);
442  else
443  delete menuPopup;
444 }
445 
447 {
448  QString label = tr("View Options");
449 
450  MythMenu *menu = new MythMenu(label, this, "options");
451 
452  if (m_type != DLG_TREE)
453  menu->AddItem(tr("Switch to List View"), SLOT(SwitchTreeView()));
454  if (m_type != DLG_GALLERY)
455  menu->AddItem(tr("Switch to Gallery View"), SLOT(SwitchGalleryView()));
456  if (m_type != DLG_BROWSER)
457  menu->AddItem(tr("Switch to Browse View"), SLOT(SwitchBrowseView()));
458 
459  return menu;
460 }
461 
463 {
464  QString label = tr("Subscription Management");
465 
466  MythMenu *menu = new MythMenu(label, this, "options");
467 
468  menu->AddItem(tr("Update Site Maps"), SLOT(UpdateTrees()));
469  menu->AddItem(tr("Update RSS"), SLOT(UpdateRSS()));
470  menu->AddItem(tr("Manage Site Subscriptions"), SLOT(RunTreeEditor()));
471  menu->AddItem(tr("Manage RSS Subscriptions"), SLOT(RunRSSEditor()));
472  if (!m_treeAutoUpdate)
473  menu->AddItem(tr("Enable Automatic Site Updates"),
474  SLOT(ToggleTreeUpdates()));
475  else
476  menu->AddItem(tr("Disable Automatic Site Updates"),
477  SLOT(ToggleTreeUpdates()));
478 // if (!m_rssAutoUpdate)
479 // menu->AddItem(tr("Enable Automatic RSS Updates"), SLOT(ToggleRSSUpdates()));
480 // else
481 // menu->AddItem(tr("Disable Automatic RSS Updates"), SLOT(ToggleRSSUpdates()));
482 
483  return menu;
484 }
485 
487 {
488  m_type = DLG_TREE;
489  SwitchView();
490 }
491 
493 {
495  SwitchView();
496 }
497 
499 {
501  SwitchView();
502 }
503 
505 {
506  NetTree *nettree =
507  new NetTree(m_type, GetMythMainWindow()->GetMainStack(), "nettree");
508 
509  if (nettree->Create())
510  {
511  gCoreContext->SaveSetting("mythnetvision.ViewMode", m_type);
512  MythScreenStack *screenStack = GetScreenStack();
513  screenStack->AddScreen(nettree);
514  screenStack->PopScreen(this, false, false);
515  deleteLater();
516  }
517  else
518  delete nettree;
519 }
520 
522 {
523  // First let's add all the RSS
524  if (!m_rssList.isEmpty())
525  {
526  MythGenericTree *rssGeneric =
527  new MythGenericTree(RSSNode, kSubFolder, false);
528 
529  // Add an upfolder
530  if (m_type != DLG_TREE)
531  rssGeneric->addNode(tr("Back"), kUpFolder, true, false);
532 
533  rssGeneric->SetData(QString("%1/mythnetvision/icons/rss.png")
534  .arg(GetShareDir()));
535 
536  RSSSite::rssList::iterator i = m_rssList.begin();
537  for (; i != m_rssList.end(); ++i)
538  {
539  ResultItem::resultList items = getRSSArticles((*i)->GetTitle(),
540  VIDEO_PODCAST);
541  MythGenericTree *ret =
542  new MythGenericTree((*i)->GetTitle(), kSubFolder, false);
543  ret->SetData(qVariantFromValue(*i));
544  rssGeneric->addNode(ret);
545 
546  // Add an upfolder
547  if (m_type != DLG_TREE)
548  ret->addNode(tr("Back"), kUpFolder, true, false);
549 
550  ResultItem::resultList::iterator it = items.begin();
551  for (; it != items.end(); ++it)
552  AddFileNode(ret, *it);
553  SetSubfolderData(ret);
554  }
555 
556  m_siteGeneric->addNode(rssGeneric);
557  SetSubfolderData(rssGeneric);
558  }
559 
560  // Now let's add all the grabber trees
561  for (GrabberScript::scriptList::iterator g = m_grabberList.begin();
562  g != m_grabberList.end(); ++g)
563  {
564 
565  QMultiMap<QPair<QString,QString>, ResultItem*> treePathsNodes =
566  getTreeArticles((*g)->GetTitle(), VIDEO_FILE);
567 
568  QList< QPair<QString,QString> > paths = treePathsNodes.uniqueKeys();
569 
570  MythGenericTree *ret = new MythGenericTree(
571  (*g)->GetTitle(), kSubFolder, false);
572  QString thumb = QString("%1mythnetvision/icons/%2").arg(GetShareDir())
573  .arg((*g)->GetImage());
574  ret->SetData(qVariantFromValue(thumb));
575 
576  // Add an upfolder
577  if (m_type != DLG_TREE)
578  ret->addNode(tr("Back"), kUpFolder, true, false);
579 
580  for (auto it2 = paths.begin(); it2 != paths.end(); ++it2)
581  {
582  QStringList curPaths = (*it2).first.split("/");
583  QString dirthumb = (*it2).second;
584  QList<ResultItem*> videos = treePathsNodes.values(*it2);
585  BuildGenericTree(ret, curPaths, dirthumb, videos);
586  }
587  m_siteGeneric->addNode(ret);
588  SetSubfolderData(ret);
589  }
591 }
592 
593 void NetTree::BuildGenericTree(MythGenericTree *dst, QStringList paths,
594  const QString& dirthumb, QList<ResultItem*> videos)
595 {
596  MythGenericTree *folder = nullptr;
597 
598  // A little loop to determine what path of the provided path might
599  // already exist in the tree.
600 
601  while (folder == nullptr && !paths.empty())
602  {
603  QString curPath = paths.takeFirst();
604  curPath.replace("|", "/");
605  MythGenericTree *tmp = dst->getChildByName(curPath);
606  if (tmp)
607  dst = tmp;
608  else
609  folder = new MythGenericTree(curPath, kSubFolder, false);
610  }
611 
612  if (!folder)
613  return;
614 
615  folder->SetData(dirthumb);
616  dst->addNode(folder);
617 
618  // Add an upfolder
619  if (m_type != DLG_TREE)
620  folder->addNode(tr("Back"), kUpFolder, true, false);
621 
622  if (!paths.empty())
623  BuildGenericTree(folder, paths, dirthumb, videos);
624  else
625  {
626  // File Handling
627  for (QList<ResultItem*>::iterator it = videos.begin();
628  it != videos.end(); ++it)
629  AddFileNode(folder, *it);
630  }
631  SetSubfolderData(folder);
632 }
633 
635 {
636  QString title = video->GetTitle();
637  title.replace("&amp;", "&");
638  MythGenericTree *sub_node = where_to_add->addNode(title, 0, true);
639  sub_node->SetData(qVariantFromValue(video));
640 
641  InfoMap textMap;
642  video->toMap(textMap);
643  sub_node->SetTextFromMap(textMap);
644 
645  m_videos.append(video);
646 }
647 
649 {
650  ResultItem *item = nullptr;
651 
652  if (m_type == DLG_TREE)
653  item = m_siteMap->GetCurrentNode()->GetData().value<ResultItem *>();
654  else
655  {
656  MythGenericTree *node =
657  GetNodePtrFromButton(m_siteButtonList->GetItemCurrent());
658 
659  if (node)
660  item = node->GetData().value<ResultItem *>();
661  }
662  return item;
663 }
664 
666 {
667  InfoMap metadataMap;
668  item->toMap(metadataMap);
669  SetTextFromMap(metadataMap);
670 
671  if (!item->GetThumbnail().isEmpty() && m_thumbImage)
672  {
673  m_thumbImage->Reset();
674  QString dlfile = item->GetThumbnail();
675  if (dlfile.contains("%SHAREDIR%"))
676  {
677  dlfile.replace("%SHAREDIR%", GetShareDir());
678  m_thumbImage->SetFilename(dlfile);
679  m_thumbImage->Load();
680  }
681  else
682  {
683  QString sFilename = getDownloadFilename(item->GetTitle(),
684  item->GetThumbnail());
685 
686  bool exists = QFile::exists(sFilename);
687  if (exists)
688  {
689  m_thumbImage->SetFilename(sFilename);
690  m_thumbImage->Load();
691  }
692  else if (item->GetThumbnail().startsWith("http"))
693  {
695  item->GetThumbnail(),
696  qVariantFromValue<uint>(0));
697  }
698  }
699  }
700  else if (m_thumbImage)
701  m_thumbImage->Reset();
702 
703  if (m_downloadable)
704  {
705  if (item->GetDownloadable())
707  else
709  }
710 }
711 
713 {
714  ResultItem res =
715  ResultItem(site->GetTitle(), site->GetSortTitle(),
716  QString(), QString(), // no subtitle information
717  site->GetDescription(),
718  site->GetURL(), site->GetImage(), QString(),
719  site->GetAuthor(), QDateTime(), nullptr, nullptr, -1, QString(),
720  QStringList(), QString(), QStringList(), 0, 0, QString(),
721  false, QStringList(), 0, 0, false);
722 
723  InfoMap metadataMap;
724  res.toMap(metadataMap);
725  SetTextFromMap(metadataMap);
726 
727  if (!site->GetImage().isEmpty() && m_thumbImage)
728  {
730  m_thumbImage->Load();
731  }
732  else if (m_thumbImage)
733  m_thumbImage->Reset();
734 
735  if (m_downloadable)
737 }
738 
740 {
741  QString title;
742 
743  if (m_type == DLG_TREE)
744  title = m_siteMap->GetItemCurrent()->GetText();
745  else
747 
748  QString thumb;
749  if (m_type == DLG_TREE)
750  thumb = m_siteMap->GetCurrentNode()->GetData().toString();
751  else
752  {
753  MythGenericTree *node =
754  GetNodePtrFromButton(m_siteButtonList->GetItemCurrent());
755 
756  if (node)
757  thumb = node->GetData().toString();
758  }
759 
760  std::shared_ptr<MythSortHelper>sh = getMythSortHelper();
761  ResultItem res =
762  ResultItem(title, sh->doTitle(title), // title, sortTitle
763  QString(), QString(), // no subtitle information
764  QString(), // description
765  QString(), thumb, QString(),
766  QString(), QDateTime(), nullptr, nullptr, -1, QString(),
767  QStringList(), QString(), QStringList(), 0, 0, QString(),
768  false, QStringList(), 0, 0, false);
769 
770  InfoMap metadataMap;
771  res.toMap(metadataMap);
772  SetTextFromMap(metadataMap);
773 
774  if (m_thumbImage)
775  {
776  if (!thumb.startsWith("http://"))
777  {
778  if (thumb.contains("%SHAREDIR%"))
779  thumb.replace("%SHAREDIR%", GetShareDir());
780 
781  bool exists = QFile::exists(thumb);
782 
783  if (exists)
784  {
785  m_thumbImage->SetFilename(thumb);
786  m_thumbImage->Load();
787  }
788  else
789  m_thumbImage->Reset();
790  }
791  else
792  {
793  const QString& url = thumb;
794  QString title2;
795  if (m_type == DLG_TREE)
796  title2 = m_siteMap->GetItemCurrent()->GetText();
797  else
798  title2 = m_siteButtonList->GetItemCurrent()->GetText();
799 
800  QString sFilename = GetDownloadFilename(title2, url);
801 
802  bool exists = QFile::exists(sFilename);
803  if (exists && !url.isEmpty())
804  {
805  m_thumbImage->SetFilename(sFilename);
806  m_thumbImage->Load();
807  }
808  else
809  m_thumbImage->Reset();
810  }
811  }
812 
813  if (m_downloadable)
815 }
816 
818 {
819  ResultItem *item;
820  RSSSite *site;
821 
822  if (m_type == DLG_TREE)
823  {
824  item = m_siteMap->GetCurrentNode()->GetData().value<ResultItem *>();
825  site = m_siteMap->GetCurrentNode()->GetData().value<RSSSite *>();
826  }
827  else
828  {
829  MythGenericTree *node =
830  GetNodePtrFromButton(m_siteButtonList->GetItemCurrent());
831 
832  if (!node)
833  return;
834 
835  item = node->GetData().value<ResultItem *>();
836  site = node->GetData().value<RSSSite *>();
837  }
838 
839  if (item)
840  UpdateResultItem(item);
841  else if (site)
842  UpdateSiteItem(site);
843  else
845 }
846 
848 {
850 
851  TreeEditor *treeedit = new TreeEditor(mainStack, "mythnettreeedit");
852 
853  if (treeedit->Create())
854  {
855  connect(treeedit, SIGNAL(ItemsChanged()), this, SLOT(DoTreeRefresh()));
856 
857  mainStack->AddScreen(treeedit);
858  }
859  else
860  delete treeedit;
861 }
862 
864 {
866 
867  RSSEditor *rssedit = new RSSEditor(mainStack, "mythnetrssedit");
868 
869  if (rssedit->Create())
870  {
871  connect(rssedit, SIGNAL(ItemsChanged()), this, SLOT(UpdateRSS()));
872 
873  mainStack->AddScreen(rssedit);
874  }
875  else
876  delete rssedit;
877 }
878 
880 {
881  CloseBusyPopup();
882 
883  TreeRefresh();
884 }
885 
887 {
888  delete m_siteGeneric;
889  m_siteGeneric = new MythGenericTree("site root", 0, false);
891 
894 
895  FillTree();
896  LoadData();
897  SwitchView();
898 }
899 
901 {
902  if (findAllDBRSS().isEmpty())
903  return;
904 
905  QString title(tr("Updating RSS. This could take a while..."));
906  OpenBusyPopup(title);
907 
908  RSSManager *rssMan = new RSSManager();
909  connect(rssMan, SIGNAL(finished()), this, SLOT(DoTreeRefresh()));
910  rssMan->startTimer();
911  rssMan->doUpdate();
912 }
913 
915 {
916  if (m_grabberList.count() == 0)
917  return;
918 
919  QString title(tr("Updating Site Maps. This could take a while..."));
920  OpenBusyPopup(title);
921  m_gdt->refreshAll();
922 }
923 
925 {
927  gCoreContext->SaveBoolSetting("mythnetvision.rssBackgroundFetch",
929 }
930 
932 {
934  gCoreContext->SaveBoolSetting("mythnetvision.backgroundFetch",
936 }
937 
938 void NetTree::customEvent(QEvent *event)
939 {
940  if (event->type() == ThumbnailDLEvent::kEventType)
941  {
942  ThumbnailDLEvent *tde = (ThumbnailDLEvent *)event;
943 
944  if (!tde)
945  return;
946 
947  ThumbnailData *data = tde->m_thumb;
948 
949  if (!data)
950  return;
951 
952  QString title = data->title;
953  QString file = data->url;
954  uint pos = data->data.value<uint>();
955 
956  if (file.isEmpty())
957  return;
958 
959  if (m_type == DLG_TREE)
960  {
961  if (title == m_siteMap->GetCurrentNode()->GetText() &&
962  m_thumbImage)
963  {
964  m_thumbImage->SetFilename(file);
965  m_thumbImage->Load();
966  m_thumbImage->Show();
967  }
968  }
969  else
970  {
971  if (!((uint)m_siteButtonList->GetCount() >= pos))
972  return;
973 
975 
976  if (item && item->GetText() == title)
977  item->SetImage(file);
978  }
979  }
980  else
981  NetBase::customEvent(event);
982 }
983 
985 {
986  folder->SetText(QString("%1").arg(folder->visibleChildCount()),
987  "childcount");
988  folder->DisplayState("subfolder", "nodetype");
989 }
void TreeRefresh()
Definition: nettree.cpp:886
void RunTreeEditor(void)
Definition: nettree.cpp:847
bool m_treeAutoUpdate
Definition: nettree.h:98
MythGenericTree * GetCurrentNode(void) const
static const QString RSSNode
Definition: nettree.h:126
MythScreenStack * GetScreenStack() const
void StreamWebVideo(void)
Definition: netbase.cpp:87
MythGenericTree * getSelectedChild(bool onlyVisible=false) const
void Show(void)
bool Create(void) override
Definition: rsseditor.cpp:312
void DoDownloadAndPlay(void)
Definition: netbase.cpp:279
static const QString SearchNode
Definition: nettree.h:127
MythGenericTree * addNode(const QString &a_string, int an_int=0, bool selectable_flag=false, bool visible=true)
uint visibleChildCount() const
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:607
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
uint m_updateFreq
Definition: nettree.h:96
QList< MythGenericTree * > * getAllChildren() const
MythUIText * m_noSites
Definition: nettree.h:89
GrabberDownloadThread * m_gdt
Definition: nettree.h:91
void SetText(const QString &text, const QString &name="", const QString &state="")
void SwitchBrowseView(void)
Definition: nettree.cpp:498
void SetData(QVariant data)
void HandleDirSelect(MythGenericTree *node)
Definition: nettree.cpp:333
void UpdateItem(MythUIButtonListItem *item)
Definition: nettree.cpp:211
void SaveSetting(const QString &key, int newValue)
void ShowMenu(void) override
Definition: nettree.cpp:401
void RunRSSEditor(void)
Definition: nettree.cpp:863
void UpdateTrees()
Definition: nettree.cpp:914
void finished(void)
void UpdateResultItem(ResultItem *item)
Definition: nettree.cpp:665
Basic menu dialog, message and a list of options.
int childCount(void) const
const QVariant GetData(void) const
int GetItemPos(MythUIButtonListItem *item) const
void UpdateRSS()
Definition: nettree.cpp:900
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
GrabberScript::scriptList findAllDBTreeGrabbers()
Definition: netutils.cpp:115
MythScreenStack * GetMainStack()
MythUIButtonListItem * GetItemAt(int pos) const
void customEvent(QEvent *levent) override
Definition: nettree.cpp:938
void DisplayState(const QString &state, const QString &name="")
void ShowWebVideo(void)
Definition: netbase.cpp:106
static MythThemedMenu * menu
static guint32 * tmp
Definition: goom_core.c:35
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
void BuildFocusList(void)
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
MythMenu * CreateShowManageMenu(void)
Definition: nettree.cpp:462
MythUIButtonList * m_siteButtonList
Definition: nettree.h:85
GrabberScript::scriptList m_grabberList
Definition: netbase.h:52
QString GetText(const QString &name="") const
void SlotItemChanged()
Definition: nettree.cpp:817
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
QMultiMap< QPair< QString, QString >, ResultItem * > getTreeArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:460
virtual void SetVisible(bool visible)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void SwitchView(void)
Definition: nettree.cpp:504
const QString & GetSortTitle() const
NetTree(DialogType type, MythScreenStack *parent, const char *name=nullptr)
Definition: nettree.cpp:47
QString GetDownloadFilename(const QString &title, const QString &url)
Definition: netutils.cpp:851
void SwitchTreeView(void)
Definition: nettree.cpp:486
DialogType
Definition: nettree.h:20
MythScreenStack * m_popupStack
Definition: netbase.h:47
ResultItem * GetStreamItem() override
Definition: nettree.cpp:648
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
const bool & GetDownloadable() const
Definition: rssparse.h:154
QString GetShareDir(void)
Definition: mythdirs.cpp:222
bool isRunning(void) const
Definition: mthread.cpp:274
void OpenBusyPopup(const QString &message="")
void Reset(void) override
Reset the image back to the default defined in the theme.
void BuildGenericTree(MythGenericTree *dst, QDomElement &domElem)
virtual void SetTextFromMap(const InfoMap &infoMap)
void FillTree(void)
Definition: nettree.cpp:521
GrabberScript::scriptList findAllDBTreeGrabbersByHost(ArticleType type)
Definition: netutils.cpp:149
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
const QString & GetImage() const
void DoTreeRefresh()
Definition: nettree.cpp:879
void SetText(const QString &text, const QString &name="", const QString &state="")
MythUIImage * m_thumbImage
Definition: netbase.h:45
MythMenu * CreateShowViewMenu(void)
Definition: nettree.cpp:446
bool Create(void) override
const char * name
Definition: ParseText.cpp:328
void SwitchGalleryView(void)
Definition: nettree.cpp:492
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void UpdateSiteItem(RSSSite *site)
Definition: nettree.cpp:712
MythUIType * GetFocusWidget(void) const
const QString & GetURL() const
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
MythMainWindow * GetMythMainWindow(void)
DialogType m_type
Definition: nettree.h:94
QString GetText(const QString &name="") const
ThumbnailData * m_thumb
RSSSite::rssList m_rssList
Definition: nettree.h:92
MythUIButtonTree * m_siteMap
Definition: nettree.h:84
int getInt() const
int GetNumSetting(const QString &key, int defaultval=0)
bool keyPressEvent(QKeyEvent *) override
Key event handler.
Definition: nettree.cpp:364
bool keyPressEvent(QKeyEvent *) override
Key event handler.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void LoadData(void) override
Definition: nettree.cpp:162
void CloseBusyPopup(void)
const QString & GetTitle() const
bool GetBoolSetting(const QString &key, bool defaultval=false)
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
void customEvent(QEvent *event) override
Definition: netbase.cpp:222
void ToggleRSSUpdates()
Definition: nettree.cpp:924
const QString & GetAuthor() const
MythGenericTree * getChildByName(const QString &a_name) const
void UpdateCurrentItem(void)
Definition: nettree.cpp:739
const QString & GetDescription() const
void SetCurrentNode(MythGenericTree *node)
Definition: nettree.cpp:140
MythUIButtonListItem * GetItemCurrent(void) const
Return the currently selected list item.
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
const QString & GetTitle() const
Definition: rssparse.h:134
void addThumb(QString title, QString url, QVariant data)
bool AssignTree(MythGenericTree *tree)
Assign the root node of the tree to be displayed.
MetadataImageDownload * m_imageDownload
Definition: netbase.h:49
void Load() override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
Definition: nettree.cpp:132
void SetSubfolderData(MythGenericTree *folder)
Definition: nettree.cpp:984
QList< ResultItem * > m_videos
Definition: nettree.h:82
MythUIStateType * m_downloadable
Definition: netbase.h:46
void SetData(QVariant data)
bool m_rssAutoUpdate
Definition: nettree.h:97
QString GetThumbnailFilename(const QString &url, const QString &title)
Definition: netcommon.cpp:9
bool DisplayState(const QString &name)
void startTimer()
~NetTree()
Definition: nettree.cpp:148
MythGenericTree * getParent(void) const
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
static const QString DownloadNode
Definition: nettree.h:128
void SetItemCurrent(MythUIButtonListItem *item)
bool GoBack()
Definition: nettree.cpp:342
bool SetFocusWidget(MythUIType *widget=nullptr)
void HandleSelect(MythUIButtonListItem *item)
Definition: nettree.cpp:309
MythGenericTree * m_siteGeneric
Definition: nettree.h:86
ResultItem::resultList getRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:794
void SaveBoolSetting(const QString &key, bool newValue)
QList< ResultItem * > resultList
Definition: rssparse.h:114
void ToggleTreeUpdates()
Definition: nettree.cpp:931
void AddFileNode(MythGenericTree *where_to_add, ResultItem *video)
Definition: nettree.cpp:634
void DisplayState(const QString &state, const QString &name)
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
QString getDownloadFilename(const QString &title, const QString &url)
const QString & GetThumbnail() const
Definition: rssparse.h:140
bool Create(void) override
Definition: nettree.cpp:60
MythGenericTree * m_currentNode
Definition: nettree.h:87
MythUIButtonListItem * GetItemCurrent() const
void LoadInBackground(QString message="")
bool Create(void) override
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
void toMap(InfoMap &metadataMap)
Definition: rssparse.cpp:76
unsigned char g
Definition: ParseText.cpp:329
ArticleType m_type