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