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