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