MythTV  master
videodlg.cpp
Go to the documentation of this file.
1 // C++
2 #include <chrono>
3 #include <functional> //binary_negate
4 #include <map>
5 #include <memory>
6 #include <set>
7 
8 // Qt
9 #include <QApplication>
10 #include <QDir>
11 #include <QFile>
12 #include <QFileInfo>
13 #include <QList>
14 #include <QTimer>
15 #include <QUrl>
16 
17 // MythTV
18 #include "libmyth/mythcontext.h"
19 #include "libmythbase/mythdirs.h"
20 #include "libmythbase/mythrandom.h"
22 #include "libmythbase/remotefile.h"
23 #include "libmythbase/remoteutil.h"
29 #include "libmythmetadata/metadataimagedownload.h" // for ImageDLFailureEvent
38 #include "libmythui/mythuibutton.h"
41 #include "libmythui/mythuihelper.h"
42 #include "libmythui/mythuiimage.h"
44 #include "libmythui/mythuitext.h"
45 
46 // MythFrontend
47 #include "editvideometadata.h"
48 #include "videodlg.h"
49 #include "videofileassoc.h"
50 #include "videofilter.h"
51 #include "videolist.h"
52 #include "videometadatasettings.h"
53 #include "videoplayercommand.h"
54 #include "videoplayersettings.h"
55 #include "videopopups.h"
56 
57 #define LOC_MML QString("Manual Metadata Lookup: ")
58 
59 static const QString sLocation = "MythVideo";
60 
61 namespace
62 {
63  bool IsValidDialogType(int num)
64  {
65  for (int i = 1; i <= VideoDialog::dtLast - 1; i <<= 1)
66  if (num == i) return true;
67  return false;
68  }
69 
70  class ParentalLevelNotifyContainer : public QObject
71  {
72  Q_OBJECT
73 
74  signals:
75  void SigLevelChanged();
76 
77  public:
78  explicit ParentalLevelNotifyContainer(QObject *lparent = nullptr) :
79  QObject(lparent)
80  {
81  connect(&m_levelCheck,
83  this, &ParentalLevelNotifyContainer::OnResultReady);
84  }
85 
86  const ParentalLevel &GetLevel() const { return m_level; }
87 
88  void SetLevel(const ParentalLevel& level)
89  {
90  m_levelCheck.Check(m_level.GetLevel(), level.GetLevel());
91  }
92 
93  private slots:
94  void OnResultReady(bool passwordValid, ParentalLevel::Level newLevel)
95  {
96  ParentalLevel lastLevel = m_level;
97  if (passwordValid)
98  {
99  m_level = newLevel;
100  }
101 
102  if (m_level.GetLevel() == ParentalLevel::plNone)
103  {
105  }
106 
107  if (lastLevel != m_level)
108  {
109  emit SigLevelChanged();
110  }
111  }
112 
113  private:
115  ParentalLevelChangeChecker m_levelCheck;
116  };
117 
118  MythGenericTree *GetNodePtrFromButton(MythUIButtonListItem *item)
119  {
120  if (item && item->GetData().canConvert<MythGenericTree *>())
121  return item->GetData().value<MythGenericTree *>();
122 
123  return nullptr;
124  }
125 
126  VideoMetadata *GetMetadataPtrFromNode(MythGenericTree *node)
127  {
128  if (node && node->GetData().canConvert<TreeNodeData>())
129  return node->GetData().value<TreeNodeData>().GetMetadata();
130 
131  return nullptr;
132  }
133 
134  bool GetLocalVideoImage(const QString &video_uid, const QString &filename,
135  const QStringList &in_dirs, QString &image,
136  QString title, int season,
137  const QString &host, const QString& sgroup,
138  int episode = 0, bool isScreenshot = false)
139  {
140  QStringList search_dirs(in_dirs);
141  QFileInfo qfi(filename);
142  search_dirs += qfi.absolutePath();
143  if (title.contains("/"))
144  title.replace("/", "-");
145 
146  const QString base_name = qfi.completeBaseName();
147  QList<QByteArray> image_types = QImageReader::supportedImageFormats();
148 
149  using image_type_list = std::set<QString>;
150  image_type_list image_exts;
151 
152  QString suffix;
153 
154  if (sgroup == "Coverart")
155  suffix = "coverart";
156  if (sgroup == "Fanart")
157  suffix = "fanart";
158  if (sgroup == "Screenshots")
159  suffix = "screenshot";
160  if (sgroup == "Banners")
161  suffix = "banner";
162 
163  for (const auto & itype : qAsConst(image_types))
164  image_exts.insert(QString(itype).toLower());
165 
166  if (!host.isEmpty())
167  {
168  QStringList hostFiles;
169 
170  RemoteGetFileList(host, "", &hostFiles, sgroup, true);
171  const QString hntm("%2.%3");
172 
173  for (const auto & ext : image_exts)
174  {
175  QStringList sfn;
176  if (episode > 0 || season > 0)
177  {
178  if (isScreenshot)
179  {
180  sfn += hntm.arg(QString("%1 Season %2x%3_%4")
181  .arg(title, QString::number(season),
182  QString::number(episode), suffix),
183  ext);
184  }
185  else
186  {
187  sfn += hntm.arg(QString("%1 Season %2_%3")
188  .arg(title, QString::number(season),
189  suffix),
190  ext);
191  }
192 
193  }
194  else
195  {
196  sfn += hntm.arg(base_name + QString("_%1").arg(suffix),
197  ext);
198  sfn += hntm.arg(video_uid + QString("_%1").arg(suffix),
199  ext);
200  }
201 
202  for (const auto & str : qAsConst(sfn))
203  {
204  if (hostFiles.contains(str))
205  {
206  image = str;
207  return true;
208  }
209  }
210  }
211  }
212 
213  const QString fntm("%1/%2.%3");
214 
215  for (const auto & dir : qAsConst(search_dirs))
216  {
217  if (dir.isEmpty()) continue;
218 
219  for (const auto & ext : image_exts)
220  {
221  QStringList sfn;
222  if (season > 0 || episode > 0)
223  {
224  if (isScreenshot)
225  {
226  sfn += fntm.arg(dir,
227  QString("%1 Season %2x%3_%4")
228  .arg(title, QString::number(season),
229  QString::number(episode),
230  suffix),
231  ext);
232  }
233  else
234  {
235  sfn += fntm.arg(dir,
236  QString("%1 Season %2_%3")
237  .arg(title, QString::number(season),
238  suffix),
239  ext);
240  }
241  }
242  if (!isScreenshot)
243  {
244  sfn += fntm.arg(dir,
245  base_name + QString("_%1").arg(suffix),
246  ext);
247  sfn += fntm.arg(dir,
248  video_uid + QString("_%1").arg(suffix),
249  ext);
250  }
251 
252  for (const auto & file : qAsConst(sfn))
253  {
254  if (QFile::exists(file))
255  {
256  image = file;
257  return true;
258  }
259  }
260  }
261  }
262 
263  return false;
264  }
265 
266  void PlayVideo(const QString &filename,
267  const VideoMetadataListManager &video_list, bool useAltPlayer = false)
268  {
269  const int WATCHED_WATERMARK = 10000; // Less than this and the chain of
270  // videos will not be followed when
271  // playing.
272 
274 
275  if (!item) return;
276 
277  QElapsedTimer playing_time;
278 
279  do
280  {
281  playing_time.start();
282 
283  if (useAltPlayer)
285  else
287 
288  if (item->GetChildID() > 0 && video_list.byID(item->GetChildID()))
289  item = video_list.byID(item->GetChildID());
290  else
291  break;
292  }
293  while (item && playing_time.hasExpired(WATCHED_WATERMARK));
294  }
295 
296  class FanartLoader: public QObject
297  {
298  Q_OBJECT
299 
300  public:
301  FanartLoader() = default;
302  ~FanartLoader() override
303  {
304  m_fanartTimer.stop();
305  m_fanartTimer.disconnect(this);
306  }
307 
308  void LoadImage(const QString &filename, MythUIImage *image)
309  {
310  if (!m_bConnected)
311  {
312  connect(&m_fanartTimer, &QTimer::timeout, this, &FanartLoader::fanartLoad);
313  m_bConnected = true;
314  }
315 
316  bool wasActive = m_fanartTimer.isActive();
317  if (filename.isEmpty())
318  {
319  if (wasActive)
320  m_fanartTimer.stop();
321 
322  image->Reset();
323  m_itemsPast++;
324  }
325  else
326  {
327  QMutexLocker locker(&m_fanartLock);
328  m_fanart = image;
329  if (filename != m_fanart->GetFilename())
330  {
331  if (wasActive)
332  m_fanartTimer.stop();
333 
334  if (m_itemsPast > 2)
335  m_fanart->Reset();
336 
337  m_fanart->SetFilename(filename);
338  m_fanartTimer.setSingleShot(true);
339  m_fanartTimer.start(300ms);
340 
341  if (wasActive)
342  m_itemsPast++;
343  else
344  m_itemsPast = 0;
345  }
346  else
347  m_itemsPast = 0;
348  }
349  }
350 
351  protected slots:
352  void fanartLoad(void)
353  {
354  QMutexLocker locker(&m_fanartLock);
355  m_fanart->Load();
356  }
357 
358  private:
359  int m_itemsPast {0};
360  QMutex m_fanartLock;
361  MythUIImage *m_fanart {nullptr};
362  QTimer m_fanartTimer;
363  bool m_bConnected {false};
364  };
365 
366  std::unique_ptr<FanartLoader> fanartLoader;
367 
368  struct CopyMetadataDestination
369  {
370  virtual void handleText(const QString &name, const QString &value) = 0;
371  virtual void handleState(const QString &name, const QString &value) = 0;
372  virtual void handleImage(const QString &name,
373  const QString &filename) = 0;
374  };
375 
376  class ScreenCopyDest : public CopyMetadataDestination
377  {
378  public:
379  explicit ScreenCopyDest(MythScreenType *screen) : m_screen(screen) {}
380 
381  void handleText(const QString &name, const QString &value) override // CopyMetadataDestination
382  {
383  CheckedSet(m_screen, name, value);
384  }
385 
386  void handleState(const QString &name, const QString &value) override // CopyMetadataDestination
387  {
388  handleText(name, value);
389  }
390 
391  void handleImage(const QString &name, const QString &filename) override // CopyMetadataDestination
392  {
393  MythUIImage *image = nullptr;
394  UIUtilW::Assign(m_screen, image, name);
395  if (image)
396  {
397  if (name != "fanart")
398  {
399  if (!filename.isEmpty())
400  {
401  image->SetFilename(filename);
402  image->Load();
403  }
404  else
405  image->Reset();
406  }
407  else
408  {
409  if (fanartLoader == nullptr)
410  fanartLoader = std::make_unique<FanartLoader>();
411  fanartLoader->LoadImage(filename, image);
412  }
413  }
414  }
415 
416  private:
417  MythScreenType *m_screen {nullptr};
418  };
419 
420  class MythUIButtonListItemCopyDest : public CopyMetadataDestination
421  {
422  public:
423  explicit MythUIButtonListItemCopyDest(MythUIButtonListItem *item) :
424  m_item(item) {}
425 
426  void handleText(const QString &name, const QString &value) override // CopyMetadataDestination
427  {
428  m_item->SetText(value, name);
429  }
430 
431  void handleState(const QString &name, const QString &value) override // CopyMetadataDestination
432  {
433  m_item->DisplayState(value, name);
434  }
435 
436  void handleImage([[maybe_unused]] const QString &name,
437  [[maybe_unused]] const QString &filename) override // CopyMetadataDestination
438  {
439  }
440 
441  private:
442  MythUIButtonListItem *m_item {nullptr};
443  };
444 
445  void CopyMetadataToUI(const VideoMetadata *metadata,
446  CopyMetadataDestination &dest)
447  {
448  using valuelist = std::map<QString, QString>;
449  valuelist tmp;
450 
451  if (metadata)
452  {
453  QString coverfile;
454  if ((metadata->IsHostSet()
455  && !metadata->GetCoverFile().startsWith("/"))
456  && !metadata->GetCoverFile().isEmpty()
457  && !IsDefaultCoverFile(metadata->GetCoverFile()))
458  {
459  coverfile = generate_file_url("Coverart", metadata->GetHost(),
460  metadata->GetCoverFile());
461  }
462  else
463  {
464  coverfile = metadata->GetCoverFile();
465  }
466 
467  if (!IsDefaultCoverFile(coverfile))
468  tmp["coverart"] = coverfile;
469 
470  tmp["coverfile"] = coverfile;
471 
472  QString screenshotfile;
473  if (metadata->IsHostSet() && !metadata->GetScreenshot().startsWith("/")
474  && !metadata->GetScreenshot().isEmpty())
475  {
476  screenshotfile = generate_file_url("Screenshots",
477  metadata->GetHost(), metadata->GetScreenshot());
478  }
479  else
480  {
481  screenshotfile = metadata->GetScreenshot();
482  }
483 
484  if (!IsDefaultScreenshot(screenshotfile))
485  tmp["screenshot"] = screenshotfile;
486 
487  tmp["screenshotfile"] = screenshotfile;
488 
489  QString bannerfile;
490  if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/")
491  && !metadata->GetBanner().isEmpty())
492  {
493  bannerfile = generate_file_url("Banners", metadata->GetHost(),
494  metadata->GetBanner());
495  }
496  else
497  {
498  bannerfile = metadata->GetBanner();
499  }
500 
501  if (!IsDefaultBanner(bannerfile))
502  tmp["banner"] = bannerfile;
503 
504  tmp["bannerfile"] = bannerfile;
505 
506  QString fanartfile;
507  if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/")
508  && !metadata->GetFanart().isEmpty())
509  {
510  fanartfile = generate_file_url("Fanart", metadata->GetHost(),
511  metadata->GetFanart());
512  }
513  else
514  {
515  fanartfile = metadata->GetFanart();
516  }
517 
518  if (!IsDefaultFanart(fanartfile))
519  tmp["fanart"] = fanartfile;
520 
521  tmp["fanartfile"] = fanartfile;
522 
523  tmp["trailerstate"] = TrailerToState(metadata->GetTrailer());
524  tmp["studiostate"] = metadata->GetStudio();
525  tmp["userratingstate"] =
526  QString::number((int)(metadata->GetUserRating()));
527  tmp["watchedstate"] = WatchedToState(metadata->GetWatched());
528 
529  tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel());
530  }
531 
532  struct helper
533  {
534  helper(valuelist &values, CopyMetadataDestination &d) :
535  m_vallist(values), m_dest(d) {}
536 
537  void handleImage(const QString &name)
538  {
539  m_dest.handleImage(name, m_vallist[name]);
540  }
541 
542  void handleState(const QString &name)
543  {
544  m_dest.handleState(name, m_vallist[name]);
545  }
546  private:
547  valuelist &m_vallist;
548  CopyMetadataDestination &m_dest;
549  };
550 
551  helper h(tmp, dest);
552 
553  h.handleImage("coverart");
554  h.handleImage("screenshot");
555  h.handleImage("banner");
556  h.handleImage("fanart");
557 
558  h.handleState("trailerstate");
559  h.handleState("userratingstate");
560  h.handleState("watchedstate");
561  h.handleState("videolevel");
562  }
563 }
564 
566 {
567  Q_OBJECT
568 
569  public:
570  static bool Exists()
571  {
572  // TODO: Add ability to theme loader to do this a better way.
573  return LoadWindowFromXML("video-ui.xml", kWindowName, nullptr);
574  }
575 
576  public:
578  const VideoMetadataListManager &listManager) :
579  MythScreenType(lparent, kWindowName), m_metadata(metadata),
580  m_listManager(listManager)
581  {
582  }
583 
584  bool Create() override // MythScreenType
585  {
586  if (!LoadWindowFromXML("video-ui.xml", kWindowName, this))
587  return false;
588 
589  UIUtilW::Assign(this, m_playButton, "play_button");
590  UIUtilW::Assign(this, m_doneButton, "done_button");
591 
592  if (m_playButton)
594 
595  if (m_doneButton)
597 
598  BuildFocusList();
599 
600  if (m_playButton || m_doneButton)
602 
603  InfoMap metadataMap;
604  m_metadata->toMap(metadataMap);
605  SetTextFromMap(metadataMap);
606 
607  ScreenCopyDest dest(this);
608  CopyMetadataToUI(m_metadata, dest);
609 
610  return true;
611  }
612 
613  private slots:
614  void OnPlay()
615  {
616  PlayVideo(m_metadata->GetFilename(), m_listManager);
617  }
618 
619  void OnDone()
620  {
621  // TODO: Close() can do horrible things, this will pop
622  // our screen, delete us, and return here.
623  Close();
624  }
625 
626  private:
627  bool OnKeyAction(const QStringList &actions)
628  {
629  bool handled = false;
630  for (const auto & action : qAsConst(actions))
631  {
632  handled = true;
633  if (action == "SELECT" || action == "PLAYBACK")
634  OnPlay();
635  else
636  handled = false;
637  }
638 
639  return handled;
640  }
641 
642  protected:
643  bool keyPressEvent(QKeyEvent *levent) override // MythScreenType
644  {
645  if (MythScreenType::keyPressEvent(levent))
646  return true;
647 
648  QStringList actions;
649  bool handled = GetMythMainWindow()->TranslateKeyPress("Video",
650  levent, actions);
651  if (!handled && !OnKeyAction(actions))
652  {
653  handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend",
654  levent, actions);
655  OnKeyAction(actions);
656  }
657  return handled;
658  }
659 
660  private:
661  static const char * const kWindowName;
664 
667 };
668 
669 const char * const ItemDetailPopup::kWindowName = "itemdetailpopup";
670 
672 {
673  private:
674  using parental_level_map = std::list<std::pair<QString, ParentalLevel::Level> >;
675 
676  static bool rating_to_pl_greater(const parental_level_map::value_type &lhs,
677  const parental_level_map::value_type &rhs)
678  {
679  return lhs.first.length() >= rhs.first.length();
680  };
681 
683 
684  public:
686  VideoDialog::BrowseType browse) :
687  m_videoList(videoList), m_type(type), m_browse(browse)
688  {
689  if (gCoreContext->GetBoolSetting("mythvideo.ParentalLevelFromRating", false))
690  {
692  sl.GetLevel() <= ParentalLevel::plHigh && sl.good(); ++sl)
693  {
694  QString ratingstring =
695  gCoreContext->GetSetting(QString("mythvideo.AutoR2PL%1")
696  .arg(sl.GetLevel()));
697 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
698  QStringList ratings =
699  ratingstring.split(':', QString::SkipEmptyParts);
700 #else
701  QStringList ratings =
702  ratingstring.split(':', Qt::SkipEmptyParts);
703 #endif
704  auto to_pl = [sl](const auto & rating)
705  { return parental_level_map::value_type(rating, sl.GetLevel()); };
706  std::transform(ratings.cbegin(), ratings.cend(),
707  std::back_inserter(m_ratingToPl), to_pl);
708  }
710  }
711 
713  gCoreContext->GetBoolSetting("mythvideo.VideoTreeRemember", false);
714 
715  m_isFileBrowser = gCoreContext->GetBoolSetting("VideoDialogNoDB", false);
716  m_groupType = gCoreContext->GetNumSetting("mythvideo.db_group_type", 0);
717 
719  gCoreContext->GetBoolSetting("mythvideo.EnableAlternatePlayer");
720 
721  m_autoMeta = gCoreContext->GetBoolSetting("mythvideo.AutoMetaDataScan", true);
722 
723  m_artDir = gCoreContext->GetSetting("VideoArtworkDir");
724  m_sshotDir = gCoreContext->GetSetting("mythvideo.screenshotDir");
725  m_fanDir = gCoreContext->GetSetting("mythvideo.fanartDir");
726  m_banDir = gCoreContext->GetSetting("mythvideo.bannerDir");
727  }
728 
730  {
731  delete m_scanner;
732 
733  if (m_rememberPosition && !m_lastTreeNodePath.isEmpty())
734  {
735  gCoreContext->SaveSetting("mythvideo.VideoTreeLastActive",
737  }
738  }
739 
741  {
742  if (metadata && !m_ratingToPl.empty())
743  {
744  QString rating = metadata->GetRating();
745  for (auto p = m_ratingToPl.begin();
746  !rating.isEmpty() && p != m_ratingToPl.end(); ++p)
747  {
748  if (rating.indexOf(p->first) != -1)
749  {
750  metadata->SetShowLevel(p->second);
751  break;
752  }
753  }
754  }
755  }
756 
757  static void DelayVideoListDestruction(const VideoListPtr& videoList)
758  {
759  m_savedPtr = new VideoListDeathDelay(videoList);
760  }
761 
762  public:
763  ParentalLevelNotifyContainer m_parentalLevel;
764  bool m_switchingLayout {false};
765 
767 
768  bool m_firstLoadPass {true};
769 
770  bool m_rememberPosition {false};
771 
773 
776 
777  bool m_treeLoaded {false};
778 
779  bool m_isFileBrowser {false};
780  int m_groupType {0};
781  bool m_isFlatList {false};
782  bool m_altPlayerEnabled {false};
785 
786  bool m_autoMeta {true};
787 
788  QString m_artDir;
789  QString m_sshotDir;
790  QString m_fanDir;
791  QString m_banDir;
793 
795  QMap<QString, int> m_notifications;
796 
797  private:
799 };
800 
802 
804 {
805  public:
807  m_savedList(toSave)
808  {
809  }
810 
812  {
813  return m_savedList;
814  }
815 
816  private:
818 };
819 
821  QObject(QCoreApplication::instance())
822 {
823  m_d = new VideoListDeathDelayPrivate(toSave);
824  QTimer::singleShot(kDelayTimeMS, this, &VideoListDeathDelay::OnTimeUp);
825 }
826 
828 {
829  delete m_d;
830 }
831 
833 {
834  return m_d->GetSaved();
835 }
836 
838 {
839  deleteLater();
840 }
841 
843 {
845 }
846 
847 VideoDialog::VideoDialog(MythScreenStack *lparent, const QString& lname,
848  const VideoListPtr& video_list, DialogType type, BrowseType browse)
849  : MythScreenType(lparent, lname),
850  m_popupStack(GetMythMainWindow()->GetStack("popup stack")),
851  m_mainStack(GetMythMainWindow()->GetMainStack()),
852  m_metadataFactory(new MetadataFactory(this)),
853  m_d(new VideoDialogPrivate(video_list, type, browse))
854 {
855  m_d->m_videoList->setCurrentVideoFilter(VideoFilterSettings(true,
856  lname));
857 
859  GetNumSetting("VideoDefaultParentalLevel",
861 
864 }
865 
867 {
868  if (!m_d->m_switchingLayout)
870 
871  SavePosition();
872 
873  delete m_d;
874 }
875 
877 {
878  m_d->m_lastTreeNodePath = "";
879 
880  if (m_d->m_type == DLG_TREE)
881  {
883  if (node)
884  m_d->m_lastTreeNodePath = node->getRouteByString().join("\n");
885  }
886  else if (m_d->m_type == DLG_BROWSER || m_d->m_type == DLG_GALLERY)
887  {
889  if (item)
890  {
891  MythGenericTree *node = GetNodePtrFromButton(item);
892  if (node)
893  m_d->m_lastTreeNodePath = node->getRouteByString().join("\n");
894  }
895  }
896 
897  gCoreContext->SaveSetting("mythvideo.VideoTreeLastActive", m_d->m_lastTreeNodePath);
898 }
899 
901 {
902  if (m_d->m_type == DLG_DEFAULT)
903  {
904  m_d->m_type = static_cast<DialogType>(
905  gCoreContext->GetNumSetting("Default MythVideo View", DLG_GALLERY));
906  m_d->m_browse = static_cast<BrowseType>(
907  gCoreContext->GetNumSetting("mythvideo.db_group_type", BRS_FOLDER));
908  }
909 
910  if (!IsValidDialogType(m_d->m_type))
911  {
913  }
914 
915  QString windowName = "videogallery";
916  bool flatlistDefault = false;
917 
918  switch (m_d->m_type)
919  {
920  case DLG_BROWSER:
921  windowName = "browser";
922  flatlistDefault = true;
923  break;
924  case DLG_GALLERY:
925  windowName = "gallery";
926  break;
927  case DLG_TREE:
928  windowName = "tree";
929  break;
930  case DLG_MANAGER:
931  m_d->m_isFlatList =
932  gCoreContext->GetBoolSetting("mythvideo.db_folder_view", true);
933  windowName = "manager";
934  flatlistDefault = true;
935  break;
936  case DLG_DEFAULT:
937  default:
938  break;
939  }
940 
941  switch (m_d->m_browse)
942  {
943  case BRS_GENRE:
945  break;
946  case BRS_CATEGORY:
948  break;
949  case BRS_YEAR:
951  break;
952  case BRS_DIRECTOR:
954  break;
955  case BRS_STUDIO:
957  break;
958  case BRS_CAST:
960  break;
961  case BRS_USERRATING:
963  break;
964  case BRS_INSERTDATE:
966  break;
967  case BRS_TVMOVIE:
969  break;
970  case BRS_FOLDER:
971  default:
973  break;
974  }
975 
976  m_d->m_isFlatList =
977  gCoreContext->GetBoolSetting(QString("mythvideo.folder_view_%1")
978  .arg(m_d->m_type), flatlistDefault);
979 
980  if (!LoadWindowFromXML("video-ui.xml", windowName, this))
981  return false;
982 
983  bool err = false;
984  if (m_d->m_type == DLG_TREE)
985  UIUtilE::Assign(this, m_videoButtonTree, "videos", &err);
986  else
987  UIUtilE::Assign(this, m_videoButtonList, "videos", &err);
988 
989  UIUtilW::Assign(this, m_titleText, "title");
990  UIUtilW::Assign(this, m_novideoText, "novideos");
991  UIUtilW::Assign(this, m_positionText, "position");
992  UIUtilW::Assign(this, m_crumbText, "breadcrumbs");
993 
994  UIUtilW::Assign(this, m_coverImage, "coverart");
995  UIUtilW::Assign(this, m_screenshot, "screenshot");
996  UIUtilW::Assign(this, m_banner, "banner");
997  UIUtilW::Assign(this, m_fanart, "fanart");
998 
999  UIUtilW::Assign(this, m_trailerState, "trailerstate");
1000  UIUtilW::Assign(this, m_parentalLevelState, "parentallevel");
1001  UIUtilW::Assign(this, m_watchedState, "watchedstate");
1002  UIUtilW::Assign(this, m_studioState, "studiostate");
1003 
1004  if (err)
1005  {
1006  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen '" + windowName + "'");
1007  return false;
1008  }
1009 
1010  CheckedSet(m_trailerState, "None");
1012  CheckedSet(m_watchedState, "None");
1013  CheckedSet(m_studioState, "None");
1014 
1015  BuildFocusList();
1016 
1017  if (m_d->m_type == DLG_TREE)
1018  {
1020 
1022  this, &VideoDialog::handleSelect);
1024  this, &VideoDialog::UpdateText);
1027  }
1028  else
1029  {
1031 
1033  this, &VideoDialog::handleSelect);
1035  this, &VideoDialog::UpdateText);
1036  }
1037 
1038  return true;
1039 }
1040 
1042 {
1043  connect(&m_d->m_parentalLevel, &ParentalLevelNotifyContainer::SigLevelChanged,
1044  this, &VideoDialog::reloadData);
1045 }
1046 
1048 {
1049  reloadData();
1050  // We only want to prompt once, on startup, hence this is done in Load()
1051  if (m_d->m_rootNode->childCount() == 1 &&
1053  PromptToScan();
1054 }
1055 
1061 {
1062  fetchVideos();
1063  loadData();
1064 
1067 
1068  bool noFiles = (m_d->m_rootNode->childCount() == 1 &&
1070 
1071  if (m_novideoText)
1072  m_novideoText->SetVisible(noFiles);
1073 }
1074 
1075 void VideoDialog::scanFinished(bool dbChanged)
1076 {
1077  delete m_d->m_scanner;
1078  m_d->m_scanner = nullptr;
1079 
1080  if (dbChanged)
1081  m_d->m_videoList->InvalidateCache();
1082 
1083  m_d->m_currentNode = nullptr;
1084  reloadData();
1085 
1086  if (m_d->m_autoMeta)
1087  VideoAutoSearch();
1088 
1089  if (m_d->m_rootNode->childCount() == 1 &&
1091  {
1092  QString message = tr("The video scan found no files, have you "
1093  "configured a video storage group?");
1094  ShowOkPopup(message);
1095  }
1096 }
1097 
1103 {
1104  m_d->m_treeLoaded = false;
1105  refreshData();
1106 }
1107 
1113 {
1114  if (m_d->m_type == DLG_TREE)
1115  {
1117 
1118  if (m_d->m_firstLoadPass)
1119  {
1120  m_d->m_firstLoadPass = false;
1121 
1122  if (m_d->m_rememberPosition)
1123  {
1124  QStringList route =
1125  gCoreContext->GetSetting("mythvideo.VideoTreeLastActive",
1126  "").split("\n");
1128  }
1129  }
1130  }
1131  else
1132  {
1134 
1135  if (!m_d->m_treeLoaded)
1136  return;
1137 
1138  if (!m_d->m_currentNode)
1139  {
1141  return;
1142  }
1143 
1144  MythGenericTree *selectedNode = m_d->m_currentNode->getSelectedChild();
1145 
1146  // restore the last saved position in the video tree if this is the first
1147  // time this method is called and the option is set in the database
1148  if (m_d->m_firstLoadPass)
1149  {
1150  if (m_d->m_rememberPosition)
1151  {
1152  QStringList lastTreeNodePath = gCoreContext->GetSetting("mythvideo.VideoTreeLastActive", "").split("\n");
1153 
1154  if (m_d->m_type == DLG_GALLERY || m_d->m_type == DLG_BROWSER)
1155  {
1156  if (!lastTreeNodePath.isEmpty())
1157  {
1158  // go through the path list and set the current node
1159  for (int i = 0; i < lastTreeNodePath.size(); i++)
1160  {
1161  MythGenericTree *node =
1162  m_d->m_currentNode->getChildByName(lastTreeNodePath.at(i));
1163  if (node != nullptr)
1164  {
1165  // check if the node name is the same as the currently selected
1166  // one in the saved tree list. if yes then we are on the right
1167  // way down the video tree to find the last saved position
1168  if (node->GetText().compare(lastTreeNodePath.at(i)) == 0)
1169  {
1170  // set the folder as the new node so we can travel further down
1171  // dont do this if its the last part of the saved video path tree
1172  if (node->getInt() == kSubFolder &&
1173  node->childCount() > 1 &&
1174  i < lastTreeNodePath.size()-1)
1175  {
1176  SetCurrentNode(node);
1177  }
1178  // in the last run the selectedNode will be the last
1179  // entry of the saved tree node.
1180  if (lastTreeNodePath.at(i) == lastTreeNodePath.last())
1181  selectedNode = node;
1182  }
1183  }
1184  }
1185  m_d->m_firstLoadPass = false;
1186  }
1187  }
1188  }
1189  }
1190 
1191  using MGTreeChildList = QList<MythGenericTree *>;
1192  MGTreeChildList *lchildren = m_d->m_currentNode->getAllChildren();
1193 
1194  for (auto * child : qAsConst(*lchildren))
1195  {
1196  if (child != nullptr)
1197  {
1198  auto *item =
1199  new MythUIButtonListItem(m_videoButtonList, QString(), nullptr,
1201 
1202  item->SetData(QVariant::fromValue(child));
1203 
1204  UpdateItem(item);
1205 
1206  if (child == selectedNode)
1208  }
1209  }
1210  }
1211 
1212  UpdatePosition();
1213 }
1214 
1220 {
1221  if (!item)
1222  return;
1223 
1224  MythGenericTree *node = GetNodePtrFromButton(item);
1225 
1226  VideoMetadata *metadata = GetMetadata(item);
1227 
1228  if (metadata)
1229  {
1230  InfoMap metadataMap;
1231  metadata->toMap(metadataMap);
1232  item->SetTextFromMap(metadataMap);
1233  }
1234 
1235  MythUIButtonListItemCopyDest dest(item);
1236  CopyMetadataToUI(metadata, dest);
1237 
1238  MythGenericTree *parent = node->getParent();
1239 
1240  if (parent && metadata && ((QString::compare(parent->GetText(),
1241  metadata->GetTitle(), Qt::CaseInsensitive) == 0) ||
1242  parent->GetText().startsWith(tr("Season"), Qt::CaseInsensitive)))
1243  item->SetText(metadata->GetSubtitle());
1244  else if (metadata && !metadata->GetSubtitle().isEmpty())
1245  item->SetText(QString("%1: %2").arg(metadata->GetTitle(), metadata->GetSubtitle()));
1246  else
1247  item->SetText(metadata ? metadata->GetTitle() : node->GetText());
1248 
1249  QString coverimage = GetCoverImage(node);
1250  QString screenshot = GetScreenshot(node);
1251  QString banner = GetBanner(node);
1252  QString fanart = GetFanart(node);
1253 
1254  if (!screenshot.isEmpty() && parent && metadata &&
1255  ((QString::compare(parent->GetText(),
1256  metadata->GetTitle(), Qt::CaseInsensitive) == 0) ||
1257  parent->GetText().startsWith(tr("Season"), Qt::CaseInsensitive)))
1258  {
1259  item->SetImage(screenshot);
1260  }
1261  else
1262  {
1263  if (coverimage.isEmpty())
1264  coverimage = GetFirstImage(node, "Coverart");
1265  item->SetImage(coverimage);
1266  }
1267 
1268  int nodeInt = node->getInt();
1269 
1270  if (coverimage.isEmpty() && nodeInt == kSubFolder)
1271  coverimage = GetFirstImage(node, "Coverart");
1272 
1273  item->SetImage(coverimage, "coverart");
1274 
1275  if (screenshot.isEmpty() && nodeInt == kSubFolder)
1276  screenshot = GetFirstImage(node, "Screenshots");
1277 
1278  item->SetImage(screenshot, "screenshot");
1279 
1280  if (banner.isEmpty() && nodeInt == kSubFolder)
1281  banner = GetFirstImage(node, "Banners");
1282 
1283  item->SetImage(banner, "banner");
1284 
1285  if (fanart.isEmpty() && nodeInt == kSubFolder)
1286  fanart = GetFirstImage(node, "Fanart");
1287 
1288  item->SetImage(fanart, "fanart");
1289 
1290  if (nodeInt == kSubFolder)
1291  {
1292  item->SetText(QString("%1").arg(node->visibleChildCount()), "childcount");
1293  item->DisplayState("subfolder", "nodetype");
1294  item->SetText(node->GetText(), "title");
1295  item->SetText(node->GetText());
1296  }
1297  else if (nodeInt == kUpFolder)
1298  {
1299  item->DisplayState("upfolder", "nodetype");
1300  item->SetText(node->GetText(), "title");
1301  item->SetText(node->GetText());
1302  }
1303 
1304  if (item == GetItemCurrent())
1305  UpdateText(item);
1306 }
1307 
1313 {
1314  MythGenericTree *oldroot = m_d->m_rootNode;
1315  if (!m_d->m_treeLoaded)
1316  {
1317  m_d->m_rootNode = m_d->m_videoList->buildVideoList(m_d->m_isFileBrowser,
1319  m_d->m_parentalLevel.GetLevel(), true);
1320  }
1321  else
1322  {
1323  m_d->m_videoList->refreshList(m_d->m_isFileBrowser,
1324  m_d->m_parentalLevel.GetLevel(),
1326  m_d->m_rootNode = m_d->m_videoList->GetTreeRoot();
1327  }
1328 
1329  m_d->m_treeLoaded = true;
1330 
1331  // Move a node down if there is a single directory item here...
1332  if (m_d->m_rootNode->childCount() == 1)
1333  {
1335  if (node->getInt() == kSubFolder && node->childCount() > 1)
1336  m_d->m_rootNode = node;
1337  else if (node->getInt() == kUpFolder)
1338  m_d->m_treeLoaded = false;
1339  }
1340  else if (m_d->m_rootNode->childCount() == 0)
1341  m_d->m_treeLoaded = false;
1342 
1343  if (!m_d->m_currentNode || m_d->m_rootNode != oldroot)
1345 }
1346 
1351 QString VideoDialog::RemoteImageCheck(const QString& host, const QString& filename)
1352 {
1353  QString result = "";
1354 #if 0
1355  LOG(VB_GENERAL, LOG_DEBUG, QString("RemoteImageCheck(%1)").arg(filename));
1356 #endif
1357 
1358  QStringList dirs = GetVideoDirsByHost(host);
1359 
1360  if (!dirs.isEmpty())
1361  {
1362  for (const auto & dir : qAsConst(dirs))
1363  {
1364  QUrl sgurl = dir;
1365  QString path = sgurl.path();
1366 
1367  QString fname = QString("%1/%2").arg(path, filename);
1368 
1369  QStringList list( QString("QUERY_SG_FILEQUERY") );
1370  list << host;
1371  list << "Videos";
1372  list << fname;
1373 
1374  bool ok = gCoreContext->SendReceiveStringList(list);
1375 
1376  if (!ok || list.at(0).startsWith("SLAVE UNREACHABLE"))
1377  {
1378  LOG(VB_GENERAL, LOG_WARNING,
1379  QString("Backend : %1 currently Unreachable. Skipping "
1380  "this one.") .arg(host));
1381  break;
1382  }
1383 
1384  if ((!list.isEmpty()) && (list.at(0) == fname))
1385  result = generate_file_url("Videos", host, filename);
1386 
1387  if (!result.isEmpty())
1388  {
1389 #if 0
1390  LOG(VB_GENERAL, LOG_DEBUG,
1391  QString("RemoteImageCheck(%1) res :%2: :%3:")
1392  .arg(fname).arg(result).arg(dir));
1393 #endif
1394  break;
1395  }
1396 
1397  }
1398  }
1399 
1400  return result;
1401 }
1402 
1408 {
1409  if (!node)
1410  return {};
1411 
1412  int nodeInt = node->getInt();
1413 
1414  QString icon_file;
1415 
1416  if (nodeInt == kSubFolder) // subdirectory
1417  {
1418  // First validate that the data can be converted
1419  if (!node->GetData().canConvert<TreeNodeData>())
1420  return icon_file;
1421 
1422  // load folder icon
1423  QString folder_path = node->GetData().value<TreeNodeData>().GetPath();
1424  QString host = node->GetData().value<TreeNodeData>().GetHost();
1425  QString prefix = node->GetData().value<TreeNodeData>().GetPrefix();
1426 
1427  if (folder_path.startsWith("myth://"))
1428  folder_path = folder_path.right(folder_path.length()
1429  - folder_path.lastIndexOf("//") - 1);
1430 
1431  QString filename = QString("%1/folder").arg(folder_path);
1432 
1433 #if 0
1434  LOG(VB_GENERAL, LOG_DEBUG,
1435  QString("GetCoverImage host : %1 prefix : %2 file : %3")
1436  .arg(host).arg(prefix).arg(filename));
1437 #endif
1438 
1439  QStringList test_files;
1440  test_files.append(filename + ".png");
1441  test_files.append(filename + ".jpg");
1442  test_files.append(filename + ".jpeg");
1443  test_files.append(filename + ".gif");
1444 
1445  // coverity[auto_causes_copy]
1446  for (auto imagePath : qAsConst(test_files))
1447  {
1448 #if 0
1449  LOG(VB_GENERAL, LOG_DEBUG, QString("Cover check :%1 : ").arg(imagePath));
1450 #endif
1451 
1452  bool foundCover = false;
1453  if (!host.isEmpty())
1454  {
1455  // Strip out any extra /'s
1456  imagePath.replace("//", "/");
1457  prefix.replace("//","/");
1458  imagePath = imagePath.right(imagePath.length() - (prefix.length() + 1));
1459  QString tmpCover = RemoteImageCheck(host, imagePath);
1460 
1461  if (!tmpCover.isEmpty())
1462  {
1463  foundCover = true;
1464  imagePath = tmpCover;
1465  }
1466  }
1467  else
1468  foundCover = QFile::exists(imagePath);
1469 
1470  if (foundCover)
1471  {
1472  icon_file = imagePath;
1473  break;
1474  }
1475  }
1476 
1477  // If we found nothing, load the first image we find
1478  if (icon_file.isEmpty())
1479  {
1480  QStringList imageTypes { "*.png", "*.jpg", "*.jpeg", "*.gif" };
1481  QStringList fList;
1482 
1483  if (!host.isEmpty())
1484  {
1485  // TODO: This can likely get a little cleaner
1486 
1487  QStringList dirs = GetVideoDirsByHost(host);
1488 
1489  if (!dirs.isEmpty())
1490  {
1491  for (const auto & dir : qAsConst(dirs))
1492  {
1493  QUrl sgurl = dir;
1494  QString path = sgurl.path();
1495 
1496  QString subdir = folder_path.right(folder_path.length() - (prefix.length() + 1));
1497 
1498  path = path + "/" + subdir;
1499 
1500  QStringList tmpList;
1501  bool ok = RemoteGetFileList(host, path, &tmpList, "Videos");
1502 
1503  if (ok)
1504  {
1505  for (const auto & pattern : qAsConst(imageTypes))
1506  {
1507  auto rePattern = QRegularExpression::wildcardToRegularExpression(pattern);
1508  QRegularExpression rx {
1509  rePattern.mid(2,rePattern.size()-4), // Remove anchors
1510  QRegularExpression::CaseInsensitiveOption };
1511  QStringList matches = tmpList.filter(rx);
1512  if (!matches.isEmpty())
1513  {
1514  fList.clear();
1515  fList.append(subdir + "/" + matches.at(0).split("::").at(1));
1516  break;
1517  }
1518  }
1519 
1520  break;
1521  }
1522  }
1523  }
1524 
1525  }
1526  else
1527  {
1528  QDir vidDir(folder_path);
1529  vidDir.setNameFilters(imageTypes);
1530  fList = vidDir.entryList();
1531  }
1532 
1533  // Take the Coverfile for the first valid node in the dir, if it exists.
1534  if (icon_file.isEmpty())
1535  {
1536  int list_count = node->visibleChildCount();
1537  if (list_count > 0)
1538  {
1539  for (int i = 0; i < list_count; i++)
1540  {
1541  MythGenericTree *subnode = node->getVisibleChildAt(i);
1542  if (subnode)
1543  {
1544  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1545  if (metadata)
1546  {
1547  if (!metadata->GetHost().isEmpty() &&
1548  !metadata->GetCoverFile().startsWith("/"))
1549  {
1550  QString test_file = generate_file_url("Coverart",
1551  metadata->GetHost(), metadata->GetCoverFile());
1552  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1553  !IsDefaultCoverFile(test_file))
1554  {
1555  icon_file = test_file;
1556  break;
1557  }
1558  }
1559  else
1560  {
1561  const QString& test_file = metadata->GetCoverFile();
1562  if (!test_file.isEmpty() &&
1563  !IsDefaultCoverFile(test_file))
1564  {
1565  icon_file = test_file;
1566  break;
1567  }
1568  }
1569  }
1570  }
1571  }
1572  }
1573  }
1574 
1575  if (!fList.isEmpty())
1576  {
1577  if (host.isEmpty())
1578  {
1579  icon_file = QString("%1/%2").arg(folder_path, fList.at(0));
1580  }
1581  else
1582  {
1583  icon_file = generate_file_url("Videos", host, fList.at(0));
1584  }
1585  }
1586  }
1587 
1588  if (!icon_file.isEmpty())
1589  {
1590  LOG(VB_GENERAL, LOG_DEBUG, QString("Found Image : %1 :")
1591  .arg(icon_file));
1592  }
1593  else
1594  {
1595  LOG(VB_GENERAL, LOG_DEBUG,
1596  QString("Could not find folder cover Image : %1 ")
1597  .arg(folder_path));
1598  }
1599  }
1600  else
1601  {
1602  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1603 
1604  if (metadata)
1605  {
1606  if (metadata->IsHostSet() &&
1607  !metadata->GetCoverFile().startsWith("/") &&
1608  !IsDefaultCoverFile(metadata->GetCoverFile()))
1609  {
1610  icon_file = generate_file_url("Coverart", metadata->GetHost(),
1611  metadata->GetCoverFile());
1612  }
1613  else
1614  {
1615  icon_file = metadata->GetCoverFile();
1616  }
1617  }
1618  }
1619 
1620  if (IsDefaultCoverFile(icon_file))
1621  icon_file.clear();
1622 
1623  return icon_file;
1624 }
1625 
1637 QString VideoDialog::GetFirstImage(MythGenericTree *node, const QString& type,
1638  const QString& gpnode, int levels)
1639 {
1640  if (!node || type.isEmpty())
1641  return {};
1642 
1643  QString icon_file;
1644 
1645  int list_count = node->visibleChildCount();
1646  if (list_count > 0)
1647  {
1648  QList<MythGenericTree *> subDirs;
1649  static constexpr int maxRecurse { 1 };
1650 
1651  for (int i = 0; i < list_count; i++)
1652  {
1653  MythGenericTree *subnode = node->getVisibleChildAt(i);
1654  if (subnode)
1655  {
1656  if (subnode->childCount() > 0)
1657  subDirs << subnode;
1658 
1659  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1660  if (metadata)
1661  {
1662  QString test_file;
1663  const QString& host = metadata->GetHost();
1664  const QString& title = metadata->GetTitle();
1665 
1666  if (type == "Coverart" && !host.isEmpty() &&
1667  !metadata->GetCoverFile().startsWith("/"))
1668  {
1669  test_file = generate_file_url("Coverart",
1670  host, metadata->GetCoverFile());
1671  }
1672  else if (type == "Coverart")
1673  test_file = metadata->GetCoverFile();
1674 
1675  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1676  !IsDefaultCoverFile(test_file) && (gpnode.isEmpty() ||
1677  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1678  {
1679  icon_file = test_file;
1680  break;
1681  }
1682 
1683  if (type == "Fanart" && !host.isEmpty() &&
1684  !metadata->GetFanart().startsWith("/"))
1685  {
1686  test_file = generate_file_url("Fanart",
1687  host, metadata->GetFanart());
1688  }
1689  else if (type == "Fanart")
1690  test_file = metadata->GetFanart();
1691 
1692  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1693  test_file != VIDEO_FANART_DEFAULT && (gpnode.isEmpty() ||
1694  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1695  {
1696  icon_file = test_file;
1697  break;
1698  }
1699 
1700  if (type == "Banners" && !host.isEmpty() &&
1701  !metadata->GetBanner().startsWith("/"))
1702  {
1703  test_file = generate_file_url("Banners",
1704  host, metadata->GetBanner());
1705  }
1706  else if (type == "Banners")
1707  test_file = metadata->GetBanner();
1708 
1709  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1710  test_file != VIDEO_BANNER_DEFAULT && (gpnode.isEmpty() ||
1711  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1712  {
1713  icon_file = test_file;
1714  break;
1715  }
1716 
1717  if (type == "Screenshots" && !host.isEmpty() &&
1718  !metadata->GetScreenshot().startsWith("/"))
1719  {
1720  test_file = generate_file_url("Screenshots",
1721  host, metadata->GetScreenshot());
1722  }
1723  else if (type == "Screenshots")
1724  test_file = metadata->GetScreenshot();
1725 
1726  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1727  test_file != VIDEO_SCREENSHOT_DEFAULT && (gpnode.isEmpty() ||
1728  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1729  {
1730  icon_file = test_file;
1731  break;
1732  }
1733  }
1734  }
1735  }
1736  if (icon_file.isEmpty() && !subDirs.isEmpty())
1737  {
1738  QString test_file;
1739  int subDirCount = subDirs.count();
1740  for (int i = 0; i < subDirCount; i ++)
1741  {
1742  if (levels < maxRecurse)
1743  {
1744  test_file = GetFirstImage(subDirs[i], type,
1745  node->GetText(), levels + 1);
1746  if (!test_file.isEmpty())
1747  {
1748  icon_file = test_file;
1749  break;
1750  }
1751  }
1752  }
1753  }
1754  }
1755  return icon_file;
1756 }
1757 
1763 {
1764  const int nodeInt = node->getInt();
1765 
1766  QString icon_file;
1767 
1768  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1769  {
1770  icon_file = VIDEO_SCREENSHOT_DEFAULT;
1771  }
1772  else
1773  {
1774  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1775 
1776  if (metadata)
1777  {
1778  if (metadata->IsHostSet() &&
1779  !metadata->GetScreenshot().startsWith("/") &&
1780  !metadata->GetScreenshot().isEmpty())
1781  {
1782  icon_file = generate_file_url("Screenshots", metadata->GetHost(),
1783  metadata->GetScreenshot());
1784  }
1785  else
1786  {
1787  icon_file = metadata->GetScreenshot();
1788  }
1789  }
1790  }
1791 
1792  if (IsDefaultScreenshot(icon_file))
1793  icon_file.clear();
1794 
1795  return icon_file;
1796 }
1797 
1803 {
1804  const int nodeInt = node->getInt();
1805 
1806  if (nodeInt == kSubFolder || nodeInt == kUpFolder)
1807  return {};
1808 
1809  QString icon_file;
1810  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1811 
1812  if (metadata)
1813  {
1814  if (metadata->IsHostSet() &&
1815  !metadata->GetBanner().startsWith("/") &&
1816  !metadata->GetBanner().isEmpty())
1817  {
1818  icon_file = generate_file_url("Banners", metadata->GetHost(),
1819  metadata->GetBanner());
1820  }
1821  else
1822  {
1823  icon_file = metadata->GetBanner();
1824  }
1825 
1826  if (IsDefaultBanner(icon_file))
1827  icon_file.clear();
1828  }
1829 
1830  return icon_file;
1831 }
1832 
1838 {
1839  const int nodeInt = node->getInt();
1840 
1841  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1842  return {};
1843 
1844  QString icon_file;
1845  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1846 
1847  if (metadata)
1848  {
1849  if (metadata->IsHostSet() &&
1850  !metadata->GetFanart().startsWith("/") &&
1851  !metadata->GetFanart().isEmpty())
1852  {
1853  icon_file = generate_file_url("Fanart", metadata->GetHost(),
1854  metadata->GetFanart());
1855  }
1856  else
1857  {
1858  icon_file = metadata->GetFanart();
1859  }
1860 
1861  if (IsDefaultFanart(icon_file))
1862  icon_file.clear();
1863  }
1864 
1865  return icon_file;
1866 }
1867 
1872 bool VideoDialog::keyPressEvent(QKeyEvent *levent)
1873 {
1874  if (GetFocusWidget()->keyPressEvent(levent))
1875  return true;
1876 
1877  QStringList actions;
1878  bool handled = GetMythMainWindow()->TranslateKeyPress("Video", levent, actions);
1879 
1880  for (int i = 0; i < actions.size() && !handled; i++)
1881  {
1882  QString action = actions[i];
1883  handled = true;
1884 
1885  if (action == "INFO")
1886  {
1888  MythGenericTree *node = GetNodePtrFromButton(item);
1889  if (!m_menuPopup && node->getInt() != kUpFolder)
1890  VideoMenu();
1891  }
1892  else if (action == "INCPARENT")
1893  shiftParental(1);
1894  else if (action == "DECPARENT")
1895  shiftParental(-1);
1896  else if (action == "1" || action == "2" ||
1897  action == "3" || action == "4")
1899  else if (action == "FILTER")
1900  ChangeFilter();
1901  else if (action == "MENU")
1902  {
1903  if (!m_menuPopup)
1904  DisplayMenu();
1905  }
1906  else if (action == "PLAYALT")
1907  {
1908  if (!m_menuPopup && GetMetadata(GetItemCurrent()) &&
1910  playVideoAlt();
1911  }
1912  else if (action == "DOWNLOADDATA")
1913  {
1915  VideoSearch();
1916  }
1917  else if (action == "INCSEARCH")
1918  searchStart();
1919  else if (action == "ITEMDETAIL")
1920  DoItemDetailShow();
1921  else if (action == "DELETE")
1922  {
1924  RemoveVideo();
1925  }
1926  else if (action == "EDIT" && !m_menuPopup)
1927  EditMetadata();
1928  else if (action == "ESCAPE")
1929  {
1930  if (m_d->m_type != DLG_TREE
1931  && !GetMythMainWindow()->IsExitingToMain()
1932  && m_d->m_currentNode != m_d->m_rootNode)
1933  handled = goBack();
1934  else
1935  handled = false;
1936  }
1937  else
1938  handled = false;
1939  }
1940 
1941  if (!handled)
1942  {
1943  handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", levent,
1944  actions);
1945 
1946  for (int i = 0; i < actions.size() && !handled; i++)
1947  {
1948  QString action = actions[i];
1949  if (action == "PLAYBACK")
1950  {
1951  handled = true;
1952  playVideo();
1953  }
1954  }
1955  }
1956 
1957  if (!handled && MythScreenType::keyPressEvent(levent))
1958  handled = true;
1959 
1960  return handled;
1961 }
1962 
1967 void VideoDialog::createBusyDialog(const QString &title)
1968 {
1969  if (m_busyPopup)
1970  return;
1971 
1972  const QString& message = title;
1973 
1974  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
1975  "mythvideobusydialog");
1976 
1977  if (m_busyPopup->Create())
1979 }
1980 
1986 {
1987  if (m_d->m_notifications.contains(metadata->GetHash()))
1988  return;
1989 
1990  int id = GetNotificationCenter()->Register(this);
1991  m_d->m_notifications[metadata->GetHash()] = id;
1992 
1993  QString msg = tr("Fetching details for %1")
1994  .arg(metadata->GetTitle());
1995  QString desc;
1996  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
1997  {
1998  desc = tr("Season %1, Episode %2")
1999  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2000  }
2001  MythBusyNotification n(msg, sLocation, desc);
2002  n.SetId(id);
2003  n.SetParent(this);
2005 }
2006 
2008 {
2009  if (!metadata || !m_d->m_notifications.contains(metadata->GetHash()))
2010  return;
2011 
2012  int id = m_d->m_notifications[metadata->GetHash()];
2013  m_d->m_notifications.remove(metadata->GetHash());
2014 
2015  QString msg;
2016  if (ok)
2017  {
2018  msg = tr("Retrieved details for %1").arg(metadata->GetTitle());
2019  }
2020  else
2021  {
2022  msg = tr("Failed to retrieve details for %1").arg(metadata->GetTitle());
2023  }
2024  QString desc;
2025  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
2026  {
2027  desc = tr("Season %1, Episode %2")
2028  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2029  }
2030  if (ok)
2031  {
2032  MythCheckNotification n(msg, sLocation, desc);
2033  n.SetId(id);
2034  n.SetParent(this);
2036  }
2037  else
2038  {
2039  MythErrorNotification n(msg, sLocation, desc);
2040  n.SetId(id);
2041  n.SetParent(this);
2043  }
2044  GetNotificationCenter()->UnRegister(this, id);
2045 }
2046 
2051 void VideoDialog::createOkDialog(const QString& title)
2052 {
2053  const QString& message = title;
2054 
2055  auto *okPopup = new MythConfirmationDialog(m_popupStack, message, false);
2056 
2057  if (okPopup->Create())
2058  m_popupStack->AddScreen(okPopup);
2059 }
2060 
2065 void VideoDialog::searchComplete(const QString& string)
2066 {
2067  LOG(VB_GENERAL, LOG_DEBUG, QString("Jumping to: %1").arg(string));
2068 
2070  QList<MythGenericTree*> *children = nullptr;
2071  QMap<int, QString> idTitle;
2072 
2073  if (parent && m_d->m_type == DLG_TREE)
2074  children = parent->getAllChildren();
2075  else
2076  children = m_d->m_currentNode->getAllChildren();
2077 
2078  for (auto * child : qAsConst(*children))
2079  {
2080  QString title = child->GetText();
2081  int id = child->getPosition();
2082  idTitle.insert(id, title);
2083  }
2084 
2085  if (m_d->m_type == DLG_TREE)
2086  {
2088  MythGenericTree *new_node = dlgParent->getChildAt(idTitle.key(string));
2089  if (new_node)
2090  {
2091  m_videoButtonTree->SetCurrentNode(new_node);
2093  }
2094  }
2095  else
2096  m_videoButtonList->SetItemCurrent(idTitle.key(string));
2097 }
2098 
2104 {
2106 
2107  QStringList childList;
2108  QList<MythGenericTree*> *children = nullptr;
2109  if (parent && m_d->m_type == DLG_TREE)
2110  children = parent->getAllChildren();
2111  else
2112  children = m_d->m_currentNode->getAllChildren();
2113 
2114  for (auto * child : qAsConst(*children))
2115  {
2116  childList << child->GetText();
2117  }
2118 
2119  MythScreenStack *popupStack =
2120  GetMythMainWindow()->GetStack("popup stack");
2121  auto *searchDialog = new MythUISearchDialog(popupStack,
2122  tr("Video Search"), childList, false, "");
2123 
2124  if (searchDialog->Create())
2125  {
2126  connect(searchDialog, &MythUISearchDialog::haveResult,
2128 
2129  popupStack->AddScreen(searchDialog);
2130  }
2131  else
2132  delete searchDialog;
2133 }
2134 
2140 {
2141  bool handled = false;
2142 
2143  if (m_d->m_currentNode != m_d->m_rootNode)
2144  {
2145  MythGenericTree *lparent = m_d->m_currentNode->getParent();
2146  if (lparent)
2147  {
2148  SetCurrentNode(lparent);
2149 
2150  handled = true;
2151  }
2152  }
2153 
2154  loadData();
2155 
2156  return handled;
2157 }
2158 
2164 {
2165  if (!node)
2166  return;
2167 
2168  m_d->m_currentNode = node;
2169 }
2170 
2176 {
2178  MythUIButtonList *currentList = ci ? ci->parent() : nullptr;
2179 
2180  if (!currentList)
2181  return;
2182 
2183  CheckedSet(m_positionText, tr("%1 of %2")
2184  .arg(currentList->IsEmpty() ? 0 : currentList->GetCurrentPos() + 1)
2185  .arg(currentList->GetCount()));
2186 }
2187 
2193 {
2194  if (!item)
2195  return;
2196 
2197  MythUIButtonList *currentList = item->parent();
2198 
2199  if (!currentList)
2200  return;
2201 
2202  VideoMetadata *metadata = GetMetadata(item);
2203 
2204  MythGenericTree *node = GetNodePtrFromButton(item);
2205 
2206  if (!node)
2207  return;
2208 
2209  if (metadata)
2210  {
2211  InfoMap metadataMap;
2212  metadata->toMap(metadataMap);
2213  SetTextFromMap(metadataMap);
2214  }
2215  else
2216  {
2217  InfoMap metadataMap;
2218  ClearMap(metadataMap);
2219  SetTextFromMap(metadataMap);
2220  }
2221 
2222  ScreenCopyDest dest(this);
2223  CopyMetadataToUI(metadata, dest);
2224 
2225  if (node->getInt() == kSubFolder && !metadata)
2226  {
2227  QString cover = GetFirstImage(node, "Coverart");
2228  QString fanart = GetFirstImage(node, "Fanart");
2229  QString banner = GetFirstImage(node, "Banners");
2230  QString screenshot = GetFirstImage(node, "Screenshots");
2231  CheckedSet(m_coverImage, cover);
2232  CheckedSet(m_fanart, fanart);
2233  CheckedSet(m_banner, banner);
2234  CheckedSet(m_screenshot, screenshot);
2235  }
2236 
2237  if (!metadata)
2238  CheckedSet(m_titleText, item->GetText());
2239  UpdatePosition();
2240 
2241  if (m_d->m_currentNode)
2242  {
2244  CheckedSet(this, "foldername", m_d->m_currentNode->GetText());
2245  }
2246 
2247  if (node && node->getInt() == kSubFolder)
2248  CheckedSet(this, "childcount",
2249  QString("%1").arg(node->visibleChildCount()));
2250 
2251  if (node)
2252  node->becomeSelectedChild();
2253 }
2254 
2260 {
2261  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2262  QString label;
2263 
2264  if (metadata)
2265  {
2266  if (!metadata->GetSubtitle().isEmpty())
2267  {
2268  label = tr("Video Options\n%1\n%2").arg(metadata->GetTitle(),
2269  metadata->GetSubtitle());
2270  }
2271  else
2272  {
2273  label = tr("Video Options\n%1").arg(metadata->GetTitle());
2274  }
2275  }
2276  else
2277  label = tr("Video Options");
2278 
2279  auto *menu = new MythMenu(label, this, "actions");
2280 
2282  MythGenericTree *node = GetNodePtrFromButton(item);
2283  if (metadata)
2284  {
2285  if (!metadata->GetTrailer().isEmpty() ||
2286  gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false) ||
2288  menu->AddItem(tr("Play..."), nullptr, CreatePlayMenu());
2289  else
2290  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2291  if (metadata->GetWatched())
2292  menu->AddItem(tr("Mark as Unwatched"), &VideoDialog::ToggleWatched);
2293  else
2294  menu->AddItem(tr("Mark as Watched"), &VideoDialog::ToggleWatched);
2295  menu->AddItem(tr("Video Info"), nullptr, CreateInfoMenu());
2296  if (!m_d->m_notifications.contains(metadata->GetHash()))
2297  {
2298  menu->AddItem(tr("Change Video Details"), nullptr, CreateManageMenu());
2299  }
2300  menu->AddItem(tr("Delete"), &VideoDialog::RemoveVideo);
2301  }
2302  else if (node && node->getInt() != kUpFolder)
2303  {
2304  menu->AddItem(tr("Play Folder"), &VideoDialog::playFolder);
2305  }
2306 
2307 
2308  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2309 
2310  if (m_menuPopup->Create())
2311  {
2314  }
2315  else
2316  delete m_menuPopup;
2317 }
2318 
2325 {
2326  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2327  QString label;
2328 
2329  if (metadata)
2330  label = tr("Playback Options\n%1").arg(metadata->GetTitle());
2331  else
2332  return nullptr;
2333 
2334  auto *menu = new MythMenu(label, this, "actions");
2335 
2336  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2337 
2338  if (m_d->m_altPlayerEnabled)
2339  {
2340  menu->AddItem(tr("Play in Alternate Player"), &VideoDialog::playVideoAlt);
2341  }
2342 
2343  if (gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false))
2344  {
2345  menu->AddItem(tr("Play With Trailers"), &VideoDialog::playVideoWithTrailers);
2346  }
2347 
2348  QString trailerFile = metadata->GetTrailer();
2349  if (QFile::exists(trailerFile) ||
2350  (!metadata->GetHost().isEmpty() && !trailerFile.isEmpty()))
2351  {
2352  menu->AddItem(tr("Play Trailer"), &VideoDialog::playTrailer);
2353  }
2354 
2355  return menu;
2356 }
2357 
2363 {
2364  QString label = tr("Video Display Menu");
2365 
2366  auto *menu = new MythMenu(label, this, "display");
2367 
2368  menu->AddItem(tr("Scan For Changes"), &VideoDialog::doVideoScan);
2369  menu->AddItem(tr("Retrieve All Details"), qOverload<>(&VideoDialog::VideoAutoSearch));
2370  menu->AddItem(tr("Filter Display"), &VideoDialog::ChangeFilter);
2371  menu->AddItem(tr("Browse By..."), nullptr, CreateMetadataBrowseMenu());
2372  menu->AddItem(tr("Change View"), nullptr, CreateViewMenu());
2373  menu->AddItem(tr("Settings"), nullptr, CreateSettingsMenu());
2374 
2375  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2376 
2377  if (m_menuPopup->Create())
2378  {
2381  }
2382  else
2383  delete m_menuPopup;
2384 }
2385 
2386 // Switch from the display menu to the actions menu on second
2387 // menu press
2388 
2389 void VideoDialog::popupClosed(const QString& which, int result)
2390 {
2391  m_menuPopup = nullptr;
2392 
2393  if (result == -2)
2394  {
2395  if (which == "display")
2396  VideoMenu();
2397  }
2398 }
2399 
2405 {
2406  QString label = tr("Change View");
2407 
2408  auto *menu = new MythMenu(label, this, "view");
2409 
2410  if (!(m_d->m_type & DLG_BROWSER))
2411  menu->AddItem(tr("Switch to Browse View"), &VideoDialog::SwitchBrowse);
2412 
2413  if (!(m_d->m_type & DLG_GALLERY))
2414  menu->AddItem(tr("Switch to Gallery View"), &VideoDialog::SwitchGallery);
2415 
2416  if (!(m_d->m_type & DLG_TREE))
2417  menu->AddItem(tr("Switch to List View"), &VideoDialog::SwitchTree);
2418 
2419  if (!(m_d->m_type & DLG_MANAGER))
2420  menu->AddItem(tr("Switch to Manage View"), &VideoDialog::SwitchManager);
2421 
2422  if (m_d->m_isFlatList)
2423  menu->AddItem(tr("Show Directory Structure"), &VideoDialog::ToggleFlatView);
2424  else
2425  menu->AddItem(tr("Hide Directory Structure"), &VideoDialog::ToggleFlatView);
2426 
2427  if (m_d->m_isFileBrowser)
2428  menu->AddItem(tr("Browse Library (recommended)"), &VideoDialog::ToggleBrowseMode);
2429  else
2430  menu->AddItem(tr("Browse Filesystem (slow)"), &VideoDialog::ToggleBrowseMode);
2431 
2432 
2433  return menu;
2434 }
2435 
2441 {
2442  QString label = tr("Video Settings");
2443 
2444  auto *menu = new MythMenu(label, this, "settings");
2445 
2446  menu->AddItem(tr("Player Settings"), &VideoDialog::ShowPlayerSettings);
2447  menu->AddItem(tr("Metadata Settings"), &VideoDialog::ShowMetadataSettings);
2448  menu->AddItem(tr("File Type Settings"), &VideoDialog::ShowExtensionSettings);
2449 
2450  return menu;
2451 }
2452 
2458 {
2459  auto *ps = new PlayerSettings(m_mainStack, "player settings");
2460 
2461  if (ps->Create())
2462  m_mainStack->AddScreen(ps);
2463  else
2464  delete ps;
2465 }
2466 
2472 {
2473  auto *ms = new MetadataSettings(m_mainStack, "metadata settings");
2474 
2475  if (ms->Create())
2476  m_mainStack->AddScreen(ms);
2477  else
2478  delete ms;
2479 }
2480 
2486 {
2487  auto *fa = new FileAssocDialog(m_mainStack, "fa dialog");
2488 
2489  if (fa->Create())
2490  m_mainStack->AddScreen(fa);
2491  else
2492  delete fa;
2493 }
2494 
2500 {
2501  QString label = tr("Browse By");
2502 
2503  auto *menu = new MythMenu(label, this, "metadata");
2504 
2505  if (m_d->m_groupType != BRS_CAST)
2506  menu->AddItem(tr("Cast"), &VideoDialog::SwitchVideoCastGroup);
2507 
2508  if (m_d->m_groupType != BRS_CATEGORY)
2509  menu->AddItem(tr("Category"), &VideoDialog::SwitchVideoCategoryGroup);
2510 
2511  if (m_d->m_groupType != BRS_INSERTDATE)
2512  menu->AddItem(tr("Date Added"), &VideoDialog::SwitchVideoInsertDateGroup);
2513 
2514  if (m_d->m_groupType != BRS_DIRECTOR)
2515  menu->AddItem(tr("Director"), &VideoDialog::SwitchVideoDirectorGroup);
2516 
2517  if (m_d->m_groupType != BRS_STUDIO)
2518  menu->AddItem(tr("Studio"), &VideoDialog::SwitchVideoStudioGroup);
2519 
2520  if (m_d->m_groupType != BRS_FOLDER)
2521  menu->AddItem(tr("Folder"), &VideoDialog::SwitchVideoFolderGroup);
2522 
2523  if (m_d->m_groupType != BRS_GENRE)
2524  menu->AddItem(tr("Genre"), &VideoDialog::SwitchVideoGenreGroup);
2525 
2526  if (m_d->m_groupType != BRS_TVMOVIE)
2527  menu->AddItem(tr("TV/Movies"), &VideoDialog::SwitchVideoTVMovieGroup);
2528 
2529  if (m_d->m_groupType != BRS_USERRATING)
2530  menu->AddItem(tr("User Rating"), &VideoDialog::SwitchVideoUserRatingGroup);
2531 
2532  if (m_d->m_groupType != BRS_YEAR)
2533  menu->AddItem(tr("Year"), &VideoDialog::SwitchVideoYearGroup);
2534 
2535  return menu;
2536 }
2537 
2543 {
2544  QString label = tr("Video Info");
2545 
2546  auto *menu = new MythMenu(label, this, "info");
2547 
2549  menu->AddItem(tr("View Details"), &VideoDialog::DoItemDetailShow2);
2550 
2551  menu->AddItem(tr("View Full Plot"), &VideoDialog::ViewPlot);
2552 
2553  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2554  if (metadata)
2555  {
2556  if (!metadata->GetCast().empty())
2557  menu->AddItem(tr("View Cast"), &VideoDialog::ShowCastDialog);
2558  if (!metadata->GetHomepage().isEmpty())
2559  menu->AddItem(tr("View Homepage"), &VideoDialog::ShowHomepage);
2560  }
2561 
2562  return menu;
2563 }
2564 
2570 {
2571  QString label = tr("Manage Video Details");
2572 
2573  auto *menu = new MythMenu(label, this, "manage");
2574 
2575  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2576 
2577  menu->AddItem(tr("Edit Details"), &VideoDialog::EditMetadata);
2578  menu->AddItem(tr("Retrieve Details"), qOverload<>(&VideoDialog::VideoSearch));
2579  if (metadata->GetProcessed())
2580  menu->AddItem(tr("Allow Updates"), &VideoDialog::ToggleProcess);
2581  else
2582  menu->AddItem(tr("Disable Updates"), &VideoDialog::ToggleProcess);
2583  menu->AddItem(tr("Reset Details"), &VideoDialog::ResetMetadata);
2584 
2585  return menu;
2586 }
2587 
2589 {
2590  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2591  if (metadata)
2592  {
2593  metadata->SetProcessed(!metadata->GetProcessed());
2594  metadata->UpdateDatabase();
2595 
2596  refreshData();
2597  }
2598 }
2599 
2605 {
2607  gCoreContext->SaveSetting("VideoDialogNoDB",
2608  QString("%1").arg((int)m_d->m_isFileBrowser));
2609  reloadData();
2610 }
2611 
2617 {
2619  gCoreContext->SaveSetting(QString("mythvideo.folder_view_%1").arg(m_d->m_type),
2620  QString("%1").arg((int)m_d->m_isFlatList));
2621  // TODO: This forces a complete tree rebuild, this is SLOW and shouldn't
2622  // be necessary since MythGenericTree can do a flat view without a rebuild,
2623  // I just don't want to re-write VideoList just now
2624  reloadData();
2625 }
2626 
2632 {
2633  SetCurrentNode(node);
2634  loadData();
2635 }
2636 
2642 {
2643  QStringList route = node->getRouteByString();
2644  if (m_d->m_videoList && m_d->m_videoList->refreshNode(node))
2645  reloadData();
2647 }
2648 
2654 {
2655  MythGenericTree *node = GetNodePtrFromButton(item);
2656  int nodeInt = node->getInt();
2657 
2658  switch (nodeInt)
2659  {
2660  case kDynamicSubFolder:
2661  handleDynamicDirSelect(node);
2662  break;
2663  case kSubFolder:
2664  handleDirSelect(node);
2665  break;
2666  case kUpFolder:
2667  goBack();
2668  break;
2669  default:
2670  {
2671  bool doPlay = true;
2672  if (m_d->m_type == DLG_GALLERY)
2673  {
2674  doPlay = !DoItemDetailShow();
2675  }
2676 
2677  if (doPlay)
2678  playVideo();
2679  }
2680  };
2681 }
2682 
2688 {
2690 }
2691 
2697 {
2699 }
2700 
2706 {
2708 }
2709 
2715 {
2717 }
2718 
2724 {
2726 }
2727 
2733 {
2735 }
2736 
2742 {
2744 }
2745 
2751 {
2753 }
2754 
2760 {
2762 }
2763 
2769 {
2771 }
2772 
2778 {
2780 }
2781 
2787 {
2789 }
2790 
2796 {
2798 }
2799 
2805 {
2807 }
2808 
2814 {
2815  m_d->m_switchingLayout = true;
2816 
2817  // save current position so it can be restored after the switch
2818  SavePosition();
2819 
2820  auto *mythvideo =
2821  new VideoDialog(GetMythMainWindow()->GetMainStack(), "mythvideo",
2822  m_d->m_videoList, type, browse);
2823 
2824  if (mythvideo->Create())
2825  {
2826  gCoreContext->SaveSetting("Default MythVideo View", type);
2827  gCoreContext->SaveSetting("mythvideo.db_group_type", browse);
2828  MythScreenStack *screenStack = GetScreenStack();
2829  screenStack->AddScreen(mythvideo);
2830  screenStack->PopScreen(this, false, false);
2831  deleteLater();
2832  }
2833  else
2834  {
2835  ShowOkPopup(tr("An error occurred when switching views."));
2836  }
2837 }
2838 
2844 {
2845  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2846 
2847  auto *plotdialog = new PlotDialog(m_popupStack, metadata);
2848 
2849  if (plotdialog->Create())
2850  m_popupStack->AddScreen(plotdialog);
2851 }
2852 
2858 {
2859  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2860 
2861  if (metadata)
2862  {
2864  auto *idp = new ItemDetailPopup(mainStack, metadata,
2865  m_d->m_videoList->getListCache());
2866 
2867  if (idp->Create())
2868  {
2869  mainStack->AddScreen(idp);
2870  return true;
2871  }
2872  }
2873 
2874  return false;
2875 }
2876 
2882 {
2883  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2884 
2885  auto *castdialog = new CastDialog(m_popupStack, metadata);
2886 
2887  if (castdialog->Create())
2888  m_popupStack->AddScreen(castdialog);
2889 }
2890 
2892 {
2893  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2894 
2895  if (!metadata)
2896  return;
2897 
2898  QString url = metadata->GetHomepage();
2899 
2900  if (url.isEmpty())
2901  return;
2902 
2903  QString browser = gCoreContext->GetSetting("WebBrowserCommand", "");
2904  QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
2905 
2906  if (browser.isEmpty())
2907  {
2908  ShowOkPopup(tr("No browser command set! MythVideo needs MythBrowser "
2909  "installed to display the homepage."));
2910  return;
2911  }
2912 
2913  if (browser.toLower() == "internal")
2914  {
2915  GetMythMainWindow()->HandleMedia("WebBrowser", url);
2916  return;
2917  }
2918 
2919  QString cmd = browser;
2920  cmd.replace("%ZOOM%", zoom);
2921  cmd.replace("%URL%", url);
2922  cmd.replace('\'', "%27");
2923  cmd.replace("&","\\&");
2924  cmd.replace(";","\\;");
2925 
2926  GetMythMainWindow()->AllowInput(false);
2928  GetMythMainWindow()->AllowInput(true);
2929 }
2930 
2936 {
2937  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2938  if (metadata)
2939  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
2940 }
2941 
2947 {
2948  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2949  if (metadata)
2950  PlayVideo(metadata->GetFilename(),
2951  m_d->m_videoList->getListCache(), true);
2952 }
2953 
2959 {
2960  const int WATCHED_WATERMARK = 10000; // Play less then this milisec and the chain of
2961  // videos will not be followed when
2962  // playing.
2963  QElapsedTimer playing_time;
2964 
2966  MythGenericTree *node = GetNodePtrFromButton(item);
2967  int list_count = 0;
2968 
2969  if (node && !(node->getInt() >= 0))
2970  list_count = node->childCount();
2971  else
2972  return;
2973 
2974  if (list_count > 0)
2975  {
2976  bool video_started = false;
2977  int i = 0;
2978  while (i < list_count &&
2979  (!video_started || playing_time.hasExpired(WATCHED_WATERMARK)))
2980  {
2981  MythGenericTree *subnode = node->getChildAt(i);
2982  if (subnode)
2983  {
2984  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
2985  if (metadata)
2986  {
2987  playing_time.start();
2988  video_started = true;
2989  PlayVideo(metadata->GetFilename(),
2990  m_d->m_videoList->getListCache());
2991  }
2992  }
2993  i++;
2994  }
2995  }
2996 }
2997 
2998 namespace
2999 {
3000  struct SimpleCollect : public DirectoryHandler
3001  {
3002  explicit SimpleCollect(QStringList &fileList) : m_fileList(fileList) {}
3003 
3004  DirectoryHandler *newDir([[maybe_unused]] const QString &dirName,
3005  [[maybe_unused]] const QString &fqDirName) override // DirectoryHandler
3006  {
3007  return this;
3008  }
3009 
3010  void handleFile([[maybe_unused]] const QString &fileName,
3011  const QString &fqFileName,
3012  [[maybe_unused]] const QString &extension,
3013  [[maybe_unused]] const QString &host) override // DirectoryHandler
3014  {
3015  m_fileList.push_back(fqFileName);
3016  }
3017 
3018  private:
3019  QStringList &m_fileList;
3020  };
3021 
3022  QStringList GetTrailersInDirectory(const QString &startDir)
3023  {
3026  .getExtensionIgnoreList(extensions);
3027  QStringList ret;
3028  SimpleCollect sc(ret);
3029 
3030  (void) ScanVideoDirectory(startDir, &sc, extensions, false);
3031  return ret;
3032  }
3033 }
3034 
3040 {
3041  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3042  if (!metadata) return;
3043 
3044  QStringList trailers = GetTrailersInDirectory(gCoreContext->
3045  GetSetting("mythvideo.TrailersDir"));
3046 
3047  if (trailers.isEmpty())
3048  return;
3049 
3050  const int trailersToPlay =
3051  gCoreContext->GetNumSetting("mythvideo.TrailersRandomCount");
3052 
3053  int i = 0;
3054  while (!trailers.isEmpty() && i < trailersToPlay)
3055  {
3056  ++i;
3057  QString trailer = trailers.takeAt(MythRandom(0, trailers.size() - 1));
3058 
3059  LOG(VB_GENERAL, LOG_DEBUG,
3060  QString("Random trailer to play will be: %1").arg(trailer));
3061 
3063  }
3064 
3065  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
3066 }
3067 
3073 {
3074  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3075  if (!metadata) return;
3076  QString url;
3077 
3078  if (metadata->IsHostSet() && !metadata->GetTrailer().startsWith("/"))
3079  {
3080  url = generate_file_url("Trailers", metadata->GetHost(),
3081  metadata->GetTrailer());
3082  }
3083  else
3084  {
3085  url = metadata->GetTrailer();
3086  }
3087 
3089 }
3090 
3096 {
3097  m_d->m_parentalLevel.SetLevel(level);
3098 }
3099 
3105 {
3107  .GetLevel() + amount).GetLevel());
3108 }
3109 
3115 {
3116  MythScreenStack *mainStack = GetScreenStack();
3117 
3118  auto *filterdialog = new VideoFilterDialog(mainStack,
3119  "videodialogfilters", m_d->m_videoList.get());
3120 
3121  if (filterdialog->Create())
3122  mainStack->AddScreen(filterdialog);
3123 
3124  connect(filterdialog, &VideoFilterDialog::filterChanged, this, &VideoDialog::reloadData);
3125 }
3126 
3132 {
3133  VideoMetadata *metadata = nullptr;
3134 
3135  if (item)
3136  {
3137  MythGenericTree *node = GetNodePtrFromButton(item);
3138  if (node)
3139  {
3140  int nodeInt = node->getInt();
3141 
3142  if (nodeInt >= 0)
3143  metadata = GetMetadataPtrFromNode(node);
3144  }
3145  }
3146 
3147  return metadata;
3148 }
3149 
3150 void VideoDialog::customEvent(QEvent *levent)
3151 {
3152  if (levent->type() == MetadataFactoryMultiResult::kEventType)
3153  {
3154  auto *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
3155 
3156  if (!mfmr)
3157  return;
3158 
3159  MetadataLookupList list = mfmr->m_results;
3160 
3161  if (list.count() > 1)
3162  {
3163  auto *metadata = list[0]->GetData().value<VideoMetadata *>();
3164  dismissFetchDialog(metadata, true);
3165  auto *resultsdialog = new MetadataResultsDialog(m_popupStack, list);
3166 
3167  connect(resultsdialog, &MetadataResultsDialog::haveResult,
3169  Qt::QueuedConnection);
3170 
3171  if (resultsdialog->Create())
3172  m_popupStack->AddScreen(resultsdialog);
3173  }
3174  }
3175  else if (levent->type() == MetadataFactorySingleResult::kEventType)
3176  {
3177  auto *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
3178 
3179  if (!mfsr)
3180  return;
3181 
3182  MetadataLookup *lookup = mfsr->m_result;
3183 
3184  if (!lookup)
3185  return;
3186 
3187  OnVideoSearchDone(lookup);
3188  }
3189  else if (levent->type() == MetadataFactoryNoResult::kEventType)
3190  {
3191  auto *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
3192 
3193  if (!mfnr)
3194  return;
3195 
3196  MetadataLookup *lookup = mfnr->m_result;
3197 
3198  if (!lookup)
3199  return;
3200 
3201  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3202  if (metadata)
3203  {
3204  dismissFetchDialog(metadata, false);
3205  metadata->SetProcessed(true);
3206  metadata->UpdateDatabase();
3207  }
3208  LOG(VB_GENERAL, LOG_INFO,
3209  QString("No results found for %1 %2 %3").arg(lookup->GetTitle())
3210  .arg(lookup->GetSeason()).arg(lookup->GetEpisode()));
3211  }
3212  else if (levent->type() == DialogCompletionEvent::kEventType)
3213  {
3214  auto *dce = dynamic_cast<DialogCompletionEvent *>(levent);
3215  if (dce != nullptr)
3216  {
3217  QString id = dce->GetId();
3218 
3219  if (id == "scanprompt")
3220  {
3221  int result = dce->GetResult();
3222  if (result == 1)
3223  doVideoScan();
3224  }
3225  else
3226  {
3227  m_menuPopup = nullptr;
3228  }
3229  }
3230  else
3231  {
3232  m_menuPopup = nullptr;
3233  }
3234  }
3235  else if (levent->type() == ImageDLFailureEvent::kEventType)
3236  {
3237  MythErrorNotification n(tr("Failed to retrieve image(s)"),
3238  sLocation,
3239  tr("Check logs"));
3241  }
3242 }
3243 
3245 {
3246  // The metadata has some cover file set
3247  dismissFetchDialog(metadata, true);
3248 
3249  metadata->SetProcessed(true);
3250  metadata->UpdateDatabase();
3251 
3252  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3253  if (item != nullptr)
3254  UpdateItem(item);
3255 }
3256 
3258 {
3259  if (m_videoButtonTree)
3260  {
3262  }
3263 
3265 }
3266 
3268 {
3269  if (m_videoButtonTree)
3270  {
3272  }
3273 
3274  QMap<int, int> idPosition;
3275 
3276  QList<MythGenericTree*> *children = m_d->m_currentNode->getAllChildren();
3277 
3278  for (auto * child : qAsConst(*children))
3279  {
3280  int nodeInt = child->getInt();
3281  if (nodeInt != kSubFolder && nodeInt != kUpFolder)
3282  {
3283  VideoMetadata *listmeta =
3284  GetMetadataPtrFromNode(child);
3285  if (listmeta)
3286  {
3287  int position = child->getPosition();
3288  int id = listmeta->GetID();
3289  idPosition.insert(id, position);
3290  }
3291  }
3292  }
3293 
3294  return m_videoButtonList->GetItemAt(idPosition.value(metadata->GetID()));
3295 }
3296 
3298  bool automode)
3299 {
3300  if (!node)
3301  node = GetNodePtrFromButton(GetItemCurrent());
3302 
3303  if (!node)
3304  return;
3305 
3306  VideoMetadata *metadata = GetMetadataPtrFromNode(node);
3307 
3308  if (!metadata)
3309  return;
3310 
3311  m_metadataFactory->Lookup(metadata, automode, true);
3312 
3313  if (!automode)
3314  {
3315  createFetchDialog(metadata);
3316  }
3317 }
3318 
3320 {
3321  if (!node)
3322  node = m_d->m_rootNode;
3323  using MGTreeChildList = QList<MythGenericTree *>;
3324  MGTreeChildList *lchildren = node->getAllChildren();
3325 
3326  LOG(VB_GENERAL, LOG_DEBUG,
3327  QString("Fetching details in %1").arg(node->GetText()));
3328 
3329  for (auto * child : qAsConst(*lchildren))
3330  {
3331  if ((child->getInt() == kSubFolder) ||
3332  (child->getInt() == kUpFolder))
3333  VideoAutoSearch(child);
3334  else
3335  {
3336  VideoMetadata *metadata = GetMetadataPtrFromNode(child);
3337 
3338  if (!metadata)
3339  continue;
3340 
3341  if (!metadata->GetProcessed())
3342  VideoSearch(child, true);
3343  }
3344  }
3345 }
3346 
3348 {
3350  if (!item)
3351  return;
3352 
3353  VideoMetadata *metadata = GetMetadata(item);
3354  if (metadata)
3355  {
3356  metadata->SetWatched(!metadata->GetWatched());
3357  metadata->UpdateDatabase();
3358  item->DisplayState(WatchedToState(metadata->GetWatched()),
3359  "watchedstate");
3360  }
3361 }
3362 
3364 {
3365  if (!lookup)
3366  return;
3367 
3368  if(!lookup->GetInetref().isEmpty() && lookup->GetInetref() != "00000000")
3369  {
3370  LOG(VB_GENERAL, LOG_INFO, LOC_MML +
3371  QString("Selected Item: Type: %1%2 : Subtype: %3%4%5 : InetRef: %6")
3372  .arg(lookup->GetType() == kMetadataVideo ? "Video" : "",
3373  lookup->GetType() == kMetadataRecording ? "Recording" : "",
3374  lookup->GetSubtype() == kProbableMovie ? "Movie" : "",
3375  lookup->GetSubtype() == kProbableTelevision ? "Television" : "",
3376  lookup->GetSubtype() == kUnknownVideo ? "Unknown" : "",
3377  lookup->GetInetref()));
3378 
3379  lookup->SetStep(kLookupData);
3380  lookup->IncrRef();
3381  m_metadataFactory->Lookup(lookup);
3382  }
3383  else
3384  {
3385  LOG(VB_GENERAL, LOG_ERR, LOC_MML +
3386  QString("Selected Item has no InetRef Number!"));
3387 
3388  OnVideoSearchDone(lookup);
3389  }
3390 }
3391 
3393 {
3394  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3395  if (metadata)
3396  {
3397  ParentalLevel curshowlevel = metadata->GetShowLevel();
3398 
3399  curshowlevel += amount;
3400 
3401  if (curshowlevel.GetLevel() != metadata->GetShowLevel())
3402  {
3403  metadata->SetShowLevel(curshowlevel.GetLevel());
3404  metadata->UpdateDatabase();
3405  refreshData();
3406  }
3407  }
3408 }
3409 
3411 {
3412  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3413  if (!metadata)
3414  return;
3415 
3416  MythScreenStack *screenStack = GetScreenStack();
3417 
3418  auto *md_editor = new EditMetadataDialog(screenStack,
3419  "mythvideoeditmetadata", metadata,
3420  m_d->m_videoList->getListCache());
3421 
3422  connect(md_editor, &EditMetadataDialog::Finished, this, &VideoDialog::refreshData);
3423 
3424  if (md_editor->Create())
3425  screenStack->AddScreen(md_editor);
3426 }
3427 
3429 {
3430  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3431 
3432  if (!metadata)
3433  return;
3434 
3435  QString message = tr("Are you sure you want to permanently delete:\n%1")
3436  .arg(metadata->GetTitle());
3437 
3438  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message);
3439 
3440  if (confirmdialog->Create())
3441  m_popupStack->AddScreen(confirmdialog);
3442 
3443  connect(confirmdialog, &MythConfirmationDialog::haveResult,
3445 }
3446 
3447 void VideoDialog::OnRemoveVideo(bool dodelete)
3448 {
3449  if (!dodelete)
3450  return;
3451 
3453  MythGenericTree *gtItem = GetNodePtrFromButton(item);
3454 
3455  VideoMetadata *metadata = GetMetadata(item);
3456 
3457  if (!metadata)
3458  return;
3459 
3460  if (m_d->m_videoList->Delete(metadata->GetID()))
3461  {
3462  if (m_videoButtonTree)
3463  m_videoButtonTree->RemoveItem(item, false); // FIXME Segfault when true
3464  else
3466 
3467  MythGenericTree *parent = gtItem->getParent();
3468  parent->deleteNode(gtItem);
3469  }
3470  else
3471  {
3472  QString message = tr("Failed to delete file");
3473 
3474  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message,
3475  false);
3476 
3477  if (confirmdialog->Create())
3478  m_popupStack->AddScreen(confirmdialog);
3479  }
3480 }
3481 
3483 {
3485  VideoMetadata *metadata = GetMetadata(item);
3486 
3487  if (metadata)
3488  {
3489  metadata->Reset();
3490  metadata->UpdateDatabase();
3491  UpdateItem(item);
3492  }
3493 }
3494 
3496 {
3497  if (!metadata)
3498  return;
3499 
3500  QStringList cover_dirs;
3501  cover_dirs += m_d->m_artDir;
3502 
3503  QString cover_file;
3504  QString inetref = metadata->GetInetRef();
3505  QString filename = metadata->GetFilename();
3506  QString title = metadata->GetTitle();
3507  int season = metadata->GetSeason();
3508  QString host = metadata->GetHost();
3509  int episode = metadata->GetEpisode();
3510 
3511  if (metadata->GetCoverFile().isEmpty() ||
3512  IsDefaultCoverFile(metadata->GetCoverFile()))
3513  {
3514  if (GetLocalVideoImage(inetref, filename,
3515  cover_dirs, cover_file, title,
3516  season, host, "Coverart", episode))
3517  {
3518  metadata->SetCoverFile(cover_file);
3519  OnVideoImageSetDone(metadata);
3520  }
3521  }
3522 
3523  QStringList fanart_dirs;
3524  fanart_dirs += m_d->m_fanDir;
3525 
3526  QString fanart_file;
3527 
3528  if (metadata->GetFanart().isEmpty())
3529  {
3530  if (GetLocalVideoImage(inetref, filename,
3531  fanart_dirs, fanart_file, title,
3532  season, host, "Fanart", episode))
3533  {
3534  metadata->SetFanart(fanart_file);
3535  OnVideoImageSetDone(metadata);
3536  }
3537  }
3538 
3539  QStringList banner_dirs;
3540  banner_dirs += m_d->m_banDir;
3541 
3542  QString banner_file;
3543 
3544  if (metadata->GetBanner().isEmpty())
3545  {
3546  if (GetLocalVideoImage(inetref, filename,
3547  banner_dirs, banner_file, title,
3548  season, host, "Banners", episode))
3549  {
3550  metadata->SetBanner(banner_file);
3551  OnVideoImageSetDone(metadata);
3552  }
3553  }
3554 
3555  QStringList screenshot_dirs;
3556  screenshot_dirs += m_d->m_sshotDir;
3557 
3558  QString screenshot_file;
3559 
3560  if (metadata->GetScreenshot().isEmpty())
3561  {
3562  if (GetLocalVideoImage(inetref, filename,
3563  screenshot_dirs, screenshot_file, title,
3564  season, host, "Screenshots", episode,
3565  true))
3566  {
3567  metadata->SetScreenshot(screenshot_file);
3568  OnVideoImageSetDone(metadata);
3569  }
3570  }
3571 }
3572 
3574 {
3575  if (!lookup)
3576  return;
3577 
3578  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3579 
3580  if (!metadata)
3581  return;
3582 
3583  dismissFetchDialog(metadata, true);
3584  metadata->SetTitle(lookup->GetTitle());
3585  metadata->SetSubtitle(lookup->GetSubtitle());
3586 
3587  if (metadata->GetTagline().isEmpty())
3588  metadata->SetTagline(lookup->GetTagline());
3589  if (metadata->GetYear() == 1895 || metadata->GetYear() == 0)
3590  metadata->SetYear(lookup->GetYear());
3591  if (metadata->GetReleaseDate() == QDate())
3592  metadata->SetReleaseDate(lookup->GetReleaseDate());
3593  if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN ||
3594  metadata->GetDirector().isEmpty())
3595  {
3596  QList<PersonInfo> director = lookup->GetPeople(kPersonDirector);
3597  if (director.count() > 0)
3598  metadata->SetDirector(director.takeFirst().name);
3599  }
3600  if (metadata->GetStudio().isEmpty())
3601  {
3602  QStringList studios = lookup->GetStudios();
3603  if (studios.count() > 0)
3604  metadata->SetStudio(studios.takeFirst());
3605  }
3606  if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT ||
3607  metadata->GetPlot().isEmpty())
3608  metadata->SetPlot(lookup->GetDescription());
3609  if (metadata->GetUserRating() == 0)
3610  metadata->SetUserRating(lookup->GetUserRating());
3611  if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
3612  metadata->SetRating(lookup->GetCertification());
3613  if (metadata->GetLength() == 0min)
3614  metadata->SetLength(lookup->GetRuntime());
3615  if (metadata->GetSeason() == 0)
3616  metadata->SetSeason(lookup->GetSeason());
3617  if (metadata->GetEpisode() == 0)
3618  metadata->SetEpisode(lookup->GetEpisode());
3619  if (metadata->GetHomepage().isEmpty())
3620  metadata->SetHomepage(lookup->GetHomepage());
3621 
3622  metadata->SetInetRef(lookup->GetInetref());
3623 
3624  m_d->AutomaticParentalAdjustment(metadata);
3625 
3626  // Cast
3627  QList<PersonInfo> actors = lookup->GetPeople(kPersonActor);
3628  QList<PersonInfo> gueststars = lookup->GetPeople(kPersonGuestStar);
3629 
3630  for (const auto & name : qAsConst(gueststars))
3631  actors.append(name);
3632 
3634  QStringList cl;
3635 
3636  for (const auto & person : qAsConst(actors))
3637  cl.append(person.name);
3638 
3639  for (const auto & name : qAsConst(cl))
3640  {
3641  QString cn = name.trimmed();
3642  if (!cn.isEmpty())
3643  {
3644  cast.emplace_back(-1, cn);
3645  }
3646  }
3647 
3648  metadata->SetCast(cast);
3649 
3650  // Genres
3651  VideoMetadata::genre_list video_genres;
3652  QStringList genres = lookup->GetCategories();
3653 
3654  for (const auto & name : qAsConst(genres))
3655  {
3656  QString genre_name = name.trimmed();
3657  if (!genre_name.isEmpty())
3658  {
3659  video_genres.emplace_back(-1, genre_name);
3660  }
3661  }
3662 
3663  metadata->SetGenres(video_genres);
3664 
3665  // Countries
3666  VideoMetadata::country_list video_countries;
3667  QStringList countries = lookup->GetCountries();
3668 
3669  for (const auto & name : qAsConst(countries))
3670  {
3671  QString country_name = name.trimmed();
3672  if (!country_name.isEmpty())
3673  {
3674  video_countries.emplace_back(-1, country_name);
3675  }
3676  }
3677 
3678  metadata->SetCountries(video_countries);
3679  metadata->SetProcessed(true);
3680 
3681  metadata->UpdateDatabase();
3682 
3683  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3684  if (item != nullptr)
3685  UpdateItem(item);
3686 
3687  StartVideoImageSet(metadata);
3688 }
3689 
3691 {
3692  if (!m_d->m_scanner)
3693  m_d->m_scanner = new VideoScanner();
3696 }
3697 
3699 {
3700  QString message = tr("There are no videos in the database, would you like "
3701  "to scan your video directories now?");
3702  auto *dialog = new MythConfirmationDialog(m_popupStack, message, true);
3703  dialog->SetReturnEvent(this, "scanprompt");
3704  if (dialog->Create())
3705  m_popupStack->AddScreen(dialog);
3706  else
3707  delete dialog;
3708 }
3709 
3710 #include "videodlg.moc"
VideoDialog::VideoListPtr
simple_ref_ptr< class VideoList > VideoListPtr
Definition: videodlg.h:45
MetadataFactory::Lookup
void Lookup(ProgramInfo *pginfo, bool automatic=true, bool getimages=true, bool allowgeneric=false)
Definition: metadatafactory.cpp:139
VideoDialogPrivate::m_isFileBrowser
bool m_isFileBrowser
Definition: videodlg.cpp:779
VideoMetadata::toMap
void toMap(InfoMap &metadataMap)
Definition: videometadata.cpp:1280
MythUIButton::Clicked
void Clicked()
VideoDialog::GetBanner
static QString GetBanner(MythGenericTree *node)
Find the Banner for a given node.
Definition: videodlg.cpp:1802
MythUIButtonList::GetItemAt
MythUIButtonListItem * GetItemAt(int pos) const
Definition: mythuibuttonlist.cpp:1673
mythuibuttontree.h
mythuimetadataresults.h
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
VideoScanner::finished
void finished(bool)
generate_file_url
QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
Definition: videoutils.h:65
VideoMetadata
Definition: videometadata.h:24
VideoDialogPrivate::m_rememberPosition
bool m_rememberPosition
Definition: videodlg.cpp:770
MythUISearchDialog
Provide a dialog to quickly find an entry in a list.
Definition: mythdialogbox.h:399
build_compdb.dest
dest
Definition: build_compdb.py:9
VideoDialog::m_d
class VideoDialogPrivate * m_d
Definition: videodlg.h:217
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1587
RefCountHandler
Definition: referencecounterlist.h:17
VideoDialog::CreateMetadataBrowseMenu
MythMenu * CreateMetadataBrowseMenu()
Create a MythMenu for MythVideo Metadata Browse modes.
Definition: videodlg.cpp:2499
videometadatasettings.h
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
VideoDialog::OnVideoImageSetDone
void OnVideoImageSetDone(VideoMetadata *metadata)
Definition: videodlg.cpp:3244
VideoDialogPrivate::parental_level_map
std::list< std::pair< QString, ParentalLevel::Level > > parental_level_map
Definition: videodlg.cpp:674
VideoDialog::playVideoAlt
void playVideoAlt()
Play the selected item in an alternate player.
Definition: videodlg.cpp:2946
mythuitext.h
WatchedToState
QString WatchedToState(bool watched)
Definition: videoutils.cpp:272
VideoDialogPrivate::AutomaticParentalAdjustment
void AutomaticParentalAdjustment(VideoMetadata *metadata)
Definition: videodlg.cpp:740
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
ItemDetailPopup::keyPressEvent
bool keyPressEvent(QKeyEvent *levent) override
Key event handler.
Definition: videodlg.cpp:643
VideoDialog::CreateSettingsMenu
MythMenu * CreateSettingsMenu()
Create a MythMenu for MythVideo Settings.
Definition: videodlg.cpp:2440
VideoMetadata::GetShowLevel
ParentalLevel::Level GetShowLevel() const
Definition: videometadata.cpp:1806
VideoDialog::BRS_USERRATING
@ BRS_USERRATING
Definition: videodlg.h:42
DialogCompletionEvent::GetId
QString GetId()
Definition: mythdialogbox.h:52
VideoDialog::StartVideoImageSet
void StartVideoImageSet(VideoMetadata *metadata)
Definition: videodlg.cpp:3495
FileAssociations::getExtensionIgnoreList
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
Definition: dbaccess.cpp:810
VideoDialog::playTrailer
void playTrailer()
Play the trailer associated with the selected item.
Definition: videodlg.cpp:3072
MythGenericTree::GetText
QString GetText(const QString &name="") const
Definition: mythgenerictree.cpp:556
VideoDialog::ShowMetadataSettings
void ShowMetadataSettings()
Pop up a MythUI Menu for MythVideo Metadata Settings.
Definition: videodlg.cpp:2471
dirscan.h
VideoMetadata::SetFanart
void SetFanart(const QString &fanart)
Definition: videometadata.cpp:1896
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:12
kMetadataRecording
@ kMetadataRecording
Definition: metadatacommon.h:44
VideoDialogPrivate::m_type
VideoDialog::DialogType m_type
Definition: videodlg.cpp:783
VideoMetadata::GetHost
const QString & GetHost() const
Definition: videometadata.cpp:1836
mythrandom.h
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1370
MythUIButtonListItem::DisplayState
void DisplayState(const QString &state, const QString &name)
Definition: mythuibuttonlist.cpp:3563
VideoDialog::m_menuPopup
MythDialogBox * m_menuPopup
Definition: videodlg.h:189
MetadataLookup::GetTitle
QString GetTitle() const
Definition: metadatacommon.h:299
VideoMetadataListManager
Definition: videometadatalistmanager.h:10
MythCheckNotification
Definition: mythnotification.h:212
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:386
VideoScanner::doScan
void doScan(const QStringList &dirs)
Definition: videoscan.cpp:422
VideoDialogPrivate::m_altPlayerEnabled
bool m_altPlayerEnabled
Definition: videodlg.cpp:782
VideoDialog::SwitchManager
void SwitchManager()
Switch to Video Manager View.
Definition: videodlg.cpp:2714
VideoDialog::BRS_INSERTDATE
@ BRS_INSERTDATE
Definition: videodlg.h:42
MetadataResultsDialog
Definition: mythuimetadataresults.h:10
MythNotificationCenter::Register
int Register(void *from)
An application can register in which case it will be assigned a reusable screen, which can be modifie...
Definition: mythnotificationcenter.cpp:1368
kMetadataVideo
@ kMetadataVideo
Definition: metadatacommon.h:43
VideoDialogPrivate::m_firstLoadPass
bool m_firstLoadPass
Definition: videodlg.cpp:768
simple_ref_ptr
Definition: quicksp.h:24
MetadataLookup::GetSubtype
LookupType GetSubtype() const
Definition: metadatacommon.h:287
parentalcontrols.h
MythUIButtonList::RemoveItem
void RemoveItem(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1485
MythGenericTree::visibleChildCount
uint visibleChildCount() const
Definition: mythgenerictree.h:101
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:966
VideoDialog::refreshData
void refreshData()
Reloads the tree without invalidating the data.
Definition: videodlg.cpp:1060
ItemDetailPopup::Exists
static bool Exists()
Definition: videodlg.cpp:570
MythGenericTree::getInt
int getInt() const
Definition: mythgenerictree.h:73
MythUISearchDialog::haveResult
void haveResult(QString)
MythUIBusyDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:32
ParentalLevel::plHigh
@ plHigh
Definition: parentalcontrols.h:13
kProbableTelevision
@ kProbableTelevision
Definition: metadatacommon.h:51
VideoDialog::DLG_BROWSER
@ DLG_BROWSER
Definition: videodlg.h:37
MythBusyNotification
Definition: mythnotification.h:219
MythUIButtonTree::itemSelected
void itemSelected(MythUIButtonListItem *item)
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
VideoDialogPrivate::DelayVideoListDestruction
static void DelayVideoListDestruction(const VideoListPtr &videoList)
Definition: videodlg.cpp:757
VideoMetadata::GetFanart
const QString & GetFanart() const
Definition: videometadata.cpp:1891
VideoDialog::VideoAutoSearch
void VideoAutoSearch()
Definition: videodlg.h:101
VideoDialog::SwitchVideoGenreGroup
void SwitchVideoGenreGroup()
Switch to Genre browse mode.
Definition: videodlg.cpp:2732
VideoDialogPrivate::m_treeLoaded
bool m_treeLoaded
Definition: videodlg.cpp:777
VideoMetadata::SetBanner
void SetBanner(const QString &banner)
Definition: videometadata.cpp:1886
MythConfirmationDialog::haveResult
void haveResult(bool)
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
VideoListDeathDelay::~VideoListDeathDelay
~VideoListDeathDelay() override
Definition: videodlg.cpp:827
VideoPlayerCommand::Play
void Play() const
Definition: videoplayercommand.cpp:409
VideoMetadata::country_list
std::vector< country_entry > country_list
Definition: videometadata.h:33
MythGenericTree::GetData
QVariant GetData(void) const
Definition: mythgenerictree.h:98
MythUIButtonTree::GetItemCurrent
MythUIButtonListItem * GetItemCurrent(void) const
Return the currently selected list item.
Definition: mythuibuttontree.cpp:556
VideoDialog::dismissFetchDialog
void dismissFetchDialog(VideoMetadata *metadata, bool ok)
Definition: videodlg.cpp:2007
VideoDialog::SwitchVideoInsertDateGroup
void SwitchVideoInsertDateGroup()
Switch to Insert Date browse mode.
Definition: videodlg.cpp:2795
MythUIButtonListItem::parent
MythUIButtonList * parent() const
Definition: mythuibuttonlist.cpp:3624
VideoDialog::handleSelect
void handleSelect(MythUIButtonListItem *item)
Handle SELECT action for a given MythUIButtonListItem.
Definition: videodlg.cpp:2653
VideoDialog::ShowHomepage
void ShowHomepage()
Definition: videodlg.cpp:2891
VideoMetadataListManager::byFilename
VideoMetadataPtr byFilename(const QString &file_name) const
Definition: videometadatalistmanager.cpp:174
MythUIButtonTree::SetCurrentNode
bool SetCurrentNode(MythGenericTree *node)
Set the currently selected node.
Definition: mythuibuttontree.cpp:346
MythGenericTree::getChildByName
MythGenericTree * getChildByName(const QString &a_name) const
Definition: mythgenerictree.cpp:378
VideoMetadata::GetHomepage
const QString & GetHomepage() const
Definition: videometadata.cpp:1626
VideoMetadata::GetSeason
int GetSeason() const
Definition: videometadata.cpp:1706
CheckedSet
void CheckedSet(MythUIStateType *uiItem, const QString &value)
Definition: videoutils.cpp:40
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythDialogBox::Closed
void Closed(QString, int)
VideoDialog::CreateManageMenu
MythMenu * CreateManageMenu()
Create a MythMenu for metadata management.
Definition: videodlg.cpp:2569
VideoMetadata::genre_list
std::vector< genre_entry > genre_list
Definition: videometadata.h:32
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
MetadataLookup::GetCertification
QString GetCertification() const
Definition: metadatacommon.h:335
mythuistatetype.h
ItemDetailPopup::m_listManager
const VideoMetadataListManager & m_listManager
Definition: videodlg.cpp:663
VideoDialogPrivate::m_scanner
VideoScanner * m_scanner
Definition: videodlg.cpp:792
MythUIButtonTree::RemoveItem
void RemoveItem(MythUIButtonListItem *item, bool deleteNode=false)
Remove the item from the tree.
Definition: mythuibuttontree.cpp:389
VideoDialog::Load
void Load() override
Called after the screen is created by MythScreenStack.
Definition: videodlg.cpp:1047
VideoDialogPrivate::~VideoDialogPrivate
~VideoDialogPrivate()
Definition: videodlg.cpp:729
build_compdb.file
file
Definition: build_compdb.py:55
VideoDialog::GetSavedVideoList
static VideoListDeathDelayPtr & GetSavedVideoList()
Definition: videodlg.cpp:842
mythdirs.h
TreeNodeData
Definition: videolist.h:68
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:643
VideoMetadata::SetShowLevel
void SetShowLevel(ParentalLevel::Level showLevel)
Definition: videometadata.cpp:1811
VideoListDeathDelay::VideoListDeathDelay
VideoListDeathDelay(const VideoDialog::VideoListPtr &toSave)
Definition: videodlg.cpp:820
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
MythUIButtonTree::AssignTree
bool AssignTree(MythGenericTree *tree)
Assign the root node of the tree to be displayed.
Definition: mythuibuttontree.cpp:213
VideoDialog::EditMetadata
void EditMetadata()
Definition: videodlg.cpp:3410
VideoDialog::CreateViewMenu
MythMenu * CreateViewMenu()
Create a MythMenu for MythVideo Views.
Definition: videodlg.cpp:2404
VideoMetadata::GetScreenshot
const QString & GetScreenshot() const
Definition: videometadata.cpp:1871
VideoDialog::SwitchVideoUserRatingGroup
void SwitchVideoUserRatingGroup()
Switch to User Rating browse mode.
Definition: videodlg.cpp:2786
ParentalLevelChangeChecker
Definition: parentalcontrols.h:43
remoteutil.h
VideoDialog::BRS_STUDIO
@ BRS_STUDIO
Definition: videodlg.h:43
mythuibuttonlist.h
ItemDetailPopup::m_doneButton
MythUIButton * m_doneButton
Definition: videodlg.cpp:666
VideoDialog::m_fanart
MythUIImage * m_fanart
Definition: videodlg.h:206
StorageGroup::ClearGroupToUseCache
static void ClearGroupToUseCache(void)
Definition: storagegroup.cpp:860
hardwareprofile.distros.mythtv_data.data_mythtv.prefix
string prefix
Definition: data_mythtv.py:40
mythuiimage.h
VideoDialog::m_studioState
MythUIStateType * m_studioState
Definition: videodlg.h:213
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1652
videopopups.h
VideoDialogPrivate::m_browse
VideoDialog::BrowseType m_browse
Definition: videodlg.cpp:784
mythprogressdialog.h
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
VideoDialog::shiftParental
void shiftParental(int amount)
Shift the parental level for the library by an integer amount.
Definition: videodlg.cpp:3104
VideoDialog::BRS_CATEGORY
@ BRS_CATEGORY
Definition: videodlg.h:40
kPersonGuestStar
@ kPersonGuestStar
Definition: metadatacommon.h:81
MetadataFactoryNoResult
Definition: metadatafactory.h:50
VideoDialog::DialogType
DialogType
Definition: videodlg.h:37
VideoMetadata::GetSubtitle
const QString & GetSubtitle() const
Definition: videometadata.cpp:1561
VideoDialog::m_positionText
MythUIText * m_positionText
Definition: videodlg.h:200
VideoDialog::m_busyPopup
MythUIBusyDialog * m_busyPopup
Definition: videodlg.h:190
VideoDialog::m_videoButtonTree
MythUIButtonTree * m_videoButtonTree
Definition: videodlg.h:195
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
ItemDetailPopup::Create
bool Create() override
Definition: videodlg.cpp:584
VideoDialogPrivate::m_savedPtr
static VideoDialog::VideoListDeathDelayPtr m_savedPtr
Definition: videodlg.cpp:766
dbaccess.h
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:113
VideoDialog::BRS_CAST
@ BRS_CAST
Definition: videodlg.h:41
mythsystemlegacy.h
MetadataLookup
Definition: metadatacommon.h:87
ItemDetailPopup::OnPlay
void OnPlay()
Definition: videodlg.cpp:614
VideoDialog::m_trailerState
MythUIStateType * m_trailerState
Definition: videodlg.h:208
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3268
VideoListDeathDelay
Definition: videodlg.h:220
MythGenericTree::getChildAt
MythGenericTree * getChildAt(uint reference) const
Definition: mythgenerictree.cpp:282
VideoDialog::GetFirstImage
QString GetFirstImage(MythGenericTree *node, const QString &type, const QString &gpnode=QString(), int levels=0)
Find the first image of "type" within a folder structure.
Definition: videodlg.cpp:1637
VideoDialog::GetItemByMetadata
virtual MythUIButtonListItem * GetItemByMetadata(VideoMetadata *metadata)
Definition: videodlg.cpp:3267
videofilter.h
VideoDialog::searchComplete
void searchComplete(const QString &string)
After using incremental search, move to the selected item.
Definition: videodlg.cpp:2065
VideoDialog::m_banner
MythUIImage * m_banner
Definition: videodlg.h:205
MythGenericTree::getSelectedChild
MythGenericTree * getSelectedChild(bool onlyVisible=false) const
Definition: mythgenerictree.cpp:311
VideoListDeathDelay::GetSaved
VideoDialog::VideoListPtr GetSaved()
Definition: videodlg.cpp:832
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
MetadataFactoryNoResult::kEventType
static const Type kEventType
Definition: metadatafactory.h:65
VideoDialog::SwitchVideoTVMovieGroup
void SwitchVideoTVMovieGroup()
Switch to Television/Movie browse mode.
Definition: videodlg.cpp:2804
VideoDialog::GetScreenshot
static QString GetScreenshot(MythGenericTree *node)
Find the Screenshot for a given node.
Definition: videodlg.cpp:1762
videoscan.h
MythUIButtonTree::itemClicked
void itemClicked(MythUIButtonListItem *item)
VideoDialog::BRS_TVMOVIE
@ BRS_TVMOVIE
Definition: videodlg.h:43
VideoDialog::playVideoWithTrailers
void playVideoWithTrailers()
Play the selected item w/ a User selectable # of trailers.
Definition: videodlg.cpp:3039
MythUIButtonList::IsEmpty
bool IsEmpty() const
Definition: mythuibuttonlist.cpp:1668
VideoDialog::GetFanart
static QString GetFanart(MythGenericTree *node)
Find the Fanart for a given node.
Definition: videodlg.cpp:1837
VideoDialog::scanFinished
void scanFinished(bool dbChanged)
Definition: videodlg.cpp:1075
VideoMetadata::GetFilename
const QString & GetFilename() const
Definition: videometadata.cpp:1816
VideoDialog::SwitchBrowse
void SwitchBrowse()
Switch to Browser View.
Definition: videodlg.cpp:2705
VideoMetadata::GetInetRef
const QString & GetInetRef() const
Definition: videometadata.cpp:1606
kSubFolder
@ kSubFolder
Definition: videolist.h:6
VideoDialog::OnVideoSearchListSelection
void OnVideoSearchListSelection(RefCountHandler< MetadataLookup > lookup)
Definition: videodlg.cpp:3363
VideoDialog::m_titleText
MythUIText * m_titleText
Definition: videodlg.h:197
VideoDialog::m_crumbText
MythUIText * m_crumbText
Definition: videodlg.h:201
MetadataLookup::GetEpisode
uint GetEpisode() const
Definition: metadatacommon.h:315
MetadataLookup::GetDescription
QString GetDescription() const
Definition: metadatacommon.h:312
videolist.h
FileAssocDialog
Definition: videofileassoc.h:13
ParentalLevel::plNone
@ plNone
Definition: parentalcontrols.h:12
kPersonActor
@ kPersonActor
Definition: metadatacommon.h:70
VideoMetadata::GetProcessed
bool GetProcessed() const
Definition: videometadata.cpp:1776
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
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
VideoDialog::m_metadataFactory
MetadataFactory * m_metadataFactory
Definition: videodlg.h:215
GetVideoDirs
QStringList GetVideoDirs()
Definition: videoutils.cpp:121
VideoDialog::goBack
bool goBack()
Move one level up in the tree.
Definition: videodlg.cpp:2139
VideoDialog::m_popupStack
MythScreenStack * m_popupStack
Definition: videodlg.h:191
VideoDialog::RemoteImageCheck
static QString RemoteImageCheck(const QString &host, const QString &filename)
Search for a given (image) filename in the Video SG.
Definition: videodlg.cpp:1351
VideoDialogPrivate::m_isFlatList
bool m_isFlatList
Definition: videodlg.cpp:781
remotefile.h
VideoDialogPrivate::m_parentalLevel
ParentalLevelNotifyContainer m_parentalLevel
Definition: videodlg.cpp:763
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:238
VideoDialog::VideoListDeathDelayPtr
QPointer< class VideoListDeathDelay > VideoListDeathDelayPtr
Definition: videodlg.h:46
metadataimagedownload.h
ParentalLevel::Level
Level
Definition: parentalcontrols.h:12
ItemDetailPopup::m_metadata
VideoMetadata * m_metadata
Definition: videodlg.cpp:662
hardwareprofile.config.p
p
Definition: config.py:33
VideoDialog::VideoSearch
void VideoSearch()
Definition: videodlg.h:99
VideoDialog::PromptToScan
void PromptToScan()
Definition: videodlg.cpp:3698
globals.h
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:118
MythGenericTree::getRouteByString
QStringList getRouteByString(void)
Definition: mythgenerictree.cpp:227
RefCountedList< MetadataLookup >
FileAssociations::ext_ignore_list
std::vector< std::pair< QString, bool > > ext_ignore_list
Definition: dbaccess.h:155
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
VideoDialog::SwitchVideoYearGroup
void SwitchVideoYearGroup()
Switch to Year browse mode.
Definition: videodlg.cpp:2750
MetadataLookup::GetData
QVariant GetData() const
Definition: metadatacommon.h:288
ImageDLFailureEvent::kEventType
static const Type kEventType
Definition: metadataimagedownload.h:67
menu
static MythThemedMenu * menu
Definition: mythtv-setup.cpp:58
VideoDialog::SwitchTree
void SwitchTree()
Switch to Tree (List) View.
Definition: videodlg.cpp:2687
kLookupData
@ kLookupData
Definition: metadatacommon.h:29
VideoDialog::ShowCastDialog
void ShowCastDialog()
Display the Cast if the selected item.
Definition: videodlg.cpp:2881
MythDialogBox::Create
bool Create(void) override
Definition: mythdialogbox.cpp:127
MythNotification::SetParent
void SetParent(void *Parent)
Contains the parent address. Required if id is set Id provided must match the parent address as provi...
Definition: mythnotification.cpp:106
VideoDialog::DLG_GALLERY
@ DLG_GALLERY
Definition: videodlg.h:37
MythUIButtonTree::SetActive
void SetActive(bool active)
Set the widget active/inactive.
Definition: mythuibuttontree.cpp:438
VideoListDeathDelay::m_d
class VideoListDeathDelayPrivate * m_d
Definition: videodlg.h:238
kPersonDirector
@ kPersonDirector
Definition: metadatacommon.h:72
VideoDialog::GetItemCurrent
virtual MythUIButtonListItem * GetItemCurrent()
Definition: videodlg.cpp:3257
VideoDialogPrivate::m_banDir
QString m_banDir
Definition: videodlg.cpp:791
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
hardwareprofile.scan.rating
def rating(profile, smoonURL, gate)
Definition: scan.py:39
MetadataLookup::GetType
MetadataType GetType() const
Definition: metadatacommon.h:286
VideoDialog::Init
void Init() override
Definition: videodlg.cpp:1041
VideoDialog::m_mainStack
MythScreenStack * m_mainStack
Definition: videodlg.h:192
VideoListDeathDelayPrivate::m_savedList
VideoDialog::VideoListPtr m_savedList
Definition: videodlg.cpp:817
VideoMetadata::SetProcessed
void SetProcessed(bool processed)
Definition: videometadata.cpp:1781
MythUIButton
A single button widget.
Definition: mythuibutton.h:21
VideoDialog::searchStart
void searchStart()
Create an incremental search dialog for the current tree level.
Definition: videodlg.cpp:2103
MythGenericTree::childCount
int childCount(void) const
Definition: mythgenerictree.cpp:255
MythErrorNotification
Definition: mythnotification.h:198
VideoDialog::BRS_YEAR
@ BRS_YEAR
Definition: videodlg.h:41
EditMetadataDialog
Definition: editvideometadata.h:19
CastDialog
Definition: videopopups.h:11
videofileassoc.h
VIDEO_PLOT_DEFAULT
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
MetadataLookup::GetSubtitle
QString GetSubtitle() const
Definition: metadatacommon.h:310
MythUIComposite::SetTextFromMap
virtual void SetTextFromMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:9
VideoDialog::SwitchVideoDirectorGroup
void SwitchVideoDirectorGroup()
Switch to Director browse mode.
Definition: videodlg.cpp:2759
MetadataLookup::GetCountries
QStringList GetCountries() const
Definition: metadatacommon.h:336
VideoDialog::SetCurrentNode
void SetCurrentNode(MythGenericTree *node)
Switch to a given MythGenericTree node.
Definition: videodlg.cpp:2163
IsDefaultBanner
bool IsDefaultBanner(const QString &banner)
Definition: videoutils.cpp:140
MythGenericTree::getVisibleChildAt
MythGenericTree * getVisibleChildAt(uint reference) const
Definition: mythgenerictree.cpp:290
trailers
Definition: trailers.py:1
MetadataFactoryMultiResult::kEventType
static const Type kEventType
Definition: metadatafactory.h:29
VideoDialog::SwitchVideoFolderGroup
void SwitchVideoFolderGroup()
Switch to Folder (filesystem) browse mode.
Definition: videodlg.cpp:2723
mythgenerictree.h
VideoDialog::BRS_DIRECTOR
@ BRS_DIRECTOR
Definition: videodlg.h:41
VideoDialog::SwitchLayout
void SwitchLayout(DialogType type, BrowseType browse)
Handle a layout or browse mode switch.
Definition: videodlg.cpp:2813
VideoDialog::SwitchVideoCastGroup
void SwitchVideoCastGroup()
Switch to Cast browse mode.
Definition: videodlg.cpp:2777
storagegroup.h
editvideometadata.h
MythUIBusyDialog
Definition: mythprogressdialog.h:36
VideoDialog::setParentalLevel
void setParentalLevel(ParentalLevel::Level level)
Set the parental level for the library.
Definition: videodlg.cpp:3095
VideoDialog::BRS_FOLDER
@ BRS_FOLDER
Definition: videodlg.h:40
VideoDialog::RemoveVideo
void RemoveVideo()
Definition: videodlg.cpp:3428
MetadataLookup::GetPeople
QList< PersonInfo > GetPeople(PeopleType type) const
Definition: metadatacommon.cpp:315
MetadataLookup::GetYear
uint GetYear() const
Definition: metadatacommon.h:349
VideoDialog::ToggleProcess
void ToggleProcess()
Definition: videodlg.cpp:2588
VideoDialog::handleDynamicDirSelect
void handleDynamicDirSelect(MythGenericTree *node)
Request the latest metadata for a folder.
Definition: videodlg.cpp:2641
VideoDialog::CreateInfoMenu
MythMenu * CreateInfoMenu()
Create a MythMenu for Info pertaining to the selected item.
Definition: videodlg.cpp:2542
kUpFolder
@ kUpFolder
Definition: videolist.h:7
VideoDialog::m_parentalLevelState
MythUIStateType * m_parentalLevelState
Definition: videodlg.h:209
VideoDialog::createOkDialog
void createOkDialog(const QString &title)
Create a MythUI "OK" Dialog.
Definition: videodlg.cpp:2051
MythUIButtonTree::GetCurrentNode
MythGenericTree * GetCurrentNode(void) const
Definition: mythuibuttontree.h:32
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3665
VideoDialog::doVideoScan
void doVideoScan()
Definition: videodlg.cpp:3690
PlotDialog
Definition: videopopups.h:25
VideoDialog::ShowExtensionSettings
void ShowExtensionSettings()
Pop up a MythUI Menu for MythVideo filte Type Settings.
Definition: videodlg.cpp:2485
MetadataLookup::GetUserRating
float GetUserRating() const
Definition: metadatacommon.h:302
VideoMetadata::GetEpisode
int GetEpisode() const
Definition: videometadata.cpp:1716
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
ParentalLevelChangeChecker::SigResultReady
void SigResultReady(bool passwordValid, ParentalLevel::Level newLevel)
VideoDialog::Create
bool Create() override
Definition: videodlg.cpp:900
IsDefaultFanart
bool IsDefaultFanart(const QString &fanart)
Definition: videoutils.cpp:145
MetadataFactoryMultiResult
Definition: metadatafactory.h:20
MythUIButtonTree::SetNodeByString
bool SetNodeByString(QStringList route)
Using a path based on the node string, set the currently selected node.
Definition: mythuibuttontree.cpp:281
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:911
MythScreenType::GetScreenStack
MythScreenStack * GetScreenStack() const
Definition: mythscreentype.cpp:217
VideoDialog::CreatePlayMenu
MythMenu * CreatePlayMenu()
Create a "Play Menu" for MythVideo. Appears if multiple play options exist.
Definition: videodlg.cpp:2324
EditMetadataDialog::Finished
void Finished()
MythGenericTree::getAllChildren
QList< MythGenericTree * > * getAllChildren() const
Definition: mythgenerictree.cpp:277
VIDEO_FANART_DEFAULT
const QString VIDEO_FANART_DEFAULT
Definition: globals.cpp:29
VideoDialog::m_watchedState
MythUIStateType * m_watchedState
Definition: videodlg.h:212
videometadatalistmanager.h
MetadataFactory
Definition: metadatafactory.h:85
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
VideoDialog::loadData
virtual void loadData()
load the data used to build the ButtonTree/List for MythVideo.
Definition: videodlg.cpp:1112
VideoListDeathDelayPrivate::VideoListDeathDelayPrivate
VideoListDeathDelayPrivate(const VideoDialog::VideoListPtr &toSave)
Definition: videodlg.cpp:806
VideoDialog::SwitchVideoCategoryGroup
void SwitchVideoCategoryGroup()
Switch to Category browse mode.
Definition: videodlg.cpp:2741
MetadataLookup::GetSeason
uint GetSeason() const
Definition: metadatacommon.h:314
VideoMetadata::GetHash
const QString & GetHash() const
Definition: videometadata.cpp:1826
ParentalLevelToState
QString ParentalLevelToState(const ParentalLevel &level)
Definition: videoutils.cpp:238
IsDefaultCoverFile
bool IsDefaultCoverFile(const QString &coverfile)
Definition: videoutils.cpp:126
VideoDialog::~VideoDialog
~VideoDialog() override
Definition: videodlg.cpp:866
MythUIButtonListItem::SetTextFromMap
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
Definition: mythuibuttonlist.cpp:3285
IsDefaultScreenshot
bool IsDefaultScreenshot(const QString &screenshot)
Definition: videoutils.cpp:135
kUnknownVideo
@ kUnknownVideo
Definition: metadatacommon.h:54
VideoDialog::customEvent
void customEvent(QEvent *levent) override
Definition: videodlg.cpp:3150
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:905
MetadataLookup::GetCategories
QStringList GetCategories() const
Definition: metadatacommon.h:301
VideoListDeathDelayPrivate
Definition: videodlg.cpp:803
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3315
VideoDialog::popupClosed
void popupClosed(const QString &which, int result)
Definition: videodlg.cpp:2389
FileAssociations::getFileAssociation
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:830
VideoDialog::UpdatePosition
void UpdatePosition()
Called after the screen is created by MythScreenStack.
Definition: videodlg.cpp:2175
VideoFilterSettings
Definition: videofilter.h:73
mythuihelper.h
VideoDialog::createBusyDialog
void createBusyDialog(const QString &title)
Create a busy dialog, used during metadata search, etc.
Definition: videodlg.cpp:1967
VideoPlayerCommand::AltPlayerFor
static VideoPlayerCommand AltPlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:362
ItemDetailPopup::OnKeyAction
bool OnKeyAction(const QStringList &actions)
Definition: videodlg.cpp:627
MetadataResultsDialog::haveResult
void haveResult(RefCountHandler< MetadataLookup >)
ItemDetailPopup
Definition: videodlg.cpp:565
VideoDialog::VideoDialog
VideoDialog(MythScreenStack *lparent, const QString &lname, const VideoListPtr &video_list, DialogType type, BrowseType browse)
Definition: videodlg.cpp:847
MetadataLookup::GetRuntime
std::chrono::minutes GetRuntime() const
Definition: metadatacommon.h:352
VideoFilterDialog
Definition: videofilter.h:273
MythMenu
Definition: mythdialogbox.h:99
MetadataFactorySingleResult
Definition: metadatafactory.h:32
VideoDialog::handleDirSelect
void handleDirSelect(MythGenericTree *node)
Descend into a selected folder.
Definition: videodlg.cpp:2631
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:404
MetadataFactorySingleResult::kEventType
static const Type kEventType
Definition: metadatafactory.h:47
MetadataSettings
Definition: videometadatasettings.h:12
VideoMetadata::SetCoverFile
void SetCoverFile(const QString &coverFile)
Definition: videometadata.cpp:1866
MythGenericTree::deleteNode
void deleteNode(MythGenericTree *child)
Definition: mythgenerictree.cpp:140
VideoDialog::DLG_DEFAULT
@ DLG_DEFAULT
Definition: videodlg.h:37
VideoDialogPrivate::rating_to_pl_greater
static bool rating_to_pl_greater(const parental_level_map::value_type &lhs, const parental_level_map::value_type &rhs)
Definition: videodlg.cpp:676
VideoDialog::dtLast
@ dtLast
Definition: videodlg.h:38
VideoDialogPrivate::m_currentNode
MythGenericTree * m_currentNode
Definition: videodlg.cpp:775
VideoDialog::reloadData
void reloadData()
Reloads the tree after having invalidated the data.
Definition: videodlg.cpp:1102
VideoDialogPrivate::m_videoList
VideoListPtr m_videoList
Definition: videodlg.cpp:772
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:272
ItemDetailPopup::ItemDetailPopup
ItemDetailPopup(MythScreenStack *lparent, VideoMetadata *metadata, const VideoMetadataListManager &listManager)
Definition: videodlg.cpp:577
ItemDetailPopup::OnDone
void OnDone()
Definition: videodlg.cpp:619
ScanVideoDirectory
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
Definition: dirscan.cpp:227
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:695
MetadataLookup::GetTagline
QString GetTagline() const
Definition: metadatacommon.h:311
MythUIButtonListItem::SetImage
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
Definition: mythuibuttonlist.cpp:3429
VideoMetadata::cast_list
std::vector< cast_entry > cast_list
Definition: videometadata.h:34
VideoDialog::ShowPlayerSettings
void ShowPlayerSettings()
Pop up a MythUI Menu for MythVideo Player Settings.
Definition: videodlg.cpp:2457
MetadataLookup::GetInetref
QString GetInetref() const
Definition: metadatacommon.h:356
VideoMetadata::GetUserRating
float GetUserRating() const
Definition: videometadata.cpp:1666
VideoDialog::DoItemDetailShow2
void DoItemDetailShow2()
Definition: videodlg.h:130
VideoMetadata::IsHostSet
bool IsHostSet() const
Definition: videometadata.cpp:2009
MythGenericTree::getParent
MythGenericTree * getParent(void) const
Definition: mythgenerictree.cpp:371
ParentalLevel
Definition: parentalcontrols.h:9
VideoDialogPrivate::m_groupType
int m_groupType
Definition: videodlg.cpp:780
VideoDialog::BRS_GENRE
@ BRS_GENRE
Definition: videodlg.h:40
GetVideoDirsByHost
QStringList GetVideoDirsByHost(const QString &host)
Definition: videoutils.cpp:76
VideoMetadata::UpdateDatabase
void UpdateDatabase()
Definition: videometadata.cpp:1956
VideoDialog::BrowseType
BrowseType
Definition: videodlg.h:40
VideoDialogPrivate
Definition: videodlg.cpp:671
VideoDialog::DLG_MANAGER
@ DLG_MANAGER
Definition: videodlg.h:38
VIDEO_RATING_DEFAULT
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
VideoDialog::ChangeFilter
void ChangeFilter()
Change the filtering of the library.
Definition: videodlg.cpp:3114
MetadataLookup::GetStudios
QStringList GetStudios() const
Definition: metadatacommon.h:364
VideoMetadata::GetWatched
bool GetWatched() const
Definition: videometadata.cpp:1766
VideoDialog::OnVideoSearchDone
void OnVideoSearchDone(MetadataLookup *lookup)
Definition: videodlg.cpp:3573
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
ItemDetailPopup::kWindowName
static const char *const kWindowName
Definition: videodlg.cpp:661
MythCoreContext::ClearBackendServerPortCache
static void ClearBackendServerPortCache()
Definition: mythcorecontext.cpp:1070
MythGenericTree
Definition: mythgenerictree.h:27
VideoDialog::ToggleWatched
void ToggleWatched()
Definition: videodlg.cpp:3347
VideoDialog::UpdateText
void UpdateText(MythUIButtonListItem *item)
Update the visible text values for a given ButtonListItem.
Definition: videodlg.cpp:2192
VideoMetadata::GetCoverFile
const QString & GetCoverFile() const
Definition: videometadata.cpp:1861
VideoDialog::GetMetadata
static VideoMetadata * GetMetadata(MythUIButtonListItem *item)
Retrieve the Database Metadata for a given MythUIButtonListItem.
Definition: videodlg.cpp:3131
VideoDialog::OnParentalChange
void OnParentalChange(int amount)
Definition: videodlg.cpp:3392
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1108
VideoListDeathDelayPrivate::GetSaved
VideoDialog::VideoListPtr GetSaved()
Definition: videodlg.cpp:811
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:124
mythcontext.h
MythNotificationCenter::UnRegister
void UnRegister(void *from, int id, bool closeimemdiately=false)
Unregister the client.
Definition: mythnotificationcenter.cpp:1373
VideoDialog::createFetchDialog
void createFetchDialog(VideoMetadata *metadata)
Create a fetch notification, used during metadata search.
Definition: videodlg.cpp:1985
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:86
metadatafactory.h
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:57
VideoDialog::m_coverImage
MythUIImage * m_coverImage
Definition: videodlg.h:203
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:116
VideoDialogPrivate::m_fanDir
QString m_fanDir
Definition: videodlg.cpp:790
VideoDialogPrivate::m_ratingToPl
parental_level_map m_ratingToPl
Definition: videodlg.cpp:798
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1554
build_compdb.action
action
Definition: build_compdb.py:9
MythNotification::SetId
void SetId(int Id)
Contains the application registration id.
Definition: mythnotification.cpp:93
VideoDialog::SavePosition
void SavePosition(void)
Definition: videodlg.cpp:876
VideoDialog::fetchVideos
void fetchVideos()
Build the buttonlist/tree.
Definition: videodlg.cpp:1312
VideoDialogPrivate::m_rootNode
MythGenericTree * m_rootNode
Definition: videodlg.cpp:774
VideoMetadata::GetID
unsigned int GetID() const
Definition: videometadata.cpp:1736
VideoDialog::SwitchGallery
void SwitchGallery()
Switch to Gallery View.
Definition: videodlg.cpp:2696
VideoMetadata::GetTitle
const QString & GetTitle() const
Definition: videometadata.cpp:1546
mythuibutton.h
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
VideoListDeathDelay::kDelayTimeMS
static constexpr std::chrono::milliseconds kDelayTimeMS
Definition: videodlg.h:232
VideoMetadata::SetScreenshot
void SetScreenshot(const QString &screenshot)
Definition: videometadata.cpp:1876
VideoDialog::playVideo
void playVideo()
Play the selected item.
Definition: videodlg.cpp:2935
VideoListDeathDelay::OnTimeUp
void OnTimeUp()
Definition: videodlg.cpp:837
VideoMetadata::SetWatched
void SetWatched(bool watched)
Definition: videometadata.cpp:1771
LOC_MML
#define LOC_MML
Definition: videodlg.cpp:57
VideoDialog::playFolder
void playFolder()
Play all the items in the selected folder.
Definition: videodlg.cpp:2958
VideoMetadata::GetTrailer
const QString & GetTrailer() const
Definition: videometadata.cpp:1851
VideoPlayerCommand::PlayerFor
static VideoPlayerCommand PlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:369
VideoScanner
Definition: videoscan.h:22
VideoDialog::DLG_TREE
@ DLG_TREE
Definition: videodlg.h:38
MetadataLookup::GetReleaseDate
QDate GetReleaseDate() const
Definition: metadatacommon.h:350
VideoFilterDialog::filterChanged
void filterChanged()
VideoDialog::m_screenshot
MythUIImage * m_screenshot
Definition: videodlg.h:204
VideoDialogPrivate::m_artDir
QString m_artDir
Definition: videodlg.cpp:788
DirectoryHandler::newDir
virtual DirectoryHandler * newDir(const QString &dir_name, const QString &fq_dir_name)=0
TrailerToState
QString TrailerToState(const QString &trailerFile)
Definition: videoutils.cpp:262
VIDEO_BANNER_DEFAULT
const QString VIDEO_BANNER_DEFAULT
Definition: globals.cpp:28
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
VideoMetadata::GetRating
const QString & GetRating() const
Definition: videometadata.cpp:1676
ItemDetailPopup::m_playButton
MythUIButton * m_playButton
Definition: videodlg.cpp:665
VideoDialog::SwitchVideoStudioGroup
void SwitchVideoStudioGroup()
Switch to Studio browse mode.
Definition: videodlg.cpp:2768
VideoDialog::ResetMetadata
void ResetMetadata()
Definition: videodlg.cpp:3482
VideoDialog::OnRemoveVideo
void OnRemoveVideo(bool dodelete)
Definition: videodlg.cpp:3447
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:880
VideoDialog::ToggleFlatView
void ToggleFlatView()
Toggle Flat View.
Definition: videodlg.cpp:2616
VideoMetadata::Reset
void Reset()
Resets to default metadata.
Definition: videometadata.cpp:2004
MythMainWindow::AllowInput
void AllowInput(bool Allow)
Definition: mythmainwindow.cpp:1526
MetadataLookup::GetHomepage
QString GetHomepage() const
Definition: metadatacommon.h:367
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:674
VideoDialog::UpdateItem
void UpdateItem(MythUIButtonListItem *item)
Update the visible representation of a MythUIButtonListItem.
Definition: videodlg.cpp:1219
VideoDialogPrivate::VideoDialogPrivate
VideoDialogPrivate(const VideoListPtr &videoList, VideoDialog::DialogType type, VideoDialog::BrowseType browse)
Definition: videodlg.cpp:685
VideoDialog::m_novideoText
MythUIText * m_novideoText
Definition: videodlg.h:198
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
VideoDialogPrivate::m_notifications
QMap< QString, int > m_notifications
Definition: videodlg.cpp:795
VideoDialogPrivate::m_autoMeta
bool m_autoMeta
Definition: videodlg.cpp:786
VideoDialog::DisplayMenu
void DisplayMenu()
Pop up a MythUI Menu for MythVideo Global Functions. Bound to MENU.
Definition: videodlg.cpp:2362
ReferenceCounter::IncrRef
virtual int IncrRef(void)
Increments reference count.
Definition: referencecounter.cpp:101
build_compdb.filename
filename
Definition: build_compdb.py:21
VideoMetadata::GetBanner
const QString & GetBanner() const
Definition: videometadata.cpp:1881
VideoDialog::VideoMenu
void VideoMenu()
Pop up a MythUI "Playback Menu" for MythVideo. Bound to INFO.
Definition: videodlg.cpp:2259
kProbableMovie
@ kProbableMovie
Definition: metadatacommon.h:53
DirectoryHandler
Definition: dirscan.h:6
kDynamicSubFolder
@ kDynamicSubFolder
Definition: videolist.h:10
VideoDialog::ToggleBrowseMode
void ToggleBrowseMode()
Toggle the browseable status for the selected item.
Definition: videodlg.cpp:2604
VideoDialog::m_videoButtonList
MythUIButtonList * m_videoButtonList
Definition: videodlg.h:194
VideoDialogPrivate::m_sshotDir
QString m_sshotDir
Definition: videodlg.cpp:789
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
MythGenericTree::becomeSelectedChild
void becomeSelectedChild(void)
Definition: mythgenerictree.cpp:325
ParentalLevel::GetLevel
Level GetLevel() const
Definition: parentalcontrols.cpp:128
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
VideoDialog::ViewPlot
void ViewPlot()
Display a MythUI Popup with the selected item's plot.
Definition: videodlg.cpp:2843
VideoDialog::GetCoverImage
static QString GetCoverImage(MythGenericTree *node)
A "hunt" for cover art to apply for a folder item.
Definition: videodlg.cpp:1407
MythRandomStd::MythRandom
uint32_t MythRandom()
generate 32 random bits
Definition: mythrandom.h:20
VideoMetadata::GetCast
const cast_list & GetCast() const
Definition: videometadata.cpp:1921
VideoDialogPrivate::m_lastTreeNodePath
QString m_lastTreeNodePath
Definition: videodlg.cpp:794
VideoMetadata::GetStudio
const QString & GetStudio() const
Definition: videometadata.cpp:1646
videoutils.h
kNoFilesFound
@ kNoFilesFound
Definition: videolist.h:9
MetadataLookup::SetStep
void SetStep(LookupStep step)
Definition: metadatacommon.h:244
videodlg.h
DirectoryHandler::handleFile
virtual void handleFile(const QString &file_name, const QString &fq_file_name, const QString &extension, const QString &host)=0
VideoDialog::keyPressEvent
bool keyPressEvent(QKeyEvent *levent) override
Handle keypresses and keybindings.
Definition: videodlg.cpp:1872
MythUIButtonTree::nodeChanged
void nodeChanged(MythGenericTree *node)
VideoDialog::DoItemDetailShow
bool DoItemDetailShow()
Display the Item Detail Popup.
Definition: videodlg.cpp:2857
simple_ref_ptr::get
T * get() const
Definition: quicksp.h:73
VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
videoplayercommand.h
videoplayersettings.h
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:897
sLocation
static const QString sLocation
Definition: videodlg.cpp:59
VideoDialogPrivate::m_switchingLayout
bool m_switchingLayout
Definition: videodlg.cpp:764
MythUIButtonListItem::NotChecked
@ NotChecked
Definition: mythuibuttonlist.h:46
ClearMap
void ClearMap(InfoMap &metadataMap)
Definition: videometadata.cpp:1462
MythNotificationCenter::Queue
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Definition: mythnotificationcenter.cpp:1349
VideoMetadataListManager::byID
VideoMetadataPtr byID(unsigned int db_id) const
Definition: videometadatalistmanager.cpp:180
RemoteGetFileList
bool RemoteGetFileList(const QString &host, const QString &path, QStringList *list, QString sgroup, bool fileNamesOnly)
Definition: remoteutil.cpp:429
VIDEO_DIRECTOR_UNKNOWN
const QString VIDEO_DIRECTOR_UNKNOWN
Definition: globals.cpp:9
PlayerSettings
Definition: videoplayersettings.h:11