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  m_d->m_videoList->refreshList(m_d->m_isFileBrowser,
1394  m_d->m_parentalLevel.GetLevel(),
1396  m_d->m_rootNode = m_d->m_videoList->GetTreeRoot();
1397  }
1398 
1399  m_d->m_treeLoaded = true;
1400 
1401  // Move a node down if there is a single directory item here...
1402  if (m_d->m_rootNode->childCount() == 1)
1403  {
1405  if (node->getInt() == kSubFolder && node->childCount() > 1)
1406  m_d->m_rootNode = node;
1407  else if (node->getInt() == kUpFolder)
1408  m_d->m_treeLoaded = false;
1409  }
1410  else if (m_d->m_rootNode->childCount() == 0)
1411  {
1412  m_d->m_treeLoaded = false;
1413  }
1414 
1415  if (!m_d->m_currentNode || m_d->m_rootNode != oldroot)
1417 }
1418 
1423 QString VideoDialog::RemoteImageCheck(const QString& host, const QString& filename)
1424 {
1425  QString result = "";
1426 #if 0
1427  LOG(VB_GENERAL, LOG_DEBUG, QString("RemoteImageCheck(%1)").arg(filename));
1428 #endif
1429 
1430  QStringList dirs = GetVideoDirsByHost(host);
1431 
1432  if (!dirs.isEmpty())
1433  {
1434  for (const auto & dir : std::as_const(dirs))
1435  {
1436  QUrl sgurl = dir;
1437  QString path = sgurl.path();
1438 
1439  QString fname = QString("%1/%2").arg(path, filename);
1440 
1441  QStringList list( QString("QUERY_SG_FILEQUERY") );
1442  list << host;
1443  list << "Videos";
1444  list << fname;
1445 
1446  bool ok = gCoreContext->SendReceiveStringList(list);
1447 
1448  if (!ok || list.at(0).startsWith("SLAVE UNREACHABLE"))
1449  {
1450  LOG(VB_GENERAL, LOG_WARNING,
1451  QString("Backend : %1 currently Unreachable. Skipping "
1452  "this one.") .arg(host));
1453  break;
1454  }
1455 
1456  if ((!list.isEmpty()) && (list.at(0) == fname))
1457  result = generate_file_url("Videos", host, filename);
1458 
1459  if (!result.isEmpty())
1460  {
1461 #if 0
1462  LOG(VB_GENERAL, LOG_DEBUG,
1463  QString("RemoteImageCheck(%1) res :%2: :%3:")
1464  .arg(fname).arg(result).arg(dir));
1465 #endif
1466  break;
1467  }
1468 
1469  }
1470  }
1471 
1472  return result;
1473 }
1474 
1480 {
1481  if (!node)
1482  return {};
1483 
1484  int nodeInt = node->getInt();
1485 
1486  QString icon_file;
1487 
1488  if (nodeInt == kSubFolder) // subdirectory
1489  {
1490  // First validate that the data can be converted
1491  if (!node->GetData().canConvert<TreeNodeData>())
1492  return icon_file;
1493 
1494  // load folder icon
1495  QString folder_path = node->GetData().value<TreeNodeData>().GetPath();
1496  QString host = node->GetData().value<TreeNodeData>().GetHost();
1497  QString prefix = node->GetData().value<TreeNodeData>().GetPrefix();
1498 
1499  if (folder_path.startsWith("myth://"))
1500  folder_path = folder_path.right(folder_path.length()
1501  - folder_path.lastIndexOf("//") - 1);
1502 
1503  QString filename = QString("%1/folder").arg(folder_path);
1504 
1505 #if 0
1506  LOG(VB_GENERAL, LOG_DEBUG,
1507  QString("GetCoverImage host : %1 prefix : %2 file : %3")
1508  .arg(host).arg(prefix).arg(filename));
1509 #endif
1510 
1511  QStringList test_files;
1512  test_files.append(filename + ".png");
1513  test_files.append(filename + ".jpg");
1514  test_files.append(filename + ".jpeg");
1515  test_files.append(filename + ".gif");
1516 
1517  // coverity[auto_causes_copy]
1518  for (auto imagePath : std::as_const(test_files))
1519  {
1520 #if 0
1521  LOG(VB_GENERAL, LOG_DEBUG, QString("Cover check :%1 : ").arg(imagePath));
1522 #endif
1523 
1524  bool foundCover = false;
1525  if (!host.isEmpty())
1526  {
1527  // Strip out any extra /'s
1528  imagePath.replace("//", "/");
1529  prefix.replace("//","/");
1530  imagePath = imagePath.right(imagePath.length() - (prefix.length() + 1));
1531  QString tmpCover = RemoteImageCheck(host, imagePath);
1532 
1533  if (!tmpCover.isEmpty())
1534  {
1535  foundCover = true;
1536  imagePath = tmpCover;
1537  }
1538  }
1539  else
1540  {
1541  foundCover = QFile::exists(imagePath);
1542  }
1543 
1544  if (foundCover)
1545  {
1546  icon_file = imagePath;
1547  break;
1548  }
1549  }
1550 
1551  // If we found nothing, load the first image we find
1552  if (icon_file.isEmpty())
1553  {
1554  QStringList imageTypes { "*.png", "*.jpg", "*.jpeg", "*.gif" };
1555  QStringList fList;
1556 
1557  if (!host.isEmpty())
1558  {
1559  // TODO: This can likely get a little cleaner
1560 
1561  QStringList dirs = GetVideoDirsByHost(host);
1562 
1563  if (!dirs.isEmpty())
1564  {
1565  for (const auto & dir : std::as_const(dirs))
1566  {
1567  QUrl sgurl = dir;
1568  QString path = sgurl.path();
1569 
1570  QString subdir = folder_path.right(folder_path.length() - (prefix.length() + 1));
1571 
1572  path = path + "/" + subdir;
1573 
1574  QStringList tmpList;
1575  bool ok = RemoteGetFileList(host, path, &tmpList, "Videos");
1576 
1577  if (ok)
1578  {
1579  for (const auto & pattern : std::as_const(imageTypes))
1580  {
1581  auto rePattern = QRegularExpression::wildcardToRegularExpression(pattern);
1582  QRegularExpression rx {
1583  rePattern.mid(2,rePattern.size()-4), // Remove anchors
1584  QRegularExpression::CaseInsensitiveOption };
1585  QStringList matches = tmpList.filter(rx);
1586  if (!matches.isEmpty())
1587  {
1588  fList.clear();
1589  fList.append(subdir + "/" + matches.at(0).split("::").at(1));
1590  break;
1591  }
1592  }
1593 
1594  break;
1595  }
1596  }
1597  }
1598 
1599  }
1600  else
1601  {
1602  QDir vidDir(folder_path);
1603  vidDir.setNameFilters(imageTypes);
1604  fList = vidDir.entryList();
1605  }
1606 
1607  // Take the Coverfile for the first valid node in the dir, if it exists.
1608  if (icon_file.isEmpty())
1609  {
1610  int list_count = node->visibleChildCount();
1611  if (list_count > 0)
1612  {
1613  for (int i = 0; i < list_count; i++)
1614  {
1615  MythGenericTree *subnode = node->getVisibleChildAt(i);
1616  if (subnode)
1617  {
1618  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1619  if (metadata)
1620  {
1621  if (!metadata->GetHost().isEmpty() &&
1622  !metadata->GetCoverFile().startsWith("/"))
1623  {
1624  QString test_file = generate_file_url("Coverart",
1625  metadata->GetHost(), metadata->GetCoverFile());
1626  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1627  !IsDefaultCoverFile(test_file))
1628  {
1629  icon_file = test_file;
1630  break;
1631  }
1632  }
1633  else
1634  {
1635  const QString& test_file = metadata->GetCoverFile();
1636  if (!test_file.isEmpty() &&
1637  !IsDefaultCoverFile(test_file))
1638  {
1639  icon_file = test_file;
1640  break;
1641  }
1642  }
1643  }
1644  }
1645  }
1646  }
1647  }
1648 
1649  if (!fList.isEmpty())
1650  {
1651  if (host.isEmpty())
1652  {
1653  icon_file = QString("%1/%2").arg(folder_path, fList.at(0));
1654  }
1655  else
1656  {
1657  icon_file = generate_file_url("Videos", host, fList.at(0));
1658  }
1659  }
1660  }
1661 
1662  if (!icon_file.isEmpty())
1663  {
1664  LOG(VB_GENERAL, LOG_DEBUG, QString("Found Image : %1 :")
1665  .arg(icon_file));
1666  }
1667  else
1668  {
1669  LOG(VB_GENERAL, LOG_DEBUG,
1670  QString("Could not find folder cover Image : %1 ")
1671  .arg(folder_path));
1672  }
1673  }
1674  else
1675  {
1676  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1677 
1678  if (metadata)
1679  {
1680  if (metadata->IsHostSet() &&
1681  !metadata->GetCoverFile().startsWith("/") &&
1682  !IsDefaultCoverFile(metadata->GetCoverFile()))
1683  {
1684  icon_file = generate_file_url("Coverart", metadata->GetHost(),
1685  metadata->GetCoverFile());
1686  }
1687  else
1688  {
1689  icon_file = metadata->GetCoverFile();
1690  }
1691  }
1692  }
1693 
1694  if (IsDefaultCoverFile(icon_file))
1695  icon_file.clear();
1696 
1697  return icon_file;
1698 }
1699 
1711 QString VideoDialog::GetFirstImage(MythGenericTree *node, const QString& type,
1712  const QString& gpnode, int levels)
1713 {
1714  if (!node || type.isEmpty())
1715  return {};
1716 
1717  QString icon_file;
1718 
1719  int list_count = node->visibleChildCount();
1720  if (list_count > 0)
1721  {
1722  QList<MythGenericTree *> subDirs;
1723  static constexpr int maxRecurse { 1 };
1724 
1725  for (int i = 0; i < list_count; i++)
1726  {
1727  MythGenericTree *subnode = node->getVisibleChildAt(i);
1728  if (subnode)
1729  {
1730  if (subnode->childCount() > 0)
1731  subDirs << subnode;
1732 
1733  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
1734  if (metadata)
1735  {
1736  QString test_file;
1737  const QString& host = metadata->GetHost();
1738  const QString& title = metadata->GetTitle();
1739 
1740  if (type == "Coverart" && !host.isEmpty() &&
1741  !metadata->GetCoverFile().startsWith("/"))
1742  {
1743  test_file = generate_file_url("Coverart",
1744  host, metadata->GetCoverFile());
1745  }
1746  else if (type == "Coverart")
1747  {
1748  test_file = metadata->GetCoverFile();
1749  }
1750 
1751  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1752  !IsDefaultCoverFile(test_file) && (gpnode.isEmpty() ||
1753  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1754  {
1755  icon_file = test_file;
1756  break;
1757  }
1758 
1759  if (type == "Fanart" && !host.isEmpty() &&
1760  !metadata->GetFanart().startsWith("/"))
1761  {
1762  test_file = generate_file_url("Fanart",
1763  host, metadata->GetFanart());
1764  }
1765  else if (type == "Fanart")
1766  {
1767  test_file = metadata->GetFanart();
1768  }
1769 
1770  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1771  test_file != VIDEO_FANART_DEFAULT && (gpnode.isEmpty() ||
1772  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1773  {
1774  icon_file = test_file;
1775  break;
1776  }
1777 
1778  if (type == "Banners" && !host.isEmpty() &&
1779  !metadata->GetBanner().startsWith("/"))
1780  {
1781  test_file = generate_file_url("Banners",
1782  host, metadata->GetBanner());
1783  }
1784  else if (type == "Banners")
1785  {
1786  test_file = metadata->GetBanner();
1787  }
1788 
1789  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1790  test_file != VIDEO_BANNER_DEFAULT && (gpnode.isEmpty() ||
1791  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1792  {
1793  icon_file = test_file;
1794  break;
1795  }
1796 
1797  if (type == "Screenshots" && !host.isEmpty() &&
1798  !metadata->GetScreenshot().startsWith("/"))
1799  {
1800  test_file = generate_file_url("Screenshots",
1801  host, metadata->GetScreenshot());
1802  }
1803  else if (type == "Screenshots")
1804  {
1805  test_file = metadata->GetScreenshot();
1806  }
1807 
1808  if (!test_file.endsWith("/") && !test_file.isEmpty() &&
1809  test_file != VIDEO_SCREENSHOT_DEFAULT && (gpnode.isEmpty() ||
1810  (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1811  {
1812  icon_file = test_file;
1813  break;
1814  }
1815  }
1816  }
1817  }
1818  if (icon_file.isEmpty() && !subDirs.isEmpty())
1819  {
1820  QString test_file;
1821  int subDirCount = subDirs.count();
1822  for (int i = 0; i < subDirCount; i ++)
1823  {
1824  if (levels < maxRecurse)
1825  {
1826  test_file = GetFirstImage(subDirs[i], type,
1827  node->GetText(), levels + 1);
1828  if (!test_file.isEmpty())
1829  {
1830  icon_file = test_file;
1831  break;
1832  }
1833  }
1834  }
1835  }
1836  }
1837  return icon_file;
1838 }
1839 
1845 {
1846  const int nodeInt = node->getInt();
1847 
1848  QString icon_file;
1849 
1850  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1851  {
1852  icon_file = VIDEO_SCREENSHOT_DEFAULT;
1853  }
1854  else
1855  {
1856  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1857 
1858  if (metadata)
1859  {
1860  if (metadata->IsHostSet() &&
1861  !metadata->GetScreenshot().startsWith("/") &&
1862  !metadata->GetScreenshot().isEmpty())
1863  {
1864  icon_file = generate_file_url("Screenshots", metadata->GetHost(),
1865  metadata->GetScreenshot());
1866  }
1867  else
1868  {
1869  icon_file = metadata->GetScreenshot();
1870  }
1871  }
1872  }
1873 
1874  if (IsDefaultScreenshot(icon_file))
1875  icon_file.clear();
1876 
1877  return icon_file;
1878 }
1879 
1885 {
1886  const int nodeInt = node->getInt();
1887 
1888  if (nodeInt == kSubFolder || nodeInt == kUpFolder)
1889  return {};
1890 
1891  QString icon_file;
1892  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1893 
1894  if (metadata)
1895  {
1896  if (metadata->IsHostSet() &&
1897  !metadata->GetBanner().startsWith("/") &&
1898  !metadata->GetBanner().isEmpty())
1899  {
1900  icon_file = generate_file_url("Banners", metadata->GetHost(),
1901  metadata->GetBanner());
1902  }
1903  else
1904  {
1905  icon_file = metadata->GetBanner();
1906  }
1907 
1908  if (IsDefaultBanner(icon_file))
1909  icon_file.clear();
1910  }
1911 
1912  return icon_file;
1913 }
1914 
1920 {
1921  const int nodeInt = node->getInt();
1922 
1923  if (nodeInt == kSubFolder || nodeInt == kUpFolder) // subdirectory
1924  return {};
1925 
1926  QString icon_file;
1927  const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1928 
1929  if (metadata)
1930  {
1931  if (metadata->IsHostSet() &&
1932  !metadata->GetFanart().startsWith("/") &&
1933  !metadata->GetFanart().isEmpty())
1934  {
1935  icon_file = generate_file_url("Fanart", metadata->GetHost(),
1936  metadata->GetFanart());
1937  }
1938  else
1939  {
1940  icon_file = metadata->GetFanart();
1941  }
1942 
1943  if (IsDefaultFanart(icon_file))
1944  icon_file.clear();
1945  }
1946 
1947  return icon_file;
1948 }
1949 
1954 bool VideoDialog::keyPressEvent(QKeyEvent *levent)
1955 {
1956  if (GetFocusWidget()->keyPressEvent(levent))
1957  return true;
1958 
1959  QStringList actions;
1960  bool handled = GetMythMainWindow()->TranslateKeyPress("Video", levent, actions);
1961 
1962  for (int i = 0; i < actions.size() && !handled; i++)
1963  {
1964  const QString& action = actions[i];
1965  handled = true;
1966 
1967  if (action == "INFO")
1968  {
1970  MythGenericTree *node = GetNodePtrFromButton(item);
1971  if (!m_menuPopup && node->getInt() != kUpFolder)
1972  VideoMenu();
1973  }
1974  else if (action == "INCPARENT")
1975  {
1976  shiftParental(1);
1977  }
1978  else if (action == "DECPARENT")
1979  {
1980  shiftParental(-1);
1981  }
1982  else if (action == "1" || action == "2" ||
1983  action == "3" || action == "4")
1984  {
1986  }
1987  else if (action == "FILTER")
1988  {
1989  ChangeFilter();
1990  }
1991  else if (action == "MENU")
1992  {
1993  if (!m_menuPopup)
1994  DisplayMenu();
1995  }
1996  else if (action == "PLAYALT")
1997  {
1998  if (!m_menuPopup && GetMetadata(GetItemCurrent()) &&
2000  playVideoAlt();
2001  }
2002  else if (action == "DOWNLOADDATA")
2003  {
2005  VideoSearch();
2006  }
2007  else if (action == "INCSEARCH")
2008  {
2009  searchStart();
2010  }
2011  else if (action == "ITEMDETAIL")
2012  {
2013  DoItemDetailShow();
2014  }
2015  else if (action == "DELETE")
2016  {
2018  RemoveVideo();
2019  }
2020  else if (action == "EDIT" && !m_menuPopup)
2021  {
2022  EditMetadata();
2023  }
2024  else if (action == "ESCAPE")
2025  {
2026  if (m_d->m_type != DLG_TREE
2027  && !GetMythMainWindow()->IsExitingToMain()
2028  && m_d->m_currentNode != m_d->m_rootNode)
2029  handled = goBack();
2030  else
2031  handled = false;
2032  }
2033  else
2034  {
2035  handled = false;
2036  }
2037  }
2038 
2039  if (!handled)
2040  {
2041  handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", levent,
2042  actions);
2043 
2044  for (int i = 0; i < actions.size() && !handled; i++)
2045  {
2046  const QString& action = actions[i];
2047  if (action == "PLAYBACK")
2048  {
2049  handled = true;
2050  playVideo();
2051  }
2052  }
2053  }
2054 
2055  if (!handled && MythScreenType::keyPressEvent(levent))
2056  handled = true;
2057 
2058  return handled;
2059 }
2060 
2065 void VideoDialog::createBusyDialog(const QString &title)
2066 {
2067  if (m_busyPopup)
2068  return;
2069 
2070  const QString& message = title;
2071 
2072  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
2073  "mythvideobusydialog");
2074 
2075  if (m_busyPopup->Create())
2077 }
2078 
2084 {
2085  if (m_d->m_notifications.contains(metadata->GetHash()))
2086  return;
2087 
2088  int id = GetNotificationCenter()->Register(this);
2089  m_d->m_notifications[metadata->GetHash()] = id;
2090 
2091  QString msg = tr("Fetching details for %1")
2092  .arg(metadata->GetTitle());
2093  QString desc;
2094  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
2095  {
2096  desc = tr("Season %1, Episode %2")
2097  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2098  }
2099  MythBusyNotification n(msg, sLocation, desc);
2100  n.SetId(id);
2101  n.SetParent(this);
2103 }
2104 
2106 {
2107  if (!metadata || !m_d->m_notifications.contains(metadata->GetHash()))
2108  return;
2109 
2110  int id = m_d->m_notifications[metadata->GetHash()];
2111  m_d->m_notifications.remove(metadata->GetHash());
2112 
2113  QString msg;
2114  if (ok)
2115  {
2116  msg = tr("Retrieved details for %1").arg(metadata->GetTitle());
2117  }
2118  else
2119  {
2120  msg = tr("Failed to retrieve details for %1").arg(metadata->GetTitle());
2121  }
2122  QString desc;
2123  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
2124  {
2125  desc = tr("Season %1, Episode %2")
2126  .arg(metadata->GetSeason()).arg(metadata->GetEpisode());
2127  }
2128  if (ok)
2129  {
2130  MythCheckNotification n(msg, sLocation, desc);
2131  n.SetId(id);
2132  n.SetParent(this);
2134  }
2135  else
2136  {
2137  MythErrorNotification n(msg, sLocation, desc);
2138  n.SetId(id);
2139  n.SetParent(this);
2141  }
2142  GetNotificationCenter()->UnRegister(this, id);
2143 }
2144 
2149 void VideoDialog::createOkDialog(const QString& title)
2150 {
2151  const QString& message = title;
2152 
2153  auto *okPopup = new MythConfirmationDialog(m_popupStack, message, false);
2154 
2155  if (okPopup->Create())
2156  m_popupStack->AddScreen(okPopup);
2157 }
2158 
2163 void VideoDialog::searchComplete(const QString& string)
2164 {
2165  LOG(VB_GENERAL, LOG_DEBUG, QString("Jumping to: %1").arg(string));
2166 
2168  QList<MythGenericTree*> *children = nullptr;
2169  QMap<int, QString> idTitle;
2170 
2171  if (parent && m_d->m_type == DLG_TREE)
2172  children = parent->getAllChildren();
2173  else
2174  children = m_d->m_currentNode->getAllChildren();
2175 
2176  for (auto * child : std::as_const(*children))
2177  {
2178  QString title = child->GetText();
2179  int id = child->getPosition();
2180  idTitle.insert(id, title);
2181  }
2182 
2183  if (m_d->m_type == DLG_TREE)
2184  {
2186  MythGenericTree *new_node = dlgParent->getChildAt(idTitle.key(string));
2187  if (new_node)
2188  {
2189  m_videoButtonTree->SetCurrentNode(new_node);
2191  }
2192  }
2193  else
2194  {
2195  m_videoButtonList->SetItemCurrent(idTitle.key(string));
2196  }
2197 }
2198 
2204 {
2206 
2207  QStringList childList;
2208  QList<MythGenericTree*> *children = nullptr;
2209  if (parent && m_d->m_type == DLG_TREE)
2210  children = parent->getAllChildren();
2211  else
2212  children = m_d->m_currentNode->getAllChildren();
2213 
2214  for (auto * child : std::as_const(*children))
2215  {
2216  childList << child->GetText();
2217  }
2218 
2219  MythScreenStack *popupStack =
2220  GetMythMainWindow()->GetStack("popup stack");
2221  auto *searchDialog = new MythUISearchDialog(popupStack,
2222  tr("Video Search"), childList, false, "");
2223 
2224  if (searchDialog->Create())
2225  {
2226  connect(searchDialog, &MythUISearchDialog::haveResult,
2228 
2229  popupStack->AddScreen(searchDialog);
2230  }
2231  else
2232  {
2233  delete searchDialog;
2234  }
2235 }
2236 
2242 {
2243  bool handled = false;
2244 
2245  if (m_d->m_currentNode != m_d->m_rootNode)
2246  {
2247  MythGenericTree *lparent = m_d->m_currentNode->getParent();
2248  if (lparent)
2249  {
2250  SetCurrentNode(lparent);
2251 
2252  handled = true;
2253  }
2254  }
2255 
2256  loadData();
2257 
2258  return handled;
2259 }
2260 
2266 {
2267  if (!node)
2268  return;
2269 
2270  m_d->m_currentNode = node;
2271 }
2272 
2278 {
2280  MythUIButtonList *currentList = ci ? ci->parent() : nullptr;
2281 
2282  if (!currentList)
2283  return;
2284 
2285  CheckedSet(m_positionText, tr("%1 of %2")
2286  .arg(currentList->IsEmpty() ? 0 : currentList->GetCurrentPos() + 1)
2287  .arg(currentList->GetCount()));
2288 }
2289 
2295 {
2296  if (!item)
2297  return;
2298 
2299  VideoMetadata *metadata = GetMetadata(item);
2300  if (!metadata)
2301  return;
2302 
2303  CopyPlaybackStateToUI(m_d->m_playbackState, metadata, item, nullptr);
2304 }
2305 
2311 {
2312  if (!item || !item->isVisible())
2313  return;
2314 
2315  MythUIButtonList *currentList = item->parent();
2316 
2317  if (!currentList)
2318  return;
2319 
2320  VideoMetadata *metadata = GetMetadata(item);
2321 
2322  MythGenericTree *node = GetNodePtrFromButton(item);
2323 
2324  if (!node)
2325  return;
2326 
2327  if (metadata)
2328  {
2329  InfoMap metadataMap;
2330  metadata->toMap(metadataMap);
2331  SetTextFromMap(metadataMap);
2332  }
2333  else
2334  {
2335  InfoMap metadataMap;
2336  ClearMap(metadataMap);
2337  SetTextFromMap(metadataMap);
2338  }
2339 
2340  ScreenCopyDest dest(this);
2341  CopyMetadataToUI(metadata, dest);
2342  CopyPlaybackStateToUI(m_d->m_playbackState, metadata, item, m_d->m_currentNode ? this : nullptr);
2343 
2344  if (node->getInt() == kSubFolder && !metadata)
2345  {
2346  QString cover = GetFirstImage(node, "Coverart");
2347  QString fanart = GetFirstImage(node, "Fanart");
2348  QString banner = GetFirstImage(node, "Banners");
2349  QString screenshot = GetFirstImage(node, "Screenshots");
2350  CheckedSet(m_coverImage, cover);
2351  CheckedSet(m_fanart, fanart);
2352  CheckedSet(m_banner, banner);
2353  CheckedSet(m_screenshot, screenshot);
2354  }
2355 
2356  if (!metadata)
2357  CheckedSet(m_titleText, item->GetText());
2358  UpdatePosition();
2359 
2360  if (m_d->m_currentNode)
2361  {
2363  CheckedSet(this, "foldername", m_d->m_currentNode->GetText());
2364  }
2365 
2366  if (node && node->getInt() == kSubFolder)
2367  CheckedSet(this, "childcount",
2368  QString("%1").arg(node->visibleChildCount()));
2369 
2370  if (node)
2371  node->becomeSelectedChild();
2372 }
2373 
2383 {
2384  if (!gCoreContext->GetBoolSetting("AutomaticSetWatched", false))
2385  return;
2386 
2387  if (!item)
2388  return;
2389 
2390  VideoMetadata *metadata = GetMetadata(item);
2391  if (!metadata)
2392  return;
2393 
2394  auto metadataNew = VideoMetadataListManager::loadOneFromDatabase(metadata->GetID());
2395  if (metadata->GetWatched() != metadataNew->GetWatched())
2396  {
2397  metadata->SetWatched(metadataNew->GetWatched());
2398  item->DisplayState(WatchedToState(metadata->GetWatched()), "watchedstate");
2399  }
2400 }
2401 
2407 {
2408  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2409  QString label;
2410 
2411  if (metadata)
2412  {
2413  if (!metadata->GetSubtitle().isEmpty())
2414  {
2415  label = tr("Video Options\n%1\n%2").arg(metadata->GetTitle(),
2416  metadata->GetSubtitle());
2417  }
2418  else
2419  {
2420  label = tr("Video Options\n%1").arg(metadata->GetTitle());
2421  }
2422  }
2423  else
2424  {
2425  label = tr("Video Options");
2426  }
2427 
2428  auto *menu = new MythMenu(label, this, "actions");
2429 
2431  MythGenericTree *node = GetNodePtrFromButton(item);
2432  if (metadata)
2433  {
2434  if (!metadata->GetTrailer().isEmpty() ||
2435  gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false) ||
2437  menu->AddItem(tr("Play..."), nullptr, CreatePlayMenu());
2438  else
2439  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2440  if (metadata->GetWatched())
2441  menu->AddItem(tr("Mark as Unwatched"), &VideoDialog::ToggleWatched);
2442  else
2443  menu->AddItem(tr("Mark as Watched"), &VideoDialog::ToggleWatched);
2444  menu->AddItem(tr("Video Info"), nullptr, CreateInfoMenu());
2445  if (!m_d->m_notifications.contains(metadata->GetHash()))
2446  {
2447  menu->AddItem(tr("Change Video Details"), nullptr, CreateManageMenu());
2448  }
2449  menu->AddItem(tr("Delete"), &VideoDialog::RemoveVideo);
2450  }
2451  else if (node && node->getInt() != kUpFolder)
2452  {
2453  menu->AddItem(tr("Play Folder"), &VideoDialog::playFolder);
2454  }
2455 
2456 
2457  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2458 
2459  if (m_menuPopup->Create())
2460  {
2463  }
2464  else
2465  {
2466  delete m_menuPopup;
2467  }
2468 }
2469 
2476 {
2477  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2478  QString label;
2479 
2480  if (metadata)
2481  label = tr("Playback Options\n%1").arg(metadata->GetTitle());
2482  else
2483  return nullptr;
2484 
2485  auto *menu = new MythMenu(label, this, "actions");
2486 
2487  menu->AddItem(tr("Play"), &VideoDialog::playVideo);
2488 
2489  if (m_d->m_altPlayerEnabled)
2490  {
2491  menu->AddItem(tr("Play in Alternate Player"), &VideoDialog::playVideoAlt);
2492  }
2493 
2494  if (gCoreContext->GetBoolSetting("mythvideo.TrailersRandomEnabled", false))
2495  {
2496  menu->AddItem(tr("Play With Trailers"), &VideoDialog::playVideoWithTrailers);
2497  }
2498 
2499  QString trailerFile = metadata->GetTrailer();
2500  if (QFile::exists(trailerFile) ||
2501  (!metadata->GetHost().isEmpty() && !trailerFile.isEmpty()))
2502  {
2503  menu->AddItem(tr("Play Trailer"), &VideoDialog::playTrailer);
2504  }
2505 
2506  return menu;
2507 }
2508 
2514 {
2515  QString label = tr("Video Display Menu");
2516 
2517  auto *menu = new MythMenu(label, this, "display");
2518 
2519  menu->AddItem(tr("Scan For Changes"), &VideoDialog::doVideoScan);
2520  menu->AddItem(tr("Retrieve All Details"), qOverload<>(&VideoDialog::VideoAutoSearch));
2521  menu->AddItem(tr("Filter Display"), &VideoDialog::ChangeFilter);
2522  menu->AddItem(tr("Browse By..."), nullptr, CreateMetadataBrowseMenu());
2523  menu->AddItem(tr("Change View"), nullptr, CreateViewMenu());
2524  menu->AddItem(tr("Settings"), nullptr, CreateSettingsMenu());
2525 
2526  m_menuPopup = new MythDialogBox(menu, m_popupStack, "videomenupopup");
2527 
2528  if (m_menuPopup->Create())
2529  {
2532  }
2533  else
2534  {
2535  delete m_menuPopup;
2536  }
2537 }
2538 
2539 // Switch from the display menu to the actions menu on second
2540 // menu press
2541 
2542 void VideoDialog::popupClosed(const QString& which, int result)
2543 {
2544  m_menuPopup = nullptr;
2545 
2546  if (result == -2)
2547  {
2548  if (which == "display")
2549  VideoMenu();
2550  }
2551 }
2552 
2558 {
2559  QString label = tr("Change View");
2560 
2561  auto *menu = new MythMenu(label, this, "view");
2562 
2563  if (!(m_d->m_type & DLG_BROWSER))
2564  menu->AddItem(tr("Switch to Browse View"), &VideoDialog::SwitchBrowse);
2565 
2566  if (!(m_d->m_type & DLG_GALLERY))
2567  menu->AddItem(tr("Switch to Gallery View"), &VideoDialog::SwitchGallery);
2568 
2569  if (!(m_d->m_type & DLG_TREE))
2570  menu->AddItem(tr("Switch to List View"), &VideoDialog::SwitchTree);
2571 
2572  if (!(m_d->m_type & DLG_MANAGER))
2573  menu->AddItem(tr("Switch to Manage View"), &VideoDialog::SwitchManager);
2574 
2575  if (m_d->m_isFlatList)
2576  menu->AddItem(tr("Show Directory Structure"), &VideoDialog::ToggleFlatView);
2577  else
2578  menu->AddItem(tr("Hide Directory Structure"), &VideoDialog::ToggleFlatView);
2579 
2580  if (m_d->m_isFileBrowser)
2581  menu->AddItem(tr("Browse Library (recommended)"), &VideoDialog::ToggleBrowseMode);
2582  else
2583  menu->AddItem(tr("Browse Filesystem (slow)"), &VideoDialog::ToggleBrowseMode);
2584 
2585 
2586  return menu;
2587 }
2588 
2594 {
2595  QString label = tr("Video Settings");
2596 
2597  auto *menu = new MythMenu(label, this, "settings");
2598 
2599  menu->AddItem(tr("Player Settings"), &VideoDialog::ShowPlayerSettings);
2600  menu->AddItem(tr("Metadata Settings"), &VideoDialog::ShowMetadataSettings);
2601  menu->AddItem(tr("File Type Settings"), &VideoDialog::ShowExtensionSettings);
2602 
2603  return menu;
2604 }
2605 
2611 {
2612  auto *ps = new PlayerSettings(m_mainStack, "player settings");
2613 
2614  if (ps->Create())
2615  m_mainStack->AddScreen(ps);
2616  else
2617  delete ps;
2618 }
2619 
2625 {
2626  auto *ms = new MetadataSettings(m_mainStack, "metadata settings");
2627 
2628  if (ms->Create())
2629  m_mainStack->AddScreen(ms);
2630  else
2631  delete ms;
2632 }
2633 
2639 {
2640  auto *fa = new FileAssocDialog(m_mainStack, "fa dialog");
2641 
2642  if (fa->Create())
2643  m_mainStack->AddScreen(fa);
2644  else
2645  delete fa;
2646 }
2647 
2653 {
2654  QString label = tr("Browse By");
2655 
2656  auto *menu = new MythMenu(label, this, "metadata");
2657 
2658  if (m_d->m_groupType != BRS_CAST)
2659  menu->AddItem(tr("Cast"), &VideoDialog::SwitchVideoCastGroup);
2660 
2661  if (m_d->m_groupType != BRS_CATEGORY)
2662  menu->AddItem(tr("Category"), &VideoDialog::SwitchVideoCategoryGroup);
2663 
2664  if (m_d->m_groupType != BRS_INSERTDATE)
2665  menu->AddItem(tr("Date Added"), &VideoDialog::SwitchVideoInsertDateGroup);
2666 
2667  if (m_d->m_groupType != BRS_DIRECTOR)
2668  menu->AddItem(tr("Director"), &VideoDialog::SwitchVideoDirectorGroup);
2669 
2670  if (m_d->m_groupType != BRS_STUDIO)
2671  menu->AddItem(tr("Studio"), &VideoDialog::SwitchVideoStudioGroup);
2672 
2673  if (m_d->m_groupType != BRS_FOLDER)
2674  menu->AddItem(tr("Folder"), &VideoDialog::SwitchVideoFolderGroup);
2675 
2676  if (m_d->m_groupType != BRS_GENRE)
2677  menu->AddItem(tr("Genre"), &VideoDialog::SwitchVideoGenreGroup);
2678 
2679  if (m_d->m_groupType != BRS_TVMOVIE)
2680  menu->AddItem(tr("TV/Movies"), &VideoDialog::SwitchVideoTVMovieGroup);
2681 
2682  if (m_d->m_groupType != BRS_USERRATING)
2683  menu->AddItem(tr("User Rating"), &VideoDialog::SwitchVideoUserRatingGroup);
2684 
2685  if (m_d->m_groupType != BRS_YEAR)
2686  menu->AddItem(tr("Year"), &VideoDialog::SwitchVideoYearGroup);
2687 
2688  return menu;
2689 }
2690 
2696 {
2697  QString label = tr("Video Info");
2698 
2699  auto *menu = new MythMenu(label, this, "info");
2700 
2702  menu->AddItem(tr("View Details"), &VideoDialog::DoItemDetailShow2);
2703 
2704  menu->AddItem(tr("View Full Plot"), &VideoDialog::ViewPlot);
2705 
2706  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2707  if (metadata)
2708  {
2709  if (!metadata->GetCast().empty())
2710  menu->AddItem(tr("View Cast"), &VideoDialog::ShowCastDialog);
2711  if (!metadata->GetHomepage().isEmpty())
2712  menu->AddItem(tr("View Homepage"), &VideoDialog::ShowHomepage);
2713  }
2714 
2715  return menu;
2716 }
2717 
2723 {
2724  QString label = tr("Manage Video Details");
2725 
2726  auto *menu = new MythMenu(label, this, "manage");
2727 
2728  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2729 
2730  menu->AddItem(tr("Edit Details"), &VideoDialog::EditMetadata);
2731  menu->AddItem(tr("Retrieve Details"), qOverload<>(&VideoDialog::VideoSearch));
2732  if (metadata->GetProcessed())
2733  menu->AddItem(tr("Allow Updates"), &VideoDialog::ToggleProcess);
2734  else
2735  menu->AddItem(tr("Disable Updates"), &VideoDialog::ToggleProcess);
2736  menu->AddItem(tr("Reset Details"), &VideoDialog::ResetMetadata);
2737 
2738  return menu;
2739 }
2740 
2742 {
2743  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2744  if (metadata)
2745  {
2746  metadata->SetProcessed(!metadata->GetProcessed());
2747  metadata->UpdateDatabase();
2748 
2749  refreshData();
2750  }
2751 }
2752 
2758 {
2760  gCoreContext->SaveSetting("VideoDialogNoDB",
2761  QString("%1").arg((int)m_d->m_isFileBrowser));
2762  reloadData();
2763 }
2764 
2770 {
2772  gCoreContext->SaveSetting(QString("mythvideo.folder_view_%1").arg(m_d->m_type),
2773  QString("%1").arg((int)m_d->m_isFlatList));
2774  // TODO: This forces a complete tree rebuild, this is SLOW and shouldn't
2775  // be necessary since MythGenericTree can do a flat view without a rebuild,
2776  // I just don't want to re-write VideoList just now
2777  reloadData();
2778 }
2779 
2785 {
2786  SetCurrentNode(node);
2787  loadData();
2788 }
2789 
2795 {
2796  QStringList route = node->getRouteByString();
2797  if (m_d->m_videoList && m_d->m_videoList->refreshNode(node))
2798  reloadData();
2800 }
2801 
2807 {
2808  MythGenericTree *node = GetNodePtrFromButton(item);
2809  int nodeInt = node->getInt();
2810 
2811  switch (nodeInt)
2812  {
2813  case kDynamicSubFolder:
2814  handleDynamicDirSelect(node);
2815  break;
2816  case kSubFolder:
2817  handleDirSelect(node);
2818  break;
2819  case kUpFolder:
2820  goBack();
2821  break;
2822  default:
2823  {
2824  bool doPlay = true;
2825  if (m_d->m_type == DLG_GALLERY)
2826  {
2827  doPlay = !DoItemDetailShow();
2828  }
2829 
2830  if (doPlay)
2831  playVideo();
2832  }
2833  };
2834 }
2835 
2841 {
2843 }
2844 
2850 {
2852 }
2853 
2859 {
2861 }
2862 
2868 {
2870 }
2871 
2877 {
2879 }
2880 
2886 {
2888 }
2889 
2895 {
2897 }
2898 
2904 {
2906 }
2907 
2913 {
2915 }
2916 
2922 {
2924 }
2925 
2931 {
2933 }
2934 
2940 {
2942 }
2943 
2949 {
2951 }
2952 
2958 {
2960 }
2961 
2967 {
2968  m_d->m_switchingLayout = true;
2969 
2970  // save current position so it can be restored after the switch
2971  SavePosition();
2972 
2973  auto *mythvideo =
2974  new VideoDialog(GetMythMainWindow()->GetMainStack(), "mythvideo",
2975  m_d->m_videoList, type, browse);
2976 
2977  if (mythvideo->Create())
2978  {
2979  gCoreContext->SaveSetting("Default MythVideo View", type);
2980  gCoreContext->SaveSetting("mythvideo.db_group_type", browse);
2981  MythScreenStack *screenStack = GetScreenStack();
2982  screenStack->AddScreen(mythvideo);
2983  screenStack->PopScreen(this, false, false);
2984  deleteLater();
2985  }
2986  else
2987  {
2988  ShowOkPopup(tr("An error occurred when switching views."));
2989  }
2990 }
2991 
2997 {
2998  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
2999 
3000  auto *plotdialog = new PlotDialog(m_popupStack, metadata);
3001 
3002  if (plotdialog->Create())
3003  m_popupStack->AddScreen(plotdialog);
3004 }
3005 
3011 {
3012  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3013 
3014  if (metadata)
3015  {
3017  auto *idp = new ItemDetailPopup(mainStack, metadata,
3018  m_d->m_videoList->getListCache(), m_d->m_playbackState);
3019 
3020  if (idp->Create())
3021  {
3022  mainStack->AddScreen(idp);
3023  return true;
3024  }
3025  }
3026 
3027  return false;
3028 }
3029 
3035 {
3036  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3037 
3038  auto *castdialog = new CastDialog(m_popupStack, metadata);
3039 
3040  if (castdialog->Create())
3041  m_popupStack->AddScreen(castdialog);
3042 }
3043 
3045 {
3046  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3047 
3048  if (!metadata)
3049  return;
3050 
3051  QString url = metadata->GetHomepage();
3052 
3053  if (url.isEmpty())
3054  return;
3055 
3056  QString browser = gCoreContext->GetSetting("WebBrowserCommand", "");
3057  QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
3058 
3059  if (browser.isEmpty())
3060  {
3061  ShowOkPopup(tr("No browser command set! MythVideo needs MythBrowser "
3062  "installed to display the homepage."));
3063  return;
3064  }
3065 
3066  if (browser.toLower() == "internal")
3067  {
3068  GetMythMainWindow()->HandleMedia("WebBrowser", url);
3069  return;
3070  }
3071 
3072  QString cmd = browser;
3073  cmd.replace("%ZOOM%", zoom);
3074  cmd.replace("%URL%", url);
3075  cmd.replace('\'', "%27");
3076  cmd.replace("&","\\&");
3077  cmd.replace(";","\\;");
3078 
3079  GetMythMainWindow()->AllowInput(false);
3081  GetMythMainWindow()->AllowInput(true);
3082 }
3083 
3089 {
3090  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3091  if (metadata)
3092  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
3093 }
3094 
3100 {
3101  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3102  if (metadata)
3103  PlayVideo(metadata->GetFilename(),
3104  m_d->m_videoList->getListCache(), true);
3105 }
3106 
3112 {
3113  const int WATCHED_WATERMARK = 10000; // Play less then this milisec and the chain of
3114  // videos will not be followed when
3115  // playing.
3116  QElapsedTimer playing_time;
3117 
3119  MythGenericTree *node = GetNodePtrFromButton(item);
3120  int list_count = 0;
3121 
3122  if (node && !(node->getInt() >= 0))
3123  list_count = node->childCount();
3124  else
3125  return;
3126 
3127  if (list_count > 0)
3128  {
3129  bool video_started = false;
3130  int i = 0;
3131  while (i < list_count &&
3132  (!video_started || playing_time.hasExpired(WATCHED_WATERMARK)))
3133  {
3134  MythGenericTree *subnode = node->getChildAt(i);
3135  if (subnode)
3136  {
3137  VideoMetadata *metadata = GetMetadataPtrFromNode(subnode);
3138  if (metadata)
3139  {
3140  playing_time.start();
3141  video_started = true;
3142  PlayVideo(metadata->GetFilename(),
3143  m_d->m_videoList->getListCache());
3144  }
3145  }
3146  i++;
3147  }
3148  }
3149 }
3150 
3151 namespace
3152 {
3154  {
3155  explicit SimpleCollect(QStringList &fileList) : m_fileList(fileList) {}
3156 
3157  DirectoryHandler *newDir([[maybe_unused]] const QString &dirName,
3158  [[maybe_unused]] const QString &fqDirName) override // DirectoryHandler
3159  {
3160  return this;
3161  }
3162 
3163  void handleFile([[maybe_unused]] const QString &fileName,
3164  const QString &fqFileName,
3165  [[maybe_unused]] const QString &extension,
3166  [[maybe_unused]] const QString &host) override // DirectoryHandler
3167  {
3168  m_fileList.push_back(fqFileName);
3169  }
3170 
3171  private:
3172  QStringList &m_fileList;
3173  };
3174 
3175  QStringList GetTrailersInDirectory(const QString &startDir)
3176  {
3179  .getExtensionIgnoreList(extensions);
3180  QStringList ret;
3181  SimpleCollect sc(ret);
3182 
3183  (void) ScanVideoDirectory(startDir, &sc, extensions, false);
3184  return ret;
3185  }
3186 }
3187 
3193 {
3194  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3195  if (!metadata) return;
3196 
3198  GetSetting("mythvideo.TrailersDir"));
3199 
3200  if (trailers.isEmpty())
3201  return;
3202 
3203  const int trailersToPlay =
3204  gCoreContext->GetNumSetting("mythvideo.TrailersRandomCount");
3205 
3206  int i = 0;
3207  while (!trailers.isEmpty() && i < trailersToPlay)
3208  {
3209  ++i;
3210  QString trailer = trailers.takeAt(MythRandom(0, trailers.size() - 1));
3211 
3212  LOG(VB_GENERAL, LOG_DEBUG,
3213  QString("Random trailer to play will be: %1").arg(trailer));
3214 
3216  }
3217 
3218  PlayVideo(metadata->GetFilename(), m_d->m_videoList->getListCache());
3219 }
3220 
3226 {
3227  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3228  if (!metadata) return;
3229  QString url;
3230 
3231  if (metadata->IsHostSet() && !metadata->GetTrailer().startsWith("/"))
3232  {
3233  url = generate_file_url("Trailers", metadata->GetHost(),
3234  metadata->GetTrailer());
3235  }
3236  else
3237  {
3238  url = metadata->GetTrailer();
3239  }
3240 
3242 }
3243 
3249 {
3250  m_d->m_parentalLevel.SetLevel(level);
3251 }
3252 
3258 {
3260  .GetLevel() + amount).GetLevel());
3261 }
3262 
3268 {
3269  MythScreenStack *mainStack = GetScreenStack();
3270 
3271  auto *filterdialog = new VideoFilterDialog(mainStack,
3272  "videodialogfilters", m_d->m_videoList.get());
3273 
3274  if (filterdialog->Create())
3275  mainStack->AddScreen(filterdialog);
3276 
3277  connect(filterdialog, &VideoFilterDialog::filterChanged, this, &VideoDialog::reloadData);
3278 }
3279 
3285 {
3286  VideoMetadata *metadata = nullptr;
3287 
3288  if (item)
3289  {
3290  MythGenericTree *node = GetNodePtrFromButton(item);
3291  if (node)
3292  {
3293  int nodeInt = node->getInt();
3294 
3295  if (nodeInt >= 0)
3296  metadata = GetMetadataPtrFromNode(node);
3297  }
3298  }
3299 
3300  return metadata;
3301 }
3302 
3303 void VideoDialog::customEvent(QEvent *levent)
3304 {
3305  if (levent->type() == MetadataFactoryMultiResult::kEventType)
3306  {
3307  auto *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
3308 
3309  if (!mfmr)
3310  return;
3311 
3312  MetadataLookupList list = mfmr->m_results;
3313 
3314  if (list.count() > 1)
3315  {
3316  auto *metadata = list[0]->GetData().value<VideoMetadata *>();
3317  dismissFetchDialog(metadata, true);
3318  auto *resultsdialog = new MetadataResultsDialog(m_popupStack, list);
3319 
3320  connect(resultsdialog, &MetadataResultsDialog::haveResult,
3322  Qt::QueuedConnection);
3323 
3324  if (resultsdialog->Create())
3325  m_popupStack->AddScreen(resultsdialog);
3326  }
3327  }
3328  else if (levent->type() == MetadataFactorySingleResult::kEventType)
3329  {
3330  auto *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
3331 
3332  if (!mfsr)
3333  return;
3334 
3335  MetadataLookup *lookup = mfsr->m_result;
3336 
3337  if (!lookup)
3338  return;
3339 
3340  OnVideoSearchDone(lookup);
3341  }
3342  else if (levent->type() == MetadataFactoryNoResult::kEventType)
3343  {
3344  auto *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
3345 
3346  if (!mfnr)
3347  return;
3348 
3349  MetadataLookup *lookup = mfnr->m_result;
3350 
3351  if (!lookup)
3352  return;
3353 
3354  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3355  if (metadata)
3356  {
3357  dismissFetchDialog(metadata, false);
3358  metadata->SetProcessed(true);
3359  metadata->UpdateDatabase();
3360  }
3361  LOG(VB_GENERAL, LOG_INFO,
3362  QString("No results found for %1 %2 %3").arg(lookup->GetTitle())
3363  .arg(lookup->GetSeason()).arg(lookup->GetEpisode()));
3364  }
3365  else if (levent->type() == DialogCompletionEvent::kEventType)
3366  {
3367  auto *dce = dynamic_cast<DialogCompletionEvent *>(levent);
3368  if (dce != nullptr)
3369  {
3370  QString id = dce->GetId();
3371 
3372  if (id == "scanprompt")
3373  {
3374  int result = dce->GetResult();
3375  if (result == 1)
3376  doVideoScan();
3377  }
3378  else
3379  {
3380  m_menuPopup = nullptr;
3381  }
3382  }
3383  else
3384  {
3385  m_menuPopup = nullptr;
3386  }
3387  }
3388  else if (levent->type() == ImageDLFailureEvent::kEventType)
3389  {
3390  MythErrorNotification n(tr("Failed to retrieve image(s)"),
3391  sLocation,
3392  tr("Check logs"));
3394  }
3395 }
3396 
3398 {
3399  // The metadata has some cover file set
3400  dismissFetchDialog(metadata, true);
3401 
3402  metadata->SetProcessed(true);
3403  metadata->UpdateDatabase();
3404 
3405  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3406  if (item != nullptr)
3407  UpdateItem(item);
3408 }
3409 
3411 {
3412  if (m_videoButtonTree)
3413  {
3415  }
3416 
3418 }
3419 
3421 {
3422  if (m_videoButtonTree)
3423  {
3425  }
3426 
3427  QMap<int, int> idPosition;
3428 
3429  QList<MythGenericTree*> *children = m_d->m_currentNode->getAllChildren();
3430 
3431  for (auto * child : std::as_const(*children))
3432  {
3433  int nodeInt = child->getInt();
3434  if (nodeInt != kSubFolder && nodeInt != kUpFolder)
3435  {
3436  VideoMetadata *listmeta =
3437  GetMetadataPtrFromNode(child);
3438  if (listmeta)
3439  {
3440  int position = child->getPosition();
3441  int id = listmeta->GetID();
3442  idPosition.insert(id, position);
3443  }
3444  }
3445  }
3446 
3447  return m_videoButtonList->GetItemAt(idPosition.value(metadata->GetID()));
3448 }
3449 
3451  bool automode)
3452 {
3453  if (!node)
3455 
3456  if (!node)
3457  return;
3458 
3459  VideoMetadata *metadata = GetMetadataPtrFromNode(node);
3460 
3461  if (!metadata)
3462  return;
3463 
3464  m_metadataFactory->Lookup(metadata, automode, true);
3465 
3466  if (!automode)
3467  {
3468  createFetchDialog(metadata);
3469  }
3470 }
3471 
3473 {
3474  if (!node)
3475  node = m_d->m_rootNode;
3476  using MGTreeChildList = QList<MythGenericTree *>;
3477  MGTreeChildList *lchildren = node->getAllChildren();
3478 
3479  LOG(VB_GENERAL, LOG_DEBUG,
3480  QString("Fetching details in %1").arg(node->GetText()));
3481 
3482  for (auto * child : std::as_const(*lchildren))
3483  {
3484  if ((child->getInt() == kSubFolder) ||
3485  (child->getInt() == kUpFolder))
3486  VideoAutoSearch(child);
3487  else
3488  {
3489  VideoMetadata *metadata = GetMetadataPtrFromNode(child);
3490 
3491  if (!metadata)
3492  continue;
3493 
3494  if (!metadata->GetProcessed())
3495  VideoSearch(child, true);
3496  }
3497  }
3498 }
3499 
3501 {
3503  if (!item)
3504  return;
3505 
3506  VideoMetadata *metadata = GetMetadata(item);
3507  if (metadata)
3508  {
3509  metadata->SetWatched(!metadata->GetWatched());
3510  metadata->UpdateDatabase();
3511  item->DisplayState(WatchedToState(metadata->GetWatched()),
3512  "watchedstate");
3513  }
3514 }
3515 
3517 {
3518  if (!lookup)
3519  return;
3520 
3521  if(!lookup->GetInetref().isEmpty() && lookup->GetInetref() != "00000000")
3522  {
3523  LOG(VB_GENERAL, LOG_INFO, LOC_MML +
3524  QString("Selected Item: Type: %1%2 : Subtype: %3%4%5 : InetRef: %6")
3525  .arg(lookup->GetType() == kMetadataVideo ? "Video" : "",
3526  lookup->GetType() == kMetadataRecording ? "Recording" : "",
3527  lookup->GetSubtype() == kProbableMovie ? "Movie" : "",
3528  lookup->GetSubtype() == kProbableTelevision ? "Television" : "",
3529  lookup->GetSubtype() == kUnknownVideo ? "Unknown" : "",
3530  lookup->GetInetref()));
3531 
3532  lookup->SetStep(kLookupData);
3533  lookup->IncrRef();
3534  m_metadataFactory->Lookup(lookup);
3535  }
3536  else
3537  {
3538  LOG(VB_GENERAL, LOG_ERR, LOC_MML +
3539  QString("Selected Item has no InetRef Number!"));
3540 
3541  OnVideoSearchDone(lookup);
3542  }
3543 }
3544 
3546 {
3547  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3548  if (metadata)
3549  {
3550  ParentalLevel curshowlevel = metadata->GetShowLevel();
3551 
3552  curshowlevel += amount;
3553 
3554  if (curshowlevel.GetLevel() != metadata->GetShowLevel())
3555  {
3556  metadata->SetShowLevel(curshowlevel.GetLevel());
3557  metadata->UpdateDatabase();
3558  refreshData();
3559  }
3560  }
3561 }
3562 
3564 {
3565  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3566  if (!metadata)
3567  return;
3568 
3569  MythScreenStack *screenStack = GetScreenStack();
3570 
3571  auto *md_editor = new EditMetadataDialog(screenStack,
3572  "mythvideoeditmetadata", metadata,
3573  m_d->m_videoList->getListCache());
3574 
3575  connect(md_editor, &EditMetadataDialog::Finished, this, &VideoDialog::refreshData);
3576 
3577  if (md_editor->Create())
3578  screenStack->AddScreen(md_editor);
3579 }
3580 
3582 {
3583  VideoMetadata *metadata = GetMetadata(GetItemCurrent());
3584 
3585  if (!metadata)
3586  return;
3587 
3588  QString message = tr("Are you sure you want to permanently delete:\n%1")
3589  .arg(metadata->GetTitle());
3590 
3591  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message);
3592 
3593  if (confirmdialog->Create())
3594  m_popupStack->AddScreen(confirmdialog);
3595 
3596  connect(confirmdialog, &MythConfirmationDialog::haveResult,
3598 }
3599 
3600 void VideoDialog::OnRemoveVideo(bool dodelete)
3601 {
3602  if (!dodelete)
3603  return;
3604 
3606  MythGenericTree *gtItem = GetNodePtrFromButton(item);
3607 
3608  VideoMetadata *metadata = GetMetadata(item);
3609 
3610  if (!metadata)
3611  return;
3612 
3613  if (m_d->m_videoList->Delete(metadata->GetID()))
3614  {
3615  if (m_videoButtonTree)
3616  m_videoButtonTree->RemoveItem(item, false); // FIXME Segfault when true
3617  else
3619 
3620  MythGenericTree *parent = gtItem->getParent();
3621  parent->deleteNode(gtItem);
3622  }
3623  else
3624  {
3625  QString message = tr("Failed to delete file");
3626 
3627  auto *confirmdialog = new MythConfirmationDialog(m_popupStack,message,
3628  false);
3629 
3630  if (confirmdialog->Create())
3631  m_popupStack->AddScreen(confirmdialog);
3632  }
3633 }
3634 
3636 {
3638  VideoMetadata *metadata = GetMetadata(item);
3639 
3640  if (metadata)
3641  {
3642  metadata->Reset();
3643  metadata->UpdateDatabase();
3644  UpdateItem(item);
3645  }
3646 }
3647 
3649 {
3650  if (!metadata)
3651  return;
3652 
3653  QStringList cover_dirs;
3654  cover_dirs += m_d->m_artDir;
3655 
3656  QString cover_file;
3657  QString inetref = metadata->GetInetRef();
3658  QString filename = metadata->GetFilename();
3659  QString title = metadata->GetTitle();
3660  int season = metadata->GetSeason();
3661  QString host = metadata->GetHost();
3662  int episode = metadata->GetEpisode();
3663 
3664  if (metadata->GetCoverFile().isEmpty() ||
3665  IsDefaultCoverFile(metadata->GetCoverFile()))
3666  {
3667  if (GetLocalVideoImage(inetref, filename,
3668  cover_dirs, cover_file, title,
3669  season, host, "Coverart", episode))
3670  {
3671  metadata->SetCoverFile(cover_file);
3672  OnVideoImageSetDone(metadata);
3673  }
3674  }
3675 
3676  QStringList fanart_dirs;
3677  fanart_dirs += m_d->m_fanDir;
3678 
3679  QString fanart_file;
3680 
3681  if (metadata->GetFanart().isEmpty())
3682  {
3683  if (GetLocalVideoImage(inetref, filename,
3684  fanart_dirs, fanart_file, title,
3685  season, host, "Fanart", episode))
3686  {
3687  metadata->SetFanart(fanart_file);
3688  OnVideoImageSetDone(metadata);
3689  }
3690  }
3691 
3692  QStringList banner_dirs;
3693  banner_dirs += m_d->m_banDir;
3694 
3695  QString banner_file;
3696 
3697  if (metadata->GetBanner().isEmpty())
3698  {
3699  if (GetLocalVideoImage(inetref, filename,
3700  banner_dirs, banner_file, title,
3701  season, host, "Banners", episode))
3702  {
3703  metadata->SetBanner(banner_file);
3704  OnVideoImageSetDone(metadata);
3705  }
3706  }
3707 
3708  QStringList screenshot_dirs;
3709  screenshot_dirs += m_d->m_sshotDir;
3710 
3711  QString screenshot_file;
3712 
3713  if (metadata->GetScreenshot().isEmpty())
3714  {
3715  if (GetLocalVideoImage(inetref, filename,
3716  screenshot_dirs, screenshot_file, title,
3717  season, host, "Screenshots", episode,
3718  true))
3719  {
3720  metadata->SetScreenshot(screenshot_file);
3721  OnVideoImageSetDone(metadata);
3722  }
3723  }
3724 }
3725 
3727 {
3728  if (!lookup)
3729  return;
3730 
3731  auto *metadata = lookup->GetData().value<VideoMetadata *>();
3732 
3733  if (!metadata)
3734  return;
3735 
3736  dismissFetchDialog(metadata, true);
3737  metadata->SetTitle(lookup->GetTitle());
3738  metadata->SetSubtitle(lookup->GetSubtitle());
3739 
3740  if (metadata->GetTagline().isEmpty())
3741  metadata->SetTagline(lookup->GetTagline());
3742  if (metadata->GetYear() == 1895 || metadata->GetYear() == 0)
3743  metadata->SetYear(lookup->GetYear());
3744  if (metadata->GetReleaseDate() == QDate())
3745  metadata->SetReleaseDate(lookup->GetReleaseDate());
3746  if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN ||
3747  metadata->GetDirector().isEmpty())
3748  {
3749  QList<PersonInfo> director = lookup->GetPeople(kPersonDirector);
3750  if (director.count() > 0)
3751  metadata->SetDirector(director.takeFirst().name);
3752  }
3753  if (metadata->GetStudio().isEmpty())
3754  {
3755  QStringList studios = lookup->GetStudios();
3756  if (studios.count() > 0)
3757  metadata->SetStudio(studios.takeFirst());
3758  }
3759  if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT ||
3760  metadata->GetPlot().isEmpty())
3761  metadata->SetPlot(lookup->GetDescription());
3762  if (metadata->GetUserRating() == 0)
3763  metadata->SetUserRating(lookup->GetUserRating());
3764  if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
3765  metadata->SetRating(lookup->GetCertification());
3766  if (metadata->GetLength() == 0min)
3767  metadata->SetLength(lookup->GetRuntime());
3768  if (metadata->GetSeason() == 0)
3769  metadata->SetSeason(lookup->GetSeason());
3770  if (metadata->GetEpisode() == 0)
3771  metadata->SetEpisode(lookup->GetEpisode());
3772  if (metadata->GetHomepage().isEmpty())
3773  metadata->SetHomepage(lookup->GetHomepage());
3774 
3775  metadata->SetInetRef(lookup->GetInetref());
3776 
3777  m_d->AutomaticParentalAdjustment(metadata);
3778 
3779  // Cast
3780  QList<PersonInfo> actors = lookup->GetPeople(kPersonActor);
3781  QList<PersonInfo> gueststars = lookup->GetPeople(kPersonGuestStar);
3782 
3783  for (const auto & name : std::as_const(gueststars))
3784  actors.append(name);
3785 
3787  QStringList cl;
3788 
3789  for (const auto & person : std::as_const(actors))
3790  cl.append(person.name);
3791 
3792  for (const auto & name : std::as_const(cl))
3793  {
3794  QString cn = name.trimmed();
3795  if (!cn.isEmpty())
3796  {
3797  cast.emplace_back(-1, cn);
3798  }
3799  }
3800 
3801  metadata->SetCast(cast);
3802 
3803  // Genres
3804  VideoMetadata::genre_list video_genres;
3805  QStringList genres = lookup->GetCategories();
3806 
3807  for (const auto & name : std::as_const(genres))
3808  {
3809  QString genre_name = name.trimmed();
3810  if (!genre_name.isEmpty())
3811  {
3812  video_genres.emplace_back(-1, genre_name);
3813  }
3814  }
3815 
3816  metadata->SetGenres(video_genres);
3817 
3818  // Countries
3819  VideoMetadata::country_list video_countries;
3820  QStringList countries = lookup->GetCountries();
3821 
3822  for (const auto & name : std::as_const(countries))
3823  {
3824  QString country_name = name.trimmed();
3825  if (!country_name.isEmpty())
3826  {
3827  video_countries.emplace_back(-1, country_name);
3828  }
3829  }
3830 
3831  metadata->SetCountries(video_countries);
3832  metadata->SetProcessed(true);
3833 
3834  metadata->UpdateDatabase();
3835 
3836  MythUIButtonListItem *item = GetItemByMetadata(metadata);
3837  if (item != nullptr)
3838  UpdateItem(item);
3839 
3840  StartVideoImageSet(metadata);
3841 }
3842 
3844 {
3845  if (!m_d->m_scanner)
3846  m_d->m_scanner = new VideoScanner();
3849 }
3850 
3852 {
3853  QString message = tr("There are no videos in the database, would you like "
3854  "to scan your video directories now?");
3855  auto *dialog = new MythConfirmationDialog(m_popupStack, message, true);
3856  dialog->SetReturnEvent(this, "scanprompt");
3857  if (dialog->Create())
3858  m_popupStack->AddScreen(dialog);
3859  else
3860  delete dialog;
3861 }
3862 
3863 #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:1884
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:3157
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:2652
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:3397
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:3099
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:2593
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:3648
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:3225
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:2624
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:3155
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:2867
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:2885
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:2105
VideoDialog::SwitchVideoInsertDateGroup
void SwitchVideoInsertDateGroup()
Switch to Insert Date browse mode.
Definition: videodlg.cpp:2948
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:2806
VideoDialog::ShowHomepage
void ShowHomepage()
Definition: videodlg.cpp:3044
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:2722
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:3563
VideoDialog::CreateViewMenu
MythMenu * CreateViewMenu()
Create a MythMenu for MythVideo Views.
Definition: videodlg.cpp:2557
VideoMetadata::GetScreenshot
const QString & GetScreenshot() const
Definition: videometadata.cpp:1869
VideoDialog::SwitchVideoUserRatingGroup
void SwitchVideoUserRatingGroup()
Switch to User Rating browse mode.
Definition: videodlg.cpp:2939
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:3257
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:1711
VideoDialog::GetItemByMetadata
virtual MythUIButtonListItem * GetItemByMetadata(VideoMetadata *metadata)
Definition: videodlg.cpp:3420
videofilter.h
VideoDialog::searchComplete
void searchComplete(const QString &string)
After using incremental search, move to the selected item.
Definition: videodlg.cpp:2163
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:2957
VideoDialog::GetScreenshot
static QString GetScreenshot(MythGenericTree *node)
Find the Screenshot for a given node.
Definition: videodlg.cpp:1844
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:3192
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:1919
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:2858
VideoMetadata::GetInetRef
const QString & GetInetRef() const
Definition: videometadata.cpp:1604
VideoDialog::OnVideoSearchListSelection
void OnVideoSearchListSelection(RefCountHandler< MetadataLookup > lookup)
Definition: videodlg.cpp:3516
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:2241
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:1423
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:3175
VideoDialog::VideoSearch
void VideoSearch()
Definition: videodlg.h:104
VideoDialog::PromptToScan
void PromptToScan()
Definition: videodlg.cpp:3851
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:2903
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:2840
VideoDialog::m_bookmarkState
MythUIStateType * m_bookmarkState
Definition: videodlg.h:220
VideoDialog::ShowCastDialog
void ShowCastDialog()
Display the Cast if the selected item.
Definition: videodlg.cpp:3034
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:3410
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:2382
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:3172
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:2203
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:2912
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:2265
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:2876
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:2966
VideoDialog::SwitchVideoCastGroup
void SwitchVideoCastGroup()
Switch to Cast browse mode.
Definition: videodlg.cpp:2930
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:3248
VideoDialog::RemoveVideo
void RemoveVideo()
Definition: videodlg.cpp:3581
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:2741
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:2794
VideoDialog::CreateInfoMenu
MythMenu * CreateInfoMenu()
Create a MythMenu for Info pertaining to the selected item.
Definition: videodlg.cpp:2695
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:2149
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:3843
PlotDialog
Definition: videopopups.h:25
VideoDialog::ShowExtensionSettings
void ShowExtensionSettings()
Pop up a MythUI Menu for MythVideo filte Type Settings.
Definition: videodlg.cpp:2638
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:2475
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:3153
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:2894
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:3303
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:2542
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:2277
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:2065
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:2784
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:687
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:2610
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:3267
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:3726
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:3500
VideoDialog::UpdateText
void UpdateText(MythUIButtonListItem *item)
Update the visible text values for a given ButtonListItem.
Definition: videodlg.cpp:2310
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:3284
VideoDialog::BRS_FOLDER
@ BRS_FOLDER
Definition: videodlg.h:42
VideoDialog::OnParentalChange
void OnParentalChange(int amount)
Definition: videodlg.cpp:3545
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:2083
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:2849
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:3088
VideoDialog::UpdateVisible
void UpdateVisible(MythUIButtonListItem *item)
Update playback state for for a given visible ButtonListItem.
Definition: videodlg.cpp:2294
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:3163
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:3111
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:2921
ParentalLevel::Level
Level
Definition: parentalcontrols.h:12
VideoDialog::ResetMetadata
void ResetMetadata()
Definition: videodlg.cpp:3635
VideoDialog::OnRemoveVideo
void OnRemoveVideo(bool dodelete)
Definition: videodlg.cpp:3600
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:2769
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:2513
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:2406
DirectoryHandler
Definition: dirscan.h:6
VideoDialog::ToggleBrowseMode
void ToggleBrowseMode()
Toggle the browseable status for the selected item.
Definition: videodlg.cpp:2757
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:2996
VideoDialog::GetCoverImage
static QString GetCoverImage(MythGenericTree *node)
A "hunt" for cover art to apply for a folder item.
Definition: videodlg.cpp:1479
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:1954
MythUIButtonTree::nodeChanged
void nodeChanged(MythGenericTree *node)
VideoDialog::DoItemDetailShow
bool DoItemDetailShow()
Display the Item Detail Popup.
Definition: videodlg.cpp:3010
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