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