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