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(const QString &name, const QString &filename) override // CopyMetadataDestination
437  {
438  (void) name;
439  (void) filename;
440  }
441 
442  private:
443  MythUIButtonListItem *m_item {nullptr};
444  };
445 
446  void CopyMetadataToUI(const VideoMetadata *metadata,
447  CopyMetadataDestination &dest)
448  {
449  using valuelist = std::map<QString, QString>;
450  valuelist tmp;
451 
452  if (metadata)
453  {
454  QString coverfile;
455  if ((metadata->IsHostSet()
456  && !metadata->GetCoverFile().startsWith("/"))
457  && !metadata->GetCoverFile().isEmpty()
458  && !IsDefaultCoverFile(metadata->GetCoverFile()))
459  {
460  coverfile = generate_file_url("Coverart", metadata->GetHost(),
461  metadata->GetCoverFile());
462  }
463  else
464  {
465  coverfile = metadata->GetCoverFile();
466  }
467 
468  if (!IsDefaultCoverFile(coverfile))
469  tmp["coverart"] = coverfile;
470 
471  tmp["coverfile"] = coverfile;
472 
473  QString screenshotfile;
474  if (metadata->IsHostSet() && !metadata->GetScreenshot().startsWith("/")
475  && !metadata->GetScreenshot().isEmpty())
476  {
477  screenshotfile = generate_file_url("Screenshots",
478  metadata->GetHost(), metadata->GetScreenshot());
479  }
480  else
481  {
482  screenshotfile = metadata->GetScreenshot();
483  }
484 
485  if (!IsDefaultScreenshot(screenshotfile))
486  tmp["screenshot"] = screenshotfile;
487 
488  tmp["screenshotfile"] = screenshotfile;
489 
490  QString bannerfile;
491  if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/")
492  && !metadata->GetBanner().isEmpty())
493  {
494  bannerfile = generate_file_url("Banners", metadata->GetHost(),
495  metadata->GetBanner());
496  }
497  else
498  {
499  bannerfile = metadata->GetBanner();
500  }
501 
502  if (!IsDefaultBanner(bannerfile))
503  tmp["banner"] = bannerfile;
504 
505  tmp["bannerfile"] = bannerfile;
506 
507  QString fanartfile;
508  if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/")
509  && !metadata->GetFanart().isEmpty())
510  {
511  fanartfile = generate_file_url("Fanart", metadata->GetHost(),
512  metadata->GetFanart());
513  }
514  else
515  {
516  fanartfile = metadata->GetFanart();
517  }
518 
519  if (!IsDefaultFanart(fanartfile))
520  tmp["fanart"] = fanartfile;
521 
522  tmp["fanartfile"] = fanartfile;
523 
524  tmp["trailerstate"] = TrailerToState(metadata->GetTrailer());
525  tmp["studiostate"] = metadata->GetStudio();
526  tmp["userratingstate"] =
527  QString::number((int)(metadata->GetUserRating()));
528  tmp["watchedstate"] = WatchedToState(metadata->GetWatched());
529 
530  tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel());
531  }
532 
533  struct helper
534  {
535  helper(valuelist &values, CopyMetadataDestination &d) :
536  m_vallist(values), m_dest(d) {}
537 
538  void handleImage(const QString &name)
539  {
540  m_dest.handleImage(name, m_vallist[name]);
541  }
542 
543  void handleState(const QString &name)
544  {
545  m_dest.handleState(name, m_vallist[name]);
546  }
547  private:
548  valuelist &m_vallist;
549  CopyMetadataDestination &m_dest;
550  };
551 
552  helper h(tmp, dest);
553 
554  h.handleImage("coverart");
555  h.handleImage("screenshot");
556  h.handleImage("banner");
557  h.handleImage("fanart");
558 
559  h.handleState("trailerstate");
560  h.handleState("userratingstate");
561  h.handleState("watchedstate");
562  h.handleState("videolevel");
563  }
564 }
565 
567 {
568  Q_OBJECT
569 
570  public:
571  static bool Exists()
572  {
573  // TODO: Add ability to theme loader to do this a better way.
574  return LoadWindowFromXML("video-ui.xml", kWindowName, nullptr);
575  }
576 
577  public:
579  const VideoMetadataListManager &listManager) :
580  MythScreenType(lparent, kWindowName), m_metadata(metadata),
581  m_listManager(listManager)
582  {
583  }
584 
585  bool Create() override // MythScreenType
586  {
587  if (!LoadWindowFromXML("video-ui.xml", kWindowName, this))
588  return false;
589 
590  UIUtilW::Assign(this, m_playButton, "play_button");
591  UIUtilW::Assign(this, m_doneButton, "done_button");
592 
593  if (m_playButton)
595 
596  if (m_doneButton)
598 
599  BuildFocusList();
600 
601  if (m_playButton || m_doneButton)
603 
604  InfoMap metadataMap;
605  m_metadata->toMap(metadataMap);
606  SetTextFromMap(metadataMap);
607 
608  ScreenCopyDest dest(this);
609  CopyMetadataToUI(m_metadata, dest);
610 
611  return true;
612  }
613 
614  private slots:
615  void OnPlay()
616  {
617  PlayVideo(m_metadata->GetFilename(), m_listManager);
618  }
619 
620  void OnDone()
621  {
622  // TODO: Close() can do horrible things, this will pop
623  // our screen, delete us, and return here.
624  Close();
625  }
626 
627  private:
628  bool OnKeyAction(const QStringList &actions)
629  {
630  bool handled = false;
631  for (const auto & action : qAsConst(actions))
632  {
633  handled = true;
634  if (action == "SELECT" || action == "PLAYBACK")
635  OnPlay();
636  else
637  handled = false;
638  }
639 
640  return handled;
641  }
642 
643  protected:
644  bool keyPressEvent(QKeyEvent *levent) override // MythScreenType
645  {
646  if (MythScreenType::keyPressEvent(levent))
647  return true;
648 
649  QStringList actions;
650  bool handled = GetMythMainWindow()->TranslateKeyPress("Video",
651  levent, actions);
652  if (!handled && !OnKeyAction(actions))
653  {
654  handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend",
655  levent, actions);
656  OnKeyAction(actions);
657  }
658  return handled;
659  }
660 
661  private:
662  static const char * const kWindowName;
665 
668 };
669 
670 const char * const ItemDetailPopup::kWindowName = "itemdetailpopup";
671 
673 {
674  private:
675  using parental_level_map = std::list<std::pair<QString, ParentalLevel::Level> >;
676 
677  static bool rating_to_pl_greater(const parental_level_map::value_type &lhs,
678  const parental_level_map::value_type &rhs)
679  {
680  return lhs.first.length() >= rhs.first.length();
681  };
682 
684 
685  public:
687  VideoDialog::BrowseType browse) :
688  m_videoList(videoList), m_type(type), m_browse(browse)
689  {
690  if (gCoreContext->GetBoolSetting("mythvideo.ParentalLevelFromRating", false))
691  {
693  sl.GetLevel() <= ParentalLevel::plHigh && sl.good(); ++sl)
694  {
695  QString ratingstring =
696  gCoreContext->GetSetting(QString("mythvideo.AutoR2PL%1")
697  .arg(sl.GetLevel()));
698 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
699  QStringList ratings =
700  ratingstring.split(':', QString::SkipEmptyParts);
701 #else
702  QStringList ratings =
703  ratingstring.split(':', Qt::SkipEmptyParts);
704 #endif
705  auto to_pl = [sl](const auto & rating)
706  { return parental_level_map::value_type(rating, sl.GetLevel()); };
707  std::transform(ratings.cbegin(), ratings.cend(),
708  std::back_inserter(m_ratingToPl), to_pl);
709  }
711  }
712 
714  gCoreContext->GetBoolSetting("mythvideo.VideoTreeRemember", false);
715 
716  m_isFileBrowser = gCoreContext->GetBoolSetting("VideoDialogNoDB", false);
717  m_groupType = gCoreContext->GetNumSetting("mythvideo.db_group_type", 0);
718 
720  gCoreContext->GetBoolSetting("mythvideo.EnableAlternatePlayer");
721 
722  m_autoMeta = gCoreContext->GetBoolSetting("mythvideo.AutoMetaDataScan", true);
723 
724  m_artDir = gCoreContext->GetSetting("VideoArtworkDir");
725  m_sshotDir = gCoreContext->GetSetting("mythvideo.screenshotDir");
726  m_fanDir = gCoreContext->GetSetting("mythvideo.fanartDir");
727  m_banDir = gCoreContext->GetSetting("mythvideo.bannerDir");
728  }
729 
731  {
732  delete m_scanner;
733 
734  if (m_rememberPosition && !m_lastTreeNodePath.isEmpty())
735  {
736  gCoreContext->SaveSetting("mythvideo.VideoTreeLastActive",
738  }
739  }
740 
742  {
743  if (metadata && !m_ratingToPl.empty())
744  {
745  QString rating = metadata->GetRating();
746  for (auto p = m_ratingToPl.begin();
747  !rating.isEmpty() && p != m_ratingToPl.end(); ++p)
748  {
749  if (rating.indexOf(p->first) != -1)
750  {
751  metadata->SetShowLevel(p->second);
752  break;
753  }
754  }
755  }
756  }
757 
758  static void DelayVideoListDestruction(const VideoListPtr& videoList)
759  {
760  m_savedPtr = new VideoListDeathDelay(videoList);
761  }
762 
763  public:
764  ParentalLevelNotifyContainer m_parentalLevel;
765  bool m_switchingLayout {false};
766 
768 
769  bool m_firstLoadPass {true};
770 
771  bool m_rememberPosition {false};
772 
774 
777 
778  bool m_treeLoaded {false};
779 
780  bool m_isFileBrowser {false};
781  int m_groupType {0};
782  bool m_isFlatList {false};
783  bool m_altPlayerEnabled {false};
786 
787  bool m_autoMeta {true};
788 
789  QString m_artDir;
790  QString m_sshotDir;
791  QString m_fanDir;
792  QString m_banDir;
794 
796  QMap<QString, int> m_notifications;
797 
798  private:
800 };
801 
803 
805 {
806  public:
808  m_savedList(toSave)
809  {
810  }
811 
813  {
814  return m_savedList;
815  }
816 
817  private:
819 };
820 
822  QObject(QCoreApplication::instance())
823 {
824  m_d = new VideoListDeathDelayPrivate(toSave);
825  QTimer::singleShot(kDelayTimeMS, this, &VideoListDeathDelay::OnTimeUp);
826 }
827 
829 {
830  delete m_d;
831 }
832 
834 {
835  return m_d->GetSaved();
836 }
837 
839 {
840  deleteLater();
841 }
842 
844 {
846 }
847 
848 VideoDialog::VideoDialog(MythScreenStack *lparent, const QString& lname,
849  const VideoListPtr& video_list, DialogType type, BrowseType browse)
850  : MythScreenType(lparent, lname),
851  m_popupStack(GetMythMainWindow()->GetStack("popup stack")),
852  m_mainStack(GetMythMainWindow()->GetMainStack()),
853  m_metadataFactory(new MetadataFactory(this)),
854  m_d(new VideoDialogPrivate(video_list, type, browse))
855 {
856  m_d->m_videoList->setCurrentVideoFilter(VideoFilterSettings(true,
857  lname));
858 
860  GetNumSetting("VideoDefaultParentalLevel",
862 
865 }
866 
868 {
869  if (!m_d->m_switchingLayout)
871 
872  SavePosition();
873 
874  delete m_d;
875 }
876 
878 {
879  m_d->m_lastTreeNodePath = "";
880 
881  if (m_d->m_type == DLG_TREE)
882  {
884  if (node)
885  m_d->m_lastTreeNodePath = node->getRouteByString().join("\n");
886  }
887  else if (m_d->m_type == DLG_BROWSER || m_d->m_type == DLG_GALLERY)
888  {
890  if (item)
891  {
892  MythGenericTree *node = GetNodePtrFromButton(item);
893  if (node)
894  m_d->m_lastTreeNodePath = node->getRouteByString().join("\n");
895  }
896  }
897 
898  gCoreContext->SaveSetting("mythvideo.VideoTreeLastActive", m_d->m_lastTreeNodePath);
899 }
900 
902 {
903  if (m_d->m_type == DLG_DEFAULT)
904  {
905  m_d->m_type = static_cast<DialogType>(
906  gCoreContext->GetNumSetting("Default MythVideo View", DLG_GALLERY));
907  m_d->m_browse = static_cast<BrowseType>(
908  gCoreContext->GetNumSetting("mythvideo.db_group_type", BRS_FOLDER));
909  }
910 
911  if (!IsValidDialogType(m_d->m_type))
912  {
914  }
915 
916  QString windowName = "videogallery";
917  bool flatlistDefault = false;
918 
919  switch (m_d->m_type)
920  {
921  case DLG_BROWSER:
922  windowName = "browser";
923  flatlistDefault = true;
924  break;
925  case DLG_GALLERY:
926  windowName = "gallery";
927  break;
928  case DLG_TREE:
929  windowName = "tree";
930  break;
931  case DLG_MANAGER:
932  m_d->m_isFlatList =
933  gCoreContext->GetBoolSetting("mythvideo.db_folder_view", true);
934  windowName = "manager";
935  flatlistDefault = true;
936  break;
937  case DLG_DEFAULT:
938  default:
939  break;
940  }
941 
942  switch (m_d->m_browse)
943  {
944  case BRS_GENRE:
946  break;
947  case BRS_CATEGORY:
949  break;
950  case BRS_YEAR:
952  break;
953  case BRS_DIRECTOR:
955  break;
956  case BRS_STUDIO:
958  break;
959  case BRS_CAST:
961  break;
962  case BRS_USERRATING:
964  break;
965  case BRS_INSERTDATE:
967  break;
968  case BRS_TVMOVIE:
970  break;
971  case BRS_FOLDER:
972  default:
974  break;
975  }
976 
977  m_d->m_isFlatList =
978  gCoreContext->GetBoolSetting(QString("mythvideo.folder_view_%1")
979  .arg(m_d->m_type), flatlistDefault);
980 
981  if (!LoadWindowFromXML("video-ui.xml", windowName, this))
982  return false;
983 
984  bool err = false;
985  if (m_d->m_type == DLG_TREE)
986  UIUtilE::Assign(this, m_videoButtonTree, "videos", &err);
987  else
988  UIUtilE::Assign(this, m_videoButtonList, "videos", &err);
989 
990  UIUtilW::Assign(this, m_titleText, "title");
991  UIUtilW::Assign(this, m_novideoText, "novideos");
992  UIUtilW::Assign(this, m_positionText, "position");
993  UIUtilW::Assign(this, m_crumbText, "breadcrumbs");
994 
995  UIUtilW::Assign(this, m_coverImage, "coverart");
996  UIUtilW::Assign(this, m_screenshot, "screenshot");
997  UIUtilW::Assign(this, m_banner, "banner");
998  UIUtilW::Assign(this, m_fanart, "fanart");
999 
1000  UIUtilW::Assign(this, m_trailerState, "trailerstate");
1001  UIUtilW::Assign(this, m_parentalLevelState, "parentallevel");
1002  UIUtilW::Assign(this, m_watchedState, "watchedstate");
1003  UIUtilW::Assign(this, m_studioState, "studiostate");
1004 
1005  if (err)
1006  {
1007  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen '" + windowName + "'");
1008  return false;
1009  }
1010 
1011  CheckedSet(m_trailerState, "None");
1013  CheckedSet(m_watchedState, "None");
1014  CheckedSet(m_studioState, "None");
1015 
1016  BuildFocusList();
1017 
1018  if (m_d->m_type == DLG_TREE)
1019  {
1021 
1023  this, &VideoDialog::handleSelect);
1025  this, &VideoDialog::UpdateText);
1028  }
1029  else
1030  {
1032 
1034  this, &VideoDialog::handleSelect);
1036  this, &VideoDialog::UpdateText);
1037  }
1038 
1039  return true;
1040 }
1041 
1043 {
1044  connect(&m_d->m_parentalLevel, &ParentalLevelNotifyContainer::SigLevelChanged,
1045  this, &VideoDialog::reloadData);
1046 }
1047 
1049 {
1050  reloadData();
1051  // We only want to prompt once, on startup, hence this is done in Load()
1052  if (m_d->m_rootNode->childCount() == 1 &&
1054  PromptToScan();
1055 }
1056 
1062 {
1063  fetchVideos();
1064  loadData();
1065 
1068 
1069  bool noFiles = (m_d->m_rootNode->childCount() == 1 &&
1071 
1072  if (m_novideoText)
1073  m_novideoText->SetVisible(noFiles);
1074 }
1075 
1076 void VideoDialog::scanFinished(bool dbChanged)
1077 {
1078  delete m_d->m_scanner;
1079  m_d->m_scanner = nullptr;
1080 
1081  if (dbChanged)
1082  m_d->m_videoList->InvalidateCache();
1083 
1084  m_d->m_currentNode = nullptr;
1085  reloadData();
1086 
1087  if (m_d->m_autoMeta)
1088  VideoAutoSearch();
1089 
1090  if (m_d->m_rootNode->childCount() == 1 &&
1092  {
1093  QString message = tr("The video scan found no files, have you "
1094  "configured a video storage group?");
1095  ShowOkPopup(message);
1096  }
1097 }
1098 
1104 {
1105  m_d->m_treeLoaded = false;
1106  refreshData();
1107 }
1108 
1114 {
1115  if (m_d->m_type == DLG_TREE)
1116  {
1118 
1119  if (m_d->m_firstLoadPass)
1120  {
1121  m_d->m_firstLoadPass = false;
1122 
1123  if (m_d->m_rememberPosition)
1124  {
1125  QStringList route =
1126  gCoreContext->GetSetting("mythvideo.VideoTreeLastActive",
1127  "").split("\n");
1129  }
1130  }
1131  }
1132  else
1133  {
1135 
1136  if (!m_d->m_treeLoaded)
1137  return;
1138 
1139  if (!m_d->m_currentNode)
1140  {
1142  return;
1143  }
1144 
1145  MythGenericTree *selectedNode = m_d->m_currentNode->getSelectedChild();
1146 
1147  // restore the last saved position in the video tree if this is the first
1148  // time this method is called and the option is set in the database
1149  if (m_d->m_firstLoadPass)
1150  {
1151  if (m_d->m_rememberPosition)
1152  {
1153  QStringList lastTreeNodePath = gCoreContext->GetSetting("mythvideo.VideoTreeLastActive", "").split("\n");
1154 
1155  if (m_d->m_type == DLG_GALLERY || m_d->m_type == DLG_BROWSER)
1156  {
1157  if (!lastTreeNodePath.isEmpty())
1158  {
1159  // go through the path list and set the current node
1160  for (int i = 0; i < lastTreeNodePath.size(); i++)
1161  {
1162  MythGenericTree *node =
1163  m_d->m_currentNode->getChildByName(lastTreeNodePath.at(i));
1164  if (node != nullptr)
1165  {
1166  // check if the node name is the same as the currently selected
1167  // one in the saved tree list. if yes then we are on the right
1168  // way down the video tree to find the last saved position
1169  if (node->GetText().compare(lastTreeNodePath.at(i)) == 0)
1170  {
1171  // set the folder as the new node so we can travel further down
1172  // dont do this if its the last part of the saved video path tree
1173  if (node->getInt() == kSubFolder &&
1174  node->childCount() > 1 &&
1175  i < lastTreeNodePath.size()-1)
1176  {
1177  SetCurrentNode(node);
1178  }
1179  // in the last run the selectedNode will be the last
1180  // entry of the saved tree node.
1181  if (lastTreeNodePath.at(i) == lastTreeNodePath.last())
1182  selectedNode = node;
1183  }
1184  }
1185  }
1186  m_d->m_firstLoadPass = false;
1187  }
1188  }
1189  }
1190  }
1191 
1192  using MGTreeChildList = QList<MythGenericTree *>;
1193  MGTreeChildList *lchildren = m_d->m_currentNode->getAllChildren();
1194 
1195  for (auto * child : qAsConst(*lchildren))
1196  {
1197  if (child != nullptr)
1198  {
1199  auto *item =
1200  new MythUIButtonListItem(m_videoButtonList, QString(), nullptr,
1202 
1203  item->SetData(QVariant::fromValue(child));
1204 
1205  UpdateItem(item);
1206 
1207  if (child == selectedNode)
1209  }
1210  }
1211  }
1212 
1213  UpdatePosition();
1214 }
1215 
1221 {
1222  if (!item)
1223  return;
1224 
1225  MythGenericTree *node = GetNodePtrFromButton(item);
1226 
1227  VideoMetadata *metadata = GetMetadata(item);
1228 
1229  if (metadata)
1230  {
1231  InfoMap metadataMap;
1232  metadata->toMap(metadataMap);
1233  item->SetTextFromMap(metadataMap);
1234  }
1235 
1236  MythUIButtonListItemCopyDest dest(item);
1237  CopyMetadataToUI(metadata, dest);
1238 
1239  MythGenericTree *parent = node->getParent();
1240 
1241  if (parent && metadata && ((QString::compare(parent->GetText(),
1242  metadata->GetTitle(), Qt::CaseInsensitive) == 0) ||
1243  parent->GetText().startsWith(tr("Season"), Qt::CaseInsensitive)))
1244  item->SetText(metadata->GetSubtitle());
1245  else if (metadata && !metadata->GetSubtitle().isEmpty())
1246  item->SetText(QString("%1: %2").arg(metadata->GetTitle(), metadata->GetSubtitle()));
1247  else
1248  item->SetText(metadata ? metadata->GetTitle() : node->GetText());
1249 
1250  QString coverimage = GetCoverImage(node);
1251  QString screenshot = GetScreenshot(node);
1252  QString banner = GetBanner(node);
1253  QString fanart = GetFanart(node);
1254 
1255  if (!screenshot.isEmpty() && parent && metadata &&
1256  ((QString::compare(parent->GetText(),
1257  metadata->GetTitle(), Qt::CaseInsensitive) == 0) ||
1258  parent->GetText().startsWith(tr("Season"), Qt::CaseInsensitive)))
1259  {
1260  item->SetImage(screenshot);
1261  }
1262  else
1263  {
1264  if (coverimage.isEmpty())
1265  coverimage = GetFirstImage(node, "Coverart");
1266  item->SetImage(coverimage);
1267  }
1268 
1269  int nodeInt = node->getInt();
1270 
1271  if (coverimage.isEmpty() && nodeInt == kSubFolder)
1272  coverimage = GetFirstImage(node, "Coverart");
1273 
1274  item->SetImage(coverimage, "coverart");
1275 
1276  if (screenshot.isEmpty() && nodeInt == kSubFolder)
1277  screenshot = GetFirstImage(node, "Screenshots");
1278 
1279  item->SetImage(screenshot, "screenshot");
1280 
1281  if (banner.isEmpty() && nodeInt == kSubFolder)
1282  banner = GetFirstImage(node, "Banners");
1283 
1284  item->SetImage(banner, "banner");
1285 
1286  if (fanart.isEmpty() && nodeInt == kSubFolder)
1287  fanart = GetFirstImage(node, "Fanart");
1288 
1289  item->SetImage(fanart, "fanart");
1290 
1291  if (nodeInt == kSubFolder)
1292  {
1293  item->SetText(QString("%1").arg(node->visibleChildCount()), "childcount");
1294  item->DisplayState("subfolder", "nodetype");
1295  item->SetText(node->GetText(), "title");
1296  item->SetText(node->GetText());
1297  }
1298  else if (nodeInt == kUpFolder)
1299  {
1300  item->DisplayState("upfolder", "nodetype");
1301  item->SetText(node->GetText(), "title");
1302  item->SetText(node->GetText());
1303  }
1304 
1305  if (item == GetItemCurrent())
1306  UpdateText(item);
1307 }
1308 
1314 {
1315  MythGenericTree *oldroot = m_d->m_rootNode;
1316  if (!m_d->m_treeLoaded)
1317  {
1318  m_d->m_rootNode = m_d->m_videoList->buildVideoList(m_d->m_isFileBrowser,
1320  m_d->m_parentalLevel.GetLevel(), true);
1321  }
1322  else
1323  {
1324  m_d->m_videoList->refreshList(m_d->m_isFileBrowser,
1325  m_d->m_parentalLevel.GetLevel(),
1327  m_d->m_rootNode = m_d->m_videoList->GetTreeRoot();
1328  }
1329 
1330  m_d->m_treeLoaded = true;
1331 
1332  // Move a node down if there is a single directory item here...
1333  if (m_d->m_rootNode->childCount() == 1)
1334  {
1336  if (node->getInt() == kSubFolder && node->childCount() > 1)
1337  m_d->m_rootNode = node;
1338  else if (node->getInt() == kUpFolder)
1339  m_d->m_treeLoaded = false;
1340  }
1341  else if (m_d->m_rootNode->childCount() == 0)
1342  m_d->m_treeLoaded = false;
1343 
1344  if (!m_d->m_currentNode || m_d->m_rootNode != oldroot)
1346 }
1347 
1352 QString VideoDialog::RemoteImageCheck(const QString& host, const QString& filename)
1353 {
1354  QString result = "";
1355 #if 0
1356  LOG(VB_GENERAL, LOG_DEBUG, QString("RemoteImageCheck(%1)").arg(filename));
1357 #endif
1358 
1359  QStringList dirs = GetVideoDirsByHost(host);
1360 
1361  if (!dirs.isEmpty())
1362  {
1363  for (const auto & dir : qAsConst(dirs))
1364  {
1365  QUrl sgurl = dir;
1366  QString path = sgurl.path();
1367 
1368  QString fname = QString("%1/%2").arg(path, filename);
1369 
1370  QStringList list( QString("QUERY_SG_FILEQUERY") );
1371  list << host;
1372  list << "Videos";
1373  list << fname;
1374 
1375  bool ok = gCoreContext->SendReceiveStringList(list);
1376 
1377  if (!ok || list.at(0).startsWith("SLAVE UNREACHABLE"))
1378  {
1379  LOG(VB_GENERAL, LOG_WARNING,
1380  QString("Backend : %1 currently Unreachable. Skipping "
1381  "this one.") .arg(host));
1382  break;
1383  }
1384 
1385  if ((!list.isEmpty()) && (list.at(0) == fname))
1386  result = generate_file_url("Videos", host, filename);
1387 
1388  if (!result.isEmpty())
1389  {
1390 #if 0
1391  LOG(VB_GENERAL, LOG_DEBUG,
1392  QString("RemoteImageCheck(%1) res :%2: :%3:")
1393  .arg(fname).arg(result).arg(dir));
1394 #endif
1395  break;
1396  }
1397 
1398  }
1399  }
1400 
1401  return result;
1402 }
1403 
1409 {
1410  if (!node)
1411  return {};
1412 
1413  int nodeInt = node->getInt();
1414 
1415  QString icon_file;
1416 
1417  if (nodeInt == kSubFolder) // subdirectory
1418  {
1419  // First validate that the data can be converted
1420  if (!node->GetData().canConvert<TreeNodeData>())
1421  return icon_file;
1422 
1423  // load folder icon
1424  QString folder_path = node->GetData().value<TreeNodeData>().GetPath();
1425  QString host = node->GetData().value<TreeNodeData>().GetHost();
1426  QString prefix = node->GetData().value<TreeNodeData>().GetPrefix();
1427 
1428  if (folder_path.startsWith("myth://"))
1429  folder_path = folder_path.right(folder_path.length()
1430  - folder_path.lastIndexOf("//") - 1);
1431 
1432  QString filename = QString("%1/folder").arg(folder_path);
1433 
1434 #if 0
1435  LOG(VB_GENERAL, LOG_DEBUG,
1436  QString("GetCoverImage host : %1 prefix : %2 file : %3")
1437  .arg(host).arg(prefix).arg(filename));
1438 #endif
1439 
1440  QStringList test_files;
1441  test_files.append(filename + ".png");
1442  test_files.append(filename + ".jpg");
1443  test_files.append(filename + ".jpeg");
1444  test_files.append(filename + ".gif");
1445 
1446  // coverity[auto_causes_copy]
1447  for (auto imagePath : qAsConst(test_files))
1448  {
1449 #if 0
1450  LOG(VB_GENERAL, LOG_DEBUG, QString("Cover check :%1 : ").arg(imagePath));
1451 #endif
1452 
1453  bool foundCover = false;
1454  if (!host.isEmpty())
1455  {
1456  // Strip out any extra /'s
1457  imagePath.replace("//", "/");
1458  prefix.replace("//","/");
1459  imagePath = imagePath.right(imagePath.length() - (prefix.length() + 1));
1460  QString tmpCover = RemoteImageCheck(host, imagePath);
1461 
1462  if (!tmpCover.isEmpty())
1463  {
1464  foundCover = true;
1465  imagePath = tmpCover;
1466  }
1467  }
1468  else
1469  foundCover = QFile::exists(imagePath);
1470 
1471  if (foundCover)
1472  {
1473  icon_file = imagePath;
1474  break;
1475  }
1476  }
1477 
1478  // If we found nothing, load the first image we find
1479  if (icon_file.isEmpty())
1480  {
1481  QStringList imageTypes { "*.png", "*.jpg", "*.jpeg", "*.gif" };
1482  QStringList fList;
1483 
1484  if (!host.isEmpty())
1485  {
1486  // TODO: This can likely get a little cleaner
1487 
1488  QStringList dirs = GetVideoDirsByHost(host);
1489 
1490  if (!dirs.isEmpty())
1491  {
1492  for (const auto & dir : qAsConst(dirs))
1493  {
1494  QUrl sgurl = dir;
1495  QString path = sgurl.path();
1496 
1497  QString subdir = folder_path.right(folder_path.length() - (prefix.length() + 1));
1498 
1499  path = path + "/" + subdir;
1500 
1501  QStringList tmpList;
1502  bool ok = RemoteGetFileList(host, path, &tmpList, "Videos");
1503 
1504  if (ok)
1505  {
1506  for (const auto & pattern : qAsConst(imageTypes))
1507  {
1508  auto rePattern = QRegularExpression::wildcardToRegularExpression(pattern);
1509  QRegularExpression rx {
1510  rePattern.mid(2,rePattern.size()-4), // Remove anchors
1511  QRegularExpression::CaseInsensitiveOption };
1512  QStringList matches = tmpList.filter(rx);
1513  if (!matches.isEmpty())
1514  {
1515  fList.clear();
1516  fList.append(subdir + "/" + matches.at(0).split("::").at(1));
1517  break;
1518  }
1519  }
1520 
1521  break;
1522  }
1523  }
1524  }
1525 
1526  }
1527  else
1528  {
1529  QDir vidDir(folder_path);
1530  vidDir.setNameFilters(imageTypes);
1531  fList = vidDir.entryList();
1532  }
1533 
1534  // Take the Coverfile for the first valid node in the dir, if it exists.
1535  if (icon_file.isEmpty())
1536  {
1537  int list_count = node->visibleChildCount();
1538  if (list_count > 0)
1539  {
1540  for (int i = 0; i < list_count; i++)
1541  {
1542  MythGenericTree *subnode = node->getVisibleChildAt(i);
1543  if (subnode)
1544  {
1545  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1546  if (metadata)
1547  {
1548  if (!metadata->GetHost().isEmpty() &&
1549  !metadata->GetCoverFile().startsWith("/"))
1550  {
1551  QString test_file = generate_file_url("Coverart",
1552  metadata->GetHost(), metadata->GetCoverFile());
1553  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1554  !IsDefaultCoverFile(test_file))
1555  {
1556  icon_file = test_file;
1557  break;
1558  }
1559  }
1560  else
1561  {
1562  const QString& test_file = metadata->GetCoverFile();
1563  if (!test_file.isEmpty() &&
1564  !IsDefaultCoverFile(test_file))
1565  {
1566  icon_file = test_file;
1567  break;
1568  }
1569  }
1570  }
1571  }
1572  }
1573  }
1574  }
1575 
1576  if (!fList.isEmpty())
1577  {
1578  if (host.isEmpty())
1579  {
1580  icon_file = QString("%1/%2").arg(folder_path, fList.at(0));
1581  }
1582  else
1583  {
1584  icon_file = generate_file_url("Videos", host, fList.at(0));
1585  }
1586  }
1587  }
1588 
1589  if (!icon_file.isEmpty())
1590  {
1591  LOG(VB_GENERAL, LOG_DEBUG, QString("Found Image : %1 :")
1592  .arg(icon_file));
1593  }
1594  else
1595  {
1596  LOG(VB_GENERAL, LOG_DEBUG,
1597  QString("Could not find folder cover Image : %1 ")
1598  .arg(folder_path));
1599  }
1600  }
1601  else
1602  {
1603  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1604 
1605  if (metadata)
1606  {
1607  if (metadata->IsHostSet() &&
1608  !metadata->GetCoverFile().startsWith("/") &&
1609  !IsDefaultCoverFile(metadata->GetCoverFile()))
1610  {
1611  icon_file = generate_file_url("Coverart", metadata->GetHost(),
1612  metadata->GetCoverFile());
1613  }
1614  else
1615  {
1616  icon_file = metadata->GetCoverFile();
1617  }
1618  }
1619  }
1620 
1621  if (IsDefaultCoverFile(icon_file))
1622  icon_file.clear();
1623 
1624  return icon_file;
1625 }
1626 
1638 QString VideoDialog::GetFirstImage(MythGenericTree *node, const QString& type,
1639  const QString& gpnode, int levels)
1640 {
1641  if (!node || type.isEmpty())
1642  return {};
1643 
1644  QString icon_file;
1645 
1646  int list_count = node->visibleChildCount();
1647  if (list_count > 0)
1648  {
1649  QList<MythGenericTree *> subDirs;
1650  static constexpr int maxRecurse { 1 };
1651 
1652  for (int i = 0; i < list_count; i++)
1653  {
1654  MythGenericTree *subnode = node->getVisibleChildAt(i);
1655  if (subnode)
1656  {
1657  if (subnode->childCount() > 0)
1658  subDirs << subnode;
1659 
1660  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1661  if (metadata)
1662  {
1663  QString test_file;
1664  const QString& host = metadata->GetHost();
1665  const QString& title = metadata->GetTitle();
1666 
1667  if (type == "Coverart" && !host.isEmpty() &&
1668  !metadata->GetCoverFile().startsWith("/"))
1669  {
1670  test_file = generate_file_url("Coverart",
1671  host, metadata->GetCoverFile());
1672  }
1673  else if (type == "Coverart")
1674  test_file = metadata->GetCoverFile();
1675 
1676  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1677  !IsDefaultCoverFile(test_file) && (gpnode.isEmpty() ||
1678  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1679  {
1680  icon_file = test_file;
1681  break;
1682  }
1683 
1684  if (type == "Fanart" && !host.isEmpty() &&
1685  !metadata->GetFanart().startsWith("/"))
1686  {
1687  test_file = generate_file_url("Fanart",
1688  host, metadata->GetFanart());
1689  }
1690  else if (type == "Fanart")
1691  test_file = metadata->GetFanart();
1692 
1693  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1694  test_file != VIDEO_FANART_DEFAULT && (gpnode.isEmpty() ||
1695  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1696  {
1697  icon_file = test_file;
1698  break;
1699  }
1700 
1701  if (type == "Banners" && !host.isEmpty() &&
1702  !metadata->GetBanner().startsWith("/"))
1703  {
1704  test_file = generate_file_url("Banners",
1705  host, metadata->GetBanner());
1706  }
1707  else if (type == "Banners")
1708  test_file = metadata->GetBanner();
1709 
1710  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1711  test_file != VIDEO_BANNER_DEFAULT && (gpnode.isEmpty() ||
1712  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1713  {
1714  icon_file = test_file;
1715  break;
1716  }
1717 
1718  if (type == "Screenshots" && !host.isEmpty() &&
1719  !metadata->GetScreenshot().startsWith("/"))
1720  {
1721  test_file = generate_file_url("Screenshots",
1722  host, metadata->GetScreenshot());
1723  }
1724  else if (type == "Screenshots")
1725  test_file = metadata->GetScreenshot();
1726 
1727  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1728  test_file != VIDEO_SCREENSHOT_DEFAULT && (gpnode.isEmpty() ||
1729  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1730  {
1731  icon_file = test_file;
1732  break;
1733  }
1734  }
1735  }
1736  }
1737  if (icon_file.isEmpty() && !subDirs.isEmpty())
1738  {
1739  QString test_file;
1740  int subDirCount = subDirs.count();
1741  for (int i = 0; i < subDirCount; i ++)
1742  {
1743  if (levels < maxRecurse)
1744  {
1745  test_file = GetFirstImage(subDirs[i], type,
1746  node->GetText(), levels + 1);
1747  if (!test_file.isEmpty())
1748  {
1749  icon_file = test_file;
1750  break;
1751  }
1752  }
1753  }
1754  }
1755  }
1756  return icon_file;
1757 }
1758 
1764 {
1765  const int nodeInt = node->getInt();
1766 
1767  QString icon_file;
1768 
1769  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1770  {
1771  icon_file = VIDEO_SCREENSHOT_DEFAULT;
1772  }
1773  else
1774  {
1775  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1776 
1777  if (metadata)
1778  {
1779  if (metadata->IsHostSet() &&
1780  !metadata->GetScreenshot().startsWith("/") &&
1781  !metadata->GetScreenshot().isEmpty())
1782  {
1783  icon_file = generate_file_url("Screenshots", metadata->GetHost(),
1784  metadata->GetScreenshot());
1785  }
1786  else
1787  {
1788  icon_file = metadata->GetScreenshot();
1789  }
1790  }
1791  }
1792 
1793  if (IsDefaultScreenshot(icon_file))
1794  icon_file.clear();
1795 
1796  return icon_file;
1797 }
1798 
1804 {
1805  const int nodeInt = node->getInt();
1806 
1807  if (nodeInt == kSubFolder || nodeInt == kUpFolder)
1808  return {};
1809 
1810  QString icon_file;
1811  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1812 
1813  if (metadata)
1814  {
1815  if (metadata->IsHostSet() &&
1816  !metadata->GetBanner().startsWith("/") &&
1817  !metadata->GetBanner().isEmpty())
1818  {
1819  icon_file = generate_file_url("Banners", metadata->GetHost(),
1820  metadata->GetBanner());
1821  }
1822  else
1823  {
1824  icon_file = metadata->GetBanner();
1825  }
1826 
1827  if (IsDefaultBanner(icon_file))
1828  icon_file.clear();
1829  }
1830 
1831  return icon_file;
1832 }
1833 
1839 {
1840  const int nodeInt = node->getInt();
1841 
1842  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1843  return {};
1844 
1845  QString icon_file;
1846  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1847 
1848  if (metadata)
1849  {
1850  if (metadata->IsHostSet() &&
1851  !metadata->GetFanart().startsWith("/") &&
1852  !metadata->GetFanart().isEmpty())
1853  {
1854  icon_file = generate_file_url("Fanart", metadata->GetHost(),
1855  metadata->GetFanart());
1856  }
1857  else
1858  {
1859  icon_file = metadata->GetFanart();
1860  }
1861 
1862  if (IsDefaultFanart(icon_file))
1863  icon_file.clear();
1864  }
1865 
1866  return icon_file;
1867 }
1868 
1873 bool VideoDialog::keyPressEvent(QKeyEvent *levent)
1874 {
1875  if (GetFocusWidget()->keyPressEvent(levent))
1876  return true;
1877 
1878  QStringList actions;
1879  bool handled = GetMythMainWindow()->TranslateKeyPress("Video", levent, actions);
1880 
1881  for (int i = 0; i < actions.size() && !handled; i++)
1882  {
1883  QString action = actions[i];
1884  handled = true;
1885 
1886  if (action == "INFO")
1887  {
1889  MythGenericTree *node = GetNodePtrFromButton(item);
1890  if (!m_menuPopup && node->getInt() != kUpFolder)
1891  VideoMenu();
1892  }
1893  else if (action == "INCPARENT")
1894  shiftParental(1);
1895  else if (action == "DECPARENT")
1896  shiftParental(-1);
1897  else if (action == "1" || action == "2" ||
1898  action == "3" || action == "4")
1900  else if (action == "FILTER")
1901  ChangeFilter();
1902  else if (action == "MENU")
1903  {
1904  if (!m_menuPopup)
1905  DisplayMenu();
1906  }
1907  else if (action == "PLAYALT")
1908  {
1909  if (!m_menuPopup && GetMetadata(GetItemCurrent()) &&
1911  playVideoAlt();
1912  }
1913  else if (action == "DOWNLOADDATA")
1914  {
1916  VideoSearch();
1917  }
1918  else if (action == "INCSEARCH")
1919  searchStart();
1920  else if (action == "ITEMDETAIL")
1921  DoItemDetailShow();
1922  else if (action == "DELETE")
1923  {
1925  RemoveVideo();
1926  }
1927  else if (action == "EDIT" && !m_menuPopup)
1928  EditMetadata();
1929  else if (action == "ESCAPE")
1930  {
1931  if (m_d->m_type != DLG_TREE
1932  && !GetMythMainWindow()->IsExitingToMain()
1933  && m_d->m_currentNode != m_d->m_rootNode)
1934  handled = goBack();
1935  else
1936  handled = false;
1937  }
1938  else
1939  handled = false;
1940  }
1941 
1942  if (!handled)
1943  {
1944  handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", levent,
1945  actions);
1946 
1947  for (int i = 0; i < actions.size() && !handled; i++)
1948  {
1949  QString action = actions[i];
1950  if (action == "PLAYBACK")
1951  {
1952  handled = true;
1953  playVideo();
1954  }
1955  }
1956  }
1957 
1958  if (!handled && MythScreenType::keyPressEvent(levent))
1959  handled = true;
1960 
1961  return handled;
1962 }
1963 
1968 void VideoDialog::createBusyDialog(const QString &title)
1969 {
1970  if (m_busyPopup)
1971  return;
1972 
1973  const QString& message = title;
1974 
1975  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
1976  "mythvideobusydialog");
1977 
1978  if (m_busyPopup->Create())
1980 }
1981 
1987 {
1988  if (m_d->m_notifications.contains(metadata->GetHash()))
1989  return;
1990 
1991  int id = GetNotificationCenter()->Register(this);
1992  m_d->m_notifications[metadata->GetHash()] = id;
1993 
1994  QString msg = tr("Fetching details for %1")
1995  .arg(metadata->GetTitle());
1996  QString desc;
1997  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
1998  {
1999  desc = tr("Season %1, Episode %2")
2000  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2001  }
2002  MythBusyNotification n(msg, sLocation, desc);
2003  n.SetId(id);
2004  n.SetParent(this);
2006 }
2007 
2009 {
2010  if (!metadata || !m_d->m_notifications.contains(metadata->GetHash()))
2011  return;
2012 
2013  int id = m_d->m_notifications[metadata->GetHash()];
2014  m_d->m_notifications.remove(metadata->GetHash());
2015 
2016  QString msg;
2017  if (ok)
2018  {
2019  msg = tr("Retrieved details for %1").arg(metadata->GetTitle());
2020  }
2021  else
2022  {
2023  msg = tr("Failed to retrieve details for %1").arg(metadata->GetTitle());
2024  }
2025  QString desc;
2026  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
2027  {
2028  desc = tr("Season %1, Episode %2")
2029  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2030  }
2031  if (ok)
2032  {
2033  MythCheckNotification n(msg, sLocation, desc);
2034  n.SetId(id);
2035  n.SetParent(this);
2037  }
2038  else
2039  {
2040  MythErrorNotification n(msg, sLocation, desc);
2041  n.SetId(id);
2042  n.SetParent(this);
2044  }
2045  GetNotificationCenter()->UnRegister(this, id);
2046 }
2047 
2052 void VideoDialog::createOkDialog(const QString& title)
2053 {
2054  const QString& message = title;
2055 
2056  auto *okPopup = new MythConfirmationDialog(m_popupStack, message, false);
2057 
2058  if (okPopup->Create())
2059  m_popupStack->AddScreen(okPopup);
2060 }
2061 
2066 void VideoDialog::searchComplete(const QString& string)
2067 {
2068  LOG(VB_GENERAL, LOG_DEBUG, QString("Jumping to: %1").arg(string));
2069 
2071  QList<MythGenericTree*> *children = nullptr;
2072  QMap<int, QString> idTitle;
2073 
2074  if (parent && m_d->m_type == DLG_TREE)
2075  children = parent->getAllChildren();
2076  else
2077  children = m_d->m_currentNode->getAllChildren();
2078 
2079  for (auto * child : qAsConst(*children))
2080  {
2081  QString title = child->GetText();
2082  int id = child->getPosition();
2083  idTitle.insert(id, title);
2084  }
2085 
2086  if (m_d->m_type == DLG_TREE)
2087  {
2089  MythGenericTree *new_node = dlgParent->getChildAt(idTitle.key(string));
2090  if (new_node)
2091  {
2092  m_videoButtonTree->SetCurrentNode(new_node);
2094  }
2095  }
2096  else
2097  m_videoButtonList->SetItemCurrent(idTitle.key(string));
2098 }
2099 
2105 {
2107 
2108  QStringList childList;
2109  QList<MythGenericTree*> *children = nullptr;
2110  if (parent && m_d->m_type == DLG_TREE)
2111  children = parent->getAllChildren();
2112  else
2113  children = m_d->m_currentNode->getAllChildren();
2114 
2115  for (auto * child : qAsConst(*children))
2116  {
2117  childList << child->GetText();
2118  }
2119 
2120  MythScreenStack *popupStack =
2121  GetMythMainWindow()->GetStack("popup stack");
2122  auto *searchDialog = new MythUISearchDialog(popupStack,
2123  tr("Video Search"), childList, false, "");
2124 
2125  if (searchDialog->Create())
2126  {
2127  connect(searchDialog, &MythUISearchDialog::haveResult,
2129 
2130  popupStack->AddScreen(searchDialog);
2131  }
2132  else
2133  delete searchDialog;
2134 }
2135 
2141 {
2142  bool handled = false;
2143 
2144  if (m_d->m_currentNode != m_d->m_rootNode)
2145  {
2146  MythGenericTree *lparent = m_d->m_currentNode->getParent();
2147  if (lparent)
2148  {
2149  SetCurrentNode(lparent);
2150 
2151  handled = true;
2152  }
2153  }
2154 
2155  loadData();
2156 
2157  return handled;
2158 }
2159 
2165 {
2166  if (!node)
2167  return;
2168 
2169  m_d->m_currentNode = node;
2170 }
2171 
2177 {
2179  MythUIButtonList *currentList = ci ? ci->parent() : nullptr;
2180 
2181  if (!currentList)
2182  return;
2183 
2184  CheckedSet(m_positionText, tr("%1 of %2")
2185  .arg(currentList->IsEmpty() ? 0 : currentList->GetCurrentPos() + 1)
2186  .arg(currentList->GetCount()));
2187 }
2188 
2194 {
2195  if (!item)
2196  return;
2197 
2198  MythUIButtonList *currentList = item->parent();
2199 
2200  if (!currentList)
2201  return;
2202 
2203  VideoMetadata *metadata = GetMetadata(item);
2204 
2205  MythGenericTree *node = GetNodePtrFromButton(item);
2206 
2207  if (!node)
2208  return;
2209 
2210  if (metadata)
2211  {
2212  InfoMap metadataMap;
2213  metadata->toMap(metadataMap);
2214  SetTextFromMap(metadataMap);
2215  }
2216  else
2217  {
2218  InfoMap metadataMap;
2219  ClearMap(metadataMap);
2220  SetTextFromMap(metadataMap);
2221  }
2222 
2223  ScreenCopyDest dest(this);
2224  CopyMetadataToUI(metadata, dest);
2225 
2226  if (node->getInt() == kSubFolder && !metadata)
2227  {
2228  QString cover = GetFirstImage(node, "Coverart");
2229  QString fanart = GetFirstImage(node, "Fanart");
2230  QString banner = GetFirstImage(node, "Banners");
2231  QString screenshot = GetFirstImage(node, "Screenshots");
2232  CheckedSet(m_coverImage, cover);
2233  CheckedSet(m_fanart, fanart);
2234  CheckedSet(m_banner, banner);
2235  CheckedSet(m_screenshot, screenshot);
2236  }
2237 
2238  if (!metadata)
2239  CheckedSet(m_titleText, item->GetText());
2240  UpdatePosition();
2241 
2242  if (m_d->m_currentNode)
2243  {
2245  CheckedSet(this, "foldername", m_d->m_currentNode->GetText());
2246  }
2247 
2248  if (node && node->getInt() == kSubFolder)
2249  CheckedSet(this, "childcount",
2250  QString("%1").arg(node->visibleChildCount()));
2251 
2252  if (node)
2253  node->becomeSelectedChild();
2254 }
2255 
2261 {
2262  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2263  QString label;
2264 
2265  if (metadata)
2266  {
2267  if (!metadata->GetSubtitle().isEmpty())
2268  {
2269  label = tr("Video Options\n%1\n%2").arg(metadata->GetTitle(),
2270  metadata->GetSubtitle());
2271  }
2272  else
2273  {
2274  label = tr("Video Options\n%1").arg(metadata->GetTitle());
2275  }
2276  }
2277  else
2278  label = tr("Video Options");
2279 
2280  auto *menu = new MythMenu(label, this, "actions");
2281 
2283  MythGenericTree *node = GetNodePtrFromButton(item);
2284  if (metadata)
2285  {
2286  if (!metadata->GetTrailer().isEmpty() ||
2287  gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false) ||
2289  menu->AddItem(tr("Play..."), nullptr, CreatePlayMenu());
2290  else
2291  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2292  if (metadata->GetWatched())
2293  menu->AddItem(tr("Mark as Unwatched"), &VideoDialog::ToggleWatched);
2294  else
2295  menu->AddItem(tr("Mark as Watched"), &VideoDialog::ToggleWatched);
2296  menu->AddItem(tr("Video Info"), nullptr, CreateInfoMenu());
2297  if (!m_d->m_notifications.contains(metadata->GetHash()))
2298  {
2299  menu->AddItem(tr("Change Video Details"), nullptr, CreateManageMenu());
2300  }
2301  menu->AddItem(tr("Delete"), &VideoDialog::RemoveVideo);
2302  }
2303  else if (node && node->getInt() != kUpFolder)
2304  {
2305  menu->AddItem(tr("Play Folder"), &VideoDialog::playFolder);
2306  }
2307 
2308 
2309  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2310 
2311  if (m_menuPopup->Create())
2312  {
2315  }
2316  else
2317  delete m_menuPopup;
2318 }
2319 
2326 {
2327  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2328  QString label;
2329 
2330  if (metadata)
2331  label = tr("Playback Options\n%1").arg(metadata->GetTitle());
2332  else
2333  return nullptr;
2334 
2335  auto *menu = new MythMenu(label, this, "actions");
2336 
2337  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2338 
2339  if (m_d->m_altPlayerEnabled)
2340  {
2341  menu->AddItem(tr("Play in Alternate Player"), &VideoDialog::playVideoAlt);
2342  }
2343 
2344  if (gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false))
2345  {
2346  menu->AddItem(tr("Play With Trailers"), &VideoDialog::playVideoWithTrailers);
2347  }
2348 
2349  QString trailerFile = metadata->GetTrailer();
2350  if (QFile::exists(trailerFile) ||
2351  (!metadata->GetHost().isEmpty() && !trailerFile.isEmpty()))
2352  {
2353  menu->AddItem(tr("Play Trailer"), &VideoDialog::playTrailer);
2354  }
2355 
2356  return menu;
2357 }
2358 
2364 {
2365  QString label = tr("Video Display Menu");
2366 
2367  auto *menu = new MythMenu(label, this, "display");
2368 
2369  menu->AddItem(tr("Scan For Changes"), &VideoDialog::doVideoScan);
2370  menu->AddItem(tr("Retrieve All Details"), qOverload<>(&VideoDialog::VideoAutoSearch));
2371  menu->AddItem(tr("Filter Display"), &VideoDialog::ChangeFilter);
2372  menu->AddItem(tr("Browse By..."), nullptr, CreateMetadataBrowseMenu());
2373  menu->AddItem(tr("Change View"), nullptr, CreateViewMenu());
2374  menu->AddItem(tr("Settings"), nullptr, CreateSettingsMenu());
2375 
2376  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2377 
2378  if (m_menuPopup->Create())
2379  {
2382  }
2383  else
2384  delete m_menuPopup;
2385 }
2386 
2387 // Switch from the display menu to the actions menu on second
2388 // menu press
2389 
2390 void VideoDialog::popupClosed(const QString& which, int result)
2391 {
2392  m_menuPopup = nullptr;
2393 
2394  if (result == -2)
2395  {
2396  if (which == "display")
2397  VideoMenu();
2398  }
2399 }
2400 
2406 {
2407  QString label = tr("Change View");
2408 
2409  auto *menu = new MythMenu(label, this, "view");
2410 
2411  if (!(m_d->m_type & DLG_BROWSER))
2412  menu->AddItem(tr("Switch to Browse View"), &VideoDialog::SwitchBrowse);
2413 
2414  if (!(m_d->m_type & DLG_GALLERY))
2415  menu->AddItem(tr("Switch to Gallery View"), &VideoDialog::SwitchGallery);
2416 
2417  if (!(m_d->m_type & DLG_TREE))
2418  menu->AddItem(tr("Switch to List View"), &VideoDialog::SwitchTree);
2419 
2420  if (!(m_d->m_type & DLG_MANAGER))
2421  menu->AddItem(tr("Switch to Manage View"), &VideoDialog::SwitchManager);
2422 
2423  if (m_d->m_isFlatList)
2424  menu->AddItem(tr("Show Directory Structure"), &VideoDialog::ToggleFlatView);
2425  else
2426  menu->AddItem(tr("Hide Directory Structure"), &VideoDialog::ToggleFlatView);
2427 
2428  if (m_d->m_isFileBrowser)
2429  menu->AddItem(tr("Browse Library (recommended)"), &VideoDialog::ToggleBrowseMode);
2430  else
2431  menu->AddItem(tr("Browse Filesystem (slow)"), &VideoDialog::ToggleBrowseMode);
2432 
2433 
2434  return menu;
2435 }
2436 
2442 {
2443  QString label = tr("Video Settings");
2444 
2445  auto *menu = new MythMenu(label, this, "settings");
2446 
2447  menu->AddItem(tr("Player Settings"), &VideoDialog::ShowPlayerSettings);
2448  menu->AddItem(tr("Metadata Settings"), &VideoDialog::ShowMetadataSettings);
2449  menu->AddItem(tr("File Type Settings"), &VideoDialog::ShowExtensionSettings);
2450 
2451  return menu;
2452 }
2453 
2459 {
2460  auto *ps = new PlayerSettings(m_mainStack, "player settings");
2461 
2462  if (ps->Create())
2463  m_mainStack->AddScreen(ps);
2464  else
2465  delete ps;
2466 }
2467 
2473 {
2474  auto *ms = new MetadataSettings(m_mainStack, "metadata settings");
2475 
2476  if (ms->Create())
2477  m_mainStack->AddScreen(ms);
2478  else
2479  delete ms;
2480 }
2481 
2487 {
2488  auto *fa = new FileAssocDialog(m_mainStack, "fa dialog");
2489 
2490  if (fa->Create())
2491  m_mainStack->AddScreen(fa);
2492  else
2493  delete fa;
2494 }
2495 
2501 {
2502  QString label = tr("Browse By");
2503 
2504  auto *menu = new MythMenu(label, this, "metadata");
2505 
2506  if (m_d->m_groupType != BRS_CAST)
2507  menu->AddItem(tr("Cast"), &VideoDialog::SwitchVideoCastGroup);
2508 
2509  if (m_d->m_groupType != BRS_CATEGORY)
2510  menu->AddItem(tr("Category"), &VideoDialog::SwitchVideoCategoryGroup);
2511 
2512  if (m_d->m_groupType != BRS_INSERTDATE)
2513  menu->AddItem(tr("Date Added"), &VideoDialog::SwitchVideoInsertDateGroup);
2514 
2515  if (m_d->m_groupType != BRS_DIRECTOR)
2516  menu->AddItem(tr("Director"), &VideoDialog::SwitchVideoDirectorGroup);
2517 
2518  if (m_d->m_groupType != BRS_STUDIO)
2519  menu->AddItem(tr("Studio"), &VideoDialog::SwitchVideoStudioGroup);
2520 
2521  if (m_d->m_groupType != BRS_FOLDER)
2522  menu->AddItem(tr("Folder"), &VideoDialog::SwitchVideoFolderGroup);
2523 
2524  if (m_d->m_groupType != BRS_GENRE)
2525  menu->AddItem(tr("Genre"), &VideoDialog::SwitchVideoGenreGroup);
2526 
2527  if (m_d->m_groupType != BRS_TVMOVIE)
2528  menu->AddItem(tr("TV/Movies"), &VideoDialog::SwitchVideoTVMovieGroup);
2529 
2530  if (m_d->m_groupType != BRS_USERRATING)
2531  menu->AddItem(tr("User Rating"), &VideoDialog::SwitchVideoUserRatingGroup);
2532 
2533  if (m_d->m_groupType != BRS_YEAR)
2534  menu->AddItem(tr("Year"), &VideoDialog::SwitchVideoYearGroup);
2535 
2536  return menu;
2537 }
2538 
2544 {
2545  QString label = tr("Video Info");
2546 
2547  auto *menu = new MythMenu(label, this, "info");
2548 
2550  menu->AddItem(tr("View Details"), &VideoDialog::DoItemDetailShow2);
2551 
2552  menu->AddItem(tr("View Full Plot"), &VideoDialog::ViewPlot);
2553 
2554  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2555  if (metadata)
2556  {
2557  if (!metadata->GetCast().empty())
2558  menu->AddItem(tr("View Cast"), &VideoDialog::ShowCastDialog);
2559  if (!metadata->GetHomepage().isEmpty())
2560  menu->AddItem(tr("View Homepage"), &VideoDialog::ShowHomepage);
2561  }
2562 
2563  return menu;
2564 }
2565 
2571 {
2572  QString label = tr("Manage Video Details");
2573 
2574  auto *menu = new MythMenu(label, this, "manage");
2575 
2576  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2577 
2578  menu->AddItem(tr("Edit Details"), &VideoDialog::EditMetadata);
2579  menu->AddItem(tr("Retrieve Details"), qOverload<>(&VideoDialog::VideoSearch));
2580  if (metadata->GetProcessed())
2581  menu->AddItem(tr("Allow Updates"), &VideoDialog::ToggleProcess);
2582  else
2583  menu->AddItem(tr("Disable Updates"), &VideoDialog::ToggleProcess);
2584  menu->AddItem(tr("Reset Details"), &VideoDialog::ResetMetadata);
2585 
2586  return menu;
2587 }
2588 
2590 {
2591  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2592  if (metadata)
2593  {
2594  metadata->SetProcessed(!metadata->GetProcessed());
2595  metadata->UpdateDatabase();
2596 
2597  refreshData();
2598  }
2599 }
2600 
2606 {
2608  gCoreContext->SaveSetting("VideoDialogNoDB",
2609  QString("%1").arg((int)m_d->m_isFileBrowser));
2610  reloadData();
2611 }
2612 
2618 {
2620  gCoreContext->SaveSetting(QString("mythvideo.folder_view_%1").arg(m_d->m_type),
2621  QString("%1").arg((int)m_d->m_isFlatList));
2622  // TODO: This forces a complete tree rebuild, this is SLOW and shouldn't
2623  // be necessary since MythGenericTree can do a flat view without a rebuild,
2624  // I just don't want to re-write VideoList just now
2625  reloadData();
2626 }
2627 
2633 {
2634  SetCurrentNode(node);
2635  loadData();
2636 }
2637 
2643 {
2644  QStringList route = node->getRouteByString();
2645  if (m_d->m_videoList && m_d->m_videoList->refreshNode(node))
2646  reloadData();
2648 }
2649 
2655 {
2656  MythGenericTree *node = GetNodePtrFromButton(item);
2657  int nodeInt = node->getInt();
2658 
2659  switch (nodeInt)
2660  {
2661  case kDynamicSubFolder:
2662  handleDynamicDirSelect(node);
2663  break;
2664  case kSubFolder:
2665  handleDirSelect(node);
2666  break;
2667  case kUpFolder:
2668  goBack();
2669  break;
2670  default:
2671  {
2672  bool doPlay = true;
2673  if (m_d->m_type == DLG_GALLERY)
2674  {
2675  doPlay = !DoItemDetailShow();
2676  }
2677 
2678  if (doPlay)
2679  playVideo();
2680  }
2681  };
2682 }
2683 
2689 {
2691 }
2692 
2698 {
2700 }
2701 
2707 {
2709 }
2710 
2716 {
2718 }
2719 
2725 {
2727 }
2728 
2734 {
2736 }
2737 
2743 {
2745 }
2746 
2752 {
2754 }
2755 
2761 {
2763 }
2764 
2770 {
2772 }
2773 
2779 {
2781 }
2782 
2788 {
2790 }
2791 
2797 {
2799 }
2800 
2806 {
2808 }
2809 
2815 {
2816  m_d->m_switchingLayout = true;
2817 
2818  // save current position so it can be restored after the switch
2819  SavePosition();
2820 
2821  auto *mythvideo =
2822  new VideoDialog(GetMythMainWindow()->GetMainStack(), "mythvideo",
2823  m_d->m_videoList, type, browse);
2824 
2825  if (mythvideo->Create())
2826  {
2827  gCoreContext->SaveSetting("Default MythVideo View", type);
2828  gCoreContext->SaveSetting("mythvideo.db_group_type", browse);
2829  MythScreenStack *screenStack = GetScreenStack();
2830  screenStack->AddScreen(mythvideo);
2831  screenStack->PopScreen(this, false, false);
2832  deleteLater();
2833  }
2834  else
2835  {
2836  ShowOkPopup(tr("An error occurred when switching views."));
2837  }
2838 }
2839 
2845 {
2846  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2847 
2848  auto *plotdialog = new PlotDialog(m_popupStack, metadata);
2849 
2850  if (plotdialog->Create())
2851  m_popupStack->AddScreen(plotdialog);
2852 }
2853 
2859 {
2860  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2861 
2862  if (metadata)
2863  {
2865  auto *idp = new ItemDetailPopup(mainStack, metadata,
2866  m_d->m_videoList->getListCache());
2867 
2868  if (idp->Create())
2869  {
2870  mainStack->AddScreen(idp);
2871  return true;
2872  }
2873  }
2874 
2875  return false;
2876 }
2877 
2883 {
2884  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2885 
2886  auto *castdialog = new CastDialog(m_popupStack, metadata);
2887 
2888  if (castdialog->Create())
2889  m_popupStack->AddScreen(castdialog);
2890 }
2891 
2893 {
2894  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2895 
2896  if (!metadata)
2897  return;
2898 
2899  QString url = metadata->GetHomepage();
2900 
2901  if (url.isEmpty())
2902  return;
2903 
2904  QString browser = gCoreContext->GetSetting("WebBrowserCommand", "");
2905  QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
2906 
2907  if (browser.isEmpty())
2908  {
2909  ShowOkPopup(tr("No browser command set! MythVideo needs MythBrowser "
2910  "installed to display the homepage."));
2911  return;
2912  }
2913 
2914  if (browser.toLower() == "internal")
2915  {
2916  GetMythMainWindow()->HandleMedia("WebBrowser", url);
2917  return;
2918  }
2919 
2920  QString cmd = browser;
2921  cmd.replace("%ZOOM%", zoom);
2922  cmd.replace("%URL%", url);
2923  cmd.replace('\'', "%27");
2924  cmd.replace("&","\\&");
2925  cmd.replace(";","\\;");
2926 
2927  GetMythMainWindow()->AllowInput(false);
2929  GetMythMainWindow()->AllowInput(true);
2930 }
2931 
2937 {
2938  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2939  if (metadata)
2940  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
2941 }
2942 
2948 {
2949  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2950  if (metadata)
2951  PlayVideo(metadata->GetFilename(),
2952  m_d->m_videoList->getListCache(), true);
2953 }
2954 
2960 {
2961  const int WATCHED_WATERMARK = 10000; // Play less then this milisec and the chain of
2962  // videos will not be followed when
2963  // playing.
2964  QElapsedTimer playing_time;
2965 
2967  MythGenericTree *node = GetNodePtrFromButton(item);
2968  int list_count = 0;
2969 
2970  if (node && !(node->getInt() >= 0))
2971  list_count = node->childCount();
2972  else
2973  return;
2974 
2975  if (list_count > 0)
2976  {
2977  bool video_started = false;
2978  int i = 0;
2979  while (i < list_count &&
2980  (!video_started || playing_time.hasExpired(WATCHED_WATERMARK)))
2981  {
2982  MythGenericTree *subnode = node->getChildAt(i);
2983  if (subnode)
2984  {
2985  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
2986  if (metadata)
2987  {
2988  playing_time.start();
2989  video_started = true;
2990  PlayVideo(metadata->GetFilename(),
2991  m_d->m_videoList->getListCache());
2992  }
2993  }
2994  i++;
2995  }
2996  }
2997 }
2998 
2999 namespace
3000 {
3001  struct SimpleCollect : public DirectoryHandler
3002  {
3003  explicit SimpleCollect(QStringList &fileList) : m_fileList(fileList) {}
3004 
3005  DirectoryHandler *newDir(const QString &dirName,
3006  const QString &fqDirName) override // DirectoryHandler
3007  {
3008  (void) dirName;
3009  (void) fqDirName;
3010  return this;
3011  }
3012 
3013  void handleFile(const QString &fileName, const QString &fqFileName,
3014  const QString &extension, const QString &host) override // DirectoryHandler
3015  {
3016  (void) fileName;
3017  (void) extension;
3018  (void) host;
3019  m_fileList.push_back(fqFileName);
3020  }
3021 
3022  private:
3023  QStringList &m_fileList;
3024  };
3025 
3026  QStringList GetTrailersInDirectory(const QString &startDir)
3027  {
3030  .getExtensionIgnoreList(extensions);
3031  QStringList ret;
3032  SimpleCollect sc(ret);
3033 
3034  (void) ScanVideoDirectory(startDir, &sc, extensions, false);
3035  return ret;
3036  }
3037 }
3038 
3044 {
3045  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3046  if (!metadata) return;
3047 
3048  QStringList trailers = GetTrailersInDirectory(gCoreContext->
3049  GetSetting("mythvideo.TrailersDir"));
3050 
3051  if (trailers.isEmpty())
3052  return;
3053 
3054  const int trailersToPlay =
3055  gCoreContext->GetNumSetting("mythvideo.TrailersRandomCount");
3056 
3057  int i = 0;
3058  while (!trailers.isEmpty() && i < trailersToPlay)
3059  {
3060  ++i;
3061  QString trailer = trailers.takeAt(MythRandom(0, trailers.size() - 1));
3062 
3063  LOG(VB_GENERAL, LOG_DEBUG,
3064  QString("Random trailer to play will be: %1").arg(trailer));
3065 
3067  }
3068 
3069  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
3070 }
3071 
3077 {
3078  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3079  if (!metadata) return;
3080  QString url;
3081 
3082  if (metadata->IsHostSet() && !metadata->GetTrailer().startsWith("/"))
3083  {
3084  url = generate_file_url("Trailers", metadata->GetHost(),
3085  metadata->GetTrailer());
3086  }
3087  else
3088  {
3089  url = metadata->GetTrailer();
3090  }
3091 
3093 }
3094 
3100 {
3101  m_d->m_parentalLevel.SetLevel(level);
3102 }
3103 
3109 {
3111  .GetLevel() + amount).GetLevel());
3112 }
3113 
3119 {
3120  MythScreenStack *mainStack = GetScreenStack();
3121 
3122  auto *filterdialog = new VideoFilterDialog(mainStack,
3123  "videodialogfilters", m_d->m_videoList.get());
3124 
3125  if (filterdialog->Create())
3126  mainStack->AddScreen(filterdialog);
3127 
3128  connect(filterdialog, &VideoFilterDialog::filterChanged, this, &VideoDialog::reloadData);
3129 }
3130 
3136 {
3137  VideoMetadata *metadata = nullptr;
3138 
3139  if (item)
3140  {
3141  MythGenericTree *node = GetNodePtrFromButton(item);
3142  if (node)
3143  {
3144  int nodeInt = node->getInt();
3145 
3146  if (nodeInt >= 0)
3147  metadata = GetMetadataPtrFromNode(node);
3148  }
3149  }
3150 
3151  return metadata;
3152 }
3153 
3154 void VideoDialog::customEvent(QEvent *levent)
3155 {
3156  if (levent->type() == MetadataFactoryMultiResult::kEventType)
3157  {
3158  auto *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
3159 
3160  if (!mfmr)
3161  return;
3162 
3163  MetadataLookupList list = mfmr->m_results;
3164 
3165  if (list.count() > 1)
3166  {
3167  auto *metadata = list[0]->GetData().value<VideoMetadata *>();
3168  dismissFetchDialog(metadata, true);
3169  auto *resultsdialog = new MetadataResultsDialog(m_popupStack, list);
3170 
3171  connect(resultsdialog, &MetadataResultsDialog::haveResult,
3173  Qt::QueuedConnection);
3174 
3175  if (resultsdialog->Create())
3176  m_popupStack->AddScreen(resultsdialog);
3177  }
3178  }
3179  else if (levent->type() == MetadataFactorySingleResult::kEventType)
3180  {
3181  auto *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
3182 
3183  if (!mfsr)
3184  return;
3185 
3186  MetadataLookup *lookup = mfsr->m_result;
3187 
3188  if (!lookup)
3189  return;
3190 
3191  OnVideoSearchDone(lookup);
3192  }
3193  else if (levent->type() == MetadataFactoryNoResult::kEventType)
3194  {
3195  auto *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
3196 
3197  if (!mfnr)
3198  return;
3199 
3200  MetadataLookup *lookup = mfnr->m_result;
3201 
3202  if (!lookup)
3203  return;
3204 
3205  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3206  if (metadata)
3207  {
3208  dismissFetchDialog(metadata, false);
3209  metadata->SetProcessed(true);
3210  metadata->UpdateDatabase();
3211  }
3212  LOG(VB_GENERAL, LOG_INFO,
3213  QString("No results found for %1 %2 %3").arg(lookup->GetTitle())
3214  .arg(lookup->GetSeason()).arg(lookup->GetEpisode()));
3215  }
3216  else if (levent->type() == DialogCompletionEvent::kEventType)
3217  {
3218  auto *dce = dynamic_cast<DialogCompletionEvent *>(levent);
3219  if (dce != nullptr)
3220  {
3221  QString id = dce->GetId();
3222 
3223  if (id == "scanprompt")
3224  {
3225  int result = dce->GetResult();
3226  if (result == 1)
3227  doVideoScan();
3228  }
3229  else
3230  {
3231  m_menuPopup = nullptr;
3232  }
3233  }
3234  else
3235  {
3236  m_menuPopup = nullptr;
3237  }
3238  }
3239  else if (levent->type() == ImageDLFailureEvent::kEventType)
3240  {
3241  MythErrorNotification n(tr("Failed to retrieve image(s)"),
3242  sLocation,
3243  tr("Check logs"));
3245  }
3246 }
3247 
3249 {
3250  // The metadata has some cover file set
3251  dismissFetchDialog(metadata, true);
3252 
3253  metadata->SetProcessed(true);
3254  metadata->UpdateDatabase();
3255 
3256  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3257  if (item != nullptr)
3258  UpdateItem(item);
3259 }
3260 
3262 {
3263  if (m_videoButtonTree)
3264  {
3266  }
3267 
3269 }
3270 
3272 {
3273  if (m_videoButtonTree)
3274  {
3276  }
3277 
3278  QMap<int, int> idPosition;
3279 
3280  QList<MythGenericTree*> *children = m_d->m_currentNode->getAllChildren();
3281 
3282  for (auto * child : qAsConst(*children))
3283  {
3284  int nodeInt = child->getInt();
3285  if (nodeInt != kSubFolder && nodeInt != kUpFolder)
3286  {
3287  VideoMetadata *listmeta =
3288  GetMetadataPtrFromNode(child);
3289  if (listmeta)
3290  {
3291  int position = child->getPosition();
3292  int id = listmeta->GetID();
3293  idPosition.insert(id, position);
3294  }
3295  }
3296  }
3297 
3298  return m_videoButtonList->GetItemAt(idPosition.value(metadata->GetID()));
3299 }
3300 
3302  bool automode)
3303 {
3304  if (!node)
3305  node = GetNodePtrFromButton(GetItemCurrent());
3306 
3307  if (!node)
3308  return;
3309 
3310  VideoMetadata *metadata = GetMetadataPtrFromNode(node);
3311 
3312  if (!metadata)
3313  return;
3314 
3315  m_metadataFactory->Lookup(metadata, automode, true);
3316 
3317  if (!automode)
3318  {
3319  createFetchDialog(metadata);
3320  }
3321 }
3322 
3324 {
3325  if (!node)
3326  node = m_d->m_rootNode;
3327  using MGTreeChildList = QList<MythGenericTree *>;
3328  MGTreeChildList *lchildren = node->getAllChildren();
3329 
3330  LOG(VB_GENERAL, LOG_DEBUG,
3331  QString("Fetching details in %1").arg(node->GetText()));
3332 
3333  for (auto * child : qAsConst(*lchildren))
3334  {
3335  if ((child->getInt() == kSubFolder) ||
3336  (child->getInt() == kUpFolder))
3337  VideoAutoSearch(child);
3338  else
3339  {
3340  VideoMetadata *metadata = GetMetadataPtrFromNode(child);
3341 
3342  if (!metadata)
3343  continue;
3344 
3345  if (!metadata->GetProcessed())
3346  VideoSearch(child, true);
3347  }
3348  }
3349 }
3350 
3352 {
3354  if (!item)
3355  return;
3356 
3357  VideoMetadata *metadata = GetMetadata(item);
3358  if (metadata)
3359  {
3360  metadata->SetWatched(!metadata->GetWatched());
3361  metadata->UpdateDatabase();
3362  item->DisplayState(WatchedToState(metadata->GetWatched()),
3363  "watchedstate");
3364  }
3365 }
3366 
3368 {
3369  if (!lookup)
3370  return;
3371 
3372  if(!lookup->GetInetref().isEmpty() && lookup->GetInetref() != "00000000")
3373  {
3374  LOG(VB_GENERAL, LOG_INFO, LOC_MML +
3375  QString("Selected Item: Type: %1%2 : Subtype: %3%4%5 : InetRef: %6")
3376  .arg(lookup->GetType() == kMetadataVideo ? "Video" : "",
3377  lookup->GetType() == kMetadataRecording ? "Recording" : "",
3378  lookup->GetSubtype() == kProbableMovie ? "Movie" : "",
3379  lookup->GetSubtype() == kProbableTelevision ? "Television" : "",
3380  lookup->GetSubtype() == kUnknownVideo ? "Unknown" : "",
3381  lookup->GetInetref()));
3382 
3383  lookup->SetStep(kLookupData);
3384  lookup->IncrRef();
3385  m_metadataFactory->Lookup(lookup);
3386  }
3387  else
3388  {
3389  LOG(VB_GENERAL, LOG_ERR, LOC_MML +
3390  QString("Selected Item has no InetRef Number!"));
3391 
3392  OnVideoSearchDone(lookup);
3393  }
3394 }
3395 
3397 {
3398  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3399  if (metadata)
3400  {
3401  ParentalLevel curshowlevel = metadata->GetShowLevel();
3402 
3403  curshowlevel += amount;
3404 
3405  if (curshowlevel.GetLevel() != metadata->GetShowLevel())
3406  {
3407  metadata->SetShowLevel(curshowlevel.GetLevel());
3408  metadata->UpdateDatabase();
3409  refreshData();
3410  }
3411  }
3412 }
3413 
3415 {
3416  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3417  if (!metadata)
3418  return;
3419 
3420  MythScreenStack *screenStack = GetScreenStack();
3421 
3422  auto *md_editor = new EditMetadataDialog(screenStack,
3423  "mythvideoeditmetadata", metadata,
3424  m_d->m_videoList->getListCache());
3425 
3426  connect(md_editor, &EditMetadataDialog::Finished, this, &VideoDialog::refreshData);
3427 
3428  if (md_editor->Create())
3429  screenStack->AddScreen(md_editor);
3430 }
3431 
3433 {
3434  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3435 
3436  if (!metadata)
3437  return;
3438 
3439  QString message = tr("Are you sure you want to permanently delete:\n%1")
3440  .arg(metadata->GetTitle());
3441 
3442  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message);
3443 
3444  if (confirmdialog->Create())
3445  m_popupStack->AddScreen(confirmdialog);
3446 
3447  connect(confirmdialog, &MythConfirmationDialog::haveResult,
3449 }
3450 
3451 void VideoDialog::OnRemoveVideo(bool dodelete)
3452 {
3453  if (!dodelete)
3454  return;
3455 
3457  MythGenericTree *gtItem = GetNodePtrFromButton(item);
3458 
3459  VideoMetadata *metadata = GetMetadata(item);
3460 
3461  if (!metadata)
3462  return;
3463 
3464  if (m_d->m_videoList->Delete(metadata->GetID()))
3465  {
3466  if (m_videoButtonTree)
3467  m_videoButtonTree->RemoveItem(item, false); // FIXME Segfault when true
3468  else
3470 
3471  MythGenericTree *parent = gtItem->getParent();
3472  parent->deleteNode(gtItem);
3473  }
3474  else
3475  {
3476  QString message = tr("Failed to delete file");
3477 
3478  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message,
3479  false);
3480 
3481  if (confirmdialog->Create())
3482  m_popupStack->AddScreen(confirmdialog);
3483  }
3484 }
3485 
3487 {
3489  VideoMetadata *metadata = GetMetadata(item);
3490 
3491  if (metadata)
3492  {
3493  metadata->Reset();
3494  metadata->UpdateDatabase();
3495  UpdateItem(item);
3496  }
3497 }
3498 
3500 {
3501  if (!metadata)
3502  return;
3503 
3504  QStringList cover_dirs;
3505  cover_dirs += m_d->m_artDir;
3506 
3507  QString cover_file;
3508  QString inetref = metadata->GetInetRef();
3509  QString filename = metadata->GetFilename();
3510  QString title = metadata->GetTitle();
3511  int season = metadata->GetSeason();
3512  QString host = metadata->GetHost();
3513  int episode = metadata->GetEpisode();
3514 
3515  if (metadata->GetCoverFile().isEmpty() ||
3516  IsDefaultCoverFile(metadata->GetCoverFile()))
3517  {
3518  if (GetLocalVideoImage(inetref, filename,
3519  cover_dirs, cover_file, title,
3520  season, host, "Coverart", episode))
3521  {
3522  metadata->SetCoverFile(cover_file);
3523  OnVideoImageSetDone(metadata);
3524  }
3525  }
3526 
3527  QStringList fanart_dirs;
3528  fanart_dirs += m_d->m_fanDir;
3529 
3530  QString fanart_file;
3531 
3532  if (metadata->GetFanart().isEmpty())
3533  {
3534  if (GetLocalVideoImage(inetref, filename,
3535  fanart_dirs, fanart_file, title,
3536  season, host, "Fanart", episode))
3537  {
3538  metadata->SetFanart(fanart_file);
3539  OnVideoImageSetDone(metadata);
3540  }
3541  }
3542 
3543  QStringList banner_dirs;
3544  banner_dirs += m_d->m_banDir;
3545 
3546  QString banner_file;
3547 
3548  if (metadata->GetBanner().isEmpty())
3549  {
3550  if (GetLocalVideoImage(inetref, filename,
3551  banner_dirs, banner_file, title,
3552  season, host, "Banners", episode))
3553  {
3554  metadata->SetBanner(banner_file);
3555  OnVideoImageSetDone(metadata);
3556  }
3557  }
3558 
3559  QStringList screenshot_dirs;
3560  screenshot_dirs += m_d->m_sshotDir;
3561 
3562  QString screenshot_file;
3563 
3564  if (metadata->GetScreenshot().isEmpty())
3565  {
3566  if (GetLocalVideoImage(inetref, filename,
3567  screenshot_dirs, screenshot_file, title,
3568  season, host, "Screenshots", episode,
3569  true))
3570  {
3571  metadata->SetScreenshot(screenshot_file);
3572  OnVideoImageSetDone(metadata);
3573  }
3574  }
3575 }
3576 
3578 {
3579  if (!lookup)
3580  return;
3581 
3582  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3583 
3584  if (!metadata)
3585  return;
3586 
3587  dismissFetchDialog(metadata, true);
3588  metadata->SetTitle(lookup->GetTitle());
3589  metadata->SetSubtitle(lookup->GetSubtitle());
3590 
3591  if (metadata->GetTagline().isEmpty())
3592  metadata->SetTagline(lookup->GetTagline());
3593  if (metadata->GetYear() == 1895 || metadata->GetYear() == 0)
3594  metadata->SetYear(lookup->GetYear());
3595  if (metadata->GetReleaseDate() == QDate())
3596  metadata->SetReleaseDate(lookup->GetReleaseDate());
3597  if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN ||
3598  metadata->GetDirector().isEmpty())
3599  {
3600  QList<PersonInfo> director = lookup->GetPeople(kPersonDirector);
3601  if (director.count() > 0)
3602  metadata->SetDirector(director.takeFirst().name);
3603  }
3604  if (metadata->GetStudio().isEmpty())
3605  {
3606  QStringList studios = lookup->GetStudios();
3607  if (studios.count() > 0)
3608  metadata->SetStudio(studios.takeFirst());
3609  }
3610  if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT ||
3611  metadata->GetPlot().isEmpty())
3612  metadata->SetPlot(lookup->GetDescription());
3613  if (metadata->GetUserRating() == 0)
3614  metadata->SetUserRating(lookup->GetUserRating());
3615  if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
3616  metadata->SetRating(lookup->GetCertification());
3617  if (metadata->GetLength() == 0min)
3618  metadata->SetLength(lookup->GetRuntime());
3619  if (metadata->GetSeason() == 0)
3620  metadata->SetSeason(lookup->GetSeason());
3621  if (metadata->GetEpisode() == 0)
3622  metadata->SetEpisode(lookup->GetEpisode());
3623  if (metadata->GetHomepage().isEmpty())
3624  metadata->SetHomepage(lookup->GetHomepage());
3625 
3626  metadata->SetInetRef(lookup->GetInetref());
3627 
3628  m_d->AutomaticParentalAdjustment(metadata);
3629 
3630  // Cast
3631  QList<PersonInfo> actors = lookup->GetPeople(kPersonActor);
3632  QList<PersonInfo> gueststars = lookup->GetPeople(kPersonGuestStar);
3633 
3634  for (const auto & name : qAsConst(gueststars))
3635  actors.append(name);
3636 
3638  QStringList cl;
3639 
3640  for (const auto & person : qAsConst(actors))
3641  cl.append(person.name);
3642 
3643  for (const auto & name : qAsConst(cl))
3644  {
3645  QString cn = name.trimmed();
3646  if (!cn.isEmpty())
3647  {
3648  cast.push_back(VideoMetadata::cast_list::
3649  value_type(-1, cn));
3650  }
3651  }
3652 
3653  metadata->SetCast(cast);
3654 
3655  // Genres
3656  VideoMetadata::genre_list video_genres;
3657  QStringList genres = lookup->GetCategories();
3658 
3659  for (const auto & name : qAsConst(genres))
3660  {
3661  QString genre_name = name.trimmed();
3662  if (!genre_name.isEmpty())
3663  {
3664  video_genres.push_back(
3665  VideoMetadata::genre_list::value_type(-1, genre_name));
3666  }
3667  }
3668 
3669  metadata->SetGenres(video_genres);
3670 
3671  // Countries
3672  VideoMetadata::country_list video_countries;
3673  QStringList countries = lookup->GetCountries();
3674 
3675  for (const auto & name : qAsConst(countries))
3676  {
3677  QString country_name = name.trimmed();
3678  if (!country_name.isEmpty())
3679  {
3680  video_countries.push_back(
3681  VideoMetadata::country_list::value_type(-1,
3682  country_name));
3683  }
3684  }
3685 
3686  metadata->SetCountries(video_countries);
3687  metadata->SetProcessed(true);
3688 
3689  metadata->UpdateDatabase();
3690 
3691  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3692  if (item != nullptr)
3693  UpdateItem(item);
3694 
3695  StartVideoImageSet(metadata);
3696 }
3697 
3699 {
3700  if (!m_d->m_scanner)
3701  m_d->m_scanner = new VideoScanner();
3704 }
3705 
3707 {
3708  QString message = tr("There are no videos in the database, would you like "
3709  "to scan your video directories now?");
3710  auto *dialog = new MythConfirmationDialog(m_popupStack, message, true);
3711  dialog->SetReturnEvent(this, "scanprompt");
3712  if (dialog->Create())
3713  m_popupStack->AddScreen(dialog);
3714  else
3715  delete dialog;
3716 }
3717 
3718 #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:780
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:1803
MythUIButtonList::GetItemAt
MythUIButtonListItem * GetItemAt(int pos) const
Definition: mythuibuttonlist.cpp:1673
mythuibuttontree.h
mythuimetadataresults.h
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:315
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:771
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:2500
videometadatasettings.h
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
VideoDialog::OnVideoImageSetDone
void OnVideoImageSetDone(VideoMetadata *metadata)
Definition: videodlg.cpp:3248
VideoDialogPrivate::parental_level_map
std::list< std::pair< QString, ParentalLevel::Level > > parental_level_map
Definition: videodlg.cpp:675
VideoDialog::playVideoAlt
void playVideoAlt()
Play the selected item in an alternate player.
Definition: videodlg.cpp:2947
mythuitext.h
WatchedToState
QString WatchedToState(bool watched)
Definition: videoutils.cpp:272
VideoDialogPrivate::AutomaticParentalAdjustment
void AutomaticParentalAdjustment(VideoMetadata *metadata)
Definition: videodlg.cpp:741
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:644
VideoDialog::CreateSettingsMenu
MythMenu * CreateSettingsMenu()
Create a MythMenu for MythVideo Settings.
Definition: videodlg.cpp:2441
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:3499
FileAssociations::getExtensionIgnoreList
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
Definition: dbaccess.cpp:811
VideoDialog::playTrailer
void playTrailer()
Play the trailer associated with the selected item.
Definition: videodlg.cpp:3076
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:2472
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:784
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:1369
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:427
VideoDialogPrivate::m_altPlayerEnabled
bool m_altPlayerEnabled
Definition: videodlg.cpp:783
VideoDialog::SwitchManager
void SwitchManager()
Switch to Video Manager View.
Definition: videodlg.cpp:2715
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:769
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:968
VideoDialog::refreshData
void refreshData()
Reloads the tree without invalidating the data.
Definition: videodlg.cpp:1061
ItemDetailPopup::Exists
static bool Exists()
Definition: videodlg.cpp:571
MythGenericTree::getInt
int getInt() const
Definition: mythgenerictree.h:73
MythUISearchDialog::haveResult
void haveResult(QString)
MythUIBusyDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:32
DialogCompletionEvent::kEventType
static Type kEventType
Definition: mythdialogbox.h:57
ImageDLFailureEvent::kEventType
static Type kEventType
Definition: metadataimagedownload.h:67
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:758
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:2733
VideoDialogPrivate::m_treeLoaded
bool m_treeLoaded
Definition: videodlg.cpp:778
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:828
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:2008
VideoDialog::SwitchVideoInsertDateGroup
void SwitchVideoInsertDateGroup()
Switch to Insert Date browse mode.
Definition: videodlg.cpp:2796
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:2654
VideoDialog::ShowHomepage
void ShowHomepage()
Definition: videodlg.cpp:2892
VideoMetadataListManager::byFilename
VideoMetadataPtr byFilename(const QString &file_name) const
Definition: videometadatalistmanager.cpp:171
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
MetadataFactoryNoResult::kEventType
static Type kEventType
Definition: metadatafactory.h:65
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:2570
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
MetadataFactoryMultiResult::kEventType
static Type kEventType
Definition: metadatafactory.h:29
MetadataLookup::GetCertification
QString GetCertification() const
Definition: metadatacommon.h:335
mythuistatetype.h
ItemDetailPopup::m_listManager
const VideoMetadataListManager & m_listManager
Definition: videodlg.cpp:664
VideoDialogPrivate::m_scanner
VideoScanner * m_scanner
Definition: videodlg.cpp:793
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:1048
VideoDialogPrivate::~VideoDialogPrivate
~VideoDialogPrivate()
Definition: videodlg.cpp:730
build_compdb.file
file
Definition: build_compdb.py:55
VideoDialog::GetSavedVideoList
static VideoListDeathDelayPtr & GetSavedVideoList()
Definition: videodlg.cpp:843
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:645
VideoMetadata::SetShowLevel
void SetShowLevel(ParentalLevel::Level showLevel)
Definition: videometadata.cpp:1811
VideoListDeathDelay::VideoListDeathDelay
VideoListDeathDelay(const VideoDialog::VideoListPtr &toSave)
Definition: videodlg.cpp:821
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:3414
VideoDialog::CreateViewMenu
MythMenu * CreateViewMenu()
Create a MythMenu for MythVideo Views.
Definition: videodlg.cpp:2405
VideoMetadata::GetScreenshot
const QString & GetScreenshot() const
Definition: videometadata.cpp:1871
VideoDialog::SwitchVideoUserRatingGroup
void SwitchVideoUserRatingGroup()
Switch to User Rating browse mode.
Definition: videodlg.cpp:2787
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:667
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:785
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:1489
VideoDialog::shiftParental
void shiftParental(int amount)
Shift the parental level for the library by an integer amount.
Definition: videodlg.cpp:3108
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:585
VideoDialogPrivate::m_savedPtr
static VideoDialog::VideoListDeathDelayPtr m_savedPtr
Definition: videodlg.cpp:767
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:615
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:1638
VideoDialog::GetItemByMetadata
virtual MythUIButtonListItem * GetItemByMetadata(VideoMetadata *metadata)
Definition: videodlg.cpp:3271
videofilter.h
VideoDialog::searchComplete
void searchComplete(const QString &string)
After using incremental search, move to the selected item.
Definition: videodlg.cpp:2066
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:833
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
VideoDialog::SwitchVideoTVMovieGroup
void SwitchVideoTVMovieGroup()
Switch to Television/Movie browse mode.
Definition: videodlg.cpp:2805
VideoDialog::GetScreenshot
static QString GetScreenshot(MythGenericTree *node)
Find the Screenshot for a given node.
Definition: videodlg.cpp:1763
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:3043
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:1838
VideoDialog::scanFinished
void scanFinished(bool dbChanged)
Definition: videodlg.cpp:1076
VideoMetadata::GetFilename
const QString & GetFilename() const
Definition: videometadata.cpp:1816
VideoDialog::SwitchBrowse
void SwitchBrowse()
Switch to Browser View.
Definition: videodlg.cpp:2706
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:3367
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:1104
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:2140
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:1352
VideoDialogPrivate::m_isFlatList
bool m_isFlatList
Definition: videodlg.cpp:782
remotefile.h
VideoDialogPrivate::m_parentalLevel
ParentalLevelNotifyContainer m_parentalLevel
Definition: videodlg.cpp:764
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:663
hardwareprofile.config.p
p
Definition: config.py:33
VideoDialog::VideoSearch
void VideoSearch()
Definition: videodlg.h:99
VideoDialog::PromptToScan
void PromptToScan()
Definition: videodlg.cpp:3706
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:2751
MetadataLookup::GetData
QVariant GetData() const
Definition: metadatacommon.h:288
menu
static MythThemedMenu * menu
Definition: mythtv-setup.cpp:58
VideoDialog::SwitchTree
void SwitchTree()
Switch to Tree (List) View.
Definition: videodlg.cpp:2688
kLookupData
@ kLookupData
Definition: metadatacommon.h:29
VideoDialog::ShowCastDialog
void ShowCastDialog()
Display the Cast if the selected item.
Definition: videodlg.cpp:2882
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:98
VideoDialog::DLG_GALLERY
@ DLG_GALLERY
Definition: videodlg.h:37
MetadataFactorySingleResult::kEventType
static Type kEventType
Definition: metadatafactory.h:47
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:3261
VideoDialogPrivate::m_banDir
QString m_banDir
Definition: videodlg.cpp:792
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:1042
VideoDialog::m_mainStack
MythScreenStack * m_mainStack
Definition: videodlg.h:192
VideoListDeathDelayPrivate::m_savedList
VideoDialog::VideoListPtr m_savedList
Definition: videodlg.cpp:818
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:2104
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:2760
MetadataLookup::GetCountries
QStringList GetCountries() const
Definition: metadatacommon.h:336
VideoDialog::SetCurrentNode
void SetCurrentNode(MythGenericTree *node)
Switch to a given MythGenericTree node.
Definition: videodlg.cpp:2164
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
VideoDialog::SwitchVideoFolderGroup
void SwitchVideoFolderGroup()
Switch to Folder (filesystem) browse mode.
Definition: videodlg.cpp:2724
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:2814
VideoDialog::SwitchVideoCastGroup
void SwitchVideoCastGroup()
Switch to Cast browse mode.
Definition: videodlg.cpp:2778
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:3099
VideoDialog::BRS_FOLDER
@ BRS_FOLDER
Definition: videodlg.h:40
VideoDialog::RemoveVideo
void RemoveVideo()
Definition: videodlg.cpp:3432
MetadataLookup::GetPeople
QList< PersonInfo > GetPeople(PeopleType type) const
Definition: metadatacommon.cpp:314
MetadataLookup::GetYear
uint GetYear() const
Definition: metadatacommon.h:349
VideoDialog::ToggleProcess
void ToggleProcess()
Definition: videodlg.cpp:2589
VideoDialog::handleDynamicDirSelect
void handleDynamicDirSelect(MythGenericTree *node)
Request the latest metadata for a folder.
Definition: videodlg.cpp:2642
VideoDialog::CreateInfoMenu
MythMenu * CreateInfoMenu()
Create a MythMenu for Info pertaining to the selected item.
Definition: videodlg.cpp:2543
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:2052
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:3698
PlotDialog
Definition: videopopups.h:25
VideoDialog::ShowExtensionSettings
void ShowExtensionSettings()
Pop up a MythUI Menu for MythVideo filte Type Settings.
Definition: videodlg.cpp:2486
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:54
ParentalLevelChangeChecker::SigResultReady
void SigResultReady(bool passwordValid, ParentalLevel::Level newLevel)
VideoDialog::Create
bool Create() override
Definition: videodlg.cpp:901
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:910
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:2325
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:1113
VideoListDeathDelayPrivate::VideoListDeathDelayPrivate
VideoListDeathDelayPrivate(const VideoDialog::VideoListPtr &toSave)
Definition: videodlg.cpp:807
VideoDialog::SwitchVideoCategoryGroup
void SwitchVideoCategoryGroup()
Switch to Category browse mode.
Definition: videodlg.cpp:2742
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:867
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:3154
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:904
MetadataLookup::GetCategories
QStringList GetCategories() const
Definition: metadatacommon.h:301
VideoListDeathDelayPrivate
Definition: videodlg.cpp:804
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3315
VideoDialog::popupClosed
void popupClosed(const QString &which, int result)
Definition: videodlg.cpp:2390
FileAssociations::getFileAssociation
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:831
VideoDialog::UpdatePosition
void UpdatePosition()
Called after the screen is created by MythScreenStack.
Definition: videodlg.cpp:2176
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:1968
VideoPlayerCommand::AltPlayerFor
static VideoPlayerCommand AltPlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:362
ItemDetailPopup::OnKeyAction
bool OnKeyAction(const QStringList &actions)
Definition: videodlg.cpp:628
MetadataResultsDialog::haveResult
void haveResult(RefCountHandler< MetadataLookup >)
ItemDetailPopup
Definition: videodlg.cpp:566
VideoDialog::VideoDialog
VideoDialog(MythScreenStack *lparent, const QString &lname, const VideoListPtr &video_list, DialogType type, BrowseType browse)
Definition: videodlg.cpp:848
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:2632
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:404
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:677
VideoDialog::dtLast
@ dtLast
Definition: videodlg.h:38
VideoDialogPrivate::m_currentNode
MythGenericTree * m_currentNode
Definition: videodlg.cpp:776
VideoDialog::reloadData
void reloadData()
Reloads the tree after having invalidated the data.
Definition: videodlg.cpp:1103
VideoDialogPrivate::m_videoList
VideoListPtr m_videoList
Definition: videodlg.cpp:773
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:578
ItemDetailPopup::OnDone
void OnDone()
Definition: videodlg.cpp:620
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:2458
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:781
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:672
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:3118
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:3577
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:662
MythCoreContext::ClearBackendServerPortCache
static void ClearBackendServerPortCache()
Definition: mythcorecontext.cpp:1069
MythGenericTree
Definition: mythgenerictree.h:27
VideoDialog::ToggleWatched
void ToggleWatched()
Definition: videodlg.cpp:3351
VideoDialog::UpdateText
void UpdateText(MythUIButtonListItem *item)
Update the visible text values for a given ButtonListItem.
Definition: videodlg.cpp:2193
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:3135
VideoDialog::OnParentalChange
void OnParentalChange(int amount)
Definition: videodlg.cpp:3396
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1108
VideoListDeathDelayPrivate::GetSaved
VideoDialog::VideoListPtr GetSaved()
Definition: videodlg.cpp:812
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:122
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:1986
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:84
metadatafactory.h
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:791
VideoDialogPrivate::m_ratingToPl
parental_level_map m_ratingToPl
Definition: videodlg.cpp:799
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
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:85
VideoDialog::SavePosition
void SavePosition(void)
Definition: videodlg.cpp:877
VideoDialog::fetchVideos
void fetchVideos()
Build the buttonlist/tree.
Definition: videodlg.cpp:1313
VideoDialogPrivate::m_rootNode
MythGenericTree * m_rootNode
Definition: videodlg.cpp:775
VideoMetadata::GetID
unsigned int GetID() const
Definition: videometadata.cpp:1736
VideoDialog::SwitchGallery
void SwitchGallery()
Switch to Gallery View.
Definition: videodlg.cpp:2697
VideoMetadata::GetTitle
const QString & GetTitle() const
Definition: videometadata.cpp:1546
mythuibutton.h
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:320
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:2936
VideoListDeathDelay::OnTimeUp
void OnTimeUp()
Definition: videodlg.cpp:838
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:2959
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:789
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:666
VideoDialog::SwitchVideoStudioGroup
void SwitchVideoStudioGroup()
Switch to Studio browse mode.
Definition: videodlg.cpp:2769
VideoDialog::ResetMetadata
void ResetMetadata()
Definition: videodlg.cpp:3486
VideoDialog::OnRemoveVideo
void OnRemoveVideo(bool dodelete)
Definition: videodlg.cpp:3451
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:879
VideoDialog::ToggleFlatView
void ToggleFlatView()
Toggle Flat View.
Definition: videodlg.cpp:2617
VideoMetadata::Reset
void Reset()
Resets to default metadata.
Definition: videometadata.cpp:2004
MythMainWindow::AllowInput
void AllowInput(bool Allow)
Definition: mythmainwindow.cpp:1519
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:676
VideoDialog::UpdateItem
void UpdateItem(MythUIButtonListItem *item)
Update the visible representation of a MythUIButtonListItem.
Definition: videodlg.cpp:1220
VideoDialogPrivate::VideoDialogPrivate
VideoDialogPrivate(const VideoListPtr &videoList, VideoDialog::DialogType type, VideoDialog::BrowseType browse)
Definition: videodlg.cpp:686
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:796
VideoDialogPrivate::m_autoMeta
bool m_autoMeta
Definition: videodlg.cpp:787
VideoDialog::DisplayMenu
void DisplayMenu()
Pop up a MythUI Menu for MythVideo Global Functions. Bound to MENU.
Definition: videodlg.cpp:2363
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:2260
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:2605
VideoDialog::m_videoButtonList
MythUIButtonList * m_videoButtonList
Definition: videodlg.h:194
VideoDialogPrivate::m_sshotDir
QString m_sshotDir
Definition: videodlg.cpp:790
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:50
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:2844
VideoDialog::GetCoverImage
static QString GetCoverImage(MythGenericTree *node)
A "hunt" for cover art to apply for a folder item.
Definition: videodlg.cpp:1408
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:795
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:1873
MythUIButtonTree::nodeChanged
void nodeChanged(MythGenericTree *node)
VideoDialog::DoItemDetailShow
bool DoItemDetailShow()
Display the Item Detail Popup.
Definition: videodlg.cpp:2858
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:896
sLocation
static const QString sLocation
Definition: videodlg.cpp:59
VideoDialogPrivate::m_switchingLayout
bool m_switchingLayout
Definition: videodlg.cpp:765
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:177
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