MythTV master
editvideometadata.cpp
Go to the documentation of this file.
1// C++
2#include <algorithm>
3
4// Qt
5#include <QImageReader>
6#include <QUrl>
7
8// MythTV
32
33// MythFrontend
34#include "editvideometadata.h"
35
36//static const QString _Location = QObject::tr("Metadata Editor");
37
39 const QString& lname, VideoMetadata *source_metadata,
40 const VideoMetadataListManager &cache) : MythScreenType(lparent, lname),
41 m_origMetadata(source_metadata),
42 m_metaCache(cache),
43 m_query(new MetadataDownload(this)),
44 m_imageDownload(new MetadataImageDownload(this))
45{
47 m_popupStack = GetMythMainWindow()->GetStack("popup stack");
48}
49
51{
52 delete m_workingMetadata;
53}
54
56{
57 if (!LoadWindowFromXML("video-ui.xml", "edit_metadata", this))
58 return false;
59
60 bool err = false;
61 UIUtilE::Assign(this, m_titleEdit, "title_edit", &err);
62 UIUtilE::Assign(this, m_subtitleEdit, "subtitle_edit", &err);
63 UIUtilE::Assign(this, m_playerEdit, "player_edit", &err);
64
65 UIUtilE::Assign(this, m_seasonSpin, "season", &err);
66 UIUtilE::Assign(this, m_episodeSpin, "episode", &err);
67
68
69 UIUtilE::Assign(this, m_categoryList, "category_select", &err);
70 UIUtilE::Assign(this, m_levelList, "level_select", &err);
71 UIUtilE::Assign(this, m_childList, "child_select", &err);
72
73 UIUtilE::Assign(this, m_browseCheck, "browse_check", &err);
74 UIUtilE::Assign(this, m_watchedCheck, "watched_check", &err);
75
76 UIUtilE::Assign(this, m_doneButton, "done_button", &err);
77
78 if (err)
79 {
80 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'edit_metadata'");
81 return false;
82 }
83
84 UIUtilW::Assign(this, m_coverartText, "coverart_text");
85 UIUtilW::Assign(this, m_screenshotText, "screenshot_text");
86 UIUtilW::Assign(this, m_bannerText, "banner_text");
87 UIUtilW::Assign(this, m_fanartText, "fanart_text");
88 UIUtilW::Assign(this, m_trailerText, "trailer_text");
89
90 UIUtilW::Assign(this, m_coverartButton, "coverart_button");
91 UIUtilW::Assign(this, m_bannerButton, "banner_button");
92 UIUtilW::Assign(this, m_fanartButton, "fanart_button");
93 UIUtilW::Assign(this, m_screenshotButton, "screenshot_button");
94 UIUtilW::Assign(this, m_trailerButton, "trailer_button");
95
96 UIUtilW::Assign(this, m_netBannerButton, "net_banner_button");
97 UIUtilW::Assign(this, m_netFanartButton, "net_fanart_button");
98 UIUtilW::Assign(this, m_netScreenshotButton, "net_screenshot_button");
99 UIUtilW::Assign(this, m_netCoverartButton, "net_coverart_button");
100
101 UIUtilW::Assign(this, m_taglineEdit, "tagline_edit");
102 UIUtilW::Assign(this, m_ratingEdit, "rating_edit");
103 UIUtilW::Assign(this, m_directorEdit, "director_edit");
104 UIUtilW::Assign(this, m_inetrefEdit, "inetref_edit");
105 UIUtilW::Assign(this, m_homepageEdit, "homepage_edit");
106 UIUtilW::Assign(this, m_plotEdit, "description_edit");
107 UIUtilW::Assign(this, m_yearSpin, "year_spin");
108 UIUtilW::Assign(this, m_userRatingSpin, "userrating_spin");
109 UIUtilW::Assign(this, m_lengthSpin, "length_spin");
110
111 UIUtilW::Assign(this, m_coverart, "coverart");
112 UIUtilW::Assign(this, m_screenshot, "screenshot");
113 UIUtilW::Assign(this, m_banner, "banner");
114 UIUtilW::Assign(this, m_fanart, "fanart");
115
116 fillWidgets();
117
119
125 if (m_taglineEdit)
126 {
129 }
130 if (m_ratingEdit)
131 {
134 }
135 if (m_directorEdit)
136 {
139 }
140 if (m_inetrefEdit)
142 if (m_homepageEdit)
143 {
146 }
147 if (m_plotEdit)
148 {
151 }
152
155 if (m_yearSpin)
159 if (m_lengthSpin)
161
163
164 // Find Artwork locally
167 if (m_bannerButton)
169 if (m_fanartButton)
173
174 // Find Artwork on the Internet
183
184 if (m_trailerButton)
186
189
198
199 return true;
200}
201
202namespace
203{
204 template <typename T>
206 {
207 bool operator()(const T &lhs, const T &rhs)
208 {
209 return StringUtil::naturalSortCompare(lhs.second, rhs.second);
210 }
211 };
212
214 {
215 QStringList ret;
216
217 QList<QByteArray> exts = QImageReader::supportedImageFormats();
218 for (const auto & ext : std::as_const(exts))
219 ret.append(QString("*.").append(ext));
220 return ret;
221 }
222
223 void FindImagePopup(const QString &prefix, const QString &prefixAlt,
224 QObject &inst, const QString &returnEvent)
225 {
226 QString fp;
227
228 if (prefix.startsWith("myth://"))
229 fp = prefix;
230 else
231 fp = prefix.isEmpty() ? prefixAlt : prefix;
232
233 MythScreenStack *popupStack =
234 GetMythMainWindow()->GetStack("popup stack");
235
236 auto *fb = new MythUIFileBrowser(popupStack, fp);
237 fb->SetNameFilter(GetSupportedImageExtensionFilter());
238 if (fb->Create())
239 {
240 fb->SetReturnEvent(&inst, returnEvent);
241 popupStack->AddScreen(fb);
242 }
243 else
244 {
245 delete fb;
246 }
247 }
248
249 void FindVideoFilePopup(const QString &prefix, const QString &prefixAlt,
250 QObject &inst, const QString &returnEvent)
251 {
252 QString fp;
253
254 if (prefix.startsWith("myth://"))
255 fp = prefix;
256 else
257 fp = prefix.isEmpty() ? prefixAlt : prefix;
258
259 MythScreenStack *popupStack =
260 GetMythMainWindow()->GetStack("popup stack");
261 QStringList exts;
262
265 for (const auto & fa : fa_list)
266 exts << QString("*.%1").arg(fa.extension.toUpper());
267
268 auto *fb = new MythUIFileBrowser(popupStack, fp);
269 fb->SetNameFilter(exts);
270 if (fb->Create())
271 {
272 fb->SetReturnEvent(&inst, returnEvent);
273 popupStack->AddScreen(fb);
274 }
275 else
276 {
277 delete fb;
278 }
279 }
280
281 const QString CEID_COVERARTFILE = "coverartfile";
282 const QString CEID_BANNERFILE = "bannerfile";
283 const QString CEID_FANARTFILE = "fanartfile";
284 const QString CEID_SCREENSHOTFILE = "screenshotfile";
285 const QString CEID_TRAILERFILE = "trailerfile";
286 const QString CEID_NEWCATEGORY = "newcategory";
287}
288
289void EditMetadataDialog::createBusyDialog(const QString& title)
290{
291 if (m_busyPopup)
292 return;
293
294 const QString& message = title;
295
297 "mythvideobusydialog");
298
299 if (m_busyPopup->Create())
301}
302
304{
307
308 m_seasonSpin->SetRange(0,9999,1,5);
310 m_episodeSpin->SetRange(0,999,1,10);
312 if (m_yearSpin)
313 {
314 m_yearSpin->SetRange(0,9999,1,100);
316 }
318 {
319 m_userRatingSpin->SetRange(0,10,1,2);
321 }
322 if (m_lengthSpin)
323 {
324 m_lengthSpin->SetRange(0,999,1,15);
326 }
327
328 // No memory leak. MythUIButtonListItem adds the new item into
329 // m_categoryList.
331 const VideoCategory::entry_list &vcl =
333 for (const auto & vc : vcl)
334 {
335 // No memory leak. MythUIButtonListItem adds the new item into
336 // m_categoryList.
337 auto *button = new MythUIButtonListItem(m_categoryList, vc.second);
338 button->SetData(vc.first);
339 }
341
343 i <= ParentalLevel::plHigh && i.good(); ++i)
344 {
345 // No memory leak. MythUIButtonListItem adds the new item into
346 // m_levelList.
347 auto *button = new MythUIButtonListItem(m_levelList,
348 tr("Level %1").arg(i.GetLevel()));
349 button->SetData(i.GetLevel());
350 }
352
353 //
354 // Fill the "always play this video next" option
355 // with all available videos.
356 //
357
358 // No memory leak. MythUIButtonListItem adds the new item into
359 // m_childList.
360 new MythUIButtonListItem(m_childList,tr("None"));
361
362 // TODO: maybe make the title list have the same sort order
363 // as elsewhere.
364 using title_list = std::vector<std::pair<unsigned int, QString> >;
366 title_list tc;
367 tc.reserve(mdl.size());
368 for (const auto & md : mdl)
369 {
370 QString title;
371 if (md->GetSeason() > 0 || md->GetEpisode() > 0)
372 {
373 title = QString("%1 %2x%3").arg(md->GetTitle(),
374 QString::number(md->GetSeason()),
375 QString::number(md->GetEpisode()));
376 }
377 else
378 {
379 title = md->GetTitle();
380 }
381 tc.emplace_back(md->GetID(), title);
382 }
383 std::sort(tc.begin(), tc.end(), title_sort<title_list::value_type>());
384
385 for (const auto & t : tc)
386 {
387 if (t.first != m_workingMetadata->GetID())
388 {
389 auto *button = new MythUIButtonListItem(m_childList,t.second);
390 button->SetData(t.first);
391 }
392 }
393
394 if (m_workingMetadata->GetChildID() > 0)
395 {
398 }
399
404 if (m_coverartText)
408 if (m_bannerText)
410 if (m_fanartText)
412 if (m_trailerText)
414
416 if (m_taglineEdit)
418 if (m_ratingEdit)
420 if (m_directorEdit)
422 if (m_inetrefEdit)
424 if (m_homepageEdit)
426 if (m_plotEdit)
428
429 if (m_coverart)
430 {
431 if (!m_workingMetadata->GetHost().isEmpty() &&
432 !m_workingMetadata->GetCoverFile().isEmpty() &&
433 !m_workingMetadata->GetCoverFile().startsWith("/"))
434 {
438 }
439 else
440 {
442 }
443
444 if (!m_workingMetadata->GetCoverFile().isEmpty())
445 m_coverart->Load();
446 }
447 if (m_screenshot)
448 {
449 if (!m_workingMetadata->GetHost().isEmpty() &&
450 !m_workingMetadata->GetScreenshot().isEmpty() &&
451 !m_workingMetadata->GetScreenshot().startsWith("/"))
452 {
456 }
457 else
458 {
460 }
461
462 if (!m_workingMetadata->GetScreenshot().isEmpty())
464 }
465 if (m_banner)
466 {
467 if (!m_workingMetadata->GetHost().isEmpty() &&
468 !m_workingMetadata->GetBanner().isEmpty() &&
469 !m_workingMetadata->GetBanner().startsWith("/"))
470 {
474 }
475 else
476 {
478 }
479
480 if (!m_workingMetadata->GetBanner().isEmpty())
481 m_banner->Load();
482 }
483 if (m_fanart)
484 {
485 if (!m_workingMetadata->GetHost().isEmpty() &&
486 !m_workingMetadata->GetFanart().isEmpty() &&
487 !m_workingMetadata->GetFanart().startsWith("/"))
488 {
492 }
493 else
494 {
496 }
497
498 if (!m_workingMetadata->GetFanart().isEmpty())
499 m_fanart->Load();
500 }
501}
502
504{
505 QString message = tr("Enter new category");
506
507 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
508
509 auto *categorydialog = new MythTextInputDialog(popupStack,message);
510
511 if (categorydialog->Create())
512 {
513 categorydialog->SetReturnEvent(this, CEID_NEWCATEGORY);
514 popupStack->AddScreen(categorydialog);
515 }
516
517}
518
519void EditMetadataDialog::AddCategory(const QString& category)
520{
521 int id = VideoCategory::GetCategory().add(category);
523 new MythUIButtonListItem(m_categoryList, category, id);
525}
526
528{
531
532 emit Finished();
533 Close();
534}
535
537{
539}
540
542{
544}
545
547{
548 m_workingMetadata->SetCategoryID(item->GetData().toInt());
549}
550
552{
554}
555
557{
559}
560
562{
564}
565
567{
569}
570
572{
574}
575
577{
579}
580
582{
584}
585
587{
589}
590
592{
594}
595
597{
599}
600
602{
603 m_workingMetadata->SetLength(m_lengthSpin->GetDuration<std::chrono::minutes>());
604}
605
607{
609}
610
612{
614 SetShowLevel(ParentalLevel(item->GetData().toInt()).GetLevel());
615}
616
618{
619 m_cachedChildSelection = item->GetData().toInt();
621}
622
624{
627}
628
630{
633}
634
636{
637 if (!m_workingMetadata->GetHost().isEmpty())
638 {
639 QString url = StorageGroup::generate_file_url("Coverart",
641 "");
642 FindImagePopup(url, "", *this, CEID_COVERARTFILE);
643 }
644 else
645 {
646 FindImagePopup(gCoreContext->GetSetting("VideoArtworkDir"),
647 GetConfDir() + "/MythVideo", *this, CEID_COVERARTFILE);
648 }
649}
650
652{
653 if (!lookup)
654 return;
655
656 if (m_busyPopup)
657 {
659 m_busyPopup = nullptr;
660 }
661
662 auto type = lookup->GetData().value<VideoArtworkType>();
663 ArtworkList list = lookup->GetArtwork(type);
664
665 if (list.isEmpty())
666 {
667 MythWarningNotification n(tr("No image found"), tr("Metadata Editor"));
669 return;
670 }
671 auto *resultsdialog = new ImageSearchResultsDialog(m_popupStack, list, type);
672
673 connect(resultsdialog, &ImageSearchResultsDialog::haveResult,
675
676 if (resultsdialog->Create())
677 m_popupStack->AddScreen(resultsdialog);
678}
679
681{
682 QString msg = tr("Downloading selected artwork...");
683 createBusyDialog(msg);
684
685 auto *lookup = new MetadataLookup();
686 lookup->SetType(kMetadataVideo);
687
688 lookup->SetSubtype(GuessLookupType(m_workingMetadata));
689 lookup->SetHost(m_workingMetadata->GetHost());
690 lookup->SetAutomatic(true);
691 lookup->SetData(QVariant::fromValue<VideoArtworkType>(type));
692
693 DownloadMap downloads;
694 downloads.insert(type, info);
695 lookup->SetDownloads(downloads);
696 lookup->SetAllowOverwrites(true);
697 lookup->SetTitle(m_workingMetadata->GetTitle());
698 lookup->SetSubtitle(m_workingMetadata->GetSubtitle());
699 lookup->SetSeason(m_workingMetadata->GetSeason());
700 lookup->SetEpisode(m_workingMetadata->GetEpisode());
701 lookup->SetInetref(m_workingMetadata->GetInetRef());
702
704}
705
707{
708 if (!lookup)
709 return;
710
711 if (m_busyPopup)
712 {
714 m_busyPopup = nullptr;
715 }
716
717 auto type = lookup->GetData().value<VideoArtworkType>();
718 DownloadMap map = lookup->GetDownloads();
719
720 if (map.count() >= 1)
721 {
722 ArtworkInfo info = map.value(type);
723 QString filename = info.url;
724
725 if (type == kArtworkCoverart)
727 else if (type == kArtworkFanart)
729 else if (type == kArtworkBanner)
731 else if (type == kArtworkScreenshot)
733 }
734}
735
737{
738 QString msg = tr("Searching for available artwork...");
739 createBusyDialog(msg);
740
741 auto *lookup = new MetadataLookup();
742 lookup->SetStep(kLookupSearch);
743 lookup->SetType(kMetadataVideo);
744 lookup->SetAutomatic(true);
745 if (m_workingMetadata->GetSeason() > 0 ||
747 lookup->SetSubtype(kProbableTelevision);
748 else if (m_workingMetadata->GetSubtitle().isEmpty())
749 lookup->SetSubtype(kProbableMovie);
750 else
751 lookup->SetSubtype(kUnknownVideo);
752 lookup->SetData(QVariant::fromValue<VideoArtworkType>(type));
753
754 lookup->SetTitle(m_workingMetadata->GetTitle());
755 lookup->SetSubtitle(m_workingMetadata->GetSubtitle());
756 lookup->SetSeason(m_workingMetadata->GetSeason());
757 lookup->SetEpisode(m_workingMetadata->GetEpisode());
758 lookup->SetInetref(m_workingMetadata->GetInetRef());
759
760 m_query->addLookup(lookup);
761}
762
764{
766}
767
769{
771}
772
774{
776}
777
779{
781}
782
784{
785 if (file.isEmpty())
786 return;
787
788 QString origfile = file;
789
790 if (file.startsWith("myth://"))
791 {
792 QUrl url(file);
793 file = url.path();
794 file = file.right(file.length() - 1);
795 if (!file.endsWith("/"))
797 else
799 }
800 else
801 {
803 }
804
806
807 if (m_coverart)
808 {
809 m_coverart->SetFilename(origfile);
810 m_coverart->Load();
811 }
812}
813
815{
816 if (!m_workingMetadata->GetHost().isEmpty())
817 {
818 QString url = StorageGroup::generate_file_url("Banners",
820 "");
821 FindImagePopup(url, "", *this, CEID_BANNERFILE);
822 }
823 else
824 {
825 FindImagePopup(gCoreContext->GetSetting("mythvideo.bannerDir"),
826 GetConfDir() + "/MythVideo/Banners", *this, CEID_BANNERFILE);
827 }
828}
829
831{
832 if (file.isEmpty())
833 return;
834
835 QString origfile = file;
836
837 if (file.startsWith("myth://"))
838 {
839 QUrl url(file);
840 file = url.path();
841 file = file.right(file.length() - 1);
842 if (!file.endsWith("/"))
844 else
845 m_workingMetadata->SetBanner(QString());
846 }
847 else
848 {
850 }
851
853
854 if (m_banner)
855 {
856 m_banner->SetFilename(origfile);
857 m_banner->Load();
858 }
859}
860
862{
863 if (!m_workingMetadata->GetHost().isEmpty())
864 {
865 QString url = StorageGroup::generate_file_url("Fanart",
867 "");
868 FindImagePopup(url, "", *this, CEID_FANARTFILE);
869 }
870 else
871 {
872 FindImagePopup(gCoreContext->GetSetting("mythvideo.fanartDir"),
873 GetConfDir() + "/MythVideo/Fanart", *this, CEID_FANARTFILE);
874 }
875}
876
878{
879 if (file.isEmpty())
880 return;
881
882 QString origfile = file;
883
884 if (file.startsWith("myth://"))
885 {
886 QUrl url(file);
887 file = url.path();
888 file = file.right(file.length() - 1);
889 if (!file.endsWith("/"))
891 else
892 m_workingMetadata->SetFanart(QString());
893 }
894 else
895 {
897 }
898
900
901 if (m_fanart)
902 {
903 m_fanart->SetFilename(origfile);
904 m_fanart->Load();
905 }
906}
907
909{
910 if (!m_workingMetadata->GetHost().isEmpty())
911 {
912 QString url = StorageGroup::generate_file_url("Screenshots",
914 "");
915 FindImagePopup(url, "", *this, CEID_SCREENSHOTFILE);
916 }
917 else
918 {
919 FindImagePopup(gCoreContext->GetSetting("mythvideo.screenshotDir"),
920 GetConfDir() + "/MythVideo/Screenshots",
921 *this, CEID_SCREENSHOTFILE);
922 }
923}
924
926{
927 if (file.isEmpty())
928 return;
929
930 QString origfile = file;
931
932 if (file.startsWith("myth://"))
933 {
934 QUrl url(file);
935 file = url.path();
936 file = file.right(file.length() - 1);
937 if (!file.endsWith("/"))
939 else
941 }
942 else
943 {
945 }
946
948
949 if (m_screenshot)
950 {
951 m_screenshot->SetFilename(origfile);
953 }
954}
955
957{
958 if (!m_workingMetadata->GetHost().isEmpty())
959 {
960 QString url = StorageGroup::generate_file_url("Trailers",
962 "");
963 FindVideoFilePopup(url, "", *this, CEID_TRAILERFILE);
964 }
965 else
966 {
967 FindVideoFilePopup(gCoreContext->GetSetting("mythvideo.TrailersDir"),
968 GetConfDir() + "/MythVideo/Trailers", *this, CEID_TRAILERFILE);
969 }
970}
971
973{
974 if (file.isEmpty())
975 return;
976
977 if (file.startsWith("myth://"))
978 {
979 QUrl url(file);
980 file = url.path();
981 file = file.right(file.length() - 1);
982 if (!file.endsWith("/"))
984 else
985 m_workingMetadata->SetTrailer(QString());
986 }
987 else
988 {
990 }
992}
993
995{
996 if (levent->type() == DialogCompletionEvent::kEventType)
997 {
998 auto *dce = (DialogCompletionEvent*)(levent);
999
1000 const QString resultid = dce->GetId();
1001
1002 if (resultid == CEID_COVERARTFILE)
1003 SetCoverArt(dce->GetResultText());
1004 else if (resultid == CEID_BANNERFILE)
1005 SetBanner(dce->GetResultText());
1006 else if (resultid == CEID_FANARTFILE)
1007 SetFanart(dce->GetResultText());
1008 else if (resultid == CEID_SCREENSHOTFILE)
1009 SetScreenshot(dce->GetResultText());
1010 else if (resultid == CEID_TRAILERFILE)
1011 SetTrailer(dce->GetResultText());
1012 else if (resultid == CEID_NEWCATEGORY)
1013 AddCategory(dce->GetResultText());
1014 }
1015 else if (levent->type() == MetadataLookupEvent::kEventType)
1016 {
1017 auto *lue = (MetadataLookupEvent *)levent;
1018
1019 MetadataLookupList lul = lue->m_lookupList;
1020
1021 if (lul.isEmpty())
1022 return;
1023
1024 // There should really only be one result here.
1025 // If not, USER ERROR!
1026 if (lul.count() == 1)
1027 {
1028 OnArtworkSearchDone(lul[0]);
1029 }
1030 else
1031 {
1032 if (m_busyPopup)
1033 {
1034 m_busyPopup->Close();
1035 m_busyPopup = nullptr;
1036 }
1037 }
1038 }
1039 else if (levent->type() == MetadataLookupFailure::kEventType)
1040 {
1041 auto *luf = (MetadataLookupFailure *)levent;
1042
1043 MetadataLookupList lul = luf->m_lookupList;
1044
1045 if (m_busyPopup)
1046 {
1047 m_busyPopup->Close();
1048 m_busyPopup = nullptr;
1049 }
1050
1051 if (!lul.empty())
1052 {
1053 MetadataLookup *lookup = lul[0];
1054 LOG(VB_GENERAL, LOG_INFO,
1055 QString("No results found for %1 %2 %3").arg(lookup->GetTitle())
1056 .arg(lookup->GetSeason()).arg(lookup->GetEpisode()));
1057 }
1058 }
1059 else if (levent->type() == ImageDLEvent::kEventType)
1060 {
1061 auto *ide = (ImageDLEvent *)levent;
1062
1063 MetadataLookup *lookup = ide->m_item;
1064
1065 if (!lookup)
1066 return;
1067
1068 handleDownloadedImages(lookup);
1069 }
1070 else if (levent->type() == ImageDLFailureEvent::kEventType)
1071 {
1072 MythErrorNotification n(tr("Failed to retrieve image"),
1073 tr("Metadata Editor"),
1074 tr("Check logs"));
1076 }
1077}
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
static const Type kEventType
Definition: mythdialogbox.h:56
MetadataImageDownload * m_imageDownload
MetadataDownload * m_query
void AddCategory(const QString &category)
MythUISpinBox * m_userRatingSpin
MythUIText * m_trailerText
MythUIText * m_coverartText
void SetLevel(MythUIButtonListItem *item)
void customEvent(QEvent *levent) override
void createBusyDialog(const QString &title)
MythUIButton * m_trailerButton
MythUITextEdit * m_taglineEdit
void SetBanner(QString file)
void OnSearchListSelection(const ArtworkInfo &info, VideoArtworkType type)
MythScreenStack * m_popupStack
void OnArtworkSearchDone(MetadataLookup *lookup)
void SetCoverArt(QString file)
MythUITextEdit * m_playerEdit
MythUIButton * m_netCoverartButton
MythUICheckBox * m_browseCheck
MythUIText * m_bannerText
MythUISpinBox * m_episodeSpin
void SetScreenshot(QString file)
const VideoMetadataListManager & m_metaCache
MythUITextEdit * m_inetrefEdit
MythUITextEdit * m_titleEdit
MythUIButton * m_bannerButton
MythUICheckBox * m_watchedCheck
MythUITextEdit * m_ratingEdit
bool Create() override
MythUITextEdit * m_directorEdit
void SetTrailer(QString file)
MythUIImage * m_fanart
EditMetadataDialog(MythScreenStack *lparent, const QString &lname, VideoMetadata *source_metadata, const VideoMetadataListManager &cache)
MythUIButton * m_screenshotButton
MythUIButton * m_netFanartButton
void SetFanart(QString file)
MythUIButton * m_fanartButton
VideoMetadata * m_workingMetadata
MythUITextEdit * m_subtitleEdit
void SetChild(MythUIButtonListItem *item)
MythUIImage * m_banner
MythUIButton * m_netScreenshotButton
MythUIButton * m_coverartButton
MythUIBusyDialog * m_busyPopup
~EditMetadataDialog() override
MythUIButtonList * m_categoryList
MythUIImage * m_screenshot
void SetCategory(MythUIButtonListItem *item)
MythUISpinBox * m_seasonSpin
MythUIButtonList * m_levelList
MythUITextEdit * m_plotEdit
MythUIButtonList * m_childList
MythUITextEdit * m_homepageEdit
MythUIButton * m_netBannerButton
MythUIText * m_fanartText
MythUIButton * m_doneButton
MythUIImage * m_coverart
void handleDownloadedImages(MetadataLookup *lookup)
MythUISpinBox * m_yearSpin
MythUIText * m_screenshotText
VideoMetadata * m_origMetadata
MythUISpinBox * m_lengthSpin
void FindNetArt(VideoArtworkType type)
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:836
const association_list & getList() const
Definition: dbaccess.cpp:811
std::vector< file_association > association_list
Definition: dbaccess.h:154
static const Type kEventType
static const Type kEventType
void haveResult(ArtworkInfo, VideoArtworkType)
void addLookup(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_lookupList takes ownership of the gi...
void addDownloads(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_downloadList takes ownership of the ...
static const Type kEventType
static const Type kEventType
uint GetSeason() const
QVariant GetData() const
ArtworkList GetArtwork(VideoArtworkType type) const
QString GetTitle() const
DownloadMap GetDownloads() const
uint GetEpisode() const
QString GetSetting(const QString &key, const QString &defaultval="")
MythScreenStack * GetStack(const QString &Stackname)
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
virtual void Close()
Dialog prompting the user to enter a text string.
bool Create(void) override
void itemClicked(MythUIButtonListItem *item)
void SetValueByData(const QVariant &data)
void itemSelected(MythUIButtonListItem *item)
void Clicked()
void SetCheckState(MythUIStateType::StateType state)
bool GetBooleanCheckState(void) const
void valueChanged()
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
void SetRange(int low, int high, int step, uint pageMultiple=5)
Set the lower and upper bounds of the spinbox, the interval and page amount.
void SetValue(int val) override
Definition: mythuispinbox.h:32
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDuration()
Definition: mythuispinbox.h:49
int GetIntValue(void) const override
Definition: mythuispinbox.h:39
QString GetText(void) const
void SetText(const QString &text, bool moveCursor=true)
void SetMaxLength(int length)
void valueChanged()
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
void LosingFocus(void)
Level GetLevel() const
const entry_list & getList()
Definition: dbaccess.cpp:241
int add(const QString &name)
Definition: dbaccess.cpp:216
std::vector< entry > entry_list
Definition: dbaccess.h:16
static QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
static VideoCategory & GetCategory()
Definition: dbaccess.cpp:489
std::list< VideoMetadataPtr > metadata_list
const metadata_list & getList() const
const QString & GetHost() const
void SetTrailer(const QString &trailer)
void SetInetRef(const QString &inetRef)
const QString & GetCoverFile() const
void SetCoverFile(const QString &coverFile)
int GetYear() const
bool GetWatched() const
const QString & GetTitle() const
int GetCategoryID() const
void SetSubtitle(const QString &subtitle, const QString &sortSubtitle="")
void SetTagline(const QString &tagline)
void SetFanart(const QString &fanart)
void SetUserRating(float userRating)
void SetYear(int year)
unsigned int GetID() const
void SetSeason(int season)
const QString & GetFanart() const
ParentalLevel::Level GetShowLevel() const
void SetEpisode(int episode)
void SetPlot(const QString &plot)
std::chrono::minutes GetLength() const
int GetChildID() const
const QString & GetInetRef() const
void SetChildID(int childID)
const QString & GetBanner() const
const QString & GetTrailer() const
const QString & GetRating() const
void SetTitle(const QString &title, const QString &sortTitle="")
const QString & GetDirector() const
void SetCategoryID(int id)
void SetLength(std::chrono::minutes length)
bool GetBrowse() const
const QString & GetScreenshot() const
void SetDirector(const QString &director)
const QString & GetSubtitle() const
void SetScreenshot(const QString &screenshot)
const QString & GetTagline() const
int GetSeason() const
void SetRating(const QString &rating)
void SetHomepage(const QString &homepage)
const QString & GetPlayCommand() const
const QString & GetHomepage() const
void SetBanner(const QString &banner)
void SetPlayCommand(const QString &playCommand)
const QString & GetPlot() const
int GetEpisode() const
float GetUserRating() const
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
const QString VIDEO_CATEGORY_UNKNOWN
Definition: globals.cpp:7
@ kLookupSearch
@ kProbableTelevision
@ kUnknownVideo
@ kProbableMovie
@ kMetadataVideo
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
LookupType GuessLookupType(ProgramInfo *pginfo)
QList< ArtworkInfo > ArtworkList
VideoArtworkType
@ kArtworkScreenshot
@ kArtworkFanart
@ kArtworkBanner
@ kArtworkCoverart
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetConfDir(void)
Definition: mythdirs.cpp:263
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythNotificationCenter * GetNotificationCenter(void)
MythMainWindow * GetMythMainWindow(void)
bool naturalSortCompare(const QString &a, const QString &b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
naturalCompare as a std::sort compatible function (ignoring the third parameter, which is never used)...
Definition: stringutil.h:57
void FindImagePopup(const QString &prefix, const QString &prefixAlt, QObject &inst, const QString &returnEvent)
void FindVideoFilePopup(const QString &prefix, const QString &prefixAlt, QObject &inst, const QString &returnEvent)
dictionary info
Definition: azlyrics.py:7
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
void CheckedSet(MythUIStateType *uiItem, const QString &value)
Definition: videoutils.cpp:40