Go to the documentation of this file.
11 #include <QApplication>
12 #include <QDomDocument>
13 #include <QDomElement>
18 #include <QRegularExpression>
20 #include <QTimerEvent>
23 #include "libmythbase/mythconfig.h"
78 #define DEBUG_CHANNEL_PREFIX 0
79 #define DEBUG_ACTIONS 0
81 #define LOC QString("TV::%1(): ").arg(__func__)
93 return (dt1 > dt2 ? 1 : -1);
123 query.
prepare(
"SELECT COUNT(cardid) FROM capturecard;");
125 count = query.
value(0).toInt();
127 LOG(VB_RECORD, LOG_INFO,
128 "ConfiguredTunerCards() = " + QString::number(count));
142 static QMutex s_lock;
143 static TV* s_tv =
nullptr;
144 QMutexLocker locker(&s_lock);
156 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ref count error");
202 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Already have a player");
208 auto flags =
static_cast<PlayerFlags>(playerflags);
241 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
246 MaxWait = (MaxWait <= 0ms) ? 20s : MaxWait;
248 MaxWait = std::chrono::milliseconds::max();
249 #endif // CONFIG_VALGRIND
258 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
259 QString(
"StartPlaying(): took %1 ms to start player.")
260 .arg(
t.elapsed().count()));
263 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
295 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Already have a TV object.");
300 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
303 bool quitAll =
false;
304 bool showDialogs =
true;
305 bool playCompleted =
false;
307 bool startSysEventSent =
false;
308 bool startLivetvEventSent =
false;
321 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed initializing TV");
343 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- begin");
348 else if (!startSysEventSent)
350 startSysEventSent =
true;
354 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- end");
358 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- begin");
359 if (!tv->
LiveTV(showDialogs, Selection))
364 else if (!startSysEventSent)
366 startSysEventSent =
true;
367 startLivetvEventSent =
true;
371 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- end");
376 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners configured");
378 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners free for live tv");
389 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Entering main playback loop.");
391 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Exiting main playback loop.");
399 curProgram = nextProgram;
413 quitAll |= !playerError.isEmpty();
416 QCoreApplication::processEvents();
420 playCompleted =
true;
430 if (startSysEventSent)
438 list.push_back(allowrerecord ?
"1" :
"0");
439 MythEvent me(
"LOCAL_PBB_DELETE_RECORDINGS", list);
450 else if (startSysEventSent)
455 if (!playerError.isEmpty())
465 if (startLivetvEventSent)
468 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
470 return playCompleted;
480 if (name ==
"playbackbox")
482 else if (name ==
"viewscheduled")
484 else if (name ==
"programguide")
486 else if (name ==
"programfinder")
488 else if (name ==
"scheduleeditor")
490 else if (name ==
"programlist")
497 "Play Program"),
"P,Media Play");
499 "Stop Program"),
"");
501 "Toggle recording status of current program"),
"R");
503 "Page the program guide back one day"),
"Home,Media Previous");
505 "Page the program guide forward one day"),
"End,Media Next");
507 "Page the program guide left"),
",,<,Ctrl+B,Media Rewind");
509 "Page the program guide right"),
">,.,Ctrl+F,Media Fast Forward");
511 "Toggle the current channel as a favorite"),
"?");
513 "Reverse the channel order in the program guide"),
"");
515 "Show the Program Guide"),
"S");
517 "Show the Program Finder"),
"#");
519 "Show the Channel Search"),
"");
520 REG_KEY(
"TV Frontend",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
521 "Cycle through channel groups and all channels in the "
522 "program guide."),
"/");
523 REG_KEY(
"TV Frontend",
"CHANUPDATE", QT_TRANSLATE_NOOP(
"MythControls",
524 "Switch channels without exiting guide in Live TV mode."),
"X");
526 "Volume down"),
"[,{,F10,Volume Down");
528 "Volume up"),
"],},F11,Volume Up");
530 "Mute"),
"|,\\,F9,Volume Mute");
531 REG_KEY(
"TV Frontend",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
532 "Cycle audio channels"),
"");
533 REG_KEY(
"TV Frontend",
"RANKINC", QT_TRANSLATE_NOOP(
"MythControls",
534 "Increase program or channel rank"),
"Right");
535 REG_KEY(
"TV Frontend",
"RANKDEC", QT_TRANSLATE_NOOP(
"MythControls",
536 "Decrease program or channel rank"),
"Left");
537 REG_KEY(
"TV Frontend",
"UPCOMING", QT_TRANSLATE_NOOP(
"MythControls",
538 "List upcoming episodes"),
"O");
540 "List scheduled upcoming episodes"),
"");
542 "List previously recorded episodes"),
"");
543 REG_KEY(
"TV Frontend",
"DETAILS", QT_TRANSLATE_NOOP(
"MythControls",
544 "Show details"),
"U");
545 REG_KEY(
"TV Frontend",
"VIEWINPUT", QT_TRANSLATE_NOOP(
"MythControls",
546 "Switch Recording Input view"),
"C");
547 REG_KEY(
"TV Frontend",
"CUSTOMEDIT", QT_TRANSLATE_NOOP(
"MythControls",
548 "Edit Custom Record Rule"),
"");
549 REG_KEY(
"TV Frontend",
"CHANGERECGROUP", QT_TRANSLATE_NOOP(
"MythControls",
550 "Change Recording Group"),
"");
551 REG_KEY(
"TV Frontend",
"CHANGEGROUPVIEW", QT_TRANSLATE_NOOP(
"MythControls",
552 "Change Group View"),
"");
554 "List recorded episodes"),
"");
574 if (selectKeys !=
"?")
577 togBkmKeys = selectKeys;
579 bkmKeys = selectKeys;
583 "Add Bookmark"), bkmKeys);
585 "Toggle Bookmark"), togBkmKeys);
586 REG_KEY(
"TV Playback",
"BACK", QT_TRANSLATE_NOOP(
"MythControls",
587 "Exit or return to DVD menu"),
"Esc,Back");
589 "Playback Compact Menu"),
"Alt+M");
591 "Clear OSD"),
"Backspace");
593 "Pause"),
"P,Space,Media Play");
595 "Fast Forward"),
"Right");
599 "Arbitrary Seek"),
"*");
601 "Seek to a position in seconds"),
"");
603 "Channel up"),
"Up");
605 "Channel down"),
"Down");
606 REG_KEY(
"TV Playback",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
607 "Switch to the next favorite channel"),
"/");
608 REG_KEY(
"TV Playback",
"PREVCHAN", QT_TRANSLATE_NOOP(
"MythControls",
609 "Switch to the previous channel"),
"H");
611 "Jump ahead"),
"PgDown");
613 "Jump back"),
"PgUp");
614 REG_KEY(
"TV Playback",
"INFOWITHCUTLIST", QT_TRANSLATE_NOOP(
"MythControls",
615 "Info utilizing cutlist"),
"");
617 "Jump to bookmark"),
"K");
618 REG_KEY(
"TV Playback",
"FFWDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
619 "Fast Forward (Sticky) or Forward one second while paused"),
">,.,Ctrl+F,Media Fast Forward");
620 REG_KEY(
"TV Playback",
"RWNDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
621 "Rewind (Sticky) or Rewind one second while paused"),
",,<,Ctrl+B,Media Rewind");
622 REG_KEY(
"TV Playback",
"NEXTSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
623 "Next Video Source"),
"Y");
624 REG_KEY(
"TV Playback",
"PREVSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
625 "Previous Video Source"),
"");
626 REG_KEY(
"TV Playback",
"NEXTINPUT", QT_TRANSLATE_NOOP(
"MythControls",
628 REG_KEY(
"TV Playback",
"NEXTCARD", QT_TRANSLATE_NOOP(
"MythControls",
630 REG_KEY(
"TV Playback",
"SKIPCOMMERCIAL", QT_TRANSLATE_NOOP(
"MythControls",
631 "Skip Commercial"),
"Z,End,Media Next");
632 REG_KEY(
"TV Playback",
"SKIPCOMMBACK", QT_TRANSLATE_NOOP(
"MythControls",
633 "Skip Commercial (Reverse)"),
"Q,Home,Media Previous");
635 "Jump to the start of the recording."),
"Ctrl+A");
636 REG_KEY(
"TV Playback",
"TOGGLEBROWSE", QT_TRANSLATE_NOOP(
"MythControls",
637 "Toggle channel browse mode"),
"O");
639 "Toggle recording status of current program"),
"R");
641 "Toggle the current channel as a favorite"),
"?");
643 "Volume down"),
"[,{,F10,Volume Down");
645 "Volume up"),
"],},F11,Volume Up");
647 "Mute"),
"|,\\,F9,Volume Mute");
649 "Set the volume"),
"");
650 REG_KEY(
"TV Playback",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
651 "Cycle audio channels"),
"");
653 "Toggle audio upmixer"),
"Ctrl+U");
655 QT_TRANSLATE_NOOP(
"MythControls",
"Move BottomLine off screen"),
"L");
657 QT_TRANSLATE_NOOP(
"MythControls",
"Save manual zoom for BottomLine"),
"");
658 REG_KEY(
"TV Playback",
"TOGGLEASPECT", QT_TRANSLATE_NOOP(
"MythControls",
659 "Toggle the video aspect ratio"),
"Ctrl+W");
660 REG_KEY(
"TV Playback",
"TOGGLEFILL", QT_TRANSLATE_NOOP(
"MythControls",
661 "Next Preconfigured Zoom mode"),
"W");
663 "Toggle any captions"),
"T");
665 "Enable any captions"),
"");
667 "Disable any captions"),
"");
668 REG_KEY(
"TV Playback",
"TOGGLETTC", QT_TRANSLATE_NOOP(
"MythControls",
669 "Toggle Teletext Captions"),
"");
670 REG_KEY(
"TV Playback",
"TOGGLESUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
671 "Toggle Subtitles"),
"");
672 REG_KEY(
"TV Playback",
"TOGGLECC608", QT_TRANSLATE_NOOP(
"MythControls",
673 "Toggle VBI CC"),
"");
674 REG_KEY(
"TV Playback",
"TOGGLECC708", QT_TRANSLATE_NOOP(
"MythControls",
675 "Toggle ATSC CC"),
"");
676 REG_KEY(
"TV Playback",
"TOGGLETTM", QT_TRANSLATE_NOOP(
"MythControls",
677 "Toggle Teletext Menu"),
"");
679 "Toggle External Subtitles"),
"");
681 "Enable External Subtitles"),
"");
683 "Disable External Subtitles"),
"");
684 REG_KEY(
"TV Playback",
"TOGGLERAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
685 "Toggle Text Subtitles"),
"");
687 REG_KEY(
"TV Playback",
"SELECTAUDIO_0", QT_TRANSLATE_NOOP(
"MythControls",
688 "Play audio track 1"),
"");
689 REG_KEY(
"TV Playback",
"SELECTAUDIO_1", QT_TRANSLATE_NOOP(
"MythControls",
690 "Play audio track 2"),
"");
691 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_0",QT_TRANSLATE_NOOP(
"MythControls",
692 "Display subtitle 1"),
"");
693 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_1",QT_TRANSLATE_NOOP(
"MythControls",
694 "Display subtitle 2"),
"");
695 REG_KEY(
"TV Playback",
"SELECTRAWTEXT_0",QT_TRANSLATE_NOOP(
"MythControls",
696 "Display Text Subtitle 1"),
"");
697 REG_KEY(
"TV Playback",
"SELECTCC608_0", QT_TRANSLATE_NOOP(
"MythControls",
698 "Display VBI CC1"),
"");
699 REG_KEY(
"TV Playback",
"SELECTCC608_1", QT_TRANSLATE_NOOP(
"MythControls",
700 "Display VBI CC2"),
"");
701 REG_KEY(
"TV Playback",
"SELECTCC608_2", QT_TRANSLATE_NOOP(
"MythControls",
702 "Display VBI CC3"),
"");
703 REG_KEY(
"TV Playback",
"SELECTCC608_3", QT_TRANSLATE_NOOP(
"MythControls",
704 "Display VBI CC4"),
"");
705 REG_KEY(
"TV Playback",
"SELECTCC708_0", QT_TRANSLATE_NOOP(
"MythControls",
706 "Display ATSC CC1"),
"");
707 REG_KEY(
"TV Playback",
"SELECTCC708_1", QT_TRANSLATE_NOOP(
"MythControls",
708 "Display ATSC CC2"),
"");
709 REG_KEY(
"TV Playback",
"SELECTCC708_2", QT_TRANSLATE_NOOP(
"MythControls",
710 "Display ATSC CC3"),
"");
711 REG_KEY(
"TV Playback",
"SELECTCC708_3", QT_TRANSLATE_NOOP(
"MythControls",
712 "Display ATSC CC4"),
"");
714 "Enable Forced Subtitles"),
"");
716 "Disable Forced Subtitles"),
"");
718 REG_KEY(
"TV Playback",
"NEXTAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
719 "Next audio track"),
"+");
720 REG_KEY(
"TV Playback",
"PREVAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
721 "Previous audio track"),
"-");
722 REG_KEY(
"TV Playback",
"NEXTSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
723 "Next subtitle track"),
"");
724 REG_KEY(
"TV Playback",
"PREVSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
725 "Previous subtitle track"),
"");
726 REG_KEY(
"TV Playback",
"NEXTRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
727 "Next Text track"),
"");
728 REG_KEY(
"TV Playback",
"PREVRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
729 "Previous Text track"),
"");
730 REG_KEY(
"TV Playback",
"NEXTCC608", QT_TRANSLATE_NOOP(
"MythControls",
731 "Next VBI CC track"),
"");
732 REG_KEY(
"TV Playback",
"PREVCC608", QT_TRANSLATE_NOOP(
"MythControls",
733 "Previous VBI CC track"),
"");
734 REG_KEY(
"TV Playback",
"NEXTCC708", QT_TRANSLATE_NOOP(
"MythControls",
735 "Next ATSC CC track"),
"");
736 REG_KEY(
"TV Playback",
"PREVCC708", QT_TRANSLATE_NOOP(
"MythControls",
737 "Previous ATSC CC track"),
"");
738 REG_KEY(
"TV Playback",
"NEXTCC", QT_TRANSLATE_NOOP(
"MythControls",
739 "Next of any captions"),
"");
741 REG_KEY(
"TV Playback",
"NEXTSCAN", QT_TRANSLATE_NOOP(
"MythControls",
742 "Next video scan overidemode"),
"");
743 REG_KEY(
"TV Playback",
"QUEUETRANSCODE", QT_TRANSLATE_NOOP(
"MythControls",
744 "Queue the current recording for transcoding"),
"X");
745 REG_KEY(
"TV Playback",
"SPEEDINC", QT_TRANSLATE_NOOP(
"MythControls",
746 "Increase the playback speed"),
"U");
747 REG_KEY(
"TV Playback",
"SPEEDDEC", QT_TRANSLATE_NOOP(
"MythControls",
748 "Decrease the playback speed"),
"J");
749 REG_KEY(
"TV Playback",
"ADJUSTSTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
750 "Turn on time stretch control"),
"A");
751 REG_KEY(
"TV Playback",
"STRETCHINC", QT_TRANSLATE_NOOP(
"MythControls",
752 "Increase time stretch speed"),
"");
753 REG_KEY(
"TV Playback",
"STRETCHDEC", QT_TRANSLATE_NOOP(
"MythControls",
754 "Decrease time stretch speed"),
"");
755 REG_KEY(
"TV Playback",
"TOGGLESTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
756 "Toggle time stretch speed"),
"");
758 QT_TRANSLATE_NOOP(
"MythControls",
759 "Turn on audio sync adjustment controls"),
"");
761 QT_TRANSLATE_NOOP(
"MythControls",
762 "Set the audio sync adjustment"),
"");
763 REG_KEY(
"TV Playback",
"TOGGLEPICCONTROLS",
764 QT_TRANSLATE_NOOP(
"MythControls",
"Playback picture adjustments"),
767 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture brightness"),
"");
769 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture contrast"),
"");
771 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture color"),
"");
773 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture hue"),
"");
775 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
776 "for this channel"),
"Ctrl+G");
778 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
779 "for this recorder"),
"G");
780 REG_KEY(
"TV Playback",
"CYCLECOMMSKIPMODE",
781 QT_TRANSLATE_NOOP(
"MythControls",
"Cycle Commercial Skip mode"),
784 "Show the Program Guide"),
"S");
786 "Show the Program Finder"),
"#");
788 "Toggle the Sleep Timer"),
"F8");
792 "Jump to previously played recording"),
"");
794 "Display menu of recorded programs to jump to"),
"");
796 "Display scheduled recording list"),
"");
798 "Display previously recorded episodes"),
"");
800 "Monitor Signal Quality"),
"Alt+F7");
802 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Root Menu"),
"");
804 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the Popup Menu"),
"");
806 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Chapter Menu"),
"");
808 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Title Menu"),
"");
810 QT_TRANSLATE_NOOP(
"MythControls",
"Exit Show without any prompts"),
813 "Jump to a chapter"),
"");
815 "Switch title"),
"");
817 "Switch angle"),
"");
819 "OSD Navigation"),
"");
821 "Zoom mode - shift up"),
"");
823 "Zoom mode - shift down"),
"");
825 "Zoom mode - shift left"),
"");
827 "Zoom mode - shift right"),
"");
829 QT_TRANSLATE_NOOP(
"MythControls",
830 "Zoom mode - increase aspect ratio"),
"3");
832 QT_TRANSLATE_NOOP(
"MythControls",
833 "Zoom mode - decrease aspect ratio"),
"7");
835 "Zoom mode - zoom in"),
"9");
837 "Zoom mode - zoom out"),
"1");
839 QT_TRANSLATE_NOOP(
"MythControls",
840 "Zoom mode - vertical zoom in"),
"8");
842 QT_TRANSLATE_NOOP(
"MythControls",
843 "Zoom mode - vertical zoom out"),
"2");
845 QT_TRANSLATE_NOOP(
"MythControls",
846 "Zoom mode - horizontal zoom in"),
"6");
848 QT_TRANSLATE_NOOP(
"MythControls",
849 "Zoom mode - horizontal zoom out"),
"4");
851 "Zoom mode - quit and abandon changes"),
"");
853 "Zoom mode - commit changes"),
"");
856 "Display list of cast members"),
"");
862 "Menu Green"),
"F3");
864 "Menu Yellow"),
"F4");
876 "Clear editing cut points"),
"C,Q,Home");
878 "Invert Begin/End cut points"),
"I,Home Page");
882 "Load cuts from detected commercials"),
"Z,End");
884 "Jump to the next cut point"),
"PgDown,Media Next");
886 "Jump to the previous cut point"),
"PgUp,Media Previous");
888 "Jump back 10x the normal amount"),
",,<,Ctrl+B,Media Rewind");
890 "Jump forward 10x the normal amount"),
">,.,Ctrl+F,Media Fast Forward");
892 "Cut point editor compact menu"),
"Alt+M");
896 "Next Page"),
"Down");
898 "Previous Page"),
"Up");
900 "Next Subpage"),
"Right");
902 "Previous Subpage"),
"Left");
904 "Toggle Teletext"),
"T");
908 "Menu Green"),
"F3");
910 "Menu Yellow"),
"F4");
914 "Menu White"),
"F6");
916 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle Background"),
"F7");
918 "Reveal hidden Text"),
"F8");
922 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle audio visualisation"),
"");
926 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle OSD playback information"),
"");
930 QT_TRANSLATE_NOOP(
"MythControls",
"Auto 3D"),
"");
932 QT_TRANSLATE_NOOP(
"MythControls",
"Ignore 3D"),
"");
934 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Side by Side"),
"");
936 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Top and Bottom"),
"");
990 { tr(
"Off",
"Sleep timer"), 0min },
991 { tr(
"30m",
"Sleep timer"), 30min },
992 { tr(
"1h",
"Sleep timer"), 60min },
993 { tr(
"1h30m",
"Sleep timer"), 90min },
994 { tr(
"2h",
"Sleep timer"), 120min }
1011 m_mainWindow(MainWindow),
1015 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Creating TV object");
1017 QObject::setObjectName(
"TV");
1034 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Finished creating TV object");
1039 QMap<QString,QString> kv;
1040 kv[
"LiveTVIdleTimeout"] =
"0";
1041 kv[
"BrowseMaxForward"] =
"240";
1042 kv[
"PlaybackExitPrompt"] =
"0";
1043 kv[
"AutomaticSetWatched"] =
"0";
1044 kv[
"EndOfRecordingExitPrompt"] =
"0";
1045 kv[
"JumpToProgramOSD"] =
"1";
1046 kv[
"GuiSizeForTV"] =
"0";
1047 kv[
"UseVideoModes"] =
"0";
1048 kv[
"JobsRunOnRecordHost"] =
"0";
1049 kv[
"ContinueEmbeddedTVPlay"] =
"0";
1050 kv[
"UseFixedWindowSize"] =
"1";
1051 kv[
"RunFrontendInWindow"] =
"0";
1052 kv[
"PersistentBrowseMode"] =
"0";
1053 kv[
"BrowseAllTuners"] =
"0";
1054 kv[
"ChannelOrdering"] =
"channum";
1056 kv[
"CustomFilters"] =
"";
1057 kv[
"ChannelFormat"] =
"<num> <sign>";
1059 kv[
"TryUnflaggedSkip"] =
"0";
1061 kv[
"ChannelGroupDefault"] =
"-1";
1062 kv[
"BrowseChannelGroup"] =
"0";
1063 kv[
"SmartForward"] =
"0";
1064 kv[
"FFRewReposTime"] =
"100";
1065 kv[
"FFRewReverse"] =
"1";
1067 kv[
"BrowseChannelGroup"] =
"0";
1068 kv[
"ChannelGroupDefault"] =
"-1";
1069 kv[
"ChannelGroupRememberLast"] =
"0";
1071 kv[
"VbiFormat"] =
"";
1072 kv[
"DecodeVBIFormat"] =
"";
1075 kv[
"PlaybackScreenPressKeyMap"] =
"P,Up,Z,],Left,Return,Return,Right,A,Down,Q,[";
1076 kv[
"LiveTVScreenPressKeyMap"] =
"P,Up,Z,S,Left,Return,Return,Right,A,Down,Q,F";
1078 constexpr std::array<const int,8> ff_rew_def { 3, 5, 10, 20, 30, 60, 120, 180 };
1079 for (
size_t i = 0; i < ff_rew_def.size(); i++)
1080 kv[QString(
"FFRewSpeed%1").arg(i)] = QString::number(ff_rew_def[i]);
1087 QString db_channel_ordering;
1089 m_dbIdleTimeout = std::chrono::minutes(kv[
"LiveTVIdleTimeout"].toUInt());
1090 auto db_browse_max_forward = std::chrono::minutes(kv[
"BrowseMaxForward"].toUInt());
1101 db_channel_ordering = kv[
"ChannelOrdering"];
1111 QString beVBI = kv[
"VbiFormat"];
1112 QString feVBI = kv[
"DecodeVBIFormat"];
1129 for (
size_t i = 0; i <
sizeof(ff_rew_def)/
sizeof(ff_rew_def[0]); i++)
1130 m_ffRewSpeeds.push_back(kv[QString(
"FFRewSpeed%1").arg(i)].toInt());
1147 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1151 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No MythMainWindow");
1172 fullscreen |= (0 == gui_width && 0 == gui_height);
1187 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created TvPlayWindow.");
1198 QCoreApplication::processEvents();
1223 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1229 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1250 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"-- lock");
1283 lcd->setFunctionLEDs(
FUNC_TV,
false);
1285 lcd->switchToTime();
1301 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1311 QCoreApplication::processEvents();
1387 .toUTC().toString(
"yyyy-MM-ddThh:mm:ssZ"));
1398 if (!
info.text[
"totalchapters"].isEmpty())
1400 QList<std::chrono::seconds> chapters;
1403 for (std::chrono::seconds chapter : std::as_const(chapters))
1404 var << QVariant((
long long)chapter.count());
1405 status.insert(
"chaptertimes", var);
1412 int currenttrack = -1;
1415 for (
int i = 0; i < list.size(); i++)
1417 if (i == currenttrack)
1418 status.insert(
"currentsubtitletrack", list[i]);
1419 tracks.insert(
"SELECTSUBTITLE_" + QString::number(i), list[i]);
1426 for (
int i = 0; i < list.size(); i++)
1428 if (i == currenttrack)
1429 status.insert(
"currentsubtitletrack", list[i]);
1430 tracks.insert(
"SELECTTTC_" + QString::number(i), list[i]);
1437 for (
int i = 0; i < list.size(); i++)
1439 if (i == currenttrack)
1440 status.insert(
"currentsubtitletrack", list[i]);
1441 tracks.insert(
"SELECTCC708_" + QString::number(i), list[i]);
1448 for (
int i = 0; i < list.size(); i++)
1450 if (i == currenttrack)
1451 status.insert(
"currentsubtitletrack", list[i]);
1452 tracks.insert(
"SELECTCC608_" + QString::number(i), list[i]);
1459 for (
int i = 0; i < list.size(); i++)
1461 if (i == currenttrack)
1462 status.insert(
"currentsubtitletrack", list[i]);
1463 tracks.insert(
"SELECTRAWTEXT_" + QString::number(i), list[i]);
1469 status.insert(
"currentsubtitletrack", tr(
"External Subtitles"));
1473 status.insert(
"totalsubtitletracks", tracks.size());
1474 if (!tracks.isEmpty())
1475 status.insert(
"subtitletracks", tracks);
1480 for (
int i = 0; i < list.size(); i++)
1482 if (i == currenttrack)
1483 status.insert(
"currentaudiotrack", list[i]);
1484 tracks.insert(
"SELECTAUDIO_" + QString::number(i), list[i]);
1487 status.insert(
"totalaudiotracks", tracks.size());
1488 if (!tracks.isEmpty())
1489 status.insert(
"audiotracks", tracks);
1513 for (
auto tit =
info.text.cbegin(); tit !=
info.text.cend(); ++tit)
1514 status.insert(tit.key(), tit.value());
1516 QHashIterator<QString,int> vit(
info.values);
1517 while (vit.hasNext())
1520 status.insert(vit.key(), vit.value());
1548 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Idle Timer. %1 minutes")
1570 else if (!Selection.empty())
1572 for (
const auto & ci : Selection)
1574 uint chanid = ci.m_chanId;
1575 QString channum = ci.m_chanNum;
1576 if (!chanid || channum.isEmpty())
1580 if (chanid && !channum.isEmpty() && !cards.isEmpty())
1618 if (!
info->GetChanID())
1625 QString key =
info->MakeUniqueKey();
1630 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"AskAllowRecording -- " +
1631 QString(
"adding '%1'").arg(
info->m_title));
1639 LOG(VB_GENERAL, LOG_INFO,
LOC +
"-- " +
1640 QString(
"removing '%1'").arg(
info->GetTitle()));
1644 delete (*it).m_info;
1661 QString single_rec = tr(
"MythTV wants to record \"%1\" on %2 in %d seconds. Do you want to:");
1663 QString record_watch = tr(
"Record and watch while it records");
1664 QString let_record1 = tr(
"Let it record and go back to the Main Menu");
1665 QString let_recordm = tr(
"Let them record and go back to the Main Menu");
1666 QString record_later1 = tr(
"Record it later, I want to watch TV");
1667 QString record_laterm = tr(
"Record them later, I want to watch TV");
1668 QString do_not_record1= tr(
"Don't let it record, I want to watch TV");
1669 QString do_not_recordm= tr(
"Don't let them record, I want to watch TV");
1676 if ((*it).m_expiry <= timeNow)
1679 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"-- " +
1680 QString(
"removing '%1'").arg((*it).m_info->m_title));
1682 delete (*it).m_info;
1690 std::chrono::milliseconds timeuntil = 0ms;
1697 (*it).m_isInSameInputGroup = (*it).m_isConflicting =
true;
1702 bool busy_input_grps_loaded =
false;
1703 std::vector<uint> busy_input_grps;
1710 (*it).m_isInSameInputGroup =
1711 (cardid == (*it).m_info->GetInputID());
1713 if ((*it).m_isInSameInputGroup)
1717 if (!busy_input_grps_loaded)
1720 busy_input_grps_loaded =
true;
1723 std::vector<uint> input_grps =
1726 for (
uint grp : input_grps)
1728 if (
find(busy_input_grps.begin(), busy_input_grps.end(),
1729 grp) != busy_input_grps.end())
1731 (*it).m_isInSameInputGroup =
true;
1741 if (!(*it).m_isInSameInputGroup)
1742 (*it).m_isConflicting =
false;
1743 else if (cardid == (*it).m_info->GetInputID())
1744 (*it).m_isConflicting =
true;
1746 (*it).m_isConflicting =
true;
1748 (busy_input.
m_mplexId == (*it).m_info->QueryMplexID())) ||
1750 (busy_input.
m_chanId == (*it).m_info->GetChanID())))
1751 (*it).m_isConflicting =
false;
1753 (*it).m_isConflicting =
true;
1755 conflict_count += (*it).m_isConflicting ? 1 : 0;
1762 if (conflict_count == 0)
1764 LOG(VB_GENERAL, LOG_INFO,
LOC +
"The scheduler wants to make "
1765 "a non-conflicting recording.");
1769 else if (conflict_count == 1 && ((*it).m_info->GetInputID() == cardid))
1772 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"UpdateOSDAskAllowDialog -- " +
1780 .replace(
"<num>", (*it).m_info->GetChanNum())
1781 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1782 .replace(
"<name>", (*it).m_info->GetChannelName());
1784 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1789 dialog.m_buttons.push_back({ record_watch,
"DIALOG_ASKALLOW_WATCH_0",
false, !((*it).m_hasRec)} );
1790 dialog.m_buttons.push_back({ let_record1,
"DIALOG_ASKALLOW_EXIT_0" });
1791 dialog.m_buttons.push_back({ ((*it).m_hasLater) ? record_later1 : do_not_record1,
1792 "DIALOG_ASKALLOW_CANCELRECORDING_0",
false, ((*it).m_hasRec) });
1797 if (conflict_count > 1)
1800 "MythTV wants to record these programs in %d seconds:");
1804 bool has_rec =
false;
1807 if (!(*it).m_isConflicting)
1810 QString title = (*it).m_info->GetTitle();
1811 if ((title.length() < 10) && !(*it).m_info->GetSubtitle().isEmpty())
1812 title +=
": " + (*it).m_info->GetSubtitle();
1813 if (title.length() > 20)
1814 title = title.left(17) +
"...";
1818 .replace(
"<num>", (*it).m_info->GetChanNum())
1819 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1820 .replace(
"<name>", (*it).m_info->GetChannelName());
1822 if (conflict_count > 1)
1824 message += tr(
"\"%1\" on %2").arg(title, channel);
1829 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1830 has_rec = (*it).m_hasRec;
1834 if (conflict_count > 1)
1837 message += tr(
"Do you want to:");
1840 bool all_have_later =
true;
1841 timeuntil = 9999999ms;
1844 if ((*it).m_isConflicting)
1846 all_have_later &= (*it).m_hasLater;
1851 timeuntil = (9999999ms == timeuntil) ? 0ms : timeuntil;
1853 if (conflict_count > 1)
1857 { let_recordm,
"DIALOG_ASKALLOW_EXIT_0",
false,
true },
1858 { all_have_later ? record_laterm : do_not_recordm,
"DIALOG_ASKALLOW_CANCELCONFLICTING_0" }
1865 { let_record1,
"DIALOG_ASKALLOW_EXIT_0",
false, !has_rec},
1866 { all_have_later ? record_later1 : do_not_record1,
"DIALOG_ASKALLOW_CANCELRECORDING_0",
false, has_rec}
1879 LOG(VB_GENERAL, LOG_ERR,
"allowrecordingbox : askAllowLock is locked");
1883 if (
Action ==
"CANCELRECORDING")
1888 else if (
Action ==
"CANCELCONFLICTING")
1892 if (pgm.m_isConflicting)
1896 else if (
Action ==
"WATCH")
1962 #define TRANSITION(ASTATE,BSTATE) ((ctxState == (ASTATE)) && (desiredNextState == (BSTATE)))
1964 #define SET_NEXT() do { nextState = desiredNextState; changed = true; } while(false)
1965 #define SET_LAST() do { nextState = ctxState; changed = true; } while(false)
1970 QByteArray msg_arr = msg.toLatin1();
1971 QString msg_i18n = TV::tr(msg_arr.constData());
1972 QByteArray msg_i18n_arr = msg_i18n.toLatin1();
1973 return (msg_arr == msg_i18n_arr) ? msg_i18n : msg;
1988 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Called after fatal error detected.");
1992 bool changed =
false;
1998 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning, called with no state to change to.");
2006 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Attempting to change from %1 to %2")
2011 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to set to an error state!");
2036 QString channum =
"";
2040 QStringList reclist;
2043 query.
prepare(
"SELECT channum FROM channel "
2044 "WHERE chanid = :CHANID");
2047 channum = query.
value(0).toString();
2049 channum = QString::number(chanid);
2052 QString::number(chanid));
2057 if (!reclist.empty())
2076 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- begin");
2078 if (chanid && !channum.isEmpty())
2083 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- end");
2087 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2101 LOG(VB_GENERAL, LOG_INFO,
LOC +
2102 QString(
"playbackURL(%1) inputtype(%2)")
2107 playbackURL,
false,
true,
2121 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2176 LOG(VB_GENERAL, LOG_ERR,
LOC +
2177 "Couldn't find recorder for in-progress recording");
2196 QString message =
"COMMFLAG_REQUEST ";
2211 TV::tr(
"TV Player" ),
2238 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unknown state transition: %1 to %2")
2243 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Changing from %1 to %2")
2254 LOG(VB_GENERAL, LOG_INFO,
LOC +
"State is LiveTV");
2256 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateOSDInput done");
2258 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateLCD done");
2260 LOG(VB_GENERAL, LOG_INFO,
LOC +
"ITVRestart done");
2266 QString msg = tr(
"%1 Settings")
2319 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Main UI disabled.");
2322 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
" -- end");
2337 MaxWait = (MaxWait <= 0ms) ? 40s : MaxWait;
2340 bool recording =
false;
2344 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid Remote Encoder");
2352 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Lost contact with backend");
2356 std::this_thread::sleep_for(5us);
2362 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timed out waiting for recorder to start");
2366 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Took %1 ms to start recorder.")
2367 .arg(
t.elapsed().count()));
2386 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
2400 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stopping ring buffer");
2411 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"stopping recorder");
2416 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
2421 const int timer_id =
Event->timerId();
2429 bool handled =
true;
2490 if (!netCmd.isEmpty())
2516 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Last Program File does not exist");
2635 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Unknown timer: %1").arg(timer_id));
2645 QString lcd_time_string;
2646 bool showProgress =
true;
2663 lcd_time_string =
info.text[
"playedtime"] +
" / " +
info.text[
"totaltime"];
2665 if (lcd_time_string.length() > lcd->
getLCDWidth())
2666 lcd_time_string.remove(
' ');
2696 int timer = startTimer(Interval);
2698 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to start timer on line %1 of %2").arg(Line).arg(__FILE__));
2715 auto StateChange = [&]()
2733 QTimer::singleShot(0,
this, StateChange);
2738 auto InputChange = [&]()
2750 QTimer::singleShot(0,
this, InputChange);
2762 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Switching to program: %1")
2832 bool is_playing =
false;
2917 bool restartTimer =
false;
2923 restartTimer =
true;
2927 LOG(VB_CHANNEL, LOG_INFO,
"REC_PROGRAM -- channel change");
2993 if ((
Event->type() == QEvent::Resize))
2999 if ( (QEvent::KeyPress ==
Event->type() || QEvent::KeyRelease ==
Event->type())
3001 return TVPlaybackState::eventFilter(Object,
Event);
3003 QScopedPointer<QEvent> sNewEvent(
nullptr);
3007 if (QEvent::KeyPress ==
Event->type())
3022 switch (
Event->type())
3025 case QEvent::UpdateRequest:
3029 return TVPlaybackState::eventFilter(Object,
Event);
3032 return TVPlaybackState::eventFilter(Object,
Event);
3039 if (
Event ==
nullptr)
3040 return TVPlaybackState::event(
Event);
3042 if (QEvent::Resize ==
Event->type())
3047 const auto *qre =
dynamic_cast<const QResizeEvent*
>(
Event);
3050 return TVPlaybackState::event(
Event);
3059 if (QEvent::KeyPress ==
Event->type())
3061 const auto * ke =
dynamic_cast<QKeyEvent*
>(
Event);
3064 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"keypress: %1 '%2'")
3065 .arg(ke->key()).arg(ke->text()));
3073 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"mythgesture: g:%1 pos:%2,%3 b:%4")
3074 .arg(ge->GetGesture()).arg(ge->GetPosition().x())
3075 .arg(ge->GetPosition().y()).arg(ge->GetButton()));
3079 bool handled =
false;
3088 switch (
Event->type())
3091 case QEvent::UpdateRequest:
3101 return QObject::event(
Event);
3106 bool handled =
true;
3161 else if (
Action.startsWith(
"TOGGLE"))
3171 else if (
Action.startsWith(
"SELECT"))
3180 else if (
Action.startsWith(
"NEXT") ||
Action.startsWith(
"PREV"))
3182 int dir = (
Action.startsWith(
"NEXT")) ? +1 : -1;
3186 else if (
Action.endsWith(
"CC"))
3211 QStringList::const_iterator it;
3212 for (it = actions.begin(); it != actions.end(); ++it)
3214 if ((*it).startsWith(
"SYSEVENT") ||
3227 QList<QKeyEvent*> keyPressList;
3229 QStringList stringKeyList = KeyList.split(
',');
3230 for (
const auto & str : std::as_const(stringKeyList))
3232 QKeySequence keySequence(str);
3233 for (i = 0; i < keySequence.count(); i++)
3235 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3236 int keynum = keySequence[i];
3237 int keyCode = keynum & ~Qt::KeyboardModifierMask;
3238 auto modifiers =
static_cast<Qt::KeyboardModifiers
>(keynum & Qt::KeyboardModifierMask);
3240 int keyCode = keySequence[i].key();
3241 Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
3243 auto * keyEvent =
new QKeyEvent(QEvent::None, keyCode, modifiers);
3244 keyPressList.append(keyEvent);
3252 auto * keyEvent =
new QKeyEvent(QEvent::None, Qt::Key_Escape, Qt::NoModifier);
3253 keyPressList.append(keyEvent);
3256 return keyPressList;
3260 QStringList &Actions,
bool IsLiveTV)
3262 if (
Event && Context ==
"TV Playback")
3269 (
Event->GetButton() == Qt::LeftButton))
3273 QPoint pos =
Event->GetPosition();
3275 const int widthDivider = 4;
3276 int w4 = size.width() / widthDivider;
3277 region = pos.x() / w4;
3278 int h3 = size.height() / 3;
3279 region += (pos.y() / h3) * widthDivider;
3291 QStringList &Actions,
bool IsLiveTV,
bool AllowJumps)
3295 if (QEvent::KeyPress ==
Event->type())
3305 if (
Event ==
nullptr)
3311 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"ignoreKeys: %1").arg(ignoreKeys));
3322 auto* eKeyEvent =
dynamic_cast<QKeyEvent*
>(
Event);
3324 if (eKeyEvent->key() <= 0)
3327 switch(eKeyEvent->nativeScanCode())
3330 keycode = Qt::Key_MediaPause;
3338 auto *key =
new QKeyEvent(QEvent::KeyPress, keycode, eKeyEvent->modifiers());
3339 QCoreApplication::postEvent(
this, key);
3345 QStringList actions;
3346 bool handled =
false;
3347 bool alreadyTranslatedPlayback =
false;
3355 alreadyTranslatedPlayback =
true;
3357 if (handled || actions.isEmpty())
3360 bool esc =
IsActionable({
"ESCAPE",
"BACK" }, actions);
3371 if (QEvent::KeyPress ==
Event->type())
3373 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3431 if (QEvent::KeyPress ==
Event->type())
3433 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3436 const QString txt = qke->text();
3440 (void)txt.toInt(&ok, 16);
3441 if (ok || txt==
"_" || txt==
"-" || txt==
"#" || txt==
".")
3452 QStringList tt_actions;
3455 if (!handled && !tt_actions.isEmpty())
3457 for (
const QString&
action : std::as_const(tt_actions))
3469 if (!alreadyTranslatedPlayback)
3472 alreadyTranslatedPlayback =
true;
3475 if (!handled && !actions.isEmpty())
3477 for (
const QString&
action : std::as_const(actions))
3486 if (!alreadyTranslatedPlayback)
3489 if (handled || actions.isEmpty())
3497 if (QEvent::KeyPress ==
Event->type())
3513 for (
int i = 0; i < actions.size(); ++i)
3514 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"handled(%1) actions[%2](%3)")
3515 .arg(handled).arg(i).arg(actions[i]));
3516 #endif // DEBUG_ACTIONS
3523 for (
int i = 0; i < actions.size() && !handled; i++)
3525 const QString&
action = actions[i];
3527 int val =
action.toInt(&ok);
3545 bool handled =
true;
3566 for (
const auto&
action : std::as_const(Actions))
3577 static const QStringList passthrough =
3580 ACTION_MUTEAUDIO,
"CYCLEAUDIOCHAN",
"BOTTOMLINEMOVE",
"BOTTOMLINESAVE",
"TOGGLEASPECT"
3590 bool endmanualzoom =
false;
3591 bool handled =
true;
3592 bool updateOSD =
true;
3621 endmanualzoom =
true;
3625 endmanualzoom =
true;
3632 static const QStringList passthrough =
3640 QString msg = tr(
"Zoom Committed");
3644 msg = endmanualzoom ? tr(
"Zoom Ignored") :
3649 else if (endmanualzoom)
3696 bool handled =
true;
3721 bool handled =
true;
3744 bool handled =
true;
3767 bool handled =
true;
3802 bool IsDVD,
bool IsDVDStillFrame)
3804 bool handled =
true;
3808 else if (
IsActionable(
"SKIPCOMMBACK", Actions) && !IsDVD)
3810 else if (
IsActionable(
"QUEUETRANSCODE", Actions) && !IsDVD)
3812 else if (
IsActionable(
"QUEUETRANSCODE_AUTO", Actions) && !IsDVD)
3814 else if (
IsActionable(
"QUEUETRANSCODE_HIGH", Actions) && !IsDVD)
3816 else if (
IsActionable(
"QUEUETRANSCODE_MEDIUM", Actions) && !IsDVD)
3818 else if (
IsActionable(
"QUEUETRANSCODE_LOW", Actions) && !IsDVD)
3824 else if (
IsActionable(
"SPEEDINC", Actions) && !IsDVDStillFrame)
3826 else if (
IsActionable(
"SPEEDDEC", Actions) && !IsDVDStillFrame)
3830 else if (
IsActionable(
"CYCLECOMMSKIPMODE",Actions) && !IsDVD)
3890 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
3916 std::chrono::milliseconds rate =
m_sigMonMode ? 0ms : 100ms;
3951 bool visible =
false;
4041 else if (
IsActionable({
"INFO",
"INFOWITHCUTLIST" }, Actions))
4062 for (
auto it = Actions.cbegin(); it != Actions.cend() && !handled; ++it)
4071 bool handled =
false;
4075 for (
int i = 0; i < Actions.size() && !handled; i++)
4077 const QString&
action = Actions[i];
4079 int val =
action.toInt(&ok);
4108 bool handled =
true;
4187 info.text[
"title"] = tr(
"Position");
4195 bool handled =
true;
4217 else if (
IsActionable(
"NEXTSOURCE", Actions) && islivetv)
4221 else if (
IsActionable(
"PREVSOURCE", Actions) && islivetv)
4225 else if (
IsActionable(
"NEXTINPUT", Actions) && islivetv)
4233 else if (
IsActionable(
"PREVCHAN", Actions) && islivetv)
4305 #ifdef DEBUG_ACTIONS
4306 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"(%1) ignoreKeys: %2").arg(
Command).arg(ignoreKeys));
4311 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Ignoring network control command because ignoreKeys is set");
4315 QStringList tokens =
Command.split(
" ", Qt::SkipEmptyParts);
4316 if (tokens.size() < 2)
4318 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not enough tokens in network control command " + QString(
"'%1'").arg(
Command));
4330 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4331 "Ignoring network control command\n\t\t\t" +
4332 QString(
"because dialog is waiting for a response"));
4336 if (tokens[1] !=
"QUERY")
4339 if (tokens.size() == 3 && tokens[1] ==
"CHANID")
4345 else if (tokens.size() == 3 && tokens[1] ==
"CHANNEL")
4349 static const QRegularExpression kChannelNumRE { R
"(^[-\.\d_#]+$)" };
4350 if (tokens[2] ==
"UP")
4352 else if (tokens[2] ==
"DOWN")
4354 else if (tokens[2].contains(kChannelNumRE))
4358 else if (tokens.size() == 3 && tokens[1] ==
"SPEED")
4362 if (tokens[2] ==
"0x")
4369 else if (tokens[2] ==
"normal")
4379 static const QRegularExpression kSpeedRE { R
"(^\-*(\d*\.)?\d+x$)" };
4380 float tmpSpeed = 1.0F;
4383 if (tokens[2].contains(kSpeedRE))
4385 QString speed = tokens[2].left(tokens[2].length()-1);
4386 tmpSpeed = speed.toFloat(&ok);
4390 static const QRegularExpression re { R
"(^(\-*\d+)\/(\d+)x$)" };
4391 auto match = re.match(tokens[2]);
4392 if (match.hasMatch())
4394 QStringList matches = match.capturedTexts();
4395 int numerator = matches[1].toInt(&ok);
4396 int denominator = matches[2].toInt(&ok);
4398 if (ok && denominator != 0)
4399 tmpSpeed =
static_cast<float>(numerator) /
static_cast<float>(denominator);
4407 float searchSpeed = fabs(tmpSpeed);
4412 if (tmpSpeed == 0.0F)
4420 else if (tmpSpeed == 1.0F)
4439 else if (tmpSpeed > 1)
4447 else if (0.125F <= tmpSpeed && tmpSpeed <= 2.0F)
4455 LOG(VB_GENERAL, LOG_WARNING, QString(
"Couldn't find %1 speed. Setting Speed to 1x")
4456 .arg(
static_cast<double>(searchSpeed)));
4463 LOG(VB_GENERAL, LOG_ERR, QString(
"Found an unknown speed of %1").arg(tokens[2]));
4467 else if (tokens.size() == 2 && tokens[1] ==
"STOP")
4474 static const QRegularExpression kDigitsRE {
"^\\d+$" };
4478 if (tokens[2] ==
"BEGINNING")
4480 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
4482 else if (tokens[2] ==
"FORWARD")
4486 else if (tokens[2] ==
"BACKWARD")
4490 else if ((tokens[2] ==
"POSITION" ||
4491 tokens[2] ==
"POSITIONWITHCUTLIST") &&
4492 (tokens.size() == 4) &&
4493 (tokens[3].contains(kDigitsRE)))
4495 DoSeekAbsolute(tokens[3].toInt(), tokens[2] ==
"POSITIONWITHCUTLIST");
4498 else if (tokens.size() >= 3 && tokens[1] ==
"SUBTITLES")
4501 uint track = tokens[2].toUInt(&ok);
4513 uint size =
static_cast<uint>(subs.size());
4516 if (track >=
start && track < finish)
4525 finish =
start + size;
4526 if (track >=
start && track < finish)
4535 finish =
start + size;
4536 if (track >=
start && track < finish)
4545 finish =
start + size;
4546 if (track >=
start && track < finish)
4555 finish =
start + size;
4556 if (track >=
start && track < finish)
4565 finish =
start + size;
4566 if (track >=
start && track < finish)
4574 else if (tokens.size() >= 3 && tokens[1] ==
"VOLUME")
4576 static const QRegularExpression re {
"(\\d+)%?" };
4577 auto match = re.match(tokens[2]);
4578 if (match.hasMatch())
4580 QStringList matches = match.capturedTexts();
4582 LOG(VB_GENERAL, LOG_INFO, QString(
"Set Volume to %1%").arg(matches[1]));
4585 int vol = matches[1].toInt(&ok);
4589 if (0 <= vol && vol <= 100)
4593 else if (tokens.size() >= 3 && tokens[1] ==
"QUERY")
4595 if (tokens[2] ==
"POSITION")
4610 static const QRegularExpression re {
"Play (.*)x" };
4612 if (match.hasMatch())
4614 QStringList matches = match.capturedTexts();
4615 speedStr = QString(
"%1x").arg(matches[1]);
4627 QString infoStr =
"";
4651 infoStr =
"Recorded";
4659 QString bufferFilename =
4661 if ((infoStr ==
"Recorded") || (infoStr ==
"LiveTV"))
4663 infoStr += QString(
" %1 %2 %3 %4 %5 %6 %7")
4664 .arg(
info.text[
"description"],
4669 QString::number(fplay),
4671 QString::number(rate));
4675 QString position =
info.text[
"description"].section(
" ",0,0);
4676 infoStr += QString(
" %1 %2 %3 %4 %5")
4680 QString::number(fplay),
4681 QString::number(rate));
4684 infoStr += QString(
" Subtitles:");
4689 infoStr += QString(
" *0:[None]*");
4691 infoStr += QString(
" 0:[None]");
4696 for (
int i = 0; i < subs.size(); i++)
4699 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4701 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4706 for (
int i = 0; i < subs.size(); i++)
4709 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4711 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4716 for (
int i = 0; i < subs.size(); i++)
4719 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4721 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4726 for (
int i = 0; i < subs.size(); i++)
4729 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4731 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4736 for (
int i = 0; i < subs.size(); i++)
4739 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4741 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4746 for (
int i = 0; i < subs.size(); i++)
4749 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4751 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4757 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4761 else if (tokens[2] ==
"VOLUME")
4764 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4773 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- begin").arg(
StateToString(desiredState)));
4780 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Created player."));
4785 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Failed to create player."));
4788 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- end %2")
4894 bool paused =
false;
4916 bool ignore =
false;
4917 bool paused =
false;
4942 if (Time > -0.001F && Time < +0.001F)
4945 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1 seconds").arg(
static_cast<double>(Time)));
4966 else if (Time < 0.0F)
4978 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1").arg(FrameNum));
5004 const int kRewind = 4;
5005 const int kForward = 8;
5006 const int kSticky = 16;
5007 const int kSlippery = 32;
5008 const int kRelative = 64;
5009 const int kAbsolute = 128;
5010 const int kIgnoreCutlist = 256;
5011 const int kWhenceMask = 3;
5016 flags =
ARBSEEK_END | kForward | kSticky | kAbsolute;
5022 flags =
ARBSEEK_SET | kRewind | kSticky | kAbsolute;
5028 int direction = (flags & kRewind) ? -1 : 1;
5037 QString message = (flags & kRewind) ? tr(
"Rewind") :
5039 if (flags & kAbsolute)
5041 float time = direction;
5042 DoSeek(time, message,
true, (flags & kIgnoreCutlist) == 0);
5049 uint64_t targetRel = frameRel +
static_cast<uint64_t
>(direction);
5050 if (frameRel == 0 && direction < 0)
5054 targetRel = std::min(targetRel, maxRel);
5062 else if (flags & kSticky)
5066 else if (flags & kRewind)
5086 void TV::DoSeek(
float Time,
const QString &Msg,
bool TimeIsOffset,
bool HonorCutlist)
5091 bool limitkeys =
false;
5133 DoSeek(Seconds, tr(
"Jump To"),
false, HonorCutlist);
5145 int64_t time = ((seek / 100) * 3600) + ((seek % 100) * 60);
5149 DoSeek(time, tr(
"Jump Ahead"),
true, HonorCutlist);
5153 DoSeek(-time, tr(
"Jump Back"),
true, HonorCutlist);
5166 DoSeek(std::max(0.0F, dur -
static_cast<float>(time)), tr(
"Jump To"),
false, HonorCutlist);
5300 auto index =
static_cast<size_t>(Index);
5369 QString jobHost =
"";
5374 QString msg = tr(
"Try Again");
5381 msg = tr(
"Transcoding");
5391 int num_chapters = 0;
5396 return num_chapters;
5444 int currentTitle = 0;
5449 return currentTitle;
5464 int currentAngle = 0;
5469 return currentAngle;
5484 std::chrono::seconds seconds = 0s;
5547 info.text[
"title"] = tr(
"Skip");
5548 info.text[
"description"] = tr(
"Searching");
5560 QMap<uint,InputInfo> sources;
5565 uint sourceid =
info[
"sourceid"].toUInt();
5568 for (
auto & input : inputs)
5571 if ((!sources.contains(input.m_sourceId)) ||
5572 ((cardid == input.m_inputId) && (cardid != sources[input.m_sourceId].m_inputId)))
5574 sources[input.m_sourceId] = input;
5579 QMap<uint,InputInfo>::const_iterator beg = sources.constFind(sourceid);
5580 QMap<uint,InputInfo>::const_iterator sit = beg;
5582 if (sit == sources.constEnd())
5588 if (sit == sources.constEnd())
5589 sit = sources.constBegin();
5594 if (sit != sources.constBegin())
5598 QMap<uint,InputInfo>::const_iterator
tmp = sources.constBegin();
5599 while (
tmp != sources.constEnd())
5626 QCoreApplication::processEvents();
5628 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1,'%2',%3)").arg(ChanID).arg(ChanNum).arg(InputID));
5635 QStringList reclist;
5638 reclist.push_back(QString::number(InputID));
5640 else if (ChanID || !ChanNum.isEmpty())
5647 if (!reclist.empty())
5655 if (ChanID && ChanNum.isEmpty())
5658 if (!ChanNum.isEmpty())
5701 if (ChanNum.isEmpty() && ChanID)
5703 if (ChanNum.isEmpty() && InputID)
5709 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully restarted");
5722 playbackURL,
false,
true,
5749 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
5763 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No recorder to switch to...");
5777 LOG(VB_GENERAL, LOG_ERR,
"TV::ToggleChannelFavorite() -- currently disabled");
5845 bool commitSmart =
false;
5857 inputStr = inputStr.isEmpty() ?
"?" : inputStr;
5861 inputStr = entryStr +
" " + inputStr;
5865 inputStr = tr(
"Seek:",
"seek to location") +
" " + inputStr;
5875 static QString
add_spacer(
const QString &chan,
const QString &spacer)
5877 if ((chan.length() >= 2) && !spacer.isEmpty())
5878 return chan.left(chan.length()-1) + spacer + chan.right(1);
5890 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
5891 int size = chan.size();
5893 qsizetype size = chan.size();
5895 if ((size > 2) && (chan.at(size - 1) == chan.at(size - 2)))
5898 chan.right(1).toUInt(&ok);
5901 chan = chan.left(chan.length()-1);
5909 QString needed_spacer;
5910 uint pref_cardid = 0;
5911 bool is_not_complete =
true;
5913 bool valid_prefix =
false;
5917 chan, pref_cardid, is_not_complete, needed_spacer);
5920 #if DEBUG_CHANNEL_PREFIX
5921 LOG(VB_GENERAL, LOG_DEBUG, QString(
"valid_pref(%1) cardid(%2) chan(%3) "
5922 "pref_cardid(%4) complete(%5) sp(%6)")
5923 .arg(valid_prefix).arg(0).arg(chan)
5924 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5932 else if (!needed_spacer.isEmpty())
5938 #if DEBUG_CHANNEL_PREFIX
5939 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ValidPref(%1) CardId(%2) Chan(%3) "
5940 " PrefCardId(%4) Complete(%5) Sp(%6)")
5942 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5949 return !is_not_complete;
5954 bool commited =
false;
5956 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
5957 QString(
"livetv(%1) qchannum(%2) qchanid(%3)")
5987 if (channum.isEmpty())
6010 uint old_chanid = 0;
6016 LOG(VB_GENERAL, LOG_ERR,
LOC +
6017 "no active ctx playingInfo.");
6079 uint cardid,
const QString &channum)
6082 uint cur_sourceid = 0;
6095 if (cur_sourceid != sourceid && sourceid)
6102 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1, '%2')").arg(Chanid).arg(
Channum));
6108 QStringList reclist;
6109 QVector<uint> tunable_on;
6113 if (channum.isEmpty() && Chanid)
6134 QString needed_spacer;
6135 uint pref_cardid = 0;
6140 dummy, needed_spacer);
6142 LOG(VB_CHANNEL, LOG_INFO,
LOC +
6143 QString(
"CheckChannelPrefix(%1, pref_cardid %2, %3, '%4') "
6145 .arg(
Channum).arg(pref_cardid).arg(dummy).arg(needed_spacer)
6149 if (pref_cardid != cardid)
6158 getit = !tunable_on.contains(cardid);
6166 if (tunable_on.empty())
6172 for (
const auto& rec : std::as_const(
tmp))
6174 if ((Chanid == 0U) || tunable_on.contains(rec.toUInt()))
6175 reclist.push_back(rec);
6180 if (!reclist.empty())
6244 for (
const auto & option : Options)
6246 uint chanid = option.m_chanId;
6247 QString channum = option.m_chanNum;
6266 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Previous channel number '%1'").arg(channum));
6267 if (channum.isEmpty())
6277 if (!ImmediateChange)
6283 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"'%1'->'%2'")
6284 .arg(cur_channum, prev_channum));
6287 if (cur_channum != prev_channum && !prev_channum.isEmpty())
6296 if (ImmediateChange)
6310 emit
HideAll(
true,
nullptr,
true);
6328 bool hideAll =
false;
6344 else if (is_prog_info_disp && !paused)
6348 else if (IncludeStatusOSD)
6366 info.text[
"title"] = (paused ? tr(
"Paused") : tr(
"Position"));
6412 const QString& Value,
int Type,
const QString& Units,
6416 info.values.insert(
"position", Position);
6417 info.values.insert(
"relposition", Position);
6418 info.text.insert(
"title", Title);
6419 info.text.insert(
"description", Desc);
6420 info.text.insert(
"value", Value);
6421 info.text.insert(
"units", Units);
6427 LOG(VB_PLAYBACK, LOG_INFO, QString(
"UpdateOSDSeekMessage(%1, %2)").arg(Msg).arg(Timeout));
6433 info.text[
"title"] = Msg;
6468 infoMap[
"callsign"].isEmpty())
6480 SignalMonitorList::const_iterator it;
6481 for (it = slist.begin(); it != slist.end(); ++it)
6482 if (
"error" == it->GetShortName())
6483 infoMap[QString(
"error%1").arg(i++)] = it->GetName();
6485 for (it = slist.begin(); it != slist.end(); ++it)
6486 if (
"message" == it->GetShortName())
6487 infoMap[QString(
"message%1").arg(i++)] = it->GetName();
6491 uint ber = 0xffffffff;
6503 for (it = slist.begin(); it != slist.end(); ++it)
6505 if (
"error" == it->GetShortName())
6507 err = it->GetName();
6511 if (
"message" == it->GetShortName())
6513 msg = it->GetName();
6514 LOG(VB_GENERAL, LOG_INFO,
"msg: " + msg);
6518 infoMap[it->GetShortName()] = QString::number(it->GetValue());
6519 if (
"signal" == it->GetShortName())
6520 sig = it->GetNormalizedValue(0, 100);
6521 else if (
"snr" == it->GetShortName())
6522 snr = it->GetValue();
6523 else if (
"ber" == it->GetShortName())
6524 ber =
static_cast<uint>(it->GetValue());
6525 else if (
"pos" == it->GetShortName())
6526 pos = it->GetValue();
6527 else if (
"script" == it->GetShortName())
6528 tuned = it->GetValue();
6529 else if (
"seen_pat" == it->GetShortName())
6530 pat = it->IsGood() ?
"a" :
"_";
6531 else if (
"matching_pat" == it->GetShortName())
6532 pat = it->IsGood() ?
"A" : pat;
6533 else if (
"seen_pmt" == it->GetShortName())
6534 pmt = it->IsGood() ?
"m" :
"_";
6535 else if (
"matching_pmt" == it->GetShortName())
6536 pmt = it->IsGood() ?
"M" : pmt;
6537 else if (
"seen_mgt" == it->GetShortName())
6538 mgt = it->IsGood() ?
"g" :
"_";
6539 else if (
"matching_mgt" == it->GetShortName())
6540 mgt = it->IsGood() ?
"G" : mgt;
6541 else if (
"seen_vct" == it->GetShortName())
6542 vct = it->IsGood() ?
"v" :
"_";
6543 else if (
"matching_vct" == it->GetShortName())
6544 vct = it->IsGood() ?
"V" : vct;
6545 else if (
"seen_nit" == it->GetShortName())
6546 nit = it->IsGood() ?
"n" :
"_";
6547 else if (
"matching_nit" == it->GetShortName())
6548 nit = it->IsGood() ?
"N" : nit;
6549 else if (
"seen_sdt" == it->GetShortName())
6550 sdt = it->IsGood() ?
"s" :
"_";
6551 else if (
"matching_sdt" == it->GetShortName())
6552 sdt = it->IsGood() ?
"S" : sdt;
6553 else if (
"seen_crypt" == it->GetShortName())
6554 crypt = it->IsGood() ?
"c" :
"_";
6555 else if (
"matching_crypt" == it->GetShortName())
6556 crypt = it->IsGood() ?
"C" : crypt;
6559 infoMap[
"signal"] = QString::number(sig);
6563 QString slock = (
"1" == infoMap[
"slock"]) ?
"L" :
"l";
6564 QString lockMsg = (slock==
"L") ? tr(
"Partial Lock") : tr(
"No Lock");
6565 QString sigMsg = allGood ? tr(
"Lock") : lockMsg;
6567 QString sigDesc = tr(
"Signal %1%").arg(sig,2);
6569 sigDesc +=
" | " + tr(
"S/N %1dB").arg(log10(snr), 3,
'f', 1);
6570 if (ber != 0xffffffff)
6571 sigDesc +=
" | " + tr(
"BE %1",
"Bit Errors").arg(ber, 2);
6572 if ((pos >= 0) && (pos < 100))
6573 sigDesc +=
" | " + tr(
"Rotor %1%").arg(pos,2);
6577 else if (tuned == 2)
6579 else if (tuned == 3)
6584 sigDesc = sigDesc + QString(
" | (%1%2%3%4%5%6%7%8%9) %10")
6585 .arg(tuneCode, slock, pat, pmt, mgt, vct,
6591 else if (!msg.isEmpty())
6594 infoMap[
"description"] = sigDesc;
6601 if (allGood || (pmt ==
"M"))
6610 bool timed_out =
false;
6625 LOG(VB_GENERAL, LOG_ERR,
LOC +
6626 "You have no OSD, but tuning has already taken too long.");
6652 static QString s_nextSrc =
GET_KEY(
"TV Playback",
"NEXTSOURCE");
6653 static QString s_togCards =
GET_KEY(
"TV Playback",
"NEXTINPUT");
6655 QString message = tr(
6656 "You should have received a channel lock by now. "
6657 "You can continue to wait for a signal, or you "
6658 "can change the channel with %1 or %2, change "
6659 "video source (%3), inputs (%4), etc.")
6660 .arg(s_chanUp, s_chanDown, s_nextSrc, s_togCards);
6663 { {tr(
"OK"),
"DIALOG_INFO_CHANNELLOCK_0" } },
6664 {
"",
"DIALOG_INFO_CHANNELLOCK_0",
true } });
6669 bool result =
false;
6735 dvdName = tr(
"DVD");
6739 mainStatus = tr(
"Menu");
6743 mainStatus = tr(
"Still Frame");
6747 int playingTitle = 0;
6748 int playingPart = 0;
6753 mainStatus = tr(
"Title: %1 (%2)").arg(playingTitle)
6755 subStatus = tr(
"Chapter: %1/%2").arg(playingPart).arg(totalParts);
6790 for (
uint i : std::as_const(list))
6791 ret += QString(
"%1,").arg(i);
6794 return ret.left(ret.length()-1);
6801 QVector<uint> tunable_cards;
6805 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6806 return tunable_cards;
6810 mplexid = (32767 == mplexid) ? 0 : mplexid;
6812 uint excluded_input = 0;
6820 for (
auto & input : inputs)
6822 if (input.m_sourceId != sourceid)
6825 if (input.m_mplexId &&
6826 input.m_mplexId != mplexid)
6829 if (!input.m_mplexId && input.m_chanId &&
6830 input.m_chanId != ChanId)
6833 tunable_cards.push_back(input.m_inputId);
6836 if (tunable_cards.empty())
6837 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6839 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) yes { %2 }").arg(ChanId).arg(
toCommaList(tunable_cards)));
6840 return tunable_cards;
6843 void TV::Embed(
bool Embed, QRect Rect,
const QStringList& Data)
6868 if (!Data.isEmpty())
6880 if (Pause ^ waspaused)
6882 if (Pause ^ waspaused)
6907 LOG(VB_GENERAL, LOG_ERR,
LOC +
"no active ctx playingInfo.");
6934 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Pausing player: %1").arg(pause));
7017 QString message = QString(
"START_EPG %1 %2").arg(EditType).arg(arg);
7019 QCoreApplication::postEvent(
this, me);
7036 QString appName = tr(
"Video");
7042 appName = tr(
"DVD");
7044 lcd->switchToVolume(appName);
7070 const float kTimeStretchMin = 0.125;
7071 const float kTimeStretchMax = 2.0;
7072 const float kTimeStretchStep = 0.05F;
7076 if (new_ts_normal > kTimeStretchMax &&
7079 new_ts_normal = kTimeStretchMax;
7081 else if (new_ts_normal < kTimeStretchMin &&
7084 new_ts_normal = kTimeStretchMin;
7087 if (new_ts_normal > kTimeStretchMax ||
7088 new_ts_normal < kTimeStretchMin)
7151 QString message = tr(
"MythTV was set to sleep after %1 minutes and will exit in %d seconds.\n"
7152 "Do you wish to continue watching?")
7156 { { tr(
"Yes"),
"DIALOG_SLEEP_YES_0" },
7157 { tr(
"No"),
"DIALOG_SLEEP_NO_0" } }});
7178 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching TV, exiting");
7188 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Sleep timeout reached, exiting player.");
7206 QString message = tr(
"MythTV has been idle for %1 minutes and "
7207 "will exit in %d seconds. Are you still watching?")
7211 { { tr(
"Yes"),
"DIALOG_IDLE_YES_0" },
7212 { tr(
"No"),
"DIALOG_IDLE_NO_0" }}});
7235 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching LiveTV, exiting");
7248 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Idle timeout reached, leaving LiveTV");
7288 QString message = me->
Message();
7290 if (message.isEmpty())
7293 std::chrono::milliseconds
timeout = 0ms;
7294 if (me->ExtraDataCount() == 1)
7296 auto t = std::chrono::seconds(me->ExtraData(0).toInt());
7297 if (
t > 0s &&
t < 1000s)
7318 if (dce->GetData().userType() == qMetaTypeId<MythTVMenuNodeTuple>())
7322 QDomNode Node = Menu.GetNodeFromPath(data.m_path);
7323 if (dce->GetResult() == -1)
7330 OSDDialogEvent(dce->GetResult(), dce->GetResultText(), dce->GetData().toString());
7355 LOG(VB_GENERAL, LOG_NOTICE,
"DVD has been ejected, exiting playback");
7370 QString message = me->
Message();
7373 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
7375 if (me->ExtraDataCount() == 1)
7378 int value = me->ExtraData(0).toInt();
7408 if (me->ExtraDataCount() >= 2)
7410 width = me->ExtraData(0).toInt();
7411 height = me->ExtraData(1).toInt();
7413 if (me->ExtraDataCount() == 3)
7422 else if (message.startsWith(
"DONE_RECORDING"))
7424 std::chrono::seconds seconds = 0s;
7427 if (tokens.size() == NUMTOKENS)
7429 cardnum = tokens[1].toUInt();
7430 seconds = std::chrono::seconds(tokens[2].toInt());
7435 LOG(VB_GENERAL, LOG_ERR, QString(
"DONE_RECORDING event received "
7436 "with invalid number of arguments, "
7437 "%1 expected, %2 actual")
7439 .arg(tokens.size()-1));
7479 if (message.startsWith(
"ASK_RECORDING "))
7482 bool hasrec =
false;
7483 bool haslater =
false;
7484 if (tokens.size() >= 5)
7486 cardnum = tokens[1].toUInt();
7487 timeuntil = tokens[2].toInt();
7488 hasrec = (tokens[3].toInt() != 0);
7489 haslater = (tokens[4].toInt() != 0);
7491 LOG(VB_GENERAL, LOG_DEBUG,
7492 LOC + message + QString(
" hasrec: %1 haslater: %2")
7493 .arg(hasrec).arg(haslater));
7502 if (message.startsWith(
"QUIT_LIVETV"))
7504 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7517 if (message.startsWith(
"LIVETV_WATCH"))
7520 if (tokens.size() >= 3)
7522 cardnum = tokens[1].toUInt();
7523 watch = tokens[2].toInt();
7547 if (message.startsWith(
"LIVETV_CHAIN"))
7550 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
7559 if (message.startsWith(
"EXIT_TO_MENU"))
7568 if (message.startsWith(
"SIGNAL"))
7570 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7571 const QStringList& signalList = me->ExtraDataList();
7587 if (message.startsWith(
"NETWORK_CONTROL"))
7589 if ((tokens.size() >= 2) &&
7590 (tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
7592 QStringList tokens2 = message.split(
" ", Qt::SkipEmptyParts);
7593 if ((tokens2.size() >= 2) &&
7594 (tokens2[1] !=
"ANSWER") && (tokens2[1] !=
"RESPONSE"))
7603 if (message.startsWith(
"START_EPG"))
7605 int editType = tokens[1].toInt();
7606 QString arg = message.section(
" ", 2, -1);
7610 if (message.startsWith(
"COMMFLAG_START") && (tokens.size() >= 2))
7613 QDateTime evrecstartts;
7625 QString msg =
"COMMFLAG_REQUEST ";
7632 if (message.startsWith(
"COMMFLAG_UPDATE") && (tokens.size() >= 3))
7635 QDateTime evrecstartts;
7649 QStringList marks = tokens[2].split(
",", Qt::SkipEmptyParts);
7650 for (
int j = 0; j < marks.size(); j++)
7652 mark = marks[j].split(
":", Qt::SkipEmptyParts);
7653 if (marks.size() >= 2)
7654 newMap[mark[0].toULongLong()] =
static_cast<MarkTypes>(mark[1].toInt());
7664 if (message ==
"NOTIFICATION")
7685 recinfo.
ToMap(infoMap);
7702 map.insert(
"message_text", tr(
"Record"));
7710 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Unknown recording during live tv.");
7723 cmdmsg = tr(
"Record");
7726 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record on");
7735 cmdmsg = tr(
"Cancel Record");
7738 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record off");
7820 title = tr(
"Adjust Volume");
7837 if (Type ==
"EDIT_CUT_POINTS")
7843 "menu_cutlist.xml", tr(
"Edit Cut Points"),
7844 metaObject()->className(),
"TV Editing");
7850 else if (Type ==
"EDIT_CUT_POINTS_COMPACT")
7856 "menu_cutlist_compact.xml", tr(
"Edit Cut Points"),
7857 metaObject()->className(),
"TV Editing");
7863 else if (Type ==
"EXIT_EDIT_MODE")
7866 dialog.m_buttons.push_back( { tr(
"Save Cuts and Exit"),
"DIALOG_CUTPOINT_SAVEEXIT_0" } );
7867 dialog.m_buttons.push_back( { tr(
"Exit Without Saving"),
"DIALOG_CUTPOINT_REVERTEXIT_0" } );
7868 dialog.m_buttons.push_back( { tr(
"Save Cuts"),
"DIALOG_CUTPOINT_SAVEMAP_0" } );
7869 dialog.m_buttons.push_back( { tr(
"Undo Changes"),
"DIALOG_CUTPOINT_REVERT_0" } );
7870 dialog.m_back = {
"",
"DIALOG_CUTPOINT_DONOTHING_0",
true };
7874 map.insert(
"title", tr(
"Edit"));
7886 if (
Action ==
"DONOTHING" && osd)
7891 QStringList actions(
Action);
7893 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unrecognised cutpoint action");
7923 QString message = tr(
"This program is currently being edited");
7924 QString def = QString(
"DIALOG_EDITING_CONTINUE_%1").arg(
static_cast<int>(paused));
7926 { { tr(
"Continue Editing"), def,
false,
true },
7927 { tr(
"Do not edit"), QString(
"DIALOG_EDITING_STOP_%1").arg(
static_cast<int>(paused)) }},
7928 {
"", def,
true} });
7944 if (!WasPaused && paused)
7961 for (
auto it = newMap.cbegin(); it != newMap.cend(); ++it)
7962 infoMap.insert(it.key(), *it);
8021 if (osd &&
Action ==
"PROBE")
8029 else if (osd &&
Action ==
"OK")
8037 else if (osd &&
Action ==
"QUIT")
8051 const QString keys[4] = {
"XMLTV",
"callsign",
"channame",
"channum", };
8060 QMap<QString,bool> modifiable;
8061 modifiable[
"callsign"] = Info[
"callsign"].isEmpty();
8062 if (!modifiable[
"callsign"])
8064 QString unsetsign = tr(
"UNKNOWN%1",
"Synthesized callsign");
8065 int unsetcmpl = unsetsign.length() - 2;
8066 unsetsign = unsetsign.left(unsetcmpl);
8067 if (Info[
"callsign"].left(unsetcmpl) == unsetsign)
8068 modifiable[
"callsign"] =
true;
8070 modifiable[
"channame"] = Info[
"channame"].isEmpty();
8072 const std::array<const QString,2> xds_keys {
"callsign",
"channame", };
8073 for (
const auto & key : xds_keys)
8075 if (!modifiable[key])
8085 if ((key ==
"callsign") &&
8086 ((
tmp.length() > 5) || (
tmp.indexOf(
" ") >= 0)))
8098 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"result %1 text %2 action %3")
8099 .arg(QString::number(Result), Text,
Action));
8105 bool handled =
true;
8106 if (
Action.startsWith(
"DIALOG_"))
8108 Action.remove(
"DIALOG_");
8109 QStringList desc =
Action.split(
"_");
8110 bool valid = desc.size() == 3;
8116 else if (valid && desc[0] ==
"VIDEOEXIT")
8120 else if (valid && desc[0] ==
"SLEEP")
8124 else if (valid && desc[0] ==
"IDLE")
8128 else if (valid && desc[0] ==
"INFO")
8132 else if (valid && desc[0] ==
"EDITING")
8136 else if (valid && desc[0] ==
"ASKALLOW")
8140 else if (valid && desc[0] ==
"EDITOR")
8144 else if (valid && desc[0] ==
"CUTPOINT")
8148 else if ((valid && desc[0] ==
"DELETE") ||
8149 (valid && desc[0] ==
"CONFIRM"))
8158 LOG(VB_GENERAL, LOG_ERR,
"Unrecognised dialog event.");
8161 else if (Result < 0)
8178 else if (
Action ==
"CANCELPLAYLIST")
8204 else if (
Action ==
"TOGGLEMANUALZOOM")
8216 else if (
Action ==
"TOGGLESTRETCH")
8228 else if (
Action.startsWith(
"ADJUSTSTRETCH"))
8230 bool floatRead =
false;
8231 float stretch =
Action.right(
Action.length() - 13).toFloat(&floatRead);
8246 else if (
Action.startsWith(
"SELECTSCAN_"))
8278 else if (
Action.startsWith(
"TOGGLEPICCONTROLS"))
8283 else if (
Action ==
"TOGGLEASPECT")
8287 else if (
Action.startsWith(
"TOGGLEASPECT"))
8291 else if (
Action ==
"TOGGLEFILL")
8295 else if (
Action.startsWith(
"TOGGLEFILL"))
8299 else if (
Action ==
"MENU")
8303 else if (
Action ==
"AUTODETECT_FILL")
8313 if (
Action ==
"CHANGROUP_ALL_CHANNELS")
8319 Action.remove(
"CHANGROUP_");
8325 QString cur_channum;
8326 QString new_channum;
8332 new_channum = cur_channum;
8334 auto it = list.cbegin();
8335 for (; it != list.cend(); ++it)
8337 if ((*it).m_chanNum == cur_channum)
8343 if (it == list.end())
8348 if (it != list.end())
8349 new_channum = (*it).m_chanNum;
8352 LOG(VB_CHANNEL, LOG_INFO,
LOC +
8353 QString(
"Channel Group: '%1'->'%2'")
8354 .arg(cur_channum, new_channum));
8360 if (cur_channum != new_channum && !new_channum.isEmpty())
8379 else if (
Action ==
"SCHEDULE")
8392 else if (
Action.startsWith(
"JUMPCAST|"))
8394 QStringList tokens =
Action.split(
"|");
8395 if (tokens.size() == 3)
8397 else if (tokens.size() == 4)
8402 else if (
Action.startsWith(
"VISUALISER"))
8406 else if (
Action.startsWith(
"3D"))
8415 if (
Action ==
"TOGGLEBROWSE")
8417 else if (
Action ==
"PREVCHAN")
8419 else if (
Action.startsWith(
"SWITCHTOINPUT_"))
8424 else if (
Action ==
"EDIT")
8455 int chapter =
Action.right(3).toInt();
8460 int title =
Action.right(3).toInt();
8465 int angle =
Action.right(3).toInt();
8468 else if (
Action ==
"EDIT")
8473 else if (
Action ==
"TOGGLEAUTOEXPIRE")
8477 else if (
Action.startsWith(
"TOGGLECOMMSKIP"))
8481 else if (
Action ==
"QUEUETRANSCODE")
8485 else if (
Action ==
"QUEUETRANSCODE_AUTO")
8489 else if (
Action ==
"QUEUETRANSCODE_HIGH")
8493 else if (
Action ==
"QUEUETRANSCODE_MEDIUM")
8497 else if (
Action ==
"QUEUETRANSCODE_LOW")
8519 LOG(VB_GENERAL, LOG_ERR,
LOC +
8520 "Unknown menu action selected: " +
Action);
8531 bool visible =
false;
8544 if (
Action ==
"CHANNELLOCK")
8549 #define BUTTON(action, text) \
8550 result = Context.AddButton(Menu, active, (action), (text), "", false, "")
8551 #define BUTTON2(action, textActive, textInactive) \
8552 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), false, "")
8553 #define BUTTON3(action, textActive, textInactive, isMenu) \
8554 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), (isMenu), "")
8569 const QString &actionName = Context.
m_action;
8571 bool result =
false;
8574 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8591 if (actionName ==
"DIALOG_CUTPOINT_MOVEPREV_0")
8599 BUTTON2(actionName, tr(
"Move Previous Cut End Here"), tr(
"Move Start of Cut Here"));
8602 else if (actionName ==
"DIALOG_CUTPOINT_MOVENEXT_0")
8610 BUTTON2(actionName, tr(
"Move Next Cut Start Here"), tr(
"Move End of Cut Here"));
8613 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOBEGINNING_0")
8616 BUTTON(actionName, tr(
"Cut to Beginning"));
8618 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOEND_0")
8623 BUTTON(actionName, tr(
"Cut to End"));
8626 else if (actionName ==
"DIALOG_CUTPOINT_DELETE_0")
8629 BUTTON2(actionName, tr(
"Delete This Cut"), tr(
"Join Surrounding Cuts"));
8631 else if (actionName ==
"DIALOG_CUTPOINT_NEWCUT_0")
8634 BUTTON(actionName, tr(
"Add New Cut"));
8636 else if (actionName ==
"DIALOG_CUTPOINT_UNDO_0")
8640 QString text = tr(
"Undo - %1");
8641 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8644 else if (actionName ==
"DIALOG_CUTPOINT_REDO_0")
8648 QString text = tr(
"Redo - %1");
8649 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8652 else if (actionName ==
"DIALOG_CUTPOINT_CLEARMAP_0")
8654 BUTTON(actionName, tr(
"Clear Cuts"));
8656 else if (actionName ==
"DIALOG_CUTPOINT_INVERTMAP_0")
8658 BUTTON(actionName, tr(
"Reverse Cuts"));
8660 else if (actionName ==
"DIALOG_CUTPOINT_LOADCOMMSKIP_0")
8662 BUTTON(actionName, tr(
"Load Detected Commercials"));
8664 else if (actionName ==
"DIALOG_CUTPOINT_REVERT_0")
8666 BUTTON(actionName, tr(
"Undo Changes"));
8668 else if (actionName ==
"DIALOG_CUTPOINT_REVERTEXIT_0")
8670 BUTTON(actionName, tr(
"Exit Without Saving"));
8672 else if (actionName ==
"DIALOG_CUTPOINT_SAVEMAP_0")
8674 BUTTON(actionName, tr(
"Save Cuts"));
8676 else if (actionName ==
"DIALOG_CUTPOINT_SAVEEXIT_0")
8678 BUTTON(actionName, tr(
"Save Cuts and Exit"));
8692 if (!text.isEmpty())
8693 BUTTON(actionName, text);
8705 const QString &actionName = Context.
m_action;
8707 bool result =
false;
8712 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8802 if (
prefix ==
"SELECTSUBTITLE_")
8804 else if (
prefix ==
"SELECTRAWTEXT_")
8806 else if (
prefix ==
"SELECTCC708_")
8808 else if (
prefix ==
"SELECTCC608_")
8810 else if (
prefix ==
"SELECTTTC_")
8812 else if (
prefix ==
"SELECTAUDIO_")
8835 static const std::array<const speed,9> s_speeds {{
8836 { 0,
"", tr(
"Adjust")},
8837 { 50,
"0.5", tr(
"0.5x")},
8838 { 90,
"0.9", tr(
"0.9x")},
8839 {100,
"1.0", tr(
"1.0x")},
8840 {110,
"1.1", tr(
"1.1x")},
8841 {120,
"1.2", tr(
"1.2x")},
8842 {130,
"1.3", tr(
"1.3x")},
8843 {140,
"1.4", tr(
"1.4x")},
8844 {150,
"1.5", tr(
"1.5x")},
8847 for (
const auto & speed : s_speeds)
8869 BUTTON(
"CHANGROUP_ALL_CHANNELS", tr(
"All Channels"));
8870 ChannelGroupList::const_iterator it;
8874 QString
action =
prefix + QString::number(it->m_grpId);
8884 static constexpr std::array<const uint,3> kCasOrd { 0, 2, 1 };
8885 for (
uint csm : kCasOrd)
8902 QString chapter1 = QString(
"%1").arg(i+1, size, 10, QChar(48));
8903 QString chapter2 = QString(
"%1").arg(i+1, 3 , 10, QChar(48));
8905 QString desc = chapter1 + QString(
" (%1)").arg(timestr);
8918 QString angleIdx = QString(
"%1").arg(i, 3, 10, QChar(48));
8933 QString titleIdx = QString(
"%1").arg(i, 3, 10, QChar(48));
8946 QVector <QString> addednames;
8948 for (
auto & input : inputs)
8950 if (input.m_inputId == inputid ||
8951 addednames.contains(input.m_displayName))
8954 addednames += input.m_displayName;
8955 QString
action = QString(
"SWITCHTOINPUT_") +
8956 QString::number(input.m_inputId);
8968 uint sourceid =
info[
"sourceid"].toUInt();
8969 QMap<uint, bool> sourceids;
8971 for (
auto & input : inputs)
8973 if (input.m_sourceId == sourceid ||
8974 sourceids[input.m_sourceId])
8977 sourceids[input.m_sourceId] =
true;
8978 QString
action = QString(
"SWITCHTOINPUT_") +
8979 QString::number(input.m_inputId);
8986 if (actionName ==
"TOGGLEAUDIOSYNC")
8988 BUTTON(actionName, tr(
"Adjust Audio Sync"));
8992 BUTTON(actionName, tr(
"None"));
8994 else if (actionName ==
"DISABLEUPMIX")
8999 BUTTON(actionName, tr(
"Disable Audio Upmixer"));
9002 else if (actionName ==
"ENABLEUPMIX")
9007 BUTTON(actionName, tr(
"Auto Detect"));
9010 else if (actionName ==
"AUTODETECT_FILL")
9017 BUTTON(actionName, tr(
"Auto Detect"));
9020 else if (actionName ==
"TOGGLEMANUALZOOM")
9022 BUTTON(actionName, tr(
"Manual Zoom Mode"));
9024 else if (actionName ==
"DISABLESUBS")
9028 BUTTON(actionName, tr(
"Disable Subtitles"));
9030 else if (actionName ==
"ENABLESUBS")
9034 BUTTON(actionName, tr(
"Enable Subtitles"));
9036 else if (actionName ==
"DISABLEFORCEDSUBS")
9042 BUTTON(actionName, tr(
"Disable Forced Subtitles"));
9045 else if (actionName ==
"ENABLEFORCEDSUBS")
9051 BUTTON(actionName, tr(
"Enable Forced Subtitles"));
9054 else if (actionName ==
"DISABLEEXTTEXT")
9058 BUTTON(actionName, tr(
"Disable External Subtitles"));
9060 else if (actionName ==
"ENABLEEXTTEXT")
9064 BUTTON(actionName, tr(
"Enable External Subtitles"));
9066 else if (actionName ==
"TOGGLETTM")
9069 BUTTON(actionName, tr(
"Toggle Teletext Menu"));
9071 else if (actionName ==
"TOGGLESUBZOOM")
9074 BUTTON(actionName, tr(
"Adjust Subtitle Zoom"));
9076 else if (actionName ==
"TOGGLESUBDELAY")
9082 BUTTON(actionName, tr(
"Adjust Subtitle Delay"));
9085 else if (actionName ==
"PAUSE")
9088 BUTTON2(actionName, tr(
"Play"), tr(
"Pause"));
9090 else if (actionName ==
"TOGGLESTRETCH")
9092 BUTTON(actionName, tr(
"Toggle"));
9094 else if (actionName ==
"TOGGLEBROWSE")
9097 BUTTON(actionName, tr(
"Toggle Browse Mode"));
9099 else if (actionName ==
"CANCELPLAYLIST")
9102 BUTTON(actionName, tr(
"Cancel Playlist"));
9104 else if (actionName ==
"DEBUGOSD")
9106 BUTTON(actionName, tr(
"Playback Data"));
9108 else if (actionName ==
"JUMPFFWD")
9111 BUTTON(actionName, tr(
"Jump Ahead"));
9113 else if (actionName ==
"JUMPRWND")
9116 BUTTON(actionName, tr(
"Jump Back"));
9118 else if (actionName ==
"JUMPTODVDROOTMENU")
9123 BUTTON2(actionName, tr(
"DVD Root Menu"), tr(
"Top menu"));
9126 else if (actionName ==
"JUMPTOPOPUPMENU")
9129 BUTTON(actionName, tr(
"Popup menu"));
9131 else if (actionName ==
"JUMPTODVDTITLEMENU")
9134 BUTTON(actionName, tr(
"DVD Title Menu"));
9136 else if (actionName ==
"JUMPTODVDCHAPTERMENU")
9139 BUTTON(actionName, tr(
"DVD Chapter Menu"));
9141 else if (actionName ==
"PREVCHAN")
9144 BUTTON(actionName, tr(
"Previous Channel"));
9146 else if (actionName ==
"GUIDE")
9148 BUTTON(actionName, tr(
"Program Guide"));
9150 else if (actionName ==
"FINDER")
9152 BUTTON(actionName, tr(
"Program Finder"));
9154 else if (actionName ==
"VIEWSCHEDULED")
9156 BUTTON(actionName, tr(
"Upcoming Recordings"));
9158 else if (actionName ==
"SCHEDULE")
9160 BUTTON(actionName, tr(
"Edit Recording Schedule"));
9162 else if (actionName ==
"DIALOG_JUMPREC_X_0")
9164 BUTTON3(actionName, tr(
"Recorded Program"),
"",
true);
9170 else if (actionName ==
"JUMPPREV")
9185 else if (actionName ==
"EDIT")
9191 BUTTON2(actionName, tr(
"Edit Channel"), tr(
"Edit Recording"));
9194 else if (actionName ==
"TOGGLEAUTOEXPIRE")
9200 tr(
"Turn Auto-Expire OFF"), tr(
"Turn Auto-Expire ON"));
9203 else if (actionName ==
"QUEUETRANSCODE")
9208 BUTTON2(actionName, tr(
"Stop Transcoding"), tr(
"Default"));
9211 else if (actionName ==
"QUEUETRANSCODE_AUTO")
9216 BUTTON(actionName, tr(
"Autodetect"));
9219 else if (actionName ==
"QUEUETRANSCODE_HIGH")
9224 BUTTON(actionName, tr(
"High Quality"));
9227 else if (actionName ==
"QUEUETRANSCODE_MEDIUM")
9232 BUTTON(actionName, tr(
"Medium Quality"));
9235 else if (actionName ==
"QUEUETRANSCODE_LOW")
9240 BUTTON(actionName, tr(
"Low Quality"));
9247 BUTTON(actionName, tr(
"Cast"));
9258 if (!text.isEmpty())
9259 BUTTON(actionName, text);
9319 QString cur_channum = QString();
9322 if (!prev_channum.isEmpty() && prev_channum != cur_channum)
9374 QString text = Menu.
Translate(Node.toElement().attribute(
"text", Menu.
GetName()));
9375 const char* windowtitle {
"???" };
9381 Menu.
Show(Node, Selected, *
this, &
menu);
9382 QDomNode parent = Node.parentNode();
9383 if (!parent.parentNode().isNull())
9387 menu.m_back = {
"", v };
9396 map.insert(
"title", tr(
"Edit"));
9405 (void)tr(
"Playback Menu");
9406 (void)tr(
"Playback Compact Menu");
9408 (void)tr(
"Select Audio Track");
9409 (void)tr(
"Visualisation");
9411 (void)tr(
"Change Aspect Ratio");
9412 (void)tr(
"Adjust Fill");
9413 (void)tr(
"Adjust Picture");
9415 (void)tr(
"Advanced");
9416 (void)tr(
"Video Scan");
9417 (void)tr(
"Deinterlacer");
9418 (void)tr(
"Subtitles");
9419 (void)tr(
"Select Subtitle");
9420 (void)tr(
"Text Subtitles");
9421 (void)tr(
"Select ATSC CC");
9422 (void)tr(
"Select VBI CC");
9423 (void)tr(
"Select Teletext CC");
9424 (void)tr(
"Playback");
9425 (void)tr(
"Adjust Time Stretch");
9426 (void)tr(
"Picture-in-Picture");
9428 (void)tr(
"Channel Groups");
9429 (void)tr(
"Navigate");
9430 (void)tr(
"Commercial Auto-Skip");
9431 (void)tr(
"Chapter");
9434 (void)tr(
"Schedule");
9436 (void)tr(
"Jump to Program");
9437 (void)tr(
"Switch Input");
9438 (void)tr(
"Switch Source");
9440 (void)tr(
"Begin Transcoding");
9442 (void)tr(
"Recorded");
9443 (void)tr(
"Upcoming");
9446 (void)tr(
"Edit Cut Points");
9447 (void)tr(
"Edit Cut Points (Compact)");
9448 (void)tr(
"Cut List Options");
9456 "menu_playback.xml", tr(
"Playback Menu"),
9457 metaObject()->className(),
"TV Playback");
9459 "menu_playback_compact.xml", tr(
"Playback Compact Menu"),
9460 metaObject()->className(),
"TV Playback");
9472 if (Level < 0 || Level > 1)
9486 QList<QString> titles_seen;
9492 for (
auto *pi : *infoList)
9494 if (pi->GetRecordingGroup() !=
"LiveTV" || LiveTVInAllPrograms ||
9495 pi->GetRecordingGroup() == currecgroup)
9503 QMap<QString,ProgramList>::const_iterator Iprog;
9507 auto progIndex =
static_cast<uint>(plist.
size());
9508 const QString& group = Iprog.key();
9513 if (progIndex == 1 && Level == 0)
9515 dialog.m_buttons.push_back( {Iprog.key(), QString(
"JUMPPROG %1 0").arg(group) });
9517 else if (progIndex > 1 && Level == 0)
9519 QString act = QString(
"DIALOG_%1_%2_1")
9521 dialog.m_buttons.push_back( {group, act,
true, Selected == group });
9523 else if (Level == 1 && Iprog.key() == Category)
9525 for (
auto pit = plist.
begin(); pit != plist.
end(); ++pit)
9529 if (titles_seen.contains(
p->GetTitle()))
9532 titles_seen.push_back(
p->GetTitle());
9535 for (
auto *q : plist)
9539 if (q->GetTitle() !=
p->GetTitle())
9542 dialog.m_buttons.push_back( { q->GetSubtitle().isEmpty() ?
9543 q->GetTitle() : q->GetSubtitle(),
9544 QString(
"JUMPPROG %1 %2").arg(Iprog.key()).arg(j) });
9552 while (!infoList->empty())
9554 delete infoList->back();
9555 infoList->pop_back();
9560 if (!Category.isEmpty())
9563 dialog.m_back = { Category,
"DIALOG_" +
ACTION_JUMPREC +
"_X_0" };
9564 else if (Level == 0)
9578 bool recorded = (
ProgInfo.GetFilesize() > 0);
9579 QString table = recorded ?
"recordedcredits" :
"credits";
9586 query.
prepare(QString(
"SELECT role, people.name,"
9587 " roles.name, people.person FROM %1"
9589 " LEFT JOIN people ON"
9590 " credits.person = people.person"
9591 " LEFT JOIN roles ON"
9592 " credits.roleid = roles.roleid"
9593 " WHERE credits.chanid = :CHANID"
9594 " AND credits.starttime = :STARTTIME"
9595 " AND role IN ('guest','actor','guest_star')"
9596 " ORDER BY role, priority;").arg(table));
9601 if (query.
exec() && query.
size() > 0)
9610 role = query.
value(0).toString();
9626 int pid = query.
value(3).toInt();
9627 pname = QString::fromUtf8(query.
value(1)
9628 .toByteArray().constData()) +
9629 "|" + QString::number(pid);
9630 character = QString::fromUtf8(query.
value(2)
9631 .toByteArray().constData());
9633 if (role ==
"actor")
9634 m_actors.append(qMakePair(pname, character));
9635 else if (role ==
"guest_star")
9637 else if (role ==
"guest")
9638 m_guests.append(qMakePair(pname, character));
9645 const QVector<string_pair> & people)
9647 for (
const auto & [actor, role] : std::as_const(people))
9651 dialog.
m_buttons.push_back( {actor.split(
'|')[0],
9652 QString(
"JUMPCAST|%1").arg(actor),
true} );
9656 dialog.
m_buttons.push_back( {QString(
"%1 as %2")
9657 .arg(actor.split(
'|')[0], role),
9658 QString(
"JUMPCAST|%1").arg(actor),
true} );
9676 const QString & category)
9680 if (category.isEmpty())
9682 dialog.
m_buttons.push_back( {
"Recorded",
9683 QString(
"JUMPCAST|%1|%2|Recorded").arg(actor).arg(person_id) } );
9684 dialog.m_buttons.push_back( {
"Upcoming",
9685 QString(
"JUMPCAST|%1|%2|Upcoming").arg(actor).arg(person_id) } );
9690 if (category ==
"Upcoming")
9702 QString table =
"recordedcredits";
9704 query.
prepare(QString(
"SELECT chanid, starttime from %1"
9705 " where person = :PERSON"
9706 " ORDER BY starttime;").arg(table));
9709 QDateTime starttime;
9710 if (query.
exec() && query.
size() > 0)
9714 int chanid = query.
value(0).toInt();
9716 auto *pi =
new ProgramInfo(chanid, starttime.toUTC());
9717 if (!pi->GetTitle().isEmpty() &&
9718 pi->GetRecordingGroup() !=
"LiveTV" &&
9719 pi->GetRecordingGroup() !=
"Deleted")
9732 show = pi->GetTitle();
9735 if (!pi->GetSubtitle().isEmpty())
9737 show += QString(
" %1x%2 %3").arg(pi->GetSeason())
9738 .arg(pi->GetEpisode())
9739 .arg(pi->GetSubtitle());
9742 dialog.m_buttons.push_back( {
show,
9743 QString(
"JUMPPROG %1 %2").arg(actor).arg(++idx) });
9760 if (!message.isEmpty())
9773 desc = tr(
"Auto-Expire OFF");
9778 desc = tr(
"Auto-Expire ON");
9783 if (!desc.isEmpty())
9799 if (!desc.isEmpty())
9808 if (!Desc.isEmpty())
9824 for (
const auto&
action : std::as_const(Actions))
9826 if (!
action.startsWith(
"JUMPPROG"))
9830 QString key =
action.section(
" ",1,-2);
9831 uint index =
action.section(
" ",-1,-1).toUInt(&ok);
9848 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to locate jump to program '%1' @ %2")
9849 .arg(key,
action.section(
" ",-1,-1)));
9871 QTimer::singleShot(0,
this, Jump);
9879 LOG(VB_GENERAL, LOG_ERR,
"Failed to open jump to program GUI");
9887 std::chrono::minutes mins { 0min };
9910 if (Time.length() > 11)
9912 bool intRead =
false;
9913 mins = std::chrono::minutes(Time.right(Time.length() - 11).toUInt(&intRead));
9926 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time " + Time);
9931 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time string " + Time);
9943 out = tr(
"Sleep") +
" " + QString::number(mins.count());
9956 errorText = tr(
"MythTV is already using all available "
9957 "inputs for the channel you selected. "
9958 "If you want to watch an in-progress recording, "
9959 "select one from the playback menu. If you "
9960 "want to watch Live TV, cancel one of the "
9961 "in-progress recordings from the delete "
9965 errorText = tr(
"Error: MythTV is using all inputs, "
9966 "but there are no active recordings?");
9969 errorText = tr(
"MythTV has no capture cards defined. "
9970 "Please run the mythtv-setup program.");
10107 else if (!dvd->StartOfTitle())
10113 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10114 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10137 bool in_menu = dvd->IsInMenu();
10138 if (in_still && !dvd->NumMenuButtons())
10140 dvd->SkipStillFrame();
10143 else if (!dvd->EndOfTitle() && !in_still && !in_menu)
10147 else if (!in_still && !in_menu)
10149 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10150 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10151 std::chrono::seconds currentTime = dvd->GetCurrentTime();
10196 bool allowed =
false;
10219 videotype = tr(
"Live TV");
10221 videotype = tr(
"this DVD");
10225 videotype = tr(
"this Video");
10228 if (videotype.isEmpty())
10229 videotype = tr(
"this recording");
10233 dialog.m_buttons.push_back({tr(
"Exit %1").arg(videotype),
ACTION_STOP});
10235 dialog.m_buttons.push_back({tr(
"Exit Without Saving"),
"DIALOG_VIDEOEXIT_CLEARLASTPLAYEDPOSITION_0"});
10238 dialog.m_buttons.push_back({tr(
"Delete this recording"),
"DIALOG_VIDEOEXIT_CONFIRMDELETE_0"});
10240 dialog.m_buttons.push_back({tr(
"Keep watching"),
"DIALOG_VIDEOEXIT_KEEPWATCHING_0"});
10241 dialog.m_back = {
"",
"DIALOG_VIDEOEXIT_KEEPWATCHING_0",
true };
10242 emit ChangeOSDDialog(dialog);
10244 if (m_videoExitDialogTimerId)
10245 KillTimer(m_videoExitDialogTimerId);
10246 m_videoExitDialogTimerId = StartTimer(kVideoExitDialogTimeout, __LINE__);
10256 LOG(VB_GENERAL, LOG_ERR,
"It is unsafe to delete at the moment");
10264 LOG(VB_GENERAL, LOG_ERR,
"This program cannot be deleted at this time.");
10271 QString message = tr(
"Cannot delete program ") + QString(
"%1 ").arg(pginfo.
GetTitle());
10274 message += QString(
"\"%1\" ").arg(pginfo.
GetSubtitle());
10278 message += tr(
"because it is not a recording.");
10282 message += tr(
"because it is in use by");
10285 for (
int i = 0; (i + 2) < byWho.size(); i += 3)
10291 message +=
" " + byWho[i+2];
10295 {{ tr(
"OK"),
"DIALOG_DELETE_OK_0" }},
10296 {
"",
"DIALOG_DELETE_OK_0",
true }});
10319 QString message = QString(
"%1\n%2\n%3")
10320 .arg(Title, infoMap[
"title"], infoMap[
"timedate"]);
10326 if (Title ==
"End Of Recording")
10328 dialog.m_buttons.push_back({tr(
"Delete it, but allow it to re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10329 dialog.m_buttons.push_back({tr(
"Delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10330 dialog.m_buttons.push_back({tr(
"Save it so I can watch it again"),
ACTION_STOP,
false,
true});
10334 dialog.m_buttons.push_back({tr(
"Yes, and allow re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10335 dialog.m_buttons.push_back({tr(
"Yes, delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10336 dialog.m_buttons.push_back({tr(
"No, keep it"),
ACTION_STOP,
false,
true});
10338 dialog.m_back = {
"",
"DIALOG_PLAY_0_0",
true };
10362 if (
Action ==
"DELETEANDRERECORD" && delete_ok)
10369 else if (
Action ==
"JUSTDELETE" && delete_ok)
10375 else if (
Action ==
"CONFIRMDELETE")
10380 else if (
Action ==
"KEEPWATCHING" && !near_end)
10384 else if (
Action ==
"CLEARLASTPLAYEDPOSITION")
10463 bool paused =
false;
10515 case Qt::ApplicationState::ApplicationSuspended:
10517 LOG(VB_GENERAL, LOG_NOTICE,
"Exiting playback on app suspecnd");
10541 LOG(VB_GENERAL, LOG_ERR,
"An exception occurred");
void ChangePictureAttribute(PictureAttribute Attribute, bool Direction, int Value)
static SignalMonitorList Parse(const QStringList &slist)
Converts a list of strings to SignalMonitorValue classes.
void HandleStateChange()
Changes the state to the state on the front of the state change queue.
bool Create(void) override
void onApplicationStateChange(Qt::ApplicationState State)
static QString toCommaList(const QVector< uint > &list)
bool IsNearEnd(void)
Returns true iff near end of recording.
static const std::chrono::milliseconds kEndOfPlaybackCheckFrequency
void emitTVPlaybackUnpaused(void)
bool IsActionable(const QString &Action, const QStringList &Actions)
QString GetSortTitle(void) const
static constexpr const char * OSD_DLG_MENU
void SetLength(std::chrono::seconds len)
bool isActive(void) const
@ kState_WatchingBD
Watching BD is the state when we are watching a BD.
bool QueryIsDeleteCandidate(bool one_playback_allowed=false) const
Returns true iff this is a recording, it is not in use (except by the recorder), and at most one play...
QVector< string_pair > m_actors
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
void PrepToSwitchToRecordedProgram(const ProgramInfo &ProgInfo)
bool StartPlayer(TVState desiredState)
bool IsRecorderErrored(void) const
QSqlQuery wrapper that fetches a DB connection from the connection pool.
static void SetState(const QVariantMap &NewState)
MythScreenStack * GetMainStack()
void SetAutoCommercialSkip(CommSkipMode SkipMode=kCommSkipOff)
void RequestEmbedding(bool Embed, const QRect &Rect={}, const QStringList &Data={})
bool m_requestDelete
User wants last video deleted.
volatile int m_endOfPlaybackTimerId
bool IsErrored(void) const
This is set if the player encountered some irrecoverable error.
static bool IsTunerShared(uint inputidA, uint inputidB)
void DialogGetText(InfoMap &Map)
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
InfoMap m_lastSignalUIInfo
#define ACTION_SETCONTRAST
void GetPlayerWriteLock() const
void StartOsdNavigation()
static const std::chrono::milliseconds kSaveLastPlayPosTimeout
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
bool DialogVisible(const QString &Window=QString())
bool IsSameProgram(const ProgramInfo *ProgInfo) const
std::chrono::milliseconds SetSignalMonitoringRate(std::chrono::milliseconds rate, int notifyFrontend=1)
Sets the signal monitoring rate.
bool SeekHandleAction(const QStringList &Actions, bool IsDVD)
#define ACTION_DISABLEUPMIX
TVState GetState(void) const
bool SetChannelInfo(const InfoMap &infoMap)
void SendMessage(const QString &message)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
static bool StateIsPlaying(TVState State)
void RefreshEditorState(bool CheckSaved=false)
static constexpr const char * OSD_WIN_BROWSE
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
#define ACTION_VIEWSCHEDULED
#define ACTION_TOGGLESUBTITLEDELAY
static constexpr const char * ACTION_DOWN
void HandleSaveLastPlayPosEvent()
void BrowseEnd(bool ChangeChannel)
Ends channel browsing.
void SaveEditing(bool edit)
Sets "editing" field in "recorded" table to "edit".
bool HandleJumpToProgramAction(const QStringList &Actions)
static const Type kMythUserMessage
RemoteEncoder * RemoteGetExistingRecorder(const ProgramInfo *pginfo)
void switchToChannel(const QString &channum="", const QString &title="", const QString &subtitle="")
@ kState_None
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
uint64_t TranslatePositionAbsToRel(uint64_t position) const
static QString GetDisplayName(uint inputid)
bool IsTunablePriv(uint ChanId)
MythVideoOutput * GetVideoOutput(void)
static void REG_KEY(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
void UnlockPlayingInfo(const char *file, int line) const
bool IsPlayerChangingBuffers(void) const
static const Type kMythEventMessage
void ProcessNetworkControlCommand(const QString &Command)
QReadWriteLock m_playerLock
lock on player and playerActive changes
int GetRecorderNumber(void) const
QString ScanTypeToUserString(FrameScanType Scan, bool Forced=false)
static constexpr std::chrono::milliseconds kSMExitTimeout
Timeout after last Signal Monitor message for ignoring OSD when exiting.
void ITVRestart(bool IsLive)
Restart the MHEG/MHP engine.
int m_ffRewIndex
Index into m_ffRewSpeeds for FF and Rewind speeds.
static const Type kUpdateBrowseInfoEventType
QStringList m_lastSignalMsg
#define ACTION_ZOOMHORIZONTALIN
bool m_subtitleZoomAdjustment
True if subtitle zoom is turned on.
bool IsHDMVNavigation(void) const
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void ShowNotificationError(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
convenience utility to display error message as notification
void ChangeOSDDialog(const MythOSDDialogData &Data)
QString GetHostname(void) const
void ShowOSDMenu(bool isCompact=false)
void SetExitPlayer(bool SetIt, bool WantsTo)
MythOverlayState m_overlayState
void ShowNoRecorderDialog(NoRecorderMsg MsgType=kNoRecorders)
volatile int m_lcdVolumeTimerId
void MenuLazyInit(void *Field)
bool TranslateKeyPressOrGesture(const QString &Context, QEvent *Event, QStringList &Actions, bool IsLiveTV, bool AllowJumps=true)
#define ACTION_TOGGLESUBS
void SetPseudoLiveTV(const ProgramInfo *pi, PseudoState new_state)
std::vector< int > m_ffRewSpeeds
static QString GetSourceName(uint sourceid)
QString GetRecordingGroup() const
static QList< QKeyEvent * > ConvertScreenPressKeyMap(const QString &KeyList)
void UpdateBookmark(bool Clear=false)
static bool QueueJob(int jobType, uint chanid, const QDateTime &recstartts, const QString &args="", const QString &comment="", QString host="", int flags=0, int status=JOB_QUEUED, QDateTime schedruntime=QDateTime())
ProgramInfo * GetLastProgram() const
void SetPlayingInfo(const ProgramInfo *info)
assign programinfo to the context
A QElapsedTimer based timer to replace use of QTime as a timer.
void UnpauseLiveTV(bool Quietly=false)
Used in ChangeChannel() to restart video output.
void DoTogglePauseFinish(float Time, bool ShowOSD)
static constexpr const char * OSD_DLG_CUTPOINT
#define ACTION_BOTTOMLINEMOVE
void ScheduleInputChange()
static constexpr const char * ACTION_SCREENSHOT
int to_track_type(const QString &str)
void ToggleChannelFavorite(const QString &changroupname)
void ChangeAspectOverride(AspectOverrideMode AspectMode=kAspect_Toggle)
void UpdateOSDProgInfo(const char *WhichInfo)
Update and display the passed OSD set with programinfo.
bool m_wantsToQuit
True if the user told MythTV to stop playback.
const QString kRecorderInUseID
QString GetZoomString(float HorizScale, float VertScale, QPoint Move)
static bool ChangeJobCmds(int jobID, int newCmds)
void HandleTeletextAction(const QString &Action, bool &Handled)
bool HandleTrackAction(const QString &Action)
bool IsInMenu(void) const override
bool IsPlayerPlaying(void) const
virtual int GetNumAngles(void) const
void HandleOSDAlreadyEditing(const QString &Action, bool WasPaused)
MythTimer m_keyRepeatTimer
Queue of unprocessed key presses.
@ kPictureAttribute_Colour
bool IsWindowVisible(const QString &Window)
bool DialogIsVisible(const QString &Dialog)
float m_tsNormal
Time stretch speed, 1.0F for normal playback.
bool IsInStillFrame(void) const override
int m_tvmFreeRecorderCount
void SaveTotalFrames(int64_t frames)
Store the Total Frames at frame 0 in the recordedmarkup table.
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
uint m_initialChanID
Initial chanid override for Live TV.
void ChangeOSDText(const QString &Window, const InfoMap &Map, OSDTimeout Timeout)
bool m_underNetworkControl
initial show started via by the network control interface
void StartChannelEditMode()
Starts channel editing mode.
void emitTVPlaybackStopped(void)
void GetPartAndTitle(int &Part, int &Title) const
std::chrono::milliseconds m_sleepTimerTimeout
Current sleep timeout in msec.
#define ACTION_ZOOMVERTICALIN
#define ACTION_LISTRECORDEDEPISODES
static bool SetStartChannel(uint inputid, const QString &channum)
bool DialogHandleGesture(MythGestureEvent *Event)
Holds information on a TV Program one might wish to record.
bool HandleOSDVideoExit(const QString &Action)
uint m_dbAutoexpireDefault
int m_idleTimerId
Timer for turning off playback after idle period.
void OSDDialogEvent(int Result, const QString &Text, QString Action)
void GetCodecDescription(InfoMap &Map)
volatile int m_ccInputTimerId
@ kPictureAttributeSupported_Volume
bool m_savedPause
saved pause state before embedding
void emitTVPlaybackPlaying(void)
#define ACTION_TOGGLECHANCONTROLS
#define ACTION_TOGGELAUDIOSYNC
QString GetChannelName(int pos=-1) const
void ChangeOSDMessage(const QString &Message)
uint GetRecordingID(void) const
void ShowPreviousChannel()
void UpdateTVChain(const QStringList &data=QStringList())
void EnableVisualiser(bool Enable, bool Toggle=false, const QString &Name=QString())
QString GetID(void) const
bool IsPaused(void) const
bool RequestNextRecorder(bool ShowDialogs, const ChannelInfoList &Selection=ChannelInfoList())
void UpdateOSDSeekMessage(const QString &Msg, enum OSDTimeout Timeout)
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
static bool StateIsRecording(TVState State)
bool StartRecorder(std::chrono::milliseconds MaxWait=-1ms)
Starts recorder, must be called before StartPlayer().
bool GetEndOfRecording() const
This is set to true if the player reaches the end of the recording without the user explicitly exitin...
This class is used as a container for messages.
void CancelNextRecording(bool cancel)
#define ACTION_ENABLEUPMIX
void RetrieveCast(const ProgramInfo &ProgInfo)
void SleepDialogTimeout()
#define ACTION_TOGGLERECORD
int RemoteGetFreeRecorderCount(void)
void TeardownPlayer(void)
bool GetPlayingInfoMap(InfoMap &infoMap) const
#define BUTTON3(action, textActive, textInactive, isMenu)
FrameScanType NextScanOverride()
virtual int GetNumTitles(void) const
QList< QKeyEvent * > m_screenPressKeyMapPlayback
void customEvent(QEvent *Event) override
This handles all custom events.
volatile int m_errorRecoveryTimerId
void ResetWindow(const QString &Window)
QStringList m_visualiserList
static constexpr const char * OSD_DLG_SLEEP
virtual QString GetAngleName(int) const
QVariant value(int i) const
void DoTogglePause(bool ShowOSD)
static void RestoreScreensaver()
void ShowOSDAlreadyEditing()
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
static constexpr const char * ACTION_LEFT
bool HasQueuedChannel() const
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
bool m_clearPosOnExit
False unless requested by user on playback exit.
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
static constexpr const char * OSD_DLG_CONFIRM
void GetChapterTimes(QList< std::chrono::seconds > &Times)
QStringList m_tvmTracks[kTrackTypeCount]
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
Internal representation of a recording rule, mirrors the record table.
void(*)(void *, bool) EMBEDRETURNVOID
void emitTVPlaybackStarted(void)
static constexpr const char * OSD_DLG_INFO
bool TimeStretchHandleAction(const QStringList &Actions)
bool ToggleHandleAction(const QStringList &Actions, bool IsDVD)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
bool FFRewHandleAction(const QStringList &Actions)
static bool ExtractKey(const QString &uniquekey, uint &chanid, QDateTime &recstartts)
Extracts chanid and recstartts from a unique key generated by MakeUniqueKey().
QString GetPlayMessage(void) const
@ BROWSE_UP
Fetch information on previous channel.
QString GetAngleName(int Angle)
void ChangeChannel(const ChannelInfoList &Options)
#define ACTION_TOGGLEPGORDER
#define ACTION_PREVRECORDED
@ CHANNEL_DIRECTION_FAVORITE
void ChangeZoom(ZoomDirection Zoom)
static EMBEDRETURNVOIDEPG RunProgramGuidePtr
bool IsErrored(void) const
#define ACTION_ENABLESUBS
float GetFrameRate(void) const
bool ActiveHandleAction(const QStringList &Actions, bool IsDVD, bool IsDVDStillFrame)
void start(void)
starts measuring elapsed time.
std::chrono::minutes m_jumptime
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
@ kPictureAttributeSupported_Range
static EMBEDRETURNVOIDSCHEDIT RunScheduleEditorPtr
#define ACTION_MENUYELLOW
void DoArbSeek(ArbSeekWhence Whence, bool HonorCutlist)
uint64_t GetCurrentFrameCount(void) const
bool IsPlaying(std::chrono::milliseconds wait_in_msec=0ms, bool wait_for=true) const
static uint Parse(const QString &vbiformat)
QString GetPreviousChannel(void) const
volatile int m_networkControlTimerId
void StartProgramEditMode()
Starts Program Cut Map Editing mode.
static void show(uint8_t *buf, int length)
bool PictureAttributeHandleAction(const QStringList &Actions)
@ kOSDFunctionalType_PictureAdjust
@ kAdjustFill_AutoDetect_DefaultHalf
bool SubtitleZoomHandleAction(const QStringList &Actions)
#define BUTTON2(action, textActive, textInactive)
void StopStuff(bool StopRingBuffer, bool StopPlayer, bool StopRecorder)
Can shut down the ringbuffers, the players, and in LiveTV it can shut down the recorders.
#define ACTION_LOADCOMMSKIP
static uint GetMplexID(uint sourceid, const QString &channum)
void JumpTo(int num, std::chrono::seconds pos)
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
bool HandlePlayerSpeedChangeFFRew(void)
bool IsValidRecorder(void) const
void DoSwitchTitle(int Title)
void ChannelEditXDSFill(InfoMap &Info)
QString m_queuedInput
Input key presses queued up so far...
int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr, bool up)
Changes brightness/contrast/colour/hue of a recording.
void EnableCaptions(uint Mode, bool UpdateOSD=true)
static constexpr const char * OSD_DLG_DELETE
void StopPlaying(void) const
uint GetBrowseChanId(const QString &Channum, uint PrefCardid, uint PrefSourceid) const
Returns a chanid for the channum, or 0 if none is available.
virtual uint64_t GetBookmark(void)
std::chrono::seconds m_fftime
static uint GetNextChannel(const ChannelInfoList &sorted, uint old_chanid, uint mplexid_restriction, uint chanid_restriction, ChannelChangeDirection direction, bool skip_non_visible=true, bool skip_same_channum_and_callsign=false, bool skip_other_sources=false)
@ kPictureAttributeSupported_Colour
static constexpr const char * ACTION_SELECT
static const Type kEventType
QString GetRecordingGroup(void) const
#define ACTION_TOGGLEUPMIX
bool ShouldSwitchToAnotherCard(const QString &channelid)
Checks if named channel exists on current tuner, or another tuner. This only works on local recorders...
void emitTVPlaybackSought(qint64 position)
void SkipCommercials(int direction)
bool m_inPlaylist
show is part of a playlist
bool m_endOfRecording
!player->IsPlaying() && StateIsPlaying()
void ChangeTimeStretch(int Dir, bool AllowEdit=true)
static constexpr const char * OSD_WIN_MESSAGE
static bool StateIsLiveTV(TVState State)
#define ACTION_BOTTOMLINESAVE
#define ACTION_ZOOMASPECTDOWN
void GoToDVDProgram(bool Direction)
std::chrono::seconds GetTotalTimeOfTitle(void) const
get the total time of the title in seconds 90000 ticks = 1 sec
static TV * AcquireRelease(int &RefCount, bool Acquire, bool Create=false)
Statically create, destroy or check the existence of the TV instance.
void ToggleCaptionsByType(uint Type)
static constexpr const char * OSD_WIN_PROGEDIT
QMap< QString, ProgramList > m_progLists
void DeleteAllChildren(void)
Delete all child widgets.
bool GetLimitKeyRepeat(void) const
volatile int m_endOfRecPromptTimerId
@ kPictureAttributeSupported_Brightness
def scan(profile, smoonURL, gate)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
QRect m_playerBounds
Prior GUI window bounds, for DoEditSchedule() and player exit().
const QString & Message() const
void Embed(bool Embed, QRect Rect={}, const QStringList &Data={})
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QString GetPathname(void) const
static bool StartTV(ProgramInfo *TVRec, uint Flags, const ChannelInfoList &Selection=ChannelInfoList())
Start playback of media.
const MythTVMenu & getMenuFromId(MenuTypeId id)
void GoToMenu(const QString &Menu)
QString GetTitleName(int Title)
bool IsPlayerErrored(void) const
bool HandleOSDCutpoint(const QString &Action)
An action (for this plugin) consists of a description, and a set of key sequences.
std::vector< SignalMonitorValue > SignalMonitorList
void ApplyTranscoderProfileChange(const QString &profile) const
Sets the transcoder profile for a recording.
NoRecorderMsg
Type of message displayed in ShowNoRecorderDialog()
void SetAutoCommercialSkip(CommSkipMode autoskip)
bool m_dbEndOfRecExitPrompt
QHash< QString, QString > InfoMap
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
uint GetCardID(void) const
void addListener(QObject *listener)
Add a listener to the observable.
virtual bool SwitchTitle(int)
void PushPreviousChannel(void)
most recently selected channel to the previous channel list
QElapsedTimer m_lockTimer
float GetPlaySpeed(void) const
MythDisplay * GetDisplay()
static void DisableScreensaver()
void SwitchInputs(uint ChanID=0, QString ChanNum="", uint InputID=0)
void SetSpeedChangeTimer(std::chrono::milliseconds When, int Line)
static QString GetKey(const QString &Context, const QString &Action)
void PrepareToExitPlayer(int Line)
bool MenuItemDisplayPlayback(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
#define BUTTON(action, text)
std::chrono::seconds secsInFuture(const QDateTime &future)
#define ACTION_ENABLEFORCEDSUBS
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
void UnregisterForPlayback(QObject *sender)
static void insert_map(InfoMap &infoMap, const InfoMap &newMap)
void(*)(TV *, bool, bool) EMBEDRETURNVOIDFINDER
uint m_sleepIndex
Index into sleep_times.
bool IsRecording(bool *ok=nullptr)
static std::vector< uint > GetInputGroups(uint inputid)
static constexpr const char * OSD_WIN_STATUS
bool IsVideoBD(void) const
@ kPictureAttributeSupported_Contrast
uint64_t GetFramesPlayed(void) const
float ComputeSecs(uint64_t position, bool use_cutlist) const
StringDeque m_prevChan
Previous channels.
#define ACTION_BIGJUMPREW
static void ToggleChannelFavorite()
void HandleOSDSleep(const QString &Action)
void HandlePseudoLiveTVTimerEvent()
@ BROWSE_RIGHT
Fetch information on current channel in the future.
#define ACTION_SETAUDIOSYNC
void AskAllowRecording(const QStringList &Msg, int Timeuntil, bool HasRec, bool HasLater)
#define ACTION_ZOOMCOMMIT
int getLCDWidth(void) const
QList< std::chrono::seconds > m_tvmChapterTimes
volatile int m_signalMonitorTimerId
#define ACTION_SWITCHTITLE
static constexpr const char * OSD_WIN_PROGINFO
ChannelGroupList m_dbChannelGroups
void DoSwitchAngle(int Angle)
ChannelInfoList m_channelGroupChannelList
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
bool StartPlaying(std::chrono::milliseconds MaxWait=-1ms)
static bool IsJobQueuedOrRunning(int jobType, uint chanid, const QDateTime &recstartts)
PictureAttributeSupported
MythTVMenu m_cutlistCompactMenu
static const std::chrono::milliseconds kInputModeTimeout
void ChangeSpeed(int Direction)
bool AudioSyncHandleAction(const QStringList &Actions)
static int GetCount(void)
void DoEditSchedule(int EditType=kScheduleProgramGuide, const QString &EditArg="")
void SetInitialTVState(bool islivetv)
determine initial tv state and playgroup for the recording
static bool IsPaused()
Check whether playback is paused.
void HandleVideoExitDialogTimerEvent()
int GetQueuedInputAsInt(bool *OK=nullptr, int Base=10) const
static int ConfiguredTunerCards()
If any cards are configured, return the number.
int Playback(const ProgramInfo &ProgInfo)
void ToggleOSD(bool IncludeStatusOSD)
Cycle through the available Info OSDs.
std::vector< InputInfo > RemoteRequestFreeInputInfo(uint excluded_input)
void FillOSDMenuActorShows(const QString &actor, int person_id, const QString &category="")
InfoMap m_chanEditMap
Channel Editing initial map.
static const uint kPreviousSource
#define ACTION_3DTOPANDBOTTOMDISCARD
static QStringList lastProgramStringList
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
bool MenuItemDisplay(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu) override
uint m_queuedChanID
Queued ChanID (from EPG channel selector)
bool m_dbUseChannelGroups
void SetRecorder(RemoteEncoder *rec)
@ kPictureAttribute_Volume
#define ACTION_TOGGLEEXTTEXT
AspectOverrideMode m_aspectOverrideMode
ProgramInfo * m_playingInfo
Currently playing info.
void ScheduleStateChange()
void AdjustSubtitleZoom(int Delta)
void HandleLCDVolumeTimerEvent()
static constexpr const char * ACTION_TVPOWERON
int m_idleDialogTimerId
Timer for idle dialog.
#define ACTION_ENABLEVISUALISATION
void(*)(const ProgramInfo *, void *) EMBEDRETURNVOIDSCHEDIT
void SetManualZoom(bool ZoomON, const QString &Desc)
static int comp_originalAirDate_rev(const ProgramInfo *a, const ProgramInfo *b)
QRecursiveMutex m_chanEditMapLock
Lock for chanEditMap and ddMap.
void HandleEndOfRecordingExitPromptTimerEvent()
void SendSystemEvent(const QString &msg)
QHash< QString, int > values
bool eventFilter(QObject *Object, QEvent *Event) override
Prevent events from being sent to another object.
void SpawnLiveTV(const QString &chainid, bool pip, const QString &startchan)
Tells TVRec to Spawn a "Live TV" recorder.
bool m_stretchAdjustment
True if time stretch is turned on.
#define ACTION_DISABLEEXTTEXT
CommSkipMode GetAutoCommercialSkip(void)
#define ACTION_SEEKABSOLUTE
void LockPlayingInfo(const char *file, int line) const
void DoSeekAbsolute(long long Seconds, bool HonorCutlist)
bool m_dbRememberLastChannelGroup
std::chrono::milliseconds m_timecode
void ShowOSDCutpoint(const QString &Type)
void ChangeAllowForcedSubtitles(bool Allow)
#define ACTION_PREVSUBPAGE
int StartTimer(std::chrono::milliseconds Interval, int Line)
virtual std::chrono::seconds GetTitleDuration(int) const
static MythThemedMenu * menu
QString GetTitle(void) const
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
void ChangeAdjustFill(AdjustFillMode FillMode=kAdjustFill_Toggle)
std::chrono::seconds m_rewtime
void setUnderNetworkControl(bool setting)
bool ManualZoomHandleAction(const QStringList &Actions)
bool GoBack(void)
Attempts to back-up by trying to jump to the 'Go up' PGC, the root menu or the title menu in turn.
MythVisualiserState m_visualiserState
@ kDisplayRawTextSubtitle
std::chrono::seconds GetTitleDuration(int Title)
@ kAdjustingPicture_Channel
MythMediaBuffer * m_buffer
static EMBEDRETURNVOID RunPlaybackBoxPtr
void ChangeChannel(int channeldirection)
void(*)(TV *, int, const QString &) EMBEDRETURNVOIDPROGLIST
void SetTeletextPage(uint Page)
MBASE_PUBLIC int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
This method chops the input a and b into pieces of digits and non-digits (a1.05 becomes a | 1 | .
static const std::chrono::milliseconds kSpeedChangeCheckFrequency
void BrowseInit(std::chrono::seconds BrowseMaxForward, bool BrowseAllTuners, bool UseChannelGroups, const QString &DBChannelOrdering)
static const std::chrono::milliseconds kKeyRepeatTimeout
#define ACTION_CHANNELSEARCH
uint GetSourceID(void) const
void SetLiveRecording(bool recording)
void SetIgnoreLastPlayPos(bool ignore)
If "ignore" is true QueryLastPlayPos() will return 0, otherwise QueryLastPlayPos() will return the la...
void HandleITVAction(const QString &Action, bool &Handled)
PlayerContext m_playerContext
#define ACTION_TOGGLEOSDDEBUG
#define ACTION_ZOOMHORIZONTALOUT
@ kOSDFunctionalType_SubtitleZoomAdjust
void RestartITV(uint Chanid, uint Cardid, bool IsLiveTV)
ProgramInfo * m_pseudoLiveTVRec
QStringList GetTracks(uint Type)
volatile int m_pseudoChangeChanTimerId
void ShowOSDIdle()
After idleTimer has expired, display a dialogue warning the user that we will exit LiveTV unless they...
#define ACTION_JUMPTODVDTITLEMENU
static void showStatus(void)
static const Type kUpdateTvProgressEventType
@ kNoRecorders
No free recorders.
MythTVMenu m_playbackCompactMenu
void QuickRecord(void)
Create a kSingleRecord if not already scheduled.
static const std::chrono::milliseconds kEndOfPlaybackFirstCheckTimer
void HideAll(bool KeepSubs=true, MythScreenType *Except=nullptr, bool DropNotification=false)
static const std::chrono::milliseconds kSleepTimerDialogTimeout
@ kStartTVIgnoreProgStart
uint GetSignalLockTimeout(const QString &input)
QString m_queuedChanNum
Input key presses queued up so far to form a valid ChanNum.
bool m_savePosOnExit
False until first timer event.
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
void LockDeletePlayer(const char *file, int line) const
prevent MythPlayer from being deleted used to ensure player can only be deleted after osd in TV() is ...
SleepTimerInfo(QString String, std::chrono::milliseconds MilliSeconds)
void PlaybackMenuShow(const MythTVMenu &Menu, const QDomNode &Node, const QDomNode &Selected)
QString GetQueuedInput() const
bool MenuItemDisplayCutlist(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
static constexpr const char * OSD_DLG_IDLE
void SetCaptionsEnabled(bool Enable, bool UpdateOSD=true)
void HandleSpeedChangeTimerEvent()
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
void PopPreviousChannel(bool ImmediateChange)
@ kDisplayNUVTeletextCaptions
std::deque< QString > StringDeque
MThreadPool * m_posThreadPool
static bool IsTunable(uint ChanId)
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
static const uint kInputKeysMax
void SetLastProgram(const ProgramInfo *ProgInfo)
QVector< string_pair > m_guest_stars
@ kOSDFunctionalType_TimeStretchAdjust
#define ACTION_ZOOMVERTICALOUT
void SetFunctionalWindow(const QString &Window, enum OSDFunctionalType Type)
static uint get_chanid(const PlayerContext *ctx, uint cardid, const QString &channum)
@ kState_Error
Error State, if we ever try to enter this state errored is set.
AdjustFillMode m_adjustFillMode
std::chrono::seconds m_playingLen
Initial CalculateLength()
bool m_asInputMode
Are we in Arbitrary seek input mode?
#define ACTION_ENABLEEXTTEXT
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
PictureAttribute next_picattr(PictureAttributeSupported Supported, PictureAttribute Attribute)
volatile int m_lcdTimerId
#define ACTION_SETBRIGHTNESS
bool ProcessSmartChannel(QString &InputStr)
QWidget * GetPaintWindow()
static const std::chrono::milliseconds kEndOfRecPromptCheckFrequency
void ToggleMoveBottomLine()
QString GetPlaybackGroup(void) const
void HandleEndOfPlaybackTimerEvent()
#define ACTION_TOGGLESLEEP
virtual bool SwitchAngle(int)
void AddKeyToInputQueue(char Key)
static constexpr const char * OSD_DLG_VIDEOEXIT
QString toTypeString(PictureAdjustType type)
@ kStartTVByNetworkCommand
#define TRANSITION(ASTATE, BSTATE)
void HandleOSDClosed(int OSDType)
static constexpr const char * ACTION_TVPOWEROFF
#define ACTION_DISABLEFORCEDSUBS
std::chrono::milliseconds milliseconds
MythVideoBoundsState m_videoBoundsState
bool GetEditMode(void) const
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
void PlaybackMenuInit(const MythTVMenu &Menu)
bool IsSameProgram(const ProgramInfo &p) const
void ShowOSDStopWatchingRecording()
@ kState_ChangingState
This is a placeholder state which we never actually enter, but is returned by GetState() when we are ...
virtual void GetChapterTimes(QList< std::chrono::seconds > ×)
RemoteEncoder * m_switchToRec
Main recorder to use after a successful SwitchCards() call.
static constexpr const char * OSD_DLG_NAVIGATE
int NumPartsInTitle(void) const
void UpdateProgress(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
virtual int GetCurrentAngle(void) const
void(*)(uint, const QString &, const QDateTime, TV *, bool, bool, int) EMBEDRETURNVOIDEPG
static eu8 clamp(eu8 value, eu8 low, eu8 high)
void ChangeAudioOffset(std::chrono::milliseconds Delta, std::chrono::milliseconds Value=-9999ms)
void InitialisePlayerState()
PictureAttributeSupported m_supportedAttributes
@ kOSDFunctionalType_SubtitleDelayAdjust
bool m_allowRerecord
User wants to rerecord the last video if deleted.
void FillOSDMenuJumpRec(const QString &Category="", int Level=0, const QString &Selected="")
void UnlockDeletePlayer(const char *file, int line) const
allow player to be deleted.
bool GetAllowForcedSubtitles(void) const
QString PopPreviousChannel(void)
MythTimer m_lastSignalUIInfoTime
TvPlayWindow * m_myWindow
Our screen, if it exists.
void ShowLCDChannelInfo()
@ kAdjustingPicture_Recording
int64_t QueryTotalFrames(void) const
If present in recording this loads total frames of the main video stream from database's stream marku...
int GetNumSetting(const QString &key, int defaultval=0)
#define ACTION_SETBOOKMARK
void BrowseDispInfo(const BrowseInfo &Browseinfo)
void DisableEdit(int HowToSave)
void HandleOSDAskAllow(const QString &Action)
static constexpr const char * OSD_WIN_INPUT
bool ContextIsPaused(const char *File, int Location)
QRecursiveMutex m_askAllowLock
static MythDB * getMythDB()
QDate GetOriginalAirDate(void) const
static constexpr const char * OSD_DLG_EDITOR
#define ACTION_DISABLESUBS
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
void AdjustSubtitleDelay(std::chrono::milliseconds Delta)
static bool SysEventHandleAction(MythMainWindow *MainWindow, QKeyEvent *e, const QStringList &actions)
MythCaptionsState m_captionsState
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
static bool IsTVRunning()
Check whether media is currently playing.
static const std::chrono::milliseconds kIdleTimerDialogTimeout
bool CheckChannelPrefix(const QString &prefix, uint &complete_valid_channel_on_rec, bool &is_extra_char_useful, QString &needed_spacer)
Checks a prefix against the channels in the DB.
void HandleOSDInfo(const QString &Action)
@ kStartTVIgnoreLastPlayPos
bool m_dbContinueEmbedded
void SetTrack(uint Type, uint TrackNo)
BrowseInfo GetBrowsedInfo() const
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
bool CalcPlayerSliderPosition(osdInfo &info, bool paddedFields=false) const
void JumpChapter(int chapter)
virtual int GetNumChapters(void)
bool HasQueuedInput() const
PictureAttribute NextPictureAdjustType(PictureAdjustType Type, PictureAttribute Attr)
static constexpr const char * ACTION_UP
bool GetBoolSetting(const QString &key, bool defaultval=false)
bool ActivePostQHandleAction(const QStringList &Actions)
#define ACTION_ZOOMASPECTUP
void ChannelEditAutoFill(InfoMap &Info)
Automatically fills in as much information as possible.
virtual int GetCurrentTitle(void) const
@ kState_WatchingPreRecorded
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
QString GetError(void) const
void LockState(void) const
PseudoState m_pseudoLiveTVState
void ReturnOSDLock() const
#define ACTION_3DSIDEBYSIDEDISCARD
std::vector< MythOSDDialogButton > m_buttons
static QString tv_i18n(const QString &msg)
bool HandleLCDTimerEvent()
void HideOSDWindow(const char *window)
bool m_ccInputMode
Are we in CC/Teletext page/stream selection mode?
void ClearInputQueues(bool Hideosd)
Clear channel key buffer of input keys.
bool HandleOSDChannelEdit(const QString &Action)
Processes channel editing key.
bool LiveTV(bool ShowDialogs, const ChannelInfoList &Selection)
Starts LiveTV.
QString GetInputType(int pos=-1) const
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
static QString GET_KEY(const QString &Context, const QString &Action)
void EnableTeletext(int Page=0x100)
uint GetEpisode(void) const
void ReturnPlayerLock() const
@ kPictureAttributeSupported_None
AutoExpireType QueryAutoExpire(void) const
Returns "autoexpire" field from "recorded" table.
static bool comp_title(const ProgramInfo *a, const ProgramInfo *b)
void ShowOSDPromptDeleteRecording(const QString &Title, bool Force=false)
static const uint kNextSource
int GetValue(PictureAttribute Attribute)
void SetWatchingRecording(bool mode)
static QString GetIcon(uint chanid)
@ kOSDFunctionalType_SmartForward
Holds information on recordings and videos.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
static const std::vector< SleepTimerInfo > s_sleepTimes
void OverrideScan(FrameScanType Scan)
void VolumeChange(bool Up, int NewVolume=-1)
volatile int m_exitPlayerTimerId
QDateTime m_lastLockSeenTime
bool NextModeIsLarger(QSize Size)
Check whether the next mode is larger in size than the current mode.
void ResizeScreenForVideo(QSize Size={})
#define ACTION_MENUCOMPACT
static constexpr const char * ACTION_GETSTATUS
bool m_subtitleDelayAdjustment
True if subtitle delay is turned on.
#define ACTION_OSDNAVIGATION
static constexpr const char * ACTION_RIGHT
void ChangeUpmix(bool Enable, bool Toggle=false)
MThreadPool * GetPosThreadPool()
#define ACTION_TOGGLEVISUALISATION
volatile int m_asInputTimerId
void SetChannel(const QString &channel)
Dialog asking for user confirmation. Ok and optional Cancel button.
void ToStringList(QStringList &list) const
Serializes ProgramInfo into a QStringList which can be passed over a socket.
bool OptionalCaptionEnabled(uint Captions)
Return whether any optional captions are enabled.
static QString add_spacer(const QString &chan, const QString &spacer)
void SetScanOverride(FrameScanType Scan)
uint GetSeason(void) const
void SendMythSystemPlayEvent(const QString &msg, const ProgramInfo *pginfo)
void timerEvent(QTimerEvent *Event) override
bool m_sigMonMode
Are we in signal monitoring mode?
bool m_ignoreKeyPresses
should we ignore keypresses
bool CreatePlayer(TVState State, bool Muted=false)
PlayerContext * GetPlayerContext()
Return a pointer to TV::m_playerContext.
void HandleOSDIdle(const QString &Action)
bool QueryIsEditing(void) const
Queries "recorded" table for its "editing" field and returns true if it is set to true.
@ kState_WatchingVideo
Watching Video is the state when we are watching a video and is not a dvd or BD.
const QString kPlayerInUseID
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
void ChangeOSDPositionUpdates(bool Enable)
MythTimer m_lastSignalMsgTime
@ kPictureAttribute_Range
volatile int m_channelGroupId
void SetIgnoreBookmark(bool ignore)
If "ignore" is true GetBookmark() will return 0, otherwise GetBookmark() will return the bookmark pos...
void EditSchedule(int EditType=kScheduleProgramGuide, const QString &arg="")
void SwitchSource(uint Direction)
bool IsFileReadable(void)
Attempts to ascertain if the main file for this ProgramInfo is readable.
QVariant m_tvmJumprecBackHack
QString toTitleString(PictureAdjustType type)
virtual QString GetTitleName(int) const
bool GetNameAndSerialNum(QString &Name, QString &SerialNumber) override
Get the dvd title and serial num.
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
#define ACTION_JUMPTODVDROOTMENU
static uint GetSourceIDForChannel(uint chanid)
@ kOSDFunctionalType_AudioSyncAdjust
MythEditorState m_editorState
#define ACTION_JUMPTOPOPUPMENU
static const std::chrono::milliseconds kErrorRecoveryCheckFrequency
void SetPlayer(MythPlayer *newplayer)
void UpdateChannelList(int GroupID)
update the channel list with channels from the selected channel group
void StopLiveTV(void)
Tells TVRec to stop a "Live TV" recorder.
void PlaybackExiting(TV *Player)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
uint64_t TranslatePositionMsToFrame(std::chrono::milliseconds position, bool use_cutlist) const
StereoscopicMode ActionToStereoscopic(const QString &Action)
RemoteEncoder * RemoteRequestFreeRecorderFromList(const QStringList &qualifiedRecorders, uint excluded_input)
void emitTVPlaybackPaused(void)
void GetChannelInfo(InfoMap &infoMap, uint chanid=0)
void SetRingBuffer(MythMediaBuffer *Buffer)
This is the coordinating class of the Recorder Subsystem.
void PauseLiveTV()
Used in ChangeChannel() to temporarily stop video output.
MythAudioState m_audioState
static void MenuStrings()
FrameScanType GetScanTypeWithOverride() const
void ChangeMuteState(bool CycleChannels=false)
int m_ffRewSpeed
Caches value of m_ffRewSpeeds[m_ffRewIndex].
volatile int m_speedChangeTimerId
void EmbedPlayback(bool Embed, const QRect &Rect={})
static void FillOSDMenuCastButton(MythOSDDialogData &dialog, const QVector< string_pair > &people)
float DoTogglePauseStart()
static EMBEDRETURNVOID RunViewScheduledPtr
@ kTrackTypeTeletextCaptions
bool event(QEvent *Event) override
This handles all standard events.
MythNotificationCenter * GetNotificationCenter(void)
TVState
TVState is an enumeration of the states used by TV and TVRec.
TVState DequeueNextState(void)
bool IsVideoDVD(void) const
#define ACTION_TOGGLERECCONTROLS
int m_sleepDialogTimerId
Timer for sleep dialog.
bool InStateChange(void) const
@ kPictureAttributeSupported_Hue
static void SetFuncPtr(const char *Name, void *Pointer)
Import pointers to functions used to embed the TV window into other containers e.g.
static const Type kEventType
static uint GetSourceID(uint inputid)
void HideWindow(const QString &Window) override
#define ACTION_TOGGLEBOOKMARK
bool DiscMenuHandleAction(const QStringList &Actions) const
volatile int m_saveLastPlayPosTimerId
void exit(int retcode=0)
Use this to exit from the thread if you are using a Qt event loop.
void UpdateOSDStatus(const QString &Title, const QString &Desc, const QString &Value, int Type, const QString &Units, int Position=0, enum OSDTimeout Timeout=kOSDTimeout_Med)
MythMainWindow * m_mainWindow
MythMainWindow * GetMythMainWindow(void)
bool IsVideoFile(void) const
QMutex m_channelGroupLock
Lock necessary when modifying channel group variables.
void UpdateOSDSignal(const QStringList &List)
Updates Signal portion of OSD...
void DoTogglePictureAttribute(PictureAdjustType Type)
void RemoteCancelNextRecording(uint inputid, bool cancel)
bool m_weDisabledGUI
true if this instance disabled MythUI drawing.
void SetCommBreakMap(const frm_dir_map_t &NewMap)
QVector< string_pair > m_guests
static const int kInitFFRWSpeed
void ForceNextStateNone()
void DisableCaptions(uint Mode, bool UpdateOSD=true)
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
PictureAttributeSupported toMask(PictureAttribute PictureAttribute)
StereoscopicMode m_stereoOverride
bool HasPlayer(void) const
void BrowseChannel(const QString &Channum)
QAtomicInt m_referenceCount
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
void SetWatched(bool ForceWatched=false)
Determines if the recording should be considered watched.
bool CheckChannel(const QString &channel)
Checks if named channel exists on current tuner.
void ChangeCaptionTrack(int Direction)
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
bool IsExitingToMain() const
bool HasSoftwareFrames() const
int m_dbPlaybackExitPrompt
void SetValues(const QString &Window, const QHash< QString, int > &Map, OSDTimeout Timeout)
void SetProgram(const ProgramInfo &pginfo)
@ kPictureAttribute_Contrast
void PlaybackMenuDeinit(const MythTVMenu &Menu)
QList< QKeyEvent * > m_screenPressKeyMapLiveTV
MythTVMenu m_playbackMenu
MythDeque< TVState > m_nextState
MythScreenStack * GetStack(const QString &Stackname)
ProgramInfo * m_lastProgram
last program played with this player
@ kStereoscopicModeTopAndBottomDiscard
#define ACTION_BIGJUMPFWD
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
void DoQueueTranscode(const QString &Profile)
bool DoPlayerSeekToFrame(uint64_t FrameNum)
@ kAdjustFill_AutoDetect_DefaultOff
void SetInPlayList(bool InPlayList)
volatile int m_queueInputTimerId
CommSkipMode m_tvmCurSkip
void ClearKeyContext(const QString &Context)
bool DialogHandleKeypress(QKeyEvent *Event)
virtual bool JumpToFrame(uint64_t frame)
MythVideoColourState m_videoColourState
QString GetHostName(void)
int m_tvmCurtrack[kTrackTypeCount]
bool HandleProgramEditorActions(const QStringList &Actions)
void SetIgnoreProgStart(bool ignore)
If "ignore" is true QueryProgStart() will return 0, otherwise QueryProgStart() will return the progst...
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
static QStringList GetValidRecorderList(uint chanid, const QString &channum)
Returns list of the recorders that have chanid or channum in their sources.
static bool AllGood(const SignalMonitorList &slist)
Returns true if all the values in the list return true on IsGood().
QString GetProgramID(void) const
void DoSeek(float Time, const QString &Msg, bool TimeIsOffset, bool HonorCutlist)
bool QueryIsInUse(QStringList &byWho) const
Returns true if Program is in use.
void DoJumpChapter(int Chapter)
A custom event that represents a mouse gesture.
QString StateToString(TVState state)
Returns a human readable QString representing a TVState.
#define ACTION_TOGGLESUBTITLEZOOM
@ BROWSE_DOWN
Fetch information on next channel.
static const std::chrono::milliseconds kLCDTimeout
@ kStereoscopicModeSideBySideDiscard
void MoveResize(QRect &Geometry)
#define ACTION_JUMPTODVDCHAPTERMENU
QString GetXDS(const QString &key) const
int GetPictureAttribute(PictureAttribute attr)
bool HandlePlayerSpeedChangeEOF(void)
void ChangeVolume(bool Direction, int Volume)
#define ACTION_DISABLEVISUALISATION
virtual bool UsingVideoModes()
@ BROWSE_FAVORITE
Fetch information on the next favorite channel.
std::chrono::milliseconds m_dbIdleTimeout
PictureAttribute m_adjustingPictureAttribute
Picture attribute to modify (on arrow left or right)
void GetPlayerReadLock() const
void SetBookmark(bool Clear=false)
void FillOSDMenuCast(void)
uint GetTrackCount(uint Type)
RemoteEncoder * m_recorder
void SaveSetting(const QString &key, int newValue)
bool BrowseHandleAction(const QStringList &Actions)
int m_sleepTimerId
Timer for turning off playback.
std::vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
static bool IsExiting(void)
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
void ChangeStereoOverride(StereoscopicMode Mode)
void UnlockState(void) const
static constexpr const char * OSD_DLG_EDITING
void ChangeFFRew(int Direction)
bool GetAllowRerecord() const
Returns true if the user told Mythtv to allow re-recording of the show.
#define ACTION_VOLUMEDOWN
static const int kScreenPressRegionCount
screen area to keypress translation region is now 0..11 0 1 2 3 4 5 6 7 8 9 10 11
#define ACTION_CHANNELDOWN
Simple screen shown while the video player is starting up.
void ApplyRecordRecGroupChange(const QString &newrecgroup)
Sets the recording group, both in this RecordingInfo and in the database.
QString GetQueuedChanNum() const
int m_ffRewState
0 == normal, +1 == fast forward, -1 == rewind
#define ACTION_NEXTSUBPAGE
#define ACTION_EXITSHOWNOPROMPTS
bool IsRecording(void) const
static EMBEDRETURNVOIDPROGLIST RunProgramListPtr
std::chrono::milliseconds m_audioOffset
void PauseRecorder(void)
Tells TVRec to pause a recorder, used for channel and input changes.
T dequeue()
Removes item from front of list and returns a copy. O(1).
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
QString GetBasename(void) const
virtual int IncrRef(void)
Increments reference count.
MythDeque< QString > m_networkControlCommands
void WindowResized(const QSize &Size)
@ kDisplayTeletextCaptions
bool DoSetPauseState(bool Pause)
void PauseAudioUntilReady()
bool DoPlayerSeek(float Time)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
#define ACTION_JUMPCHAPTER
@ kState_WatchingDVD
Watching DVD is the state when we are watching a DVD.
uint GetQueuedChanID() const
void DoSkipCommercials(int Direction)
void dispatch(const MythEvent &event)
QString GetActionText(const QString &Context, const QString &Action) const
void setChannelProgress(const QString &time, float value)
static constexpr const char * OSD_DLG_ASKALLOW
bool BrowseStart(bool SkipBrowse=false)
Begins channel browsing.
@ kStereoscopicModeIgnore3D
static int comp_season_rev(const ProgramInfo *a, const ProgramInfo *b)
static const std::chrono::milliseconds kVideoExitDialogTimeout
@ kPictureAttribute_Brightness
bool m_audiosyncAdjustment
True if audiosync is turned on.
virtual bool FastForward(float seconds)
void removeListener(QObject *listener)
Remove a listener to the observable.
bool ProcessKeypressOrGesture(QEvent *Event)
#define ACTION_TOGGLEBACKGROUND
void ChangeState(TVState newState)
Puts a state change on the nextState queue.
virtual void UpdateSliderInfo(osdInfo &Info, bool PaddedFields=false)
#define ACTION_SWITCHANGLE
bool Init()
Performs instance initialization, returns true on success.
static QString GetStartChannel(uint inputid)
@ kOSDFunctionalType_Default
void UpdateLastPlayPosition(uint64_t frame)
void ToggleDetectLetterBox()
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
General purpose reference counter.
void start(QRunnable *runnable, const QString &debugName, int priority=0)
static EMBEDRETURNVOIDFINDER RunProgramFinderPtr
bool SubtitleDelayHandleAction(const QStringList &Actions)
@ kNoCurrRec
No current recordings.
bool HasPathname(void) const
void UpdateOSDTimeoutMessage()
PictureAdjustType m_adjustingPicture
Picture attribute type to modify.
volatile int m_videoExitDialogTimerId
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
void PlaybackLoop()
The main playback loop.
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
bool GetJumpToProgram() const
This is set if the user asked MythTV to jump to the previous recording in the playlist.
uint64_t TranslatePositionRelToAbs(uint64_t position) const
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
void emitTVPlaybackAborted(void)
@ BROWSE_LEFT
Fetch information on current channel in the past.
void enqueue(const T &d)
Adds item to the back of the list. O(1).
void ChangeTrack(uint Type, int Direction)
@ kAdjustingPicture_Playback
static QVector< uint > IsTunableOn(PlayerContext *Context, uint ChanId)
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
void ForceNextStateNone(void)
Removes any pending state changes, and puts kState_None on the queue.
void IsOSDVisible(bool &Visible)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
bool TranslateGesture(const QString &Context, MythGestureEvent *Event, QStringList &Actions, bool IsLiveTV)
RemoteEncoder * RemoteRequestNextFreeRecorder(int inputid)
virtual MythScreenType * GetTopScreen(void) const
QMap< QString, AskProgramInfo > m_askAllowPrograms
QString GetSubtitle(void) const
virtual bool Rewind(float seconds)
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
virtual int GetCurrentChapter(void)
std::vector< ChannelInfo > ChannelInfoList
@ kNoTuners
No capture cards configured.
QString m_dbChannelFormat