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