11#include <QApplication>
12#include <QDomDocument>
18#include <QRegularExpression>
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);
126 query.
prepare(
"SELECT COUNT(cardid) FROM capturecard;");
128 count = query.
value(0).toInt();
130 LOG(VB_RECORD, LOG_INFO,
131 "ConfiguredTunerCards() = " + QString::number(count));
145 static QMutex s_lock;
146 static TV* s_tv =
nullptr;
147 QMutexLocker locker(&s_lock);
159 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ref count error");
205 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Already have a player");
211 auto flags =
static_cast<PlayerFlags>(playerflags);
244 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
249 MaxWait = (MaxWait <= 0ms) ? 20s : MaxWait;
251 MaxWait = std::chrono::milliseconds::max();
261 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
262 QString(
"StartPlaying(): took %1 ms to start player.")
263 .arg(
t.elapsed().count()));
266 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
298 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Already have a TV object.");
303 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
306 bool quitAll =
false;
307 bool showDialogs =
true;
308 bool playCompleted =
false;
310 bool startSysEventSent =
false;
311 bool startLivetvEventSent =
false;
324 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed initializing TV");
346 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- begin");
351 else if (!startSysEventSent)
353 startSysEventSent =
true;
357 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- end");
361 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- begin");
362 if (!tv->
LiveTV(showDialogs, Selection))
367 else if (!startSysEventSent)
369 startSysEventSent =
true;
370 startLivetvEventSent =
true;
374 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- end");
379 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners configured");
381 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners free for live tv");
392 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Entering main playback loop.");
394 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Exiting main playback loop.");
402 curProgram = nextProgram;
416 quitAll |= !playerError.isEmpty();
419 QCoreApplication::processEvents();
423 playCompleted =
true;
433 if (startSysEventSent)
441 list.push_back(allowrerecord ?
"1" :
"0");
442 MythEvent me(
"LOCAL_PBB_DELETE_RECORDINGS", list);
453 else if (startSysEventSent)
458 if (!playerError.isEmpty())
468 if (startLivetvEventSent)
471 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
473 return playCompleted;
483 if (name ==
"playbackbox")
485 else if (name ==
"viewscheduled")
487 else if (name ==
"programguide")
489 else if (name ==
"programfinder")
491 else if (name ==
"scheduleeditor")
493 else if (name ==
"programlist")
500 "Play Program"),
"P,Media Play");
502 "Stop Program"),
"");
504 "Toggle recording status of current program"),
"R");
506 "Page the program guide back one day"),
"Home,Media Previous");
508 "Page the program guide forward one day"),
"End,Media Next");
510 "Page the program guide left"),
",,<,Ctrl+B,Media Rewind");
512 "Page the program guide right"),
">,.,Ctrl+F,Media Fast Forward");
514 "Toggle the current channel as a favorite"),
"?");
516 "Reverse the channel order in the program guide"),
"");
518 "Show the Program Guide"),
"S");
520 "Show the Program Finder"),
"#");
522 "Show the Channel Search"),
"");
523 REG_KEY(
"TV Frontend",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
524 "Cycle through channel groups and all channels in the "
525 "program guide."),
"/");
526 REG_KEY(
"TV Frontend",
"CHANUPDATE", QT_TRANSLATE_NOOP(
"MythControls",
527 "Switch channels without exiting guide in Live TV mode."),
"X");
529 "Volume down"),
"[,{,F10,Volume Down");
531 "Volume up"),
"],},F11,Volume Up");
533 "Mute"),
"|,\\,F9,Volume Mute");
534 REG_KEY(
"TV Frontend",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
535 "Cycle audio channels"),
"");
536 REG_KEY(
"TV Frontend",
"RANKINC", QT_TRANSLATE_NOOP(
"MythControls",
537 "Increase program or channel rank"),
"Right");
538 REG_KEY(
"TV Frontend",
"RANKDEC", QT_TRANSLATE_NOOP(
"MythControls",
539 "Decrease program or channel rank"),
"Left");
540 REG_KEY(
"TV Frontend",
"UPCOMING", QT_TRANSLATE_NOOP(
"MythControls",
541 "List upcoming episodes"),
"O");
543 "List scheduled upcoming episodes"),
"");
545 "List previously recorded episodes"),
"");
546 REG_KEY(
"TV Frontend",
"DETAILS", QT_TRANSLATE_NOOP(
"MythControls",
547 "Show details"),
"U");
548 REG_KEY(
"TV Frontend",
"VIEWINPUT", QT_TRANSLATE_NOOP(
"MythControls",
549 "Switch Recording Input view"),
"C");
550 REG_KEY(
"TV Frontend",
"CUSTOMEDIT", QT_TRANSLATE_NOOP(
"MythControls",
551 "Edit Custom Record Rule"),
"");
552 REG_KEY(
"TV Frontend",
"CHANGERECGROUP", QT_TRANSLATE_NOOP(
"MythControls",
553 "Change Recording Group"),
"");
554 REG_KEY(
"TV Frontend",
"CHANGEGROUPVIEW", QT_TRANSLATE_NOOP(
"MythControls",
555 "Change Group View"),
"");
557 "List recorded episodes"),
"");
577 if (selectKeys !=
"?")
580 togBkmKeys = selectKeys;
582 bkmKeys = selectKeys;
586 "Add Bookmark"), bkmKeys);
588 "Toggle Bookmark"), togBkmKeys);
589 REG_KEY(
"TV Playback",
"BACK", QT_TRANSLATE_NOOP(
"MythControls",
590 "Exit or return to DVD menu"),
"Esc,Back");
592 "Playback Compact Menu"),
"Alt+M");
594 "Clear OSD"),
"Backspace");
596 "Pause"),
"P,Space,Media Play");
598 "Fast Forward"),
"Right");
602 "Arbitrary Seek"),
"*");
604 "Seek to a position in seconds"),
"");
606 "Channel up"),
"Up");
608 "Channel down"),
"Down");
609 REG_KEY(
"TV Playback",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
610 "Switch to the next favorite channel"),
"/");
611 REG_KEY(
"TV Playback",
"PREVCHAN", QT_TRANSLATE_NOOP(
"MythControls",
612 "Switch to the previous channel"),
"H");
614 "Jump ahead"),
"PgDown");
616 "Jump back"),
"PgUp");
617 REG_KEY(
"TV Playback",
"INFOWITHCUTLIST", QT_TRANSLATE_NOOP(
"MythControls",
618 "Info utilizing cutlist"),
"");
620 "Jump to bookmark"),
"K");
621 REG_KEY(
"TV Playback",
"FFWDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
622 "Fast Forward (Sticky) or Forward one second while paused"),
">,.,Ctrl+F,Media Fast Forward");
623 REG_KEY(
"TV Playback",
"RWNDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
624 "Rewind (Sticky) or Rewind one second while paused"),
",,<,Ctrl+B,Media Rewind");
625 REG_KEY(
"TV Playback",
"NEXTSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
626 "Next Video Source"),
"Y");
627 REG_KEY(
"TV Playback",
"PREVSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
628 "Previous Video Source"),
"");
629 REG_KEY(
"TV Playback",
"NEXTINPUT", QT_TRANSLATE_NOOP(
"MythControls",
631 REG_KEY(
"TV Playback",
"NEXTCARD", QT_TRANSLATE_NOOP(
"MythControls",
633 REG_KEY(
"TV Playback",
"SKIPCOMMERCIAL", QT_TRANSLATE_NOOP(
"MythControls",
634 "Skip Commercial"),
"Z,End,Media Next");
635 REG_KEY(
"TV Playback",
"SKIPCOMMBACK", QT_TRANSLATE_NOOP(
"MythControls",
636 "Skip Commercial (Reverse)"),
"Q,Home,Media Previous");
638 "Jump to the start of the recording."),
"Ctrl+A");
639 REG_KEY(
"TV Playback",
"TOGGLEBROWSE", QT_TRANSLATE_NOOP(
"MythControls",
640 "Toggle channel browse mode"),
"O");
642 "Toggle recording status of current program"),
"R");
644 "Toggle the current channel as a favorite"),
"?");
646 "Volume down"),
"[,{,F10,Volume Down");
648 "Volume up"),
"],},F11,Volume Up");
650 "Mute"),
"|,\\,F9,Volume Mute");
652 "Set the volume"),
"");
653 REG_KEY(
"TV Playback",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
654 "Cycle audio channels"),
"");
656 "Toggle audio upmixer"),
"Ctrl+U");
658 QT_TRANSLATE_NOOP(
"MythControls",
"Move BottomLine off screen"),
"L");
660 QT_TRANSLATE_NOOP(
"MythControls",
"Save manual zoom for BottomLine"),
"");
661 REG_KEY(
"TV Playback",
"TOGGLEASPECT", QT_TRANSLATE_NOOP(
"MythControls",
662 "Toggle the video aspect ratio"),
"Ctrl+W");
663 REG_KEY(
"TV Playback",
"TOGGLEFILL", QT_TRANSLATE_NOOP(
"MythControls",
664 "Next Preconfigured Zoom mode"),
"W");
666 "Toggle any captions"),
"T");
668 "Enable any captions"),
"");
670 "Disable any captions"),
"");
671 REG_KEY(
"TV Playback",
"TOGGLETTC", QT_TRANSLATE_NOOP(
"MythControls",
672 "Toggle Teletext Captions"),
"");
673 REG_KEY(
"TV Playback",
"TOGGLESUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
674 "Toggle Subtitles"),
"");
675 REG_KEY(
"TV Playback",
"TOGGLECC608", QT_TRANSLATE_NOOP(
"MythControls",
676 "Toggle VBI CC"),
"");
677 REG_KEY(
"TV Playback",
"TOGGLECC708", QT_TRANSLATE_NOOP(
"MythControls",
678 "Toggle ATSC CC"),
"");
679 REG_KEY(
"TV Playback",
"TOGGLETTM", QT_TRANSLATE_NOOP(
"MythControls",
680 "Toggle Teletext Menu"),
"");
682 "Toggle External Subtitles"),
"");
684 "Enable External Subtitles"),
"");
686 "Disable External Subtitles"),
"");
687 REG_KEY(
"TV Playback",
"TOGGLERAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
688 "Toggle Text Subtitles"),
"");
690 REG_KEY(
"TV Playback",
"SELECTAUDIO_0", QT_TRANSLATE_NOOP(
"MythControls",
691 "Play audio track 1"),
"");
692 REG_KEY(
"TV Playback",
"SELECTAUDIO_1", QT_TRANSLATE_NOOP(
"MythControls",
693 "Play audio track 2"),
"");
694 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_0",QT_TRANSLATE_NOOP(
"MythControls",
695 "Display subtitle 1"),
"");
696 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_1",QT_TRANSLATE_NOOP(
"MythControls",
697 "Display subtitle 2"),
"");
698 REG_KEY(
"TV Playback",
"SELECTRAWTEXT_0",QT_TRANSLATE_NOOP(
"MythControls",
699 "Display Text Subtitle 1"),
"");
700 REG_KEY(
"TV Playback",
"SELECTCC608_0", QT_TRANSLATE_NOOP(
"MythControls",
701 "Display VBI CC1"),
"");
702 REG_KEY(
"TV Playback",
"SELECTCC608_1", QT_TRANSLATE_NOOP(
"MythControls",
703 "Display VBI CC2"),
"");
704 REG_KEY(
"TV Playback",
"SELECTCC608_2", QT_TRANSLATE_NOOP(
"MythControls",
705 "Display VBI CC3"),
"");
706 REG_KEY(
"TV Playback",
"SELECTCC608_3", QT_TRANSLATE_NOOP(
"MythControls",
707 "Display VBI CC4"),
"");
708 REG_KEY(
"TV Playback",
"SELECTCC708_0", QT_TRANSLATE_NOOP(
"MythControls",
709 "Display ATSC CC1"),
"");
710 REG_KEY(
"TV Playback",
"SELECTCC708_1", QT_TRANSLATE_NOOP(
"MythControls",
711 "Display ATSC CC2"),
"");
712 REG_KEY(
"TV Playback",
"SELECTCC708_2", QT_TRANSLATE_NOOP(
"MythControls",
713 "Display ATSC CC3"),
"");
714 REG_KEY(
"TV Playback",
"SELECTCC708_3", QT_TRANSLATE_NOOP(
"MythControls",
715 "Display ATSC CC4"),
"");
717 "Enable Forced Subtitles"),
"");
719 "Disable Forced Subtitles"),
"");
721 REG_KEY(
"TV Playback",
"NEXTAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
722 "Next audio track"),
"+");
723 REG_KEY(
"TV Playback",
"PREVAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
724 "Previous audio track"),
"-");
725 REG_KEY(
"TV Playback",
"NEXTSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
726 "Next subtitle track"),
"");
727 REG_KEY(
"TV Playback",
"PREVSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
728 "Previous subtitle track"),
"");
729 REG_KEY(
"TV Playback",
"NEXTRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
730 "Next Text track"),
"");
731 REG_KEY(
"TV Playback",
"PREVRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
732 "Previous Text track"),
"");
733 REG_KEY(
"TV Playback",
"NEXTCC608", QT_TRANSLATE_NOOP(
"MythControls",
734 "Next VBI CC track"),
"");
735 REG_KEY(
"TV Playback",
"PREVCC608", QT_TRANSLATE_NOOP(
"MythControls",
736 "Previous VBI CC track"),
"");
737 REG_KEY(
"TV Playback",
"NEXTCC708", QT_TRANSLATE_NOOP(
"MythControls",
738 "Next ATSC CC track"),
"");
739 REG_KEY(
"TV Playback",
"PREVCC708", QT_TRANSLATE_NOOP(
"MythControls",
740 "Previous ATSC CC track"),
"");
741 REG_KEY(
"TV Playback",
"NEXTCC", QT_TRANSLATE_NOOP(
"MythControls",
742 "Next of any captions"),
"");
744 REG_KEY(
"TV Playback",
"NEXTSCAN", QT_TRANSLATE_NOOP(
"MythControls",
745 "Next video scan overidemode"),
"");
746 REG_KEY(
"TV Playback",
"QUEUETRANSCODE", QT_TRANSLATE_NOOP(
"MythControls",
747 "Queue the current recording for transcoding"),
"X");
748 REG_KEY(
"TV Playback",
"SPEEDINC", QT_TRANSLATE_NOOP(
"MythControls",
749 "Increase the playback speed"),
"U");
750 REG_KEY(
"TV Playback",
"SPEEDDEC", QT_TRANSLATE_NOOP(
"MythControls",
751 "Decrease the playback speed"),
"J");
752 REG_KEY(
"TV Playback",
"ADJUSTSTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
753 "Turn on time stretch control"),
"A");
754 REG_KEY(
"TV Playback",
"STRETCHINC", QT_TRANSLATE_NOOP(
"MythControls",
755 "Increase time stretch speed"),
"");
756 REG_KEY(
"TV Playback",
"STRETCHDEC", QT_TRANSLATE_NOOP(
"MythControls",
757 "Decrease time stretch speed"),
"");
758 REG_KEY(
"TV Playback",
"TOGGLESTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
759 "Toggle time stretch speed"),
"");
761 QT_TRANSLATE_NOOP(
"MythControls",
762 "Turn on audio sync adjustment controls"),
"");
764 QT_TRANSLATE_NOOP(
"MythControls",
765 "Set the audio sync adjustment"),
"");
766 REG_KEY(
"TV Playback",
"TOGGLEPICCONTROLS",
767 QT_TRANSLATE_NOOP(
"MythControls",
"Playback picture adjustments"),
770 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture brightness"),
"");
772 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture contrast"),
"");
774 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture color"),
"");
776 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture hue"),
"");
778 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
779 "for this channel"),
"Ctrl+G");
781 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
782 "for this recorder"),
"G");
783 REG_KEY(
"TV Playback",
"CYCLECOMMSKIPMODE",
784 QT_TRANSLATE_NOOP(
"MythControls",
"Cycle Commercial Skip mode"),
787 "Show the Program Guide"),
"S");
789 "Show the Program Finder"),
"#");
791 "Toggle the Sleep Timer"),
"F8");
795 "Jump to previously played recording"),
"");
797 "Display menu of recorded programs to jump to"),
"");
799 "Display scheduled recording list"),
"");
801 "Display previously recorded episodes"),
"");
803 "Monitor Signal Quality"),
"Alt+F7");
805 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Root Menu"),
"");
807 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the Popup Menu"),
"");
809 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Chapter Menu"),
"");
811 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Title Menu"),
"");
813 QT_TRANSLATE_NOOP(
"MythControls",
"Exit Show without any prompts"),
816 "Jump to a chapter"),
"");
818 "Switch title"),
"");
820 "Switch angle"),
"");
822 "OSD Navigation"),
"");
824 "Zoom mode - shift up"),
"");
826 "Zoom mode - shift down"),
"");
828 "Zoom mode - shift left"),
"");
830 "Zoom mode - shift right"),
"");
832 QT_TRANSLATE_NOOP(
"MythControls",
833 "Zoom mode - increase aspect ratio"),
"3");
835 QT_TRANSLATE_NOOP(
"MythControls",
836 "Zoom mode - decrease aspect ratio"),
"7");
838 "Zoom mode - zoom in"),
"9");
840 "Zoom mode - zoom out"),
"1");
842 QT_TRANSLATE_NOOP(
"MythControls",
843 "Zoom mode - vertical zoom in"),
"8");
845 QT_TRANSLATE_NOOP(
"MythControls",
846 "Zoom mode - vertical zoom out"),
"2");
848 QT_TRANSLATE_NOOP(
"MythControls",
849 "Zoom mode - horizontal zoom in"),
"6");
851 QT_TRANSLATE_NOOP(
"MythControls",
852 "Zoom mode - horizontal zoom out"),
"4");
854 "Zoom mode - quit and abandon changes"),
"");
856 "Zoom mode - commit changes"),
"");
859 "Display list of cast members"),
"");
865 "Menu Green"),
"F3");
867 "Menu Yellow"),
"F4");
879 "Clear editing cut points"),
"C,Q,Home");
881 "Invert Begin/End cut points"),
"I,Home Page");
885 "Load cuts from detected commercials"),
"Z,End");
887 "Jump to the next cut point"),
"PgDown,Media Next");
889 "Jump to the previous cut point"),
"PgUp,Media Previous");
891 "Jump back 10x the normal amount"),
",,<,Ctrl+B,Media Rewind");
893 "Jump forward 10x the normal amount"),
">,.,Ctrl+F,Media Fast Forward");
895 "Cut point editor compact menu"),
"Alt+M");
899 "Next Page"),
"Down");
901 "Previous Page"),
"Up");
903 "Next Subpage"),
"Right");
905 "Previous Subpage"),
"Left");
907 "Toggle Teletext"),
"T");
911 "Menu Green"),
"F3");
913 "Menu Yellow"),
"F4");
917 "Menu White"),
"F6");
919 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle Background"),
"F7");
921 "Reveal hidden Text"),
"F8");
925 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle audio visualisation"),
"");
929 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle OSD playback information"),
"");
933 QT_TRANSLATE_NOOP(
"MythControls",
"Auto 3D"),
"");
935 QT_TRANSLATE_NOOP(
"MythControls",
"Ignore 3D"),
"");
937 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Side by Side"),
"");
939 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Top and Bottom"),
"");
993 { tr(
"Off",
"Sleep timer"), 0min },
994 { tr(
"30m",
"Sleep timer"), 30min },
995 { tr(
"1h",
"Sleep timer"), 60min },
996 { tr(
"1h30m",
"Sleep timer"), 90min },
997 { tr(
"2h",
"Sleep timer"), 120min }
1014 m_mainWindow(MainWindow),
1018 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Creating TV object");
1020 QObject::setObjectName(
"TV");
1037 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Finished creating TV object");
1042 QMap<QString,QString> kv;
1043 kv[
"LiveTVIdleTimeout"] =
"0";
1044 kv[
"BrowseMaxForward"] =
"240";
1045 kv[
"PlaybackExitPrompt"] =
"0";
1046 kv[
"AutomaticSetWatched"] =
"0";
1047 kv[
"EndOfRecordingExitPrompt"] =
"0";
1048 kv[
"JumpToProgramOSD"] =
"1";
1049 kv[
"GuiSizeForTV"] =
"0";
1050 kv[
"UseVideoModes"] =
"0";
1051 kv[
"JobsRunOnRecordHost"] =
"0";
1052 kv[
"ContinueEmbeddedTVPlay"] =
"0";
1053 kv[
"UseFixedWindowSize"] =
"1";
1054 kv[
"RunFrontendInWindow"] =
"0";
1055 kv[
"PersistentBrowseMode"] =
"0";
1056 kv[
"BrowseAllTuners"] =
"0";
1057 kv[
"ChannelOrdering"] =
"channum";
1059 kv[
"CustomFilters"] =
"";
1060 kv[
"ChannelFormat"] =
"<num> <sign>";
1062 kv[
"TryUnflaggedSkip"] =
"0";
1064 kv[
"ChannelGroupDefault"] =
"-1";
1065 kv[
"BrowseChannelGroup"] =
"0";
1066 kv[
"SmartForward"] =
"0";
1067 kv[
"FFRewReposTime"] =
"100";
1068 kv[
"FFRewReverse"] =
"1";
1070 kv[
"BrowseChannelGroup"] =
"0";
1071 kv[
"ChannelGroupDefault"] =
"-1";
1072 kv[
"ChannelGroupRememberLast"] =
"0";
1074 kv[
"VbiFormat"] =
"";
1075 kv[
"DecodeVBIFormat"] =
"";
1078 kv[
"PlaybackScreenPressKeyMap"] =
"P,Up,Z,],Left,Return,Return,Right,A,Down,Q,[";
1079 kv[
"LiveTVScreenPressKeyMap"] =
"P,Up,Z,S,Left,Return,Return,Right,A,Down,Q,F";
1081 constexpr std::array<const int,8> ff_rew_def { 3, 5, 10, 20, 30, 60, 120, 180 };
1082 for (
size_t i = 0; i < ff_rew_def.size(); i++)
1083 kv[QString(
"FFRewSpeed%1").arg(i)] = QString::number(ff_rew_def[i]);
1090 QString db_channel_ordering;
1092 m_dbIdleTimeout = std::chrono::minutes(kv[
"LiveTVIdleTimeout"].toUInt());
1093 auto db_browse_max_forward = std::chrono::minutes(kv[
"BrowseMaxForward"].toUInt());
1104 db_channel_ordering = kv[
"ChannelOrdering"];
1118 QString beVBI = kv[
"VbiFormat"];
1119 QString feVBI = kv[
"DecodeVBIFormat"];
1136 for (
size_t i = 0; i <
sizeof(ff_rew_def)/
sizeof(ff_rew_def[0]); i++)
1137 m_ffRewSpeeds.push_back(kv[QString(
"FFRewSpeed%1").arg(i)].toInt());
1154 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1158 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No MythMainWindow");
1179 fullscreen |= (0 == gui_width && 0 == gui_height);
1194 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created TvPlayWindow.");
1205 QCoreApplication::processEvents();
1230 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1236 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1257 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"-- lock");
1290 lcd->setFunctionLEDs(
FUNC_TV,
false);
1292 lcd->switchToTime();
1308 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1318 QCoreApplication::processEvents();
1394 .toUTC().toString(
"yyyy-MM-ddThh:mm:ssZ"));
1405 if (!
info.text[
"totalchapters"].isEmpty())
1407 QList<std::chrono::seconds> chapters;
1410 var.reserve(chapters.size());
1411 for (std::chrono::seconds chapter : std::as_const(chapters))
1412 var << QVariant((
long long)chapter.count());
1413 status.insert(
"chaptertimes", var);
1420 int currenttrack = -1;
1423 for (
int i = 0; i < list.size(); i++)
1425 if (i == currenttrack)
1426 status.insert(
"currentsubtitletrack", list[i]);
1427 tracks.insert(
"SELECTSUBTITLE_" + QString::number(i), list[i]);
1434 for (
int i = 0; i < list.size(); i++)
1436 if (i == currenttrack)
1437 status.insert(
"currentsubtitletrack", list[i]);
1438 tracks.insert(
"SELECTTTC_" + QString::number(i), list[i]);
1445 for (
int i = 0; i < list.size(); i++)
1447 if (i == currenttrack)
1448 status.insert(
"currentsubtitletrack", list[i]);
1449 tracks.insert(
"SELECTCC708_" + QString::number(i), list[i]);
1456 for (
int i = 0; i < list.size(); i++)
1458 if (i == currenttrack)
1459 status.insert(
"currentsubtitletrack", list[i]);
1460 tracks.insert(
"SELECTCC608_" + QString::number(i), list[i]);
1467 for (
int i = 0; i < list.size(); i++)
1469 if (i == currenttrack)
1470 status.insert(
"currentsubtitletrack", list[i]);
1471 tracks.insert(
"SELECTRAWTEXT_" + QString::number(i), list[i]);
1477 status.insert(
"currentsubtitletrack", tr(
"External Subtitles"));
1481 status.insert(
"totalsubtitletracks", tracks.size());
1482 if (!tracks.isEmpty())
1483 status.insert(
"subtitletracks", tracks);
1488 for (
int i = 0; i < list.size(); i++)
1490 if (i == currenttrack)
1491 status.insert(
"currentaudiotrack", list[i]);
1492 tracks.insert(
"SELECTAUDIO_" + QString::number(i), list[i]);
1495 status.insert(
"totalaudiotracks", tracks.size());
1496 if (!tracks.isEmpty())
1497 status.insert(
"audiotracks", tracks);
1521 for (
auto tit =
info.text.cbegin(); tit !=
info.text.cend(); ++tit)
1522 status.insert(tit.key(), tit.value());
1524 for (
auto vit =
info.values.cbegin(); vit !=
info.values.cend(); ++vit)
1525 status.insert(vit.key(), vit.value());
1552 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Idle Timer. %1 minutes")
1574 else if (!Selection.empty())
1576 for (
const auto & ci : Selection)
1578 uint chanid = ci.m_chanId;
1579 QString channum = ci.m_chanNum;
1580 if (!chanid || channum.isEmpty())
1584 if (chanid && !channum.isEmpty() && !cards.isEmpty())
1622 if (!
info->GetChanID())
1629 QString key =
info->MakeUniqueKey();
1634 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"AskAllowRecording -- " +
1635 QString(
"adding '%1'").arg(
info->m_title));
1643 LOG(VB_GENERAL, LOG_INFO,
LOC +
"-- " +
1644 QString(
"removing '%1'").arg(
info->GetTitle()));
1648 delete (*it).m_info;
1665 QString single_rec = tr(
"MythTV wants to record \"%1\" on %2 in %d seconds. Do you want to:");
1667 QString record_watch = tr(
"Record and watch while it records");
1668 QString let_record1 = tr(
"Let it record and go back to the Main Menu");
1669 QString let_recordm = tr(
"Let them record and go back to the Main Menu");
1670 QString record_later1 = tr(
"Record it later, I want to watch TV");
1671 QString record_laterm = tr(
"Record them later, I want to watch TV");
1672 QString do_not_record1= tr(
"Don't let it record, I want to watch TV");
1673 QString do_not_recordm= tr(
"Don't let them record, I want to watch TV");
1680 if ((*it).m_expiry <= timeNow)
1683 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"-- " +
1684 QString(
"removing '%1'").arg((*it).m_info->m_title));
1686 delete (*it).m_info;
1694 std::chrono::milliseconds timeuntil = 0ms;
1701 (*it).m_isInSameInputGroup = (*it).m_isConflicting =
true;
1706 bool busy_input_grps_loaded =
false;
1707 std::vector<uint> busy_input_grps;
1714 (*it).m_isInSameInputGroup =
1715 (cardid == (*it).m_info->GetInputID());
1717 if ((*it).m_isInSameInputGroup)
1721 if (!busy_input_grps_loaded)
1724 busy_input_grps_loaded =
true;
1727 std::vector<uint> input_grps =
1730 for (
uint grp : input_grps)
1732#ifdef __cpp_lib_ranges_contains
1733 if (std::ranges::contains(busy_input_grps, grp))
1736 grp) != busy_input_grps.end())
1739 (*it).m_isInSameInputGroup =
true;
1749 if (!(*it).m_isInSameInputGroup)
1750 (*it).m_isConflicting =
false;
1751 else if (cardid == (*it).m_info->GetInputID())
1752 (*it).m_isConflicting =
true;
1754 (*it).m_isConflicting =
true;
1756 (busy_input.
m_mplexId == (*it).m_info->QueryMplexID())) ||
1758 (busy_input.
m_chanId == (*it).m_info->GetChanID())))
1759 (*it).m_isConflicting =
false;
1761 (*it).m_isConflicting =
true;
1763 conflict_count += (*it).m_isConflicting ? 1 : 0;
1770 if (conflict_count == 0)
1772 LOG(VB_GENERAL, LOG_INFO,
LOC +
"The scheduler wants to make "
1773 "a non-conflicting recording.");
1777 else if (conflict_count == 1 && ((*it).m_info->GetInputID() == cardid))
1780 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"UpdateOSDAskAllowDialog -- " +
1788 .replace(
"<num>", (*it).m_info->GetChanNum())
1789 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1790 .replace(
"<name>", (*it).m_info->GetChannelName());
1792 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1798 .m_timeout=timeuntil };
1799 dialog.m_buttons.push_back({ record_watch,
"DIALOG_ASKALLOW_WATCH_0",
false, !((*it).m_hasRec)} );
1800 dialog.m_buttons.push_back({ let_record1,
"DIALOG_ASKALLOW_EXIT_0" });
1801 dialog.m_buttons.push_back({ ((*it).m_hasLater) ? record_later1 : do_not_record1,
1802 "DIALOG_ASKALLOW_CANCELRECORDING_0",
false, ((*it).m_hasRec) });
1807 if (conflict_count > 1)
1810 "MythTV wants to record these programs in %d seconds:");
1814 bool has_rec =
false;
1817 if (!(*it).m_isConflicting)
1820 QString title = (*it).m_info->GetTitle();
1821 if ((title.length() < 10) && !(*it).m_info->GetSubtitle().isEmpty())
1822 title +=
": " + (*it).m_info->GetSubtitle();
1823 if (title.length() > 20)
1824 title = title.left(17) +
"...";
1828 .replace(
"<num>", (*it).m_info->GetChanNum())
1829 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1830 .replace(
"<name>", (*it).m_info->GetChannelName());
1832 if (conflict_count > 1)
1834 message += tr(
"\"%1\" on %2").arg(title, channel);
1839 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1840 has_rec = (*it).m_hasRec;
1844 if (conflict_count > 1)
1847 message += tr(
"Do you want to:");
1850 bool all_have_later =
true;
1851 timeuntil = 9999999ms;
1854 if ((*it).m_isConflicting)
1856 all_have_later &= (*it).m_hasLater;
1861 timeuntil = (9999999ms == timeuntil) ? 0ms : timeuntil;
1863 if (conflict_count > 1)
1869 .m_timeout=timeuntil,
1871 { let_recordm,
"DIALOG_ASKALLOW_EXIT_0",
false,
true },
1872 { all_have_later ? record_laterm : do_not_recordm,
"DIALOG_ASKALLOW_CANCELCONFLICTING_0" }
1881 .m_timeout=timeuntil,
1883 { let_record1,
"DIALOG_ASKALLOW_EXIT_0",
false, !has_rec},
1884 { all_have_later ? record_later1 : do_not_record1,
"DIALOG_ASKALLOW_CANCELRECORDING_0",
false, has_rec}
1897 LOG(VB_GENERAL, LOG_ERR,
"allowrecordingbox : askAllowLock is locked");
1901 if (
Action ==
"CANCELRECORDING")
1906 else if (
Action ==
"CANCELCONFLICTING")
1910 if (pgm.m_isConflicting)
1914 else if (
Action ==
"WATCH")
1980#define TRANSITION(ASTATE,BSTATE) ((ctxState == (ASTATE)) && (desiredNextState == (BSTATE)))
1982#define SET_NEXT() do { nextState = desiredNextState; changed = true; } while(false)
1983#define SET_LAST() do { nextState = ctxState; changed = true; } while(false)
1988 QByteArray msg_arr = msg.toLatin1();
1989 QString msg_i18n = TV::tr(msg_arr.constData());
1990 QByteArray msg_i18n_arr = msg_i18n.toLatin1();
1991 return (msg_arr == msg_i18n_arr) ? msg_i18n : msg;
2006 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Called after fatal error detected.");
2010 bool changed =
false;
2016 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning, called with no state to change to.");
2024 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Attempting to change from %1 to %2")
2029 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to set to an error state!");
2054 QString channum =
"";
2058 QStringList reclist;
2061 query.
prepare(
"SELECT channum FROM channel "
2062 "WHERE chanid = :CHANID");
2065 channum = query.
value(0).toString();
2067 channum = QString::number(chanid);
2070 QString::number(chanid));
2075 if (!reclist.empty())
2094 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- begin");
2096 if (chanid && !channum.isEmpty())
2101 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- end");
2105 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2119 LOG(VB_GENERAL, LOG_INFO,
LOC +
2120 QString(
"playbackURL(%1) inputtype(%2)")
2125 playbackURL,
false,
true,
2139 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2194 LOG(VB_GENERAL, LOG_ERR,
LOC +
2195 "Couldn't find recorder for in-progress recording");
2214 QString message =
"COMMFLAG_REQUEST ";
2229 TV::tr(
"TV Player" ),
2256 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unknown state transition: %1 to %2")
2261 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Changing from %1 to %2")
2272 LOG(VB_GENERAL, LOG_INFO,
LOC +
"State is LiveTV");
2274 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateOSDInput done");
2276 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateLCD done");
2278 LOG(VB_GENERAL, LOG_INFO,
LOC +
"ITVRestart done");
2284 QString msg = tr(
"%1 Settings")
2337 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Main UI disabled.");
2340 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
" -- end");
2355 MaxWait = (MaxWait <= 0ms) ? 40s : MaxWait;
2358 bool recording =
false;
2362 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid Remote Encoder");
2370 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Lost contact with backend");
2374 std::this_thread::sleep_for(5us);
2380 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timed out waiting for recorder to start");
2384 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Took %1 ms to start recorder.")
2385 .arg(
t.elapsed().count()));
2404 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
2418 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stopping ring buffer");
2429 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"stopping recorder");
2434 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
2439 const int timer_id =
Event->timerId();
2447 bool handled =
true;
2508 if (!netCmd.isEmpty())
2534 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Last Program File does not exist");
2653 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Unknown timer: %1").arg(timer_id));
2663 QString lcd_time_string;
2664 bool showProgress =
true;
2681 lcd_time_string =
info.text[
"playedtime"] +
" / " +
info.text[
"totaltime"];
2683 if (lcd_time_string.length() > lcd->
getLCDWidth())
2684 lcd_time_string.remove(
' ');
2714 int timer = startTimer(Interval);
2716 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to start timer on line %1 of %2").arg(Line).arg(__FILE__));
2733 auto StateChange = [&]()
2751 QTimer::singleShot(0,
this, StateChange);
2756 auto InputChange = [&]()
2768 QTimer::singleShot(0,
this, InputChange);
2780 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Switching to program: %1")
2850 bool is_playing =
false;
2935 bool restartTimer =
false;
2941 restartTimer =
true;
2945 LOG(VB_CHANNEL, LOG_INFO,
"REC_PROGRAM -- channel change");
3011 if ((
Event->type() == QEvent::Resize))
3017 if ( (QEvent::KeyPress ==
Event->type() || QEvent::KeyRelease ==
Event->type())
3019 return TVPlaybackState::eventFilter(Object,
Event);
3021 QScopedPointer<QEvent> sNewEvent(
nullptr);
3025 if (QEvent::KeyPress ==
Event->type())
3040 switch (
Event->type())
3043 case QEvent::UpdateRequest:
3047 return TVPlaybackState::eventFilter(Object,
Event);
3050 return TVPlaybackState::eventFilter(Object,
Event);
3057 if (
Event ==
nullptr)
3058 return TVPlaybackState::event(
Event);
3060 if (QEvent::Resize ==
Event->type())
3065 const auto *qre =
dynamic_cast<const QResizeEvent*
>(
Event);
3068 return TVPlaybackState::event(
Event);
3077 if (QEvent::KeyPress ==
Event->type())
3079 const auto * ke =
dynamic_cast<QKeyEvent*
>(
Event);
3082 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"keypress: %1 '%2'")
3083 .arg(ke->key()).arg(ke->text()));
3091 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"mythgesture: g:%1 pos:%2,%3 b:%4")
3092 .arg(ge->GetGesture()).arg(ge->GetPosition().x())
3093 .arg(ge->GetPosition().y()).arg(ge->GetButton()));
3097 bool handled =
false;
3106 switch (
Event->type())
3109 case QEvent::UpdateRequest:
3119 return QObject::event(
Event);
3124 bool handled =
true;
3178 else if (
Action.startsWith(
"TOGGLE"))
3188 else if (
Action.startsWith(
"SELECT"))
3197 else if (
Action.startsWith(
"NEXT") ||
Action.startsWith(
"PREV"))
3199 int dir = (
Action.startsWith(
"NEXT")) ? +1 : -1;
3203 else if (
Action.endsWith(
"CC"))
3228 QStringList::const_iterator it;
3229 for (it = actions.begin(); it != actions.end(); ++it)
3231 if ((*it).startsWith(
"SYSEVENT") ||
3244 QList<QKeyEvent*> keyPressList;
3246 QStringList stringKeyList = KeyList.split(
',');
3248 for (
const auto & str : std::as_const(stringKeyList))
3250 QKeySequence keySequence(str);
3251 for (i = 0; i < keySequence.count(); i++)
3253#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3254 int keynum = keySequence[i];
3255 int keyCode = keynum & ~Qt::KeyboardModifierMask;
3256 auto modifiers =
static_cast<Qt::KeyboardModifiers
>(keynum & Qt::KeyboardModifierMask);
3258 int keyCode = keySequence[i].key();
3259 Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
3261 auto * keyEvent =
new QKeyEvent(QEvent::None, keyCode, modifiers);
3262 keyPressList.append(keyEvent);
3270 auto * keyEvent =
new QKeyEvent(QEvent::None, Qt::Key_Escape, Qt::NoModifier);
3271 keyPressList.append(keyEvent);
3274 return keyPressList;
3278 QStringList &Actions,
bool IsLiveTV)
3280 if (
Event && Context ==
"TV Playback")
3287 (
Event->GetButton() == Qt::LeftButton))
3291 QPoint pos =
Event->GetPosition();
3293 const int widthDivider = 4;
3294 int w4 = size.width() / widthDivider;
3295 region = pos.x() / w4;
3296 int h3 = size.height() / 3;
3297 region += (pos.y() / h3) * widthDivider;
3309 QStringList &Actions,
bool IsLiveTV,
bool AllowJumps)
3313 if (QEvent::KeyPress ==
Event->type())
3323 if (
Event ==
nullptr)
3329 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"ignoreKeys: %1").arg(ignoreKeys));
3340 auto* eKeyEvent =
dynamic_cast<QKeyEvent*
>(
Event);
3342 if (eKeyEvent->key() <= 0)
3345 switch(eKeyEvent->nativeScanCode())
3348 keycode = Qt::Key_MediaPause;
3356 auto *key =
new QKeyEvent(QEvent::KeyPress, keycode, eKeyEvent->modifiers());
3357 QCoreApplication::postEvent(
this, key);
3363 QStringList actions;
3364 bool handled =
false;
3365 bool alreadyTranslatedPlayback =
false;
3373 alreadyTranslatedPlayback =
true;
3375 if (handled || actions.isEmpty())
3378 bool esc =
IsActionable({
"ESCAPE",
"BACK" }, actions);
3389 if (QEvent::KeyPress ==
Event->type())
3391 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3449 if (QEvent::KeyPress ==
Event->type())
3451 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3454 const QString txt = qke->text();
3458 (void)txt.toInt(&ok, 16);
3459 if (ok || txt==
"_" || txt==
"-" || txt==
"#" || txt==
".")
3470 QStringList tt_actions;
3473 if (!handled && !tt_actions.isEmpty())
3475 for (
const QString&
action : std::as_const(tt_actions))
3487 if (!alreadyTranslatedPlayback)
3490 alreadyTranslatedPlayback =
true;
3493 if (!handled && !actions.isEmpty())
3495 for (
const QString&
action : std::as_const(actions))
3504 if (!alreadyTranslatedPlayback)
3507 if (handled || actions.isEmpty())
3515 if (QEvent::KeyPress ==
Event->type())
3531 for (
int i = 0; i < actions.size(); ++i)
3532 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"handled(%1) actions[%2](%3)")
3533 .arg(handled).arg(i).arg(actions[i]));
3541 for (
int i = 0; i < actions.size() && !handled; i++)
3543 const QString&
action = actions[i];
3545 int val =
action.toInt(&ok);
3563 bool handled =
true;
3583 for (
const auto&
action : std::as_const(Actions))
3594 static const QStringList passthrough =
3597 ACTION_MUTEAUDIO,
"CYCLEAUDIOCHAN",
"BOTTOMLINEMOVE",
"BOTTOMLINESAVE",
"TOGGLEASPECT"
3607 bool endmanualzoom =
false;
3608 bool handled =
true;
3609 bool updateOSD =
true;
3637 endmanualzoom =
true;
3639 endmanualzoom =
true;
3644 static const QStringList passthrough =
3652 QString msg = tr(
"Zoom Committed");
3656 msg = endmanualzoom ? tr(
"Zoom Ignored") :
3661 else if (endmanualzoom)
3708 bool handled =
true;
3733 bool handled =
true;
3756 bool handled =
true;
3779 bool handled =
true;
3814 bool IsDVD,
bool IsDVDStillFrame)
3816 bool handled =
true;
3818 if (
IsActionable(
"SKIPCOMMERCIAL", Actions) && !IsDVD) {
3820 }
else if (
IsActionable(
"SKIPCOMMBACK", Actions) && !IsDVD) {
3822 }
else if (
IsActionable(
"QUEUETRANSCODE", Actions) && !IsDVD) {
3824 }
else if (
IsActionable(
"QUEUETRANSCODE_AUTO", Actions) && !IsDVD) {
3826 }
else if (
IsActionable(
"QUEUETRANSCODE_HIGH", Actions) && !IsDVD) {
3828 }
else if (
IsActionable(
"QUEUETRANSCODE_MEDIUM", Actions) && !IsDVD) {
3830 }
else if (
IsActionable(
"QUEUETRANSCODE_LOW", Actions) && !IsDVD) {
3836 }
else if (
IsActionable(
"SPEEDINC", Actions) && !IsDVDStillFrame) {
3838 }
else if (
IsActionable(
"SPEEDDEC", Actions) && !IsDVDStillFrame) {
3842 }
else if (
IsActionable(
"CYCLECOMMSKIPMODE",Actions) && !IsDVD) {
3901 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
3927 std::chrono::milliseconds rate =
m_sigMonMode ? 0ms : 100ms;
3962 bool visible =
false;
4052 else if (
IsActionable({
"INFO",
"INFOWITHCUTLIST" }, Actions))
4073 for (
auto it = Actions.cbegin(); it != Actions.cend() && !handled; ++it)
4082 bool handled =
false;
4086 for (
int i = 0; i < Actions.size() && !handled; i++)
4088 const QString&
action = Actions[i];
4090 int val =
action.toInt(&ok);
4119 bool handled =
true;
4142 }
else if (
IsActionable(
"TOGGLEPICCONTROLS", Actions)) {
4191 info.text[
"title"] = tr(
"Position");
4199 bool handled =
true;
4221 else if (
IsActionable(
"NEXTSOURCE", Actions) && islivetv)
4225 else if (
IsActionable(
"PREVSOURCE", Actions) && islivetv)
4229 else if (
IsActionable(
"NEXTINPUT", Actions) && islivetv)
4237 else if (
IsActionable(
"PREVCHAN", Actions) && islivetv)
4310 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"(%1) ignoreKeys: %2").arg(
Command).arg(ignoreKeys));
4315 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Ignoring network control command because ignoreKeys is set");
4319 QStringList tokens =
Command.split(
" ", Qt::SkipEmptyParts);
4320 if (tokens.size() < 2)
4322 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not enough tokens in network control command " + QString(
"'%1'").arg(
Command));
4334 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4335 "Ignoring network control command\n\t\t\t" +
4336 QString(
"because dialog is waiting for a response"));
4340 if (tokens[1] !=
"QUERY")
4343 if (tokens.size() == 3 && tokens[1] ==
"CHANID")
4349 else if (tokens.size() == 3 && tokens[1] ==
"CHANNEL")
4353 static const QRegularExpression kChannelNumRE { R
"(^[-\.\d_#]+$)" };
4354 if (tokens[2] ==
"UP")
4356 else if (tokens[2] ==
"DOWN")
4358 else if (tokens[2].contains(kChannelNumRE))
4362 else if (tokens.size() == 3 && tokens[1] ==
"SPEED")
4366 if (tokens[2] ==
"0x")
4373 else if (tokens[2] ==
"normal")
4383 static const QRegularExpression kSpeedRE { R
"(^\-*(\d*\.)?\d+x$)" };
4384 float tmpSpeed = 1.0F;
4387 if (tokens[2].contains(kSpeedRE))
4389 QString speed = tokens[2].left(tokens[2].length()-1);
4390 tmpSpeed = speed.toFloat(&ok);
4394 static const QRegularExpression re { R
"(^(\-*\d+)\/(\d+)x$)" };
4395 auto match = re.match(tokens[2]);
4396 if (match.hasMatch())
4398 QStringList matches = match.capturedTexts();
4399 int numerator = matches[1].toInt(&ok);
4400 int denominator = matches[2].toInt(&ok);
4402 if (ok && denominator != 0)
4403 tmpSpeed =
static_cast<float>(numerator) /
static_cast<float>(denominator);
4411 float searchSpeed = fabs(tmpSpeed);
4416 if (tmpSpeed == 0.0F)
4424 else if (tmpSpeed == 1.0F)
4443 else if (tmpSpeed > 1)
4451 else if (0.125F <= tmpSpeed && tmpSpeed <= 2.0F)
4459 LOG(VB_GENERAL, LOG_WARNING, QString(
"Couldn't find %1 speed. Setting Speed to 1x")
4460 .arg(
static_cast<double>(searchSpeed)));
4467 LOG(VB_GENERAL, LOG_ERR, QString(
"Found an unknown speed of %1").arg(tokens[2]));
4471 else if (tokens.size() == 2 && tokens[1] ==
"STOP")
4478 static const QRegularExpression kDigitsRE {
"^\\d+$" };
4482 if (tokens[2] ==
"BEGINNING")
4484 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
4486 else if (tokens[2] ==
"FORWARD")
4490 else if (tokens[2] ==
"BACKWARD")
4494 else if ((tokens[2] ==
"POSITION" ||
4495 tokens[2] ==
"POSITIONWITHCUTLIST") &&
4496 (tokens.size() == 4) &&
4497 (tokens[3].contains(kDigitsRE)))
4499 DoSeekAbsolute(tokens[3].toInt(), tokens[2] ==
"POSITIONWITHCUTLIST");
4502 else if (tokens.size() >= 3 && tokens[1] ==
"SUBTITLES")
4505 uint track = tokens[2].toUInt(&ok);
4517 uint size =
static_cast<uint>(subs.size());
4520 if (track >=
start && track < finish)
4529 finish =
start + size;
4530 if (track >=
start && track < finish)
4539 finish =
start + size;
4540 if (track >=
start && track < finish)
4549 finish =
start + size;
4550 if (track >=
start && track < finish)
4559 finish =
start + size;
4560 if (track >=
start && track < finish)
4569 finish =
start + size;
4570 if (track >=
start && track < finish)
4578 else if (tokens.size() >= 3 && tokens[1] ==
"VOLUME")
4580 static const QRegularExpression re {
"(\\d+)%?" };
4581 auto match = re.match(tokens[2]);
4582 if (match.hasMatch())
4584 QStringList matches = match.capturedTexts();
4586 LOG(VB_GENERAL, LOG_INFO, QString(
"Set Volume to %1%").arg(matches[1]));
4589 int vol = matches[1].toInt(&ok);
4593 if (0 <= vol && vol <= 100)
4597 else if (tokens.size() >= 3 && tokens[1] ==
"QUERY")
4599 if (tokens[2] ==
"POSITION")
4614 static const QRegularExpression re {
"Play (.*)x" };
4616 if (match.hasMatch())
4618 QStringList matches = match.capturedTexts();
4619 speedStr = QString(
"%1x").arg(matches[1]);
4631 QString infoStr =
"";
4655 infoStr =
"Recorded";
4663 QString bufferFilename =
4665 if ((infoStr ==
"Recorded") || (infoStr ==
"LiveTV"))
4667 infoStr += QString(
" %1 %2 %3 %4 %5 %6 %7")
4668 .arg(
info.text[
"description"],
4673 QString::number(fplay),
4675 QString::number(rate));
4679 QString position =
info.text[
"description"].section(
" ",0,0);
4680 infoStr += QString(
" %1 %2 %3 %4 %5")
4684 QString::number(fplay),
4685 QString::number(rate));
4688 infoStr += QString(
" Subtitles:");
4693 infoStr += QString(
" *0:[None]*");
4695 infoStr += QString(
" 0:[None]");
4700 for (
int i = 0; i < subs.size(); i++)
4703 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4705 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4710 for (
int i = 0; i < subs.size(); i++)
4713 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4715 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4720 for (
int i = 0; i < subs.size(); i++)
4723 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4725 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4730 for (
int i = 0; i < subs.size(); i++)
4733 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4735 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4740 for (
int i = 0; i < subs.size(); i++)
4743 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4745 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4750 for (
int i = 0; i < subs.size(); i++)
4753 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4755 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4761 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4765 else if (tokens[2] ==
"VOLUME")
4768 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4777 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- begin").arg(
StateToString(desiredState)));
4784 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Created player."));
4789 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Failed to create player."));
4792 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- end %2")
4898 bool paused =
false;
4920 bool ignore =
false;
4921 bool paused =
false;
4946 if (Time > -0.001F && Time < +0.001F)
4949 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1 seconds").arg(
static_cast<double>(Time)));
4970 else if (Time < 0.0F)
4982 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1").arg(FrameNum));
5008 const int kRewind = 4;
5009 const int kForward = 8;
5010 const int kSticky = 16;
5011 const int kSlippery = 32;
5012 const int kRelative = 64;
5013 const int kAbsolute = 128;
5014 const int kIgnoreCutlist = 256;
5015 const int kWhenceMask = 3;
5020 flags =
ARBSEEK_END | kForward | kSticky | kAbsolute;
5026 flags =
ARBSEEK_SET | kRewind | kSticky | kAbsolute;
5032 int direction = (flags & kRewind) ? -1 : 1;
5041 QString message = (flags & kRewind) ? tr(
"Rewind") :
5043 if (flags & kAbsolute)
5045 float time = direction;
5046 DoSeek(time, message,
true, (flags & kIgnoreCutlist) == 0);
5053 uint64_t targetRel = frameRel +
static_cast<uint64_t
>(direction);
5054 if (frameRel == 0 && direction < 0)
5058 targetRel = std::min(targetRel, maxRel);
5066 else if (flags & kSticky)
5070 else if (flags & kRewind)
5090void TV::DoSeek(
float Time,
const QString &Msg,
bool TimeIsOffset,
bool HonorCutlist)
5095 bool limitkeys =
false;
5137 DoSeek(Seconds, tr(
"Jump To"),
false, HonorCutlist);
5149 int64_t time = ((seek / 100) * 3600) + ((seek % 100) * 60);
5153 DoSeek(time, tr(
"Jump Ahead"),
true, HonorCutlist);
5157 DoSeek(-time, tr(
"Jump Back"),
true, HonorCutlist);
5170 DoSeek(std::max(0.0F, dur -
static_cast<float>(time)), tr(
"Jump To"),
false, HonorCutlist);
5303 auto index =
static_cast<size_t>(Index);
5372 QString jobHost =
"";
5377 QString msg = tr(
"Try Again");
5384 msg = tr(
"Transcoding");
5394 int num_chapters = 0;
5399 return num_chapters;
5447 int currentTitle = 0;
5452 return currentTitle;
5467 int currentAngle = 0;
5472 return currentAngle;
5487 std::chrono::seconds seconds = 0s;
5550 info.text[
"title"] = tr(
"Skip");
5551 info.text[
"description"] = tr(
"Searching");
5563 QMap<uint,InputInfo> sources;
5568 uint sourceid =
info[
"sourceid"].toUInt();
5571 for (
auto & input : inputs)
5574 if ((!sources.contains(input.m_sourceId)) ||
5575 ((cardid == input.m_inputId) && (cardid != sources[input.m_sourceId].m_inputId)))
5577 sources[input.m_sourceId] = input;
5582 QMap<uint,InputInfo>::const_iterator beg = sources.constFind(sourceid);
5583 QMap<uint,InputInfo>::const_iterator sit = beg;
5585 if (sit == sources.constEnd())
5591 if (sit == sources.constEnd())
5592 sit = sources.constBegin();
5597 if (sit != sources.constBegin())
5603 QMap<uint,InputInfo>::const_iterator tmp = sources.constBegin();
5604 while (tmp != sources.constEnd())
5631 QCoreApplication::processEvents();
5633 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1,'%2',%3)").arg(ChanID).arg(ChanNum).arg(InputID));
5640 QStringList reclist;
5643 reclist.push_back(QString::number(InputID));
5645 else if (ChanID || !ChanNum.isEmpty())
5652 if (!reclist.empty())
5660 if (ChanID && ChanNum.isEmpty())
5663 if (!ChanNum.isEmpty())
5706 if (ChanNum.isEmpty() && ChanID)
5708 if (ChanNum.isEmpty() && InputID)
5714 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully restarted");
5727 playbackURL,
false,
true,
5754 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
5768 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No recorder to switch to...");
5782 LOG(VB_GENERAL, LOG_ERR,
"TV::ToggleChannelFavorite() -- currently disabled");
5850 bool commitSmart =
false;
5862 inputStr = inputStr.isEmpty() ?
"?" : inputStr;
5866 inputStr = entryStr +
" " + inputStr;
5870 inputStr = tr(
"Seek:",
"seek to location") +
" " + inputStr;
5880static QString
add_spacer(
const QString &chan,
const QString &spacer)
5882 if ((chan.length() >= 2) && !spacer.isEmpty())
5883 return chan.left(chan.length()-1) + spacer + chan.right(1);
5895#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
5896 int size = chan.size();
5898 qsizetype size = chan.size();
5900 if ((size > 2) && (chan.at(size - 1) == chan.at(size - 2)))
5903#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
5904 chan.rightRef(1).toUInt(&ok);
5906 (void)QStringView(chan).right(1).toUInt(&ok);
5910 chan = chan.left(chan.length()-1);
5918 QString needed_spacer;
5919 uint pref_cardid = 0;
5920 bool is_not_complete =
true;
5922 bool valid_prefix =
false;
5926 chan, pref_cardid, is_not_complete, needed_spacer);
5929#if DEBUG_CHANNEL_PREFIX
5930 LOG(VB_GENERAL, LOG_DEBUG, QString(
"valid_pref(%1) cardid(%2) chan(%3) "
5931 "pref_cardid(%4) complete(%5) sp(%6)")
5932 .arg(valid_prefix).arg(0).arg(chan)
5933 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5941 else if (!needed_spacer.isEmpty())
5947#if DEBUG_CHANNEL_PREFIX
5948 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ValidPref(%1) CardId(%2) Chan(%3) "
5949 " PrefCardId(%4) Complete(%5) Sp(%6)")
5951 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5958 return !is_not_complete;
5963 bool commited =
false;
5965 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
5966 QString(
"livetv(%1) qchannum(%2) qchanid(%3)")
5996 if (channum.isEmpty())
6019 uint old_chanid = 0;
6025 LOG(VB_GENERAL, LOG_ERR,
LOC +
6026 "no active ctx playingInfo.");
6088 uint cardid,
const QString &channum)
6091 uint cur_sourceid = 0;
6104 if (cur_sourceid != sourceid && sourceid)
6111 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1, '%2')").arg(Chanid).arg(
Channum));
6117 QStringList reclist;
6118 QVector<uint> tunable_on;
6122 if (channum.isEmpty() && Chanid)
6143 QString needed_spacer;
6144 uint pref_cardid = 0;
6149 dummy, needed_spacer);
6151 LOG(VB_CHANNEL, LOG_INFO,
LOC +
6152 QString(
"CheckChannelPrefix(%1, pref_cardid %2, %3, '%4') "
6154 .arg(
Channum).arg(pref_cardid).arg(dummy).arg(needed_spacer)
6158 if (pref_cardid != cardid)
6167 getit = !tunable_on.contains(cardid);
6175 if (tunable_on.empty())
6181 for (
const auto& rec : std::as_const(tmp))
6183 if ((Chanid == 0U) || tunable_on.contains(rec.toUInt()))
6184 reclist.push_back(rec);
6189 if (!reclist.empty())
6253 for (
const auto & option : Options)
6255 uint chanid = option.m_chanId;
6256 QString channum = option.m_chanNum;
6275 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Previous channel number '%1'").arg(channum));
6276 if (channum.isEmpty())
6286 if (!ImmediateChange)
6292 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"'%1'->'%2'")
6293 .arg(cur_channum, prev_channum));
6296 if (cur_channum != prev_channum && !prev_channum.isEmpty())
6305 if (ImmediateChange)
6319 emit
HideAll(
true,
nullptr,
true);
6337 bool hideAll =
false;
6353 else if (is_prog_info_disp && !paused)
6357 else if (IncludeStatusOSD)
6375 info.text[
"title"] = (paused ? tr(
"Paused") : tr(
"Position"));
6421 const QString& Value,
int Type,
const QString& Units,
6425 info.values.insert(
"position", Position);
6426 info.values.insert(
"relposition", Position);
6427 info.text.insert(
"title", Title);
6428 info.text.insert(
"description", Desc);
6429 info.text.insert(
"value", Value);
6430 info.text.insert(
"units", Units);
6436 LOG(VB_PLAYBACK, LOG_INFO, QString(
"UpdateOSDSeekMessage(%1, %2)").arg(Msg).arg(Timeout));
6442 info.text[
"title"] = Msg;
6477 infoMap[
"callsign"].isEmpty())
6489 SignalMonitorList::const_iterator it;
6490 for (it = slist.begin(); it != slist.end(); ++it)
6491 if (
"error" == it->GetShortName())
6492 infoMap[QString(
"error%1").arg(i++)] = it->GetName();
6494 for (it = slist.begin(); it != slist.end(); ++it)
6495 if (
"message" == it->GetShortName())
6496 infoMap[QString(
"message%1").arg(i++)] = it->GetName();
6500 uint ber = 0xffffffff;
6512 for (it = slist.begin(); it != slist.end(); ++it)
6514 if (
"error" == it->GetShortName())
6516 err = it->GetName();
6520 if (
"message" == it->GetShortName())
6522 msg = it->GetName();
6523 LOG(VB_GENERAL, LOG_INFO,
"msg: " + msg);
6527 infoMap[it->GetShortName()] = QString::number(it->GetValue());
6528 if (
"signal" == it->GetShortName())
6529 sig = it->GetNormalizedValue(0, 100);
6530 else if (
"snr" == it->GetShortName())
6531 snr = it->GetValue();
6532 else if (
"ber" == it->GetShortName())
6533 ber =
static_cast<uint>(it->GetValue());
6534 else if (
"pos" == it->GetShortName())
6535 pos = it->GetValue();
6536 else if (
"script" == it->GetShortName())
6537 tuned = it->GetValue();
6538 else if (
"seen_pat" == it->GetShortName())
6539 pat = it->IsGood() ?
"a" :
"_";
6540 else if (
"matching_pat" == it->GetShortName())
6541 pat = it->IsGood() ?
"A" : pat;
6542 else if (
"seen_pmt" == it->GetShortName())
6543 pmt = it->IsGood() ?
"m" :
"_";
6544 else if (
"matching_pmt" == it->GetShortName())
6545 pmt = it->IsGood() ?
"M" : pmt;
6546 else if (
"seen_mgt" == it->GetShortName())
6547 mgt = it->IsGood() ?
"g" :
"_";
6548 else if (
"matching_mgt" == it->GetShortName())
6549 mgt = it->IsGood() ?
"G" : mgt;
6550 else if (
"seen_vct" == it->GetShortName())
6551 vct = it->IsGood() ?
"v" :
"_";
6552 else if (
"matching_vct" == it->GetShortName())
6553 vct = it->IsGood() ?
"V" : vct;
6554 else if (
"seen_nit" == it->GetShortName())
6555 nit = it->IsGood() ?
"n" :
"_";
6556 else if (
"matching_nit" == it->GetShortName())
6557 nit = it->IsGood() ?
"N" : nit;
6558 else if (
"seen_sdt" == it->GetShortName())
6559 sdt = it->IsGood() ?
"s" :
"_";
6560 else if (
"matching_sdt" == it->GetShortName())
6561 sdt = it->IsGood() ?
"S" : sdt;
6562 else if (
"seen_crypt" == it->GetShortName())
6563 crypt = it->IsGood() ?
"c" :
"_";
6564 else if (
"matching_crypt" == it->GetShortName())
6565 crypt = it->IsGood() ?
"C" : crypt;
6568 infoMap[
"signal"] = QString::number(sig);
6572 QString slock = (
"1" == infoMap[
"slock"]) ?
"L" :
"l";
6573 QString lockMsg = (slock==
"L") ? tr(
"Partial Lock") : tr(
"No Lock");
6574 QString sigMsg = allGood ? tr(
"Lock") : lockMsg;
6576 QString sigDesc = tr(
"Signal %1%").arg(sig,2);
6578 sigDesc +=
" | " + tr(
"S/N %1dB").arg(log10(snr), 3,
'f', 1);
6579 if (ber != 0xffffffff)
6580 sigDesc +=
" | " + tr(
"BE %1",
"Bit Errors").arg(ber, 2);
6581 if ((pos >= 0) && (pos < 100))
6582 sigDesc +=
" | " + tr(
"Rotor %1%").arg(pos,2);
6586 else if (tuned == 2)
6588 else if (tuned == 3)
6593 sigDesc = sigDesc + QString(
" | (%1%2%3%4%5%6%7%8%9) %10")
6594 .arg(tuneCode, slock, pat, pmt, mgt, vct,
6600 else if (!msg.isEmpty())
6603 infoMap[
"description"] = sigDesc;
6610 if (allGood || (pmt ==
"M"))
6619 bool timed_out =
false;
6634 LOG(VB_GENERAL, LOG_ERR,
LOC +
6635 "You have no OSD, but tuning has already taken too long.");
6661 static QString s_nextSrc =
GET_KEY(
"TV Playback",
"NEXTSOURCE");
6662 static QString s_togCards =
GET_KEY(
"TV Playback",
"NEXTINPUT");
6664 QString message = tr(
6665 "You should have received a channel lock by now. "
6666 "You can continue to wait for a signal, or you "
6667 "can change the channel with %1 or %2, change "
6668 "video source (%3), inputs (%4), etc.")
6669 .arg(s_chanUp, s_chanDown, s_nextSrc, s_togCards);
6675 .m_buttons={ {tr(
"OK"),
"DIALOG_INFO_CHANNELLOCK_0" } },
6676 .m_back={ .m_text=
"", .m_data=
"DIALOG_INFO_CHANNELLOCK_0", .m_exit=
true } });
6681 bool result =
false;
6747 dvdName = tr(
"DVD");
6751 mainStatus = tr(
"Menu");
6755 mainStatus = tr(
"Still Frame");
6759 int playingTitle = 0;
6760 int playingPart = 0;
6765 mainStatus = tr(
"Title: %1 (%2)").arg(playingTitle)
6767 subStatus = tr(
"Chapter: %1/%2").arg(playingPart).arg(totalParts);
6802 for (
uint i : std::as_const(list))
6803 ret += QString(
"%1,").arg(i);
6806 return ret.left(ret.length()-1);
6813 QVector<uint> tunable_cards;
6817 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6818 return tunable_cards;
6822 mplexid = (32767 == mplexid) ? 0 : mplexid;
6824 uint excluded_input = 0;
6832 for (
auto & input : inputs)
6834 if (input.m_sourceId != sourceid)
6837 if (input.m_mplexId &&
6838 input.m_mplexId != mplexid)
6841 if (!input.m_mplexId && input.m_chanId &&
6842 input.m_chanId != ChanId)
6845 tunable_cards.push_back(input.m_inputId);
6848 if (tunable_cards.empty())
6849 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6851 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) yes { %2 }").arg(ChanId).arg(
toCommaList(tunable_cards)));
6852 return tunable_cards;
6855void TV::Embed(
bool Embed, QRect Rect,
const QStringList& Data)
6880 if (!Data.isEmpty())
6892 if (Pause ^ waspaused)
6894 if (Pause ^ waspaused)
6919 LOG(VB_GENERAL, LOG_ERR,
LOC +
"no active ctx playingInfo.");
6946 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Pausing player: %1").arg(pause));
7029 QString message = QString(
"START_EPG %1 %2").arg(EditType).arg(arg);
7031 QCoreApplication::postEvent(
this, me);
7048 QString appName = tr(
"Video");
7054 appName = tr(
"DVD");
7056 lcd->switchToVolume(appName);
7082 const float kTimeStretchMin = 0.125;
7083 const float kTimeStretchMax = 2.0;
7084 const float kTimeStretchStep = 0.05F;
7088 if (new_ts_normal > kTimeStretchMax &&
7091 new_ts_normal = kTimeStretchMax;
7093 else if (new_ts_normal < kTimeStretchMin &&
7096 new_ts_normal = kTimeStretchMin;
7099 if (new_ts_normal > kTimeStretchMax ||
7100 new_ts_normal < kTimeStretchMin)
7163 QString message = tr(
"MythTV was set to sleep after %1 minutes and will exit in %d seconds.\n"
7164 "Do you wish to continue watching?")
7171 .m_buttons={ { tr(
"Yes"),
"DIALOG_SLEEP_YES_0" },
7172 { tr(
"No"),
"DIALOG_SLEEP_NO_0" } }});
7193 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching TV, exiting");
7203 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Sleep timeout reached, exiting player.");
7221 QString message = tr(
"MythTV has been idle for %1 minutes and "
7222 "will exit in %d seconds. Are you still watching?")
7229 .m_buttons={ { tr(
"Yes"),
"DIALOG_IDLE_YES_0" },
7230 { tr(
"No"),
"DIALOG_IDLE_NO_0" }}});
7253 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching LiveTV, exiting");
7266 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Idle timeout reached, leaving LiveTV");
7306 QString message = me->
Message();
7308 if (message.isEmpty())
7311 std::chrono::milliseconds
timeout = 0ms;
7312 if (me->ExtraDataCount() == 1)
7314 auto t = std::chrono::seconds(me->ExtraData(0).toInt());
7315 if (
t > 0s &&
t < 1000s)
7339 if (dce->GetData().userType() == qMetaTypeId<MythTVMenuNodeTuple>())
7343 QDomNode Node = Menu.GetNodeFromPath(data.m_path);
7344 if (dce->GetResult() == -1)
7351 OSDDialogEvent(dce->GetResult(), dce->GetResultText(), dce->GetData().toString());
7376 LOG(VB_GENERAL, LOG_NOTICE,
"DVD has been ejected, exiting playback");
7391 QString message = me->
Message();
7394 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
7396 if (me->ExtraDataCount() == 1)
7399 int value = me->ExtraData(0).toInt();
7429 if (me->ExtraDataCount() >= 2)
7431 width = me->ExtraData(0).toInt();
7432 height = me->ExtraData(1).toInt();
7434 if (me->ExtraDataCount() == 3)
7443 else if (message.startsWith(
"DONE_RECORDING"))
7445 std::chrono::seconds seconds = 0s;
7448 if (tokens.size() == NUMTOKENS)
7450 cardnum = tokens[1].toUInt();
7451 seconds = std::chrono::seconds(tokens[2].toInt());
7456 LOG(VB_GENERAL, LOG_ERR, QString(
"DONE_RECORDING event received "
7457 "with invalid number of arguments, "
7458 "%1 expected, %2 actual")
7460 .arg(tokens.size()-1));
7500 if (message.startsWith(
"ASK_RECORDING "))
7503 bool hasrec =
false;
7504 bool haslater =
false;
7505 if (tokens.size() >= 5)
7507 cardnum = tokens[1].toUInt();
7508 timeuntil = tokens[2].toInt();
7509 hasrec = (tokens[3].toInt() != 0);
7510 haslater = (tokens[4].toInt() != 0);
7512 LOG(VB_GENERAL, LOG_DEBUG,
7513 LOC + message + QString(
" hasrec: %1 haslater: %2")
7514 .arg(hasrec).arg(haslater));
7523 if (message.startsWith(
"QUIT_LIVETV"))
7525 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7538 if (message.startsWith(
"LIVETV_WATCH"))
7541 if (tokens.size() >= 3)
7543 cardnum = tokens[1].toUInt();
7544 watch = tokens[2].toInt();
7568 if (message.startsWith(
"LIVETV_CHAIN"))
7571 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
7580 if (message.startsWith(
"EXIT_TO_MENU"))
7589 if (message.startsWith(
"SIGNAL"))
7591 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7592 const QStringList& signalList = me->ExtraDataList();
7608 if (message.startsWith(
"NETWORK_CONTROL"))
7610 if ((tokens.size() >= 2) &&
7611 (tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
7613 QStringList tokens2 = message.split(
" ", Qt::SkipEmptyParts);
7614 if ((tokens2.size() >= 2) &&
7615 (tokens2[1] !=
"ANSWER") && (tokens2[1] !=
"RESPONSE"))
7624 if (message.startsWith(
"START_EPG"))
7626 int editType = tokens[1].toInt();
7627 QString arg = message.section(
" ", 2, -1);
7631 if (message.startsWith(
"COMMFLAG_START") && (tokens.size() >= 2))
7634 QDateTime evrecstartts;
7646 QString msg =
"COMMFLAG_REQUEST ";
7653 if (message.startsWith(
"COMMFLAG_UPDATE") && (tokens.size() >= 3))
7656 QDateTime evrecstartts;
7670 QStringList marks = tokens[2].split(
",", Qt::SkipEmptyParts);
7671 for (
int j = 0; j < marks.size(); j++)
7673 mark = marks[j].split(
":", Qt::SkipEmptyParts);
7674 if (marks.size() >= 2)
7675 newMap[mark[0].toULongLong()] =
static_cast<MarkTypes>(mark[1].toInt());
7685 if (message ==
"NOTIFICATION")
7706 recinfo.
ToMap(infoMap);
7723 map.insert(
"message_text", tr(
"Record"));
7731 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Unknown recording during live tv.");
7744 cmdmsg = tr(
"Record");
7747 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record on");
7756 cmdmsg = tr(
"Cancel Record");
7759 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record off");
7807 sup &= ~kPictureAttributeSupported_Range;
7841 title = tr(
"Adjust Volume");
7858 if (Type ==
"EDIT_CUT_POINTS")
7864 "menu_cutlist.xml", tr(
"Edit Cut Points"),
7865 metaObject()->className(),
"TV Editing");
7871 else if (Type ==
"EDIT_CUT_POINTS_COMPACT")
7877 "menu_cutlist_compact.xml", tr(
"Edit Cut Points"),
7878 metaObject()->className(),
"TV Editing");
7884 else if (Type ==
"EXIT_EDIT_MODE")
7887 .m_message=tr(
"Exit Recording Editor") };
7888 dialog.m_buttons.push_back( { tr(
"Save Cuts and Exit"),
"DIALOG_CUTPOINT_SAVEEXIT_0" } );
7889 dialog.m_buttons.push_back( { tr(
"Exit Without Saving"),
"DIALOG_CUTPOINT_REVERTEXIT_0" } );
7890 dialog.m_buttons.push_back( { tr(
"Save Cuts"),
"DIALOG_CUTPOINT_SAVEMAP_0" } );
7891 dialog.m_buttons.push_back( { tr(
"Undo Changes"),
"DIALOG_CUTPOINT_REVERT_0" } );
7892 dialog.m_back = { .m_text=
"",
7893 .m_data=
"DIALOG_CUTPOINT_DONOTHING_0",
7898 map.insert(
"title", tr(
"Edit"));
7910 if (
Action ==
"DONOTHING" && osd)
7915 QStringList actions(
Action);
7917 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unrecognised cutpoint action");
7947 QString message = tr(
"This program is currently being edited");
7948 QString def = QString(
"DIALOG_EDITING_CONTINUE_%1").arg(
static_cast<int>(paused));
7953 .m_buttons={ { tr(
"Continue Editing"), def,
false,
true },
7954 { tr(
"Do not edit"), QString(
"DIALOG_EDITING_STOP_%1").arg(
static_cast<int>(paused)) }},
7955 .m_back={ .m_text=
"", .m_data=def, .m_exit=
true} });
7971 if (!WasPaused && paused)
7988 for (
auto it = newMap.cbegin(); it != newMap.cend(); ++it)
7989 infoMap.insert(it.key(), *it);
8048 if (osd &&
Action ==
"PROBE")
8056 else if (osd &&
Action ==
"OK")
8064 else if (osd &&
Action ==
"QUIT")
8078 const QString keys[4] = {
"XMLTV",
"callsign",
"channame",
"channum", };
8087 QMap<QString,bool> modifiable;
8088 modifiable[
"callsign"] = Info[
"callsign"].isEmpty();
8089 if (!modifiable[
"callsign"])
8091 QString unsetsign = tr(
"UNKNOWN%1",
"Synthesized callsign");
8092 int unsetcmpl = unsetsign.length() - 2;
8093 unsetsign = unsetsign.left(unsetcmpl);
8094 if (Info[
"callsign"].left(unsetcmpl) == unsetsign)
8095 modifiable[
"callsign"] =
true;
8097 modifiable[
"channame"] = Info[
"channame"].isEmpty();
8099 const std::array<const QString,2> xds_keys {
"callsign",
"channame", };
8100 for (
const auto & key : xds_keys)
8102 if (!modifiable[key])
8112 if ((key ==
"callsign") &&
8113 ((tmp.length() > 5) || (tmp.indexOf(
" ") >= 0)))
8125 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"result %1 text %2 action %3")
8126 .arg(QString::number(Result), Text,
Action));
8132 bool handled =
true;
8133 if (
Action.startsWith(
"DIALOG_"))
8135 Action.remove(
"DIALOG_");
8136 QStringList desc =
Action.split(
"_");
8137 bool valid = desc.size() == 3;
8143 else if (valid && desc[0] ==
"VIDEOEXIT")
8147 else if (valid && desc[0] ==
"SLEEP")
8151 else if (valid && desc[0] ==
"IDLE")
8155 else if (valid && desc[0] ==
"INFO")
8159 else if (valid && desc[0] ==
"EDITING")
8163 else if (valid && desc[0] ==
"ASKALLOW")
8167 else if (valid && desc[0] ==
"EDITOR")
8171 else if (valid && desc[0] ==
"CUTPOINT")
8175 else if ((valid && desc[0] ==
"DELETE") ||
8176 (valid && desc[0] ==
"CONFIRM"))
8185 LOG(VB_GENERAL, LOG_ERR,
"Unrecognised dialog event.");
8188 else if (Result < 0)
8205 else if (
Action ==
"CANCELPLAYLIST")
8231 else if (
Action ==
"TOGGLEMANUALZOOM")
8243 else if (
Action ==
"TOGGLESTRETCH")
8255 else if (
Action.startsWith(
"ADJUSTSTRETCH"))
8257 bool floatRead =
false;
8258#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8259 float stretch =
Action.rightRef(
Action.length() - 13).toFloat(&floatRead);
8261 float stretch = QStringView(
Action).right(
Action.length() - 13).toFloat(&floatRead);
8277 else if (
Action.startsWith(
"SELECTSCAN_"))
8279#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8313 else if (
Action.startsWith(
"TOGGLEPICCONTROLS"))
8315#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8322 else if (
Action ==
"TOGGLEASPECT")
8326 else if (
Action.startsWith(
"TOGGLEASPECT"))
8328#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8334 else if (
Action ==
"TOGGLEFILL")
8338 else if (
Action.startsWith(
"TOGGLEFILL"))
8340#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8346 else if (
Action ==
"MENU")
8350 else if (
Action ==
"AUTODETECT_FILL")
8360 if (
Action ==
"CHANGROUP_ALL_CHANNELS")
8366 Action.remove(
"CHANGROUP_");
8372 QString cur_channum;
8373 QString new_channum;
8379 new_channum = cur_channum;
8381 auto it = list.cbegin();
8382 for (; it != list.cend(); ++it)
8384 if ((*it).m_chanNum == cur_channum)
8390 if (it == list.end())
8395 if (it != list.end())
8396 new_channum = (*it).m_chanNum;
8399 LOG(VB_CHANNEL, LOG_INFO,
LOC +
8400 QString(
"Channel Group: '%1'->'%2'")
8401 .arg(cur_channum, new_channum));
8407 if (cur_channum != new_channum && !new_channum.isEmpty())
8426 else if (
Action ==
"SCHEDULE")
8439 else if (
Action.startsWith(
"JUMPCAST|"))
8441 QStringList tokens =
Action.split(
"|");
8442 if (tokens.size() == 3)
8444 else if (tokens.size() == 4)
8449 else if (
Action.startsWith(
"VISUALISER"))
8453 else if (
Action.startsWith(
"3D"))
8462 if (
Action ==
"TOGGLEBROWSE")
8466 else if (
Action ==
"PREVCHAN")
8470 else if (
Action.startsWith(
"SWITCHTOINPUT_"))
8472#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8479 else if (
Action ==
"EDIT")
8510#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8511 int chapter =
Action.rightRef(3).toInt();
8513 int chapter = QStringView(
Action).right(3).toInt();
8519#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8520 int title =
Action.rightRef(3).toInt();
8522 int title = QStringView(
Action).right(3).toInt();
8528#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8529 int angle =
Action.rightRef(3).toInt();
8531 int angle = QStringView(
Action).right(3).toInt();
8535 else if (
Action ==
"EDIT")
8540 else if (
Action ==
"TOGGLEAUTOEXPIRE")
8544 else if (
Action.startsWith(
"TOGGLECOMMSKIP"))
8546#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
8552 else if (
Action ==
"QUEUETRANSCODE")
8556 else if (
Action ==
"QUEUETRANSCODE_AUTO")
8560 else if (
Action ==
"QUEUETRANSCODE_HIGH")
8564 else if (
Action ==
"QUEUETRANSCODE_MEDIUM")
8568 else if (
Action ==
"QUEUETRANSCODE_LOW")
8590 LOG(VB_GENERAL, LOG_ERR,
LOC +
8591 "Unknown menu action selected: " +
Action);
8602 bool visible =
false;
8615 if (
Action ==
"CHANNELLOCK")
8620#define BUTTON(action, text) \
8621 result = Context.AddButton(Menu, active, (action), (text), "", false, "")
8622#define BUTTON2(action, textActive, textInactive) \
8623 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), false, "")
8624#define BUTTON3(action, textActive, textInactive, isMenu) \
8625 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), (isMenu), "")
8640 const QString &actionName = Context.
m_action;
8642 bool result =
false;
8645 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8662 if (actionName ==
"DIALOG_CUTPOINT_MOVEPREV_0")
8670 BUTTON2(actionName, tr(
"Move Previous Cut End Here"), tr(
"Move Start of Cut Here"));
8673 else if (actionName ==
"DIALOG_CUTPOINT_MOVENEXT_0")
8681 BUTTON2(actionName, tr(
"Move Next Cut Start Here"), tr(
"Move End of Cut Here"));
8684 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOBEGINNING_0")
8687 BUTTON(actionName, tr(
"Cut to Beginning"));
8689 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOEND_0")
8694 BUTTON(actionName, tr(
"Cut to End"));
8697 else if (actionName ==
"DIALOG_CUTPOINT_DELETE_0")
8700 BUTTON2(actionName, tr(
"Delete This Cut"), tr(
"Join Surrounding Cuts"));
8702 else if (actionName ==
"DIALOG_CUTPOINT_NEWCUT_0")
8705 BUTTON(actionName, tr(
"Add New Cut"));
8707 else if (actionName ==
"DIALOG_CUTPOINT_UNDO_0")
8711 QString text = tr(
"Undo - %1");
8712 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8715 else if (actionName ==
"DIALOG_CUTPOINT_REDO_0")
8719 QString text = tr(
"Redo - %1");
8720 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8723 else if (actionName ==
"DIALOG_CUTPOINT_CLEARMAP_0")
8725 BUTTON(actionName, tr(
"Clear Cuts"));
8727 else if (actionName ==
"DIALOG_CUTPOINT_INVERTMAP_0")
8729 BUTTON(actionName, tr(
"Reverse Cuts"));
8731 else if (actionName ==
"DIALOG_CUTPOINT_LOADCOMMSKIP_0")
8733 BUTTON(actionName, tr(
"Load Detected Commercials"));
8735 else if (actionName ==
"DIALOG_CUTPOINT_REVERT_0")
8737 BUTTON(actionName, tr(
"Undo Changes"));
8739 else if (actionName ==
"DIALOG_CUTPOINT_REVERTEXIT_0")
8741 BUTTON(actionName, tr(
"Exit Without Saving"));
8743 else if (actionName ==
"DIALOG_CUTPOINT_SAVEMAP_0")
8745 BUTTON(actionName, tr(
"Save Cuts"));
8747 else if (actionName ==
"DIALOG_CUTPOINT_SAVEEXIT_0")
8749 BUTTON(actionName, tr(
"Save Cuts and Exit"));
8763 if (!text.isEmpty())
8764 BUTTON(actionName, text);
8776 const QString &actionName = Context.
m_action;
8778 bool result =
false;
8783 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8873 if (
prefix ==
"SELECTSUBTITLE_") {
8875 }
else if (
prefix ==
"SELECTRAWTEXT_") {
8877 }
else if (
prefix ==
"SELECTCC708_") {
8879 }
else if (
prefix ==
"SELECTCC608_") {
8881 }
else if (
prefix ==
"SELECTTTC_") {
8883 }
else if (
prefix ==
"SELECTAUDIO_") {
8905 static const std::array<const speed,9> s_speeds {{
8906 { .m_speedX100=0, .m_suffix=
"", .m_trans=tr(
"Adjust")},
8907 { .m_speedX100=50, .m_suffix=
"0.5", .m_trans=tr(
"0.5x")},
8908 { .m_speedX100=90, .m_suffix=
"0.9", .m_trans=tr(
"0.9x")},
8909 {.m_speedX100=100, .m_suffix=
"1.0", .m_trans=tr(
"1.0x")},
8910 {.m_speedX100=110, .m_suffix=
"1.1", .m_trans=tr(
"1.1x")},
8911 {.m_speedX100=120, .m_suffix=
"1.2", .m_trans=tr(
"1.2x")},
8912 {.m_speedX100=130, .m_suffix=
"1.3", .m_trans=tr(
"1.3x")},
8913 {.m_speedX100=140, .m_suffix=
"1.4", .m_trans=tr(
"1.4x")},
8914 {.m_speedX100=150, .m_suffix=
"1.5", .m_trans=tr(
"1.5x")},
8917 for (
const auto & speed : s_speeds)
8939 BUTTON(
"CHANGROUP_ALL_CHANNELS", tr(
"All Channels"));
8940 ChannelGroupList::const_iterator it;
8944 QString
action =
prefix + QString::number(it->m_grpId);
8954 static constexpr std::array<const uint,3> kCasOrd { 0, 2, 1 };
8955 for (
uint csm : kCasOrd)
8972 QString chapter1 = QString(
"%1").arg(i+1, size, 10, QChar{
'0'});
8973 QString chapter2 = QString(
"%1").arg(i+1, 3 , 10, QChar{
'0'});
8975 QString desc = chapter1 + QString(
" (%1)").arg(timestr);
8988 QString angleIdx = QString(
"%1").arg(i, 3, 10, QChar{
'0'});
9003 QString titleIdx = QString(
"%1").arg(i, 3, 10, QChar{
'0'});
9016 QVector <QString> addednames;
9018 for (
auto & input : inputs)
9020 if (input.m_inputId == inputid ||
9021 addednames.contains(input.m_displayName))
9024 addednames += input.m_displayName;
9025 QString
action = QString(
"SWITCHTOINPUT_") +
9026 QString::number(input.m_inputId);
9038 uint sourceid =
info[
"sourceid"].toUInt();
9039 QMap<uint, bool> sourceids;
9041 for (
auto & input : inputs)
9043 if (input.m_sourceId == sourceid ||
9044 sourceids[input.m_sourceId])
9047 sourceids[input.m_sourceId] =
true;
9048 QString
action = QString(
"SWITCHTOINPUT_") +
9049 QString::number(input.m_inputId);
9056 if (actionName ==
"TOGGLEAUDIOSYNC")
9058 BUTTON(actionName, tr(
"Adjust Audio Sync"));
9062 BUTTON(actionName, tr(
"None"));
9064 else if (actionName ==
"DISABLEUPMIX")
9069 BUTTON(actionName, tr(
"Disable Audio Upmixer"));
9072 else if (actionName ==
"ENABLEUPMIX")
9077 BUTTON(actionName, tr(
"Auto Detect"));
9080 else if (actionName ==
"AUTODETECT_FILL")
9087 BUTTON(actionName, tr(
"Auto Detect"));
9090 else if (actionName ==
"TOGGLEMANUALZOOM")
9092 BUTTON(actionName, tr(
"Manual Zoom Mode"));
9094 else if (actionName ==
"DISABLESUBS")
9098 BUTTON(actionName, tr(
"Disable Subtitles"));
9100 else if (actionName ==
"ENABLESUBS")
9104 BUTTON(actionName, tr(
"Enable Subtitles"));
9106 else if (actionName ==
"DISABLEFORCEDSUBS")
9112 BUTTON(actionName, tr(
"Disable Forced Subtitles"));
9115 else if (actionName ==
"ENABLEFORCEDSUBS")
9121 BUTTON(actionName, tr(
"Enable Forced Subtitles"));
9124 else if (actionName ==
"DISABLEEXTTEXT")
9128 BUTTON(actionName, tr(
"Disable External Subtitles"));
9130 else if (actionName ==
"ENABLEEXTTEXT")
9134 BUTTON(actionName, tr(
"Enable External Subtitles"));
9136 else if (actionName ==
"TOGGLETTM")
9139 BUTTON(actionName, tr(
"Toggle Teletext Menu"));
9141 else if (actionName ==
"TOGGLESUBZOOM")
9144 BUTTON(actionName, tr(
"Adjust Subtitle Zoom"));
9146 else if (actionName ==
"TOGGLESUBDELAY")
9152 BUTTON(actionName, tr(
"Adjust Subtitle Delay"));
9155 else if (actionName ==
"PAUSE")
9158 BUTTON2(actionName, tr(
"Play"), tr(
"Pause"));
9160 else if (actionName ==
"TOGGLESTRETCH")
9162 BUTTON(actionName, tr(
"Toggle"));
9164 else if (actionName ==
"TOGGLEBROWSE")
9167 BUTTON(actionName, tr(
"Toggle Browse Mode"));
9169 else if (actionName ==
"CANCELPLAYLIST")
9172 BUTTON(actionName, tr(
"Cancel Playlist"));
9174 else if (actionName ==
"DEBUGOSD")
9176 BUTTON(actionName, tr(
"Playback Data"));
9178 else if (actionName ==
"JUMPFFWD")
9181 BUTTON(actionName, tr(
"Jump Ahead"));
9183 else if (actionName ==
"JUMPRWND")
9186 BUTTON(actionName, tr(
"Jump Back"));
9188 else if (actionName ==
"JUMPTODVDROOTMENU")
9193 BUTTON2(actionName, tr(
"DVD Root Menu"), tr(
"Top menu"));
9196 else if (actionName ==
"JUMPTOPOPUPMENU")
9199 BUTTON(actionName, tr(
"Popup menu"));
9201 else if (actionName ==
"JUMPTODVDTITLEMENU")
9204 BUTTON(actionName, tr(
"DVD Title Menu"));
9206 else if (actionName ==
"JUMPTODVDCHAPTERMENU")
9209 BUTTON(actionName, tr(
"DVD Chapter Menu"));
9211 else if (actionName ==
"PREVCHAN")
9214 BUTTON(actionName, tr(
"Previous Channel"));
9216 else if (actionName ==
"GUIDE")
9218 BUTTON(actionName, tr(
"Program Guide"));
9220 else if (actionName ==
"FINDER")
9222 BUTTON(actionName, tr(
"Program Finder"));
9224 else if (actionName ==
"VIEWSCHEDULED")
9226 BUTTON(actionName, tr(
"Upcoming Recordings"));
9228 else if (actionName ==
"SCHEDULE")
9230 BUTTON(actionName, tr(
"Edit Recording Schedule"));
9232 else if (actionName ==
"DIALOG_JUMPREC_X_0")
9234 BUTTON3(actionName, tr(
"Recorded Program"),
"",
true);
9240 else if (actionName ==
"JUMPPREV")
9257 else if (actionName ==
"EDIT")
9263 BUTTON2(actionName, tr(
"Edit Channel"), tr(
"Edit Recording"));
9266 else if (actionName ==
"TOGGLEAUTOEXPIRE")
9272 tr(
"Turn Auto-Expire OFF"), tr(
"Turn Auto-Expire ON"));
9275 else if (actionName ==
"QUEUETRANSCODE")
9280 BUTTON2(actionName, tr(
"Stop Transcoding"), tr(
"Default"));
9283 else if (actionName ==
"QUEUETRANSCODE_AUTO")
9288 BUTTON(actionName, tr(
"Autodetect"));
9291 else if (actionName ==
"QUEUETRANSCODE_HIGH")
9296 BUTTON(actionName, tr(
"High Quality"));
9299 else if (actionName ==
"QUEUETRANSCODE_MEDIUM")
9304 BUTTON(actionName, tr(
"Medium Quality"));
9307 else if (actionName ==
"QUEUETRANSCODE_LOW")
9312 BUTTON(actionName, tr(
"Low Quality"));
9319 BUTTON(actionName, tr(
"Cast"));
9330 if (!text.isEmpty())
9331 BUTTON(actionName, text);
9391 QString cur_channum = QString();
9394 if (!prev_channum.isEmpty() && prev_channum != cur_channum)
9446 QString text = Menu.
Translate(Node.toElement().attribute(
"text", Menu.
GetName()));
9447 const char* windowtitle {
"???" };
9453 Menu.
Show(Node, Selected, *
this, &
menu);
9454 QDomNode parent = Node.parentNode();
9455 if (!parent.parentNode().isNull())
9459 menu.m_back = { .m_text=
"", .m_data=v };
9468 map.insert(
"title", tr(
"Edit"));
9477 (void)tr(
"Playback Menu");
9478 (void)tr(
"Playback Compact Menu");
9480 (void)tr(
"Select Audio Track");
9481 (void)tr(
"Visualisation");
9483 (void)tr(
"Change Aspect Ratio");
9484 (void)tr(
"Adjust Fill");
9485 (void)tr(
"Adjust Picture");
9487 (void)tr(
"Advanced");
9488 (void)tr(
"Video Scan");
9489 (void)tr(
"Deinterlacer");
9490 (void)tr(
"Subtitles");
9491 (void)tr(
"Select Subtitle");
9492 (void)tr(
"Text Subtitles");
9493 (void)tr(
"Select ATSC CC");
9494 (void)tr(
"Select VBI CC");
9495 (void)tr(
"Select Teletext CC");
9496 (void)tr(
"Playback");
9497 (void)tr(
"Adjust Time Stretch");
9498 (void)tr(
"Picture-in-Picture");
9500 (void)tr(
"Channel Groups");
9501 (void)tr(
"Navigate");
9502 (void)tr(
"Commercial Auto-Skip");
9503 (void)tr(
"Chapter");
9506 (void)tr(
"Schedule");
9508 (void)tr(
"Jump to Program");
9509 (void)tr(
"Switch Input");
9510 (void)tr(
"Switch Source");
9512 (void)tr(
"Begin Transcoding");
9514 (void)tr(
"Recorded");
9515 (void)tr(
"Upcoming");
9518 (void)tr(
"Edit Cut Points");
9519 (void)tr(
"Edit Cut Points (Compact)");
9520 (void)tr(
"Cut List Options");
9528 "menu_playback.xml", tr(
"Playback Menu"),
9529 metaObject()->className(),
"TV Playback");
9531 "menu_playback_compact.xml", tr(
"Playback Compact Menu"),
9532 metaObject()->className(),
"TV Playback");
9544 if (Level < 0 || Level > 1)
9551 .m_message=tr(
"Recorded Program") };
9559 QList<QString> titles_seen;
9565 for (
auto *pi : *infoList)
9567 if (pi->GetRecordingGroup() !=
"LiveTV" || LiveTVInAllPrograms ||
9568 pi->GetRecordingGroup() == currecgroup)
9576 QMap<QString,ProgramList>::const_iterator Iprog;
9580 auto progIndex =
static_cast<uint>(plist.
size());
9581 const QString& group = Iprog.key();
9586 if (progIndex == 1 && Level == 0)
9588 dialog.m_buttons.push_back( {Iprog.key(), QString(
"JUMPPROG %1 0").arg(group) });
9590 else if (progIndex > 1 && Level == 0)
9592 QString act = QString(
"DIALOG_%1_%2_1")
9594 dialog.m_buttons.push_back( {group, act,
true, Selected == group });
9596 else if (Level == 1 && Iprog.key() == Category)
9598 for (
auto pit = plist.
begin(); pit != plist.
end(); ++pit)
9602 if (titles_seen.contains(
p->GetTitle()))
9605 titles_seen.push_back(
p->GetTitle());
9608 for (
auto *q : plist)
9612 if (q->GetTitle() !=
p->GetTitle())
9615 dialog.m_buttons.push_back( { q->GetSubtitle().isEmpty() ?
9616 q->GetTitle() : q->GetSubtitle(),
9617 QString(
"JUMPPROG %1 %2").arg(Iprog.key()).arg(j) });
9625 while (!infoList->empty())
9627 delete infoList->back();
9628 infoList->pop_back();
9633 if (!Category.isEmpty())
9637 dialog.m_back = { .m_text=Category,
9640 else if (Level == 0)
9643 dialog.m_back = { .m_text=
"",
9656 bool recorded = (
ProgInfo.GetFilesize() > 0);
9657 QString table = recorded ?
"recordedcredits" :
"credits";
9664 query.
prepare(QString(
"SELECT role, people.name,"
9665 " roles.name, people.person FROM %1"
9667 " LEFT JOIN people ON"
9668 " credits.person = people.person"
9669 " LEFT JOIN roles ON"
9670 " credits.roleid = roles.roleid"
9671 " WHERE credits.chanid = :CHANID"
9672 " AND credits.starttime = :STARTTIME"
9673 " AND role IN ('guest','actor','guest_star')"
9674 " ORDER BY role, priority;").arg(table));
9679 if (query.
exec() && query.
size() > 0)
9687 role = query.
value(0).toString();
9703 int pid = query.
value(3).toInt();
9704 pname = QString::fromUtf8(query.
value(1)
9705 .toByteArray().constData()) +
9706 "|" + QString::number(pid);
9707 character = QString::fromUtf8(query.
value(2)
9708 .toByteArray().constData());
9710 if (role ==
"actor")
9711 m_actors.append(qMakePair(pname, character));
9712 else if (role ==
"guest_star")
9714 else if (role ==
"guest")
9715 m_guests.append(qMakePair(pname, character));
9722 const QVector<string_pair> & people)
9724 for (
const auto & [actor, role] : std::as_const(people))
9728 dialog.
m_buttons.push_back( {actor.split(
'|')[0],
9729 QString(
"JUMPCAST|%1").arg(actor),
true} );
9733 dialog.
m_buttons.push_back( {QString(
"%1 as %2")
9734 .arg(actor.split(
'|')[0], role),
9735 QString(
"JUMPCAST|%1").arg(actor),
true} );
9753 const QString & category)
9757 if (category.isEmpty())
9759 dialog.m_buttons.push_back( {
"Recorded",
9760 QString(
"JUMPCAST|%1|%2|Recorded").arg(actor).arg(person_id) } );
9761 dialog.m_buttons.push_back( {
"Upcoming",
9762 QString(
"JUMPCAST|%1|%2|Upcoming").arg(actor).arg(person_id) } );
9767 if (category ==
"Upcoming")
9779 QString table =
"recordedcredits";
9781 query.
prepare(QString(
"SELECT chanid, starttime from %1"
9782 " where person = :PERSON"
9783 " ORDER BY starttime;").arg(table));
9786 QDateTime starttime;
9787 if (query.
exec() && query.
size() > 0)
9791 int chanid = query.
value(0).toInt();
9793 auto *pi =
new ProgramInfo(chanid, starttime.toUTC());
9794 if (!pi->GetTitle().isEmpty() &&
9795 pi->GetRecordingGroup() !=
"LiveTV" &&
9796 pi->GetRecordingGroup() !=
"Deleted")
9809 show = pi->GetTitle();
9812 if (!pi->GetSubtitle().isEmpty())
9814 show += QString(
" %1x%2 %3").arg(pi->GetSeason())
9815 .arg(pi->GetEpisode())
9816 .arg(pi->GetSubtitle());
9819 dialog.m_buttons.push_back( {
show,
9820 QString(
"JUMPPROG %1 %2").arg(actor).arg(++idx) });
9837 if (!message.isEmpty())
9850 desc = tr(
"Auto-Expire OFF");
9855 desc = tr(
"Auto-Expire ON");
9860 if (!desc.isEmpty())
9876 if (!desc.isEmpty())
9885 if (!Desc.isEmpty())
9901 for (
const auto&
action : std::as_const(Actions))
9903 if (!
action.startsWith(
"JUMPPROG"))
9907 QString key =
action.section(
" ",1,-2);
9908 uint index =
action.section(
" ",-1,-1).toUInt(&ok);
9925 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to locate jump to program '%1' @ %2")
9926 .arg(key,
action.section(
" ",-1,-1)));
9948 QTimer::singleShot(0,
this, Jump);
9956 LOG(VB_GENERAL, LOG_ERR,
"Failed to open jump to program GUI");
9964 std::chrono::minutes mins { 0min };
9987 if (Time.length() > 11)
9989 bool intRead =
false;
9990 mins = std::chrono::minutes(Time.right(Time.length() - 11).toUInt(&intRead));
10003 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time " + Time);
10008 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time string " + Time);
10020 out = tr(
"Sleep") +
" " + QString::number(mins.count());
10022 out = tr(
"Sleep") +
" " +
kSleepTimes[0].dispString;
10033 errorText = tr(
"MythTV is already using all available "
10034 "inputs for the channel you selected. "
10035 "If you want to watch an in-progress recording, "
10036 "select one from the playback menu. If you "
10037 "want to watch Live TV, cancel one of the "
10038 "in-progress recordings from the delete "
10042 errorText = tr(
"Error: MythTV is using all inputs, "
10043 "but there are no active recordings?");
10046 errorText = tr(
"MythTV has no capture cards defined. "
10047 "Please run the mythtv-setup program.");
10053 .m_message=errorText,
10055 .m_buttons={{ tr(
"OK"),
"DIALOG_INFO_X_X" }}});
10188 else if (!dvd->StartOfTitle())
10194 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10195 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10218 bool in_menu = dvd->IsInMenu();
10219 if (in_still && !dvd->NumMenuButtons())
10221 dvd->SkipStillFrame();
10224 else if (!dvd->EndOfTitle() && !in_still && !in_menu)
10228 else if (!in_still && !in_menu)
10230 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10231 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10232 std::chrono::seconds currentTime = dvd->GetCurrentTime();
10277 bool allowed =
false;
10300 videotype = tr(
"Live TV");
10302 videotype = tr(
"this DVD");
10306 videotype = tr(
"this Video");
10309 if (videotype.isEmpty())
10310 videotype = tr(
"this recording");
10313 .m_message=tr(
"You are exiting %1").arg(videotype) };
10315 dialog.m_buttons.push_back({tr(
"Exit %1").arg(videotype),
ACTION_STOP});
10317 dialog.m_buttons.push_back({tr(
"Exit Without Saving"),
"DIALOG_VIDEOEXIT_CLEARLASTPLAYEDPOSITION_0"});
10320 dialog.m_buttons.push_back({tr(
"Delete this recording"),
"DIALOG_VIDEOEXIT_CONFIRMDELETE_0"});
10322 dialog.m_buttons.push_back({tr(
"Keep watching"),
"DIALOG_VIDEOEXIT_KEEPWATCHING_0"});
10323 dialog.m_back = { .m_text=
"",
10324 .m_data=
"DIALOG_VIDEOEXIT_KEEPWATCHING_0",
10326 emit ChangeOSDDialog(dialog);
10328 if (m_videoExitDialogTimerId)
10329 KillTimer(m_videoExitDialogTimerId);
10330 m_videoExitDialogTimerId = StartTimer(kVideoExitDialogTimeout, __LINE__);
10340 LOG(VB_GENERAL, LOG_ERR,
"It is unsafe to delete at the moment");
10348 LOG(VB_GENERAL, LOG_ERR,
"This program cannot be deleted at this time.");
10355 QString message = tr(
"Cannot delete program ") + QString(
"%1 ").arg(pginfo.
GetTitle());
10358 message += QString(
"\"%1\" ").arg(pginfo.
GetSubtitle());
10362 message += tr(
"because it is not a recording.");
10366 message += tr(
"because it is in use by");
10369 for (
int i = 0; (i + 2) < byWho.size(); i += 3)
10375 message +=
" " + byWho[i+2];
10380 .m_message=message,
10382 .m_buttons={{ tr(
"OK"),
"DIALOG_DELETE_OK_0" }},
10383 .m_back={ .m_text=
"", .m_data=
"DIALOG_DELETE_OK_0", .m_exit=
true }});
10406 QString message = QString(
"%1\n%2\n%3")
10407 .arg(Title, infoMap[
"title"], infoMap[
"timedate"]);
10413 .m_message=message };
10414 if (Title ==
"End Of Recording")
10416 dialog.m_buttons.push_back({tr(
"Delete it, but allow it to re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10417 dialog.m_buttons.push_back({tr(
"Delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10418 dialog.m_buttons.push_back({tr(
"Save it so I can watch it again"),
ACTION_STOP,
false,
true});
10422 dialog.m_buttons.push_back({tr(
"Yes, and allow re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10423 dialog.m_buttons.push_back({tr(
"Yes, delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10424 dialog.m_buttons.push_back({tr(
"No, keep it"),
ACTION_STOP,
false,
true});
10426 dialog.m_back = { .m_text=
"",
10427 .m_data=
"DIALOG_PLAY_0_0",
10452 if (
Action ==
"DELETEANDRERECORD" && delete_ok)
10459 else if (
Action ==
"JUSTDELETE" && delete_ok)
10465 else if (
Action ==
"CONFIRMDELETE")
10470 else if (
Action ==
"KEEPWATCHING" && !near_end)
10474 else if (
Action ==
"CLEARLASTPLAYEDPOSITION")
10553 bool paused =
false;
10605 case Qt::ApplicationState::ApplicationSuspended:
10607 LOG(VB_GENERAL, LOG_NOTICE,
"Exiting playback on app suspecnd");
10631 LOG(VB_GENERAL, LOG_ERR,
"An exception occurred");
10636#include "moc_tv_play.cpp"
std::vector< ChannelInfo > ChannelInfoList
An action (for this plugin) consists of a description, and a set of key sequences.
static bool IsTunerShared(uint inputidA, uint inputidB)
static QString GetStartChannel(uint inputid)
static std::vector< uint > GetInputGroups(uint inputid)
static uint GetSourceID(uint inputid)
static bool SetStartChannel(uint inputid, const QString &channum)
static QString GetDisplayName(uint inputid)
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
static QStringList GetValidRecorderList(uint chanid, const QString &channum)
Returns list of the recorders that have chanid or channum in their sources.
static uint GetMplexID(uint sourceid, const QString &channum)
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
static QString GetIcon(uint chanid)
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
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)
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
static uint GetSourceIDForChannel(uint chanid)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
static const Type kEventType
static bool ChangeJobCmds(int jobID, int newCmds)
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())
static bool IsJobQueuedOrRunning(int jobType, uint chanid, const QDateTime &recstartts)
int getLCDWidth(void) const
void switchToChannel(const QString &channum="", const QString &title="", const QString &subtitle="")
void setChannelProgress(const QString &time, float value)
QString GetID(void) const
void JumpTo(int num, std::chrono::seconds pos)
QString GetChannelName(int pos=-1) const
void SetProgram(const ProgramInfo &pginfo)
QString GetInputType(int pos=-1) const
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
void start(QRunnable *runnable, const QString &debugName, int priority=0)
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void exit(int retcode=0)
Use this to exit from the thread if you are using a Qt event loop.
std::chrono::milliseconds m_audioOffset
bool IsHDMVNavigation(void) const
Dialog asking for user confirmation.
void emitTVPlaybackStarted(void)
void UnregisterForPlayback(QObject *sender)
Unregister sender from being called when TVPlaybackAboutToStart signal is emitted.
void emitTVPlaybackSought(qint64 position)
void emitTVPlaybackStopped(void)
QString GetHostName(void)
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
void SaveSetting(const QString &key, int newValue)
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Register sender for TVPlaybackAboutToStart signal.
void emitTVPlaybackUnpaused(void)
void SendSystemEvent(const QString &msg)
void emitTVPlaybackPaused(void)
void emitTVPlaybackAborted(void)
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
void dispatch(const MythEvent &event)
void SendMessage(const QString &message)
void emitTVPlaybackPlaying(void)
int GetNumSetting(const QString &key, int defaultval=0)
bool GetBoolSetting(const QString &key, bool defaultval=false)
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
static MythDB * getMythDB()
int NumPartsInTitle(void) const
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.
std::chrono::seconds GetTotalTimeOfTitle(void) const
get the total time of the title in seconds 90000 ticks = 1 sec
bool IsInStillFrame(void) const override
bool GetNameAndSerialNum(QString &Name, QString &SerialNumber) override
Get the dvd title and serial num.
void GetPartAndTitle(int &Part, int &Title) const
T dequeue()
Removes item from front of list and returns a copy. O(1).
void enqueue(const T &d)
Adds item to the back of the list. O(1).
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
virtual bool UsingVideoModes()
bool NextModeIsLarger(QSize Size)
Check whether the next mode is larger in size than the current mode.
This class is used as a container for messages.
const QString & Message() const
static const Type kUpdateTvProgressEventType
static const Type kUpdateBrowseInfoEventType
static const Type kMythEventMessage
static const Type kMythUserMessage
A custom event that represents a mouse gesture.
static const Type kEventType
QWidget * GetPaintWindow()
void ClearKeyContext(const QString &Context)
static void DisableScreensaver()
QString GetActionText(const QString &Context, const QString &Action) const
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
MythDisplay * GetDisplay()
MythScreenStack * GetMainStack()
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
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 IsExitingToMain() const
void MoveResize(QRect &Geometry)
MythScreenStack * GetStack(const QString &Stackname)
static QString GetKey(const QString &Context, const QString &Action)
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
static void RestoreScreensaver()
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
std::vector< MythOSDDialogButton > m_buttons
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
bool IsInMenu(void) const override
QStringList GetTracks(uint Type)
uint GetTrackCount(uint Type)
bool HandleProgramEditorActions(const QStringList &Actions)
virtual void UpdateSliderInfo(osdInfo &Info, bool PaddedFields=false)
void SetWatched(bool ForceWatched=false)
Determines if the recording should be considered watched.
void GetCodecDescription(InfoMap &Map)
virtual bool Rewind(float seconds)
virtual int GetNumAngles(void) const
uint64_t TranslatePositionAbsToRel(uint64_t position) const
CommSkipMode GetAutoCommercialSkip(void)
uint64_t TranslatePositionMsToFrame(std::chrono::milliseconds position, bool use_cutlist) const
virtual QString GetTitleName(int) const
virtual int GetNumTitles(void) const
virtual QString GetAngleName(int) const
virtual std::chrono::seconds GetTitleDuration(int) const
void SetWatchingRecording(bool mode)
uint64_t TranslatePositionRelToAbs(uint64_t position) const
virtual bool JumpToFrame(uint64_t frame)
virtual bool FastForward(float seconds)
virtual int GetCurrentAngle(void) const
virtual int GetNumChapters(void)
uint64_t GetCurrentFrameCount(void) const
QString GetError(void) const
virtual int GetCurrentTitle(void) const
void SkipCommercials(int direction)
MythVideoOutput * GetVideoOutput(void)
bool IsPaused(void) const
bool IsPlaying(std::chrono::milliseconds wait_in_msec=0ms, bool wait_for=true) const
uint64_t GetFramesPlayed(void) const
void SetLength(std::chrono::seconds len)
virtual int GetCurrentChapter(void)
bool IsNearEnd(void)
Returns true iff near end of recording.
bool IsErrored(void) const
virtual uint64_t GetBookmark(void)
bool GetLimitKeyRepeat(void) const
float GetPlaySpeed(void) const
float ComputeSecs(uint64_t position, bool use_cutlist) const
bool GetEditMode(void) const
QString GetXDS(const QString &key) const
virtual void GetChapterTimes(QList< std::chrono::seconds > ×)
virtual bool SwitchAngle(int)
bool GetAllowForcedSubtitles(void) const
virtual bool SwitchTitle(int)
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
void JumpChapter(int chapter)
void SetCommBreakMap(const frm_dir_map_t &NewMap)
void SetAutoCommercialSkip(CommSkipMode autoskip)
float GetFrameRate(void) const
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
virtual MythScreenType * GetTopScreen(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
A QElapsedTimer based timer to replace use of QTime as a timer.
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
void start(void)
starts measuring elapsed time.
static void SetState(const QVariantMap &NewState)
void DeleteAllChildren(void)
Delete all child widgets.
StereoscopicMode m_stereoOverride
AspectOverrideMode m_aspectOverrideMode
AdjustFillMode m_adjustFillMode
PictureAttributeSupported m_supportedAttributes
int GetValue(PictureAttribute Attribute)
std::chrono::milliseconds m_timecode
bool HasSoftwareFrames() const
void SetScanOverride(FrameScanType Scan)
FrameScanType NextScanOverride()
FrameScanType GetScanTypeWithOverride() const
QStringList m_visualiserList
void SetValues(const QString &Window, const QHash< QString, int > &Map, OSDTimeout Timeout)
bool DialogVisible(const QString &Window=QString())
void ResetWindow(const QString &Window)
bool DialogHandleGesture(MythGestureEvent *Event)
void DialogGetText(InfoMap &Map)
bool DialogHandleKeypress(QKeyEvent *Event)
void SetFunctionalWindow(const QString &Window, enum OSDFunctionalType Type)
bool IsWindowVisible(const QString &Window)
void HideWindow(const QString &Window) override
static int GetCount(void)
void SetRingBuffer(MythMediaBuffer *Buffer)
void SetPlayingInfo(const ProgramInfo *info)
assign programinfo to the context
bool IsErrored(void) const
This is set if the player encountered some irrecoverable error.
StringDeque m_prevChan
Previous channels.
QStringList m_lastSignalMsg
QString GetPlayMessage(void) const
void SetPseudoLiveTV(const ProgramInfo *pi, PseudoState new_state)
PseudoState m_pseudoLiveTVState
MythTimer m_lastSignalMsgTime
void LockState(void) const
void LockPlayingInfo(const char *file, int line) const
TVState GetState(void) const
static constexpr std::chrono::milliseconds kSMExitTimeout
Timeout after last Signal Monitor message for ignoring OSD when exiting.
bool HasPlayer(void) const
bool IsPlayerErrored(void) const
void PushPreviousChannel(void)
most recently selected channel to the previous channel list
bool IsPlayerPlaying(void) const
std::chrono::seconds m_rewtime
int m_ffRewState
0 == normal, +1 == fast forward, -1 == rewind
TVState DequeueNextState(void)
void ForceNextStateNone(void)
Removes any pending state changes, and puts kState_None on the queue.
void UnlockDeletePlayer(const char *file, int line) const
allow player to be deleted.
void UnlockState(void) const
int m_ffRewIndex
Index into m_ffRewSpeeds for FF and Rewind speeds.
RemoteEncoder * m_recorder
void UpdateTVChain(const QStringList &data=QStringList())
bool HandlePlayerSpeedChangeFFRew(void)
bool InStateChange(void) const
InfoMap m_lastSignalUIInfo
void SetPlayer(MythPlayer *newplayer)
int m_ffRewSpeed
Caches value of m_ffRewSpeeds[m_ffRewIndex].
bool IsPlayerChangingBuffers(void) 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 ...
void SetRecorder(RemoteEncoder *rec)
bool IsRecorderErrored(void) const
bool HandlePlayerSpeedChangeEOF(void)
float m_tsNormal
Time stretch speed, 1.0F for normal playback.
std::chrono::seconds m_fftime
QString GetPreviousChannel(void) const
MythMediaBuffer * m_buffer
bool GetPlayingInfoMap(InfoMap &infoMap) const
void SetInitialTVState(bool islivetv)
determine initial tv state and playgroup for the recording
void ChangeState(TVState newState)
Puts a state change on the nextState queue.
std::chrono::minutes m_jumptime
QString PopPreviousChannel(void)
MythDeque< TVState > m_nextState
uint GetCardID(void) const
bool IsSameProgram(const ProgramInfo &p) const
std::chrono::seconds m_playingLen
Initial CalculateLength()
MythTimer m_lastSignalUIInfoTime
void TeardownPlayer(void)
void UnlockPlayingInfo(const char *file, int line) const
ProgramInfo * m_pseudoLiveTVRec
void StopPlaying(void) const
ProgramInfo * m_playingInfo
Currently playing info.
Holds information on recordings and videos.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
QString GetBasename(void) const
bool HasPathname(void) const
static bool ExtractKey(const QString &uniquekey, uint &chanid, QDateTime &recstartts)
Extracts chanid and recstartts from a unique key generated by MakeUniqueKey().
bool QueryIsInUse(QStringList &byWho) const
Returns true if Program is in use.
bool IsVideoFile(void) const
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
bool IsVideoDVD(void) const
void SetIgnoreProgStart(bool ignore)
If "ignore" is true QueryProgStart() will return 0, otherwise QueryProgStart() will return the progst...
AutoExpireType QueryAutoExpire(void) const
Returns "autoexpire" field from "recorded" table.
void SetIgnoreBookmark(bool ignore)
If "ignore" is true GetBookmark() will return 0, otherwise GetBookmark() will return the bookmark pos...
uint GetEpisode(void) const
QString GetProgramID(void) const
QString GetRecordingGroup(void) const
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
uint GetRecordingID(void) const
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...
int64_t QueryTotalFrames(void) const
If present in recording this loads total frames of the main video stream from database's stream marku...
bool IsFileReadable(void)
Attempts to ascertain if the main file for this ProgramInfo is readable.
void SetIgnoreLastPlayPos(bool ignore)
If "ignore" is true QueryLastPlayPos() will return 0, otherwise QueryLastPlayPos() will return the la...
QString GetHostname(void) const
bool IsRecording(void) const
uint GetSourceID(void) const
QString GetPlaybackGroup(void) const
QString GetTitle(void) const
bool QueryIsEditing(void) const
Queries "recorded" table for its "editing" field and returns true if it is set to true.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
void SaveTotalFrames(int64_t frames)
Store the Total Frames at frame 0 in the recordedmarkup table.
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
QString GetSortTitle(void) const
bool IsVideoBD(void) const
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...
QString GetPathname(void) const
QDate GetOriginalAirDate(void) const
void SaveEditing(bool edit)
Sets "editing" field in "recorded" table to "edit".
void ToStringList(QStringList &list) const
Serializes ProgramInfo into a QStringList which can be passed over a socket.
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
QString GetSubtitle(void) const
uint GetSeason(void) const
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
Holds information on a TV Program one might wish to record.
void QuickRecord(void)
Create a kSingleRecord if not already scheduled.
void ApplyRecordRecGroupChange(const QString &newrecgroup)
Sets the recording group, both in this RecordingInfo and in the database.
void ApplyTranscoderProfileChange(const QString &profile) const
Sets the transcoder profile for a recording.
Internal representation of a recording rule, mirrors the record table.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
General purpose reference counter.
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
QAtomicInt m_referenceCount
virtual int IncrRef(void)
Increments reference count.
std::chrono::milliseconds SetSignalMonitoringRate(std::chrono::milliseconds rate, int notifyFrontend=1)
Sets the signal monitoring rate.
void StopLiveTV(void)
Tells TVRec to stop a "Live TV" recorder.
bool ShouldSwitchToAnotherCard(const QString &channelid)
Checks if named channel exists on current tuner, or another tuner.
void SpawnLiveTV(const QString &chainid, bool pip, const QString &startchan)
Tells TVRec to Spawn a "Live TV" recorder.
void ChangeChannel(int channeldirection)
void SetLiveRecording(bool recording)
int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr, bool up)
Changes brightness/contrast/colour/hue of a recording.
int GetPictureAttribute(PictureAttribute attr)
bool IsValidRecorder(void) const
void GetChannelInfo(InfoMap &infoMap, uint chanid=0)
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 PauseRecorder(void)
Tells TVRec to pause a recorder, used for channel and input changes.
void SetChannel(const QString &channel)
uint GetSignalLockTimeout(const QString &input)
bool SetChannelInfo(const InfoMap &infoMap)
bool CheckChannel(const QString &channel)
Checks if named channel exists on current tuner.
void CancelNextRecording(bool cancel)
int GetRecorderNumber(void) const
void ToggleChannelFavorite(const QString &changroupname)
bool IsRecording(bool *ok=nullptr)
static bool IsExiting(void)
static bool AllGood(const SignalMonitorList &slist)
Returns true if all the values in the list return true on IsGood().
static SignalMonitorList Parse(const QStringList &slist)
Converts a list of strings to SignalMonitorValue classes.
static QString GetSourceName(uint sourceid)
void BrowseEnd(bool ChangeChannel)
Ends channel browsing.
BrowseInfo GetBrowsedInfo() const
void BrowseDispInfo(const BrowseInfo &Browseinfo)
void BrowseChannel(const QString &Channum)
void BrowseInit(std::chrono::seconds BrowseMaxForward, bool BrowseAllTuners, bool UseChannelGroups, const QString &DBChannelOrdering)
uint GetBrowseChanId(const QString &Channum, uint PrefCardid, uint PrefSourceid) const
Returns a chanid for the channum, or 0 if none is available.
bool BrowseStart(bool SkipBrowse=false)
Begins channel browsing.
void ChangeAspectOverride(AspectOverrideMode AspectMode=kAspect_Toggle)
void GoToDVDProgram(bool Direction)
MythAudioState m_audioState
void SetCaptionsEnabled(bool Enable, bool UpdateOSD=true)
void ChangeZoom(ZoomDirection Zoom)
void GoToMenu(const QString &Menu)
void DisableEdit(int HowToSave)
void EnableCaptions(uint Mode, bool UpdateOSD=true)
void ChangeCaptionTrack(int Direction)
void UpdateLastPlayPosition(uint64_t frame)
void ChangeMuteState(bool CycleChannels=false)
void HideAll(bool KeepSubs=true, MythScreenType *Except=nullptr, bool DropNotification=false)
void ResizeScreenForVideo(QSize Size={})
void DisableCaptions(uint Mode, bool UpdateOSD=true)
void EmbedPlayback(bool Embed, const QRect &Rect={})
void UpdateBookmark(bool Clear=false)
void ChangeOSDMessage(const QString &Message)
void ChangeStereoOverride(StereoscopicMode Mode)
void ChangeOSDDialog(const MythOSDDialogData &Data)
void AdjustSubtitleDelay(std::chrono::milliseconds Delta)
void InitialisePlayerState()
void RefreshEditorState(bool CheckSaved=false)
void AdjustSubtitleZoom(int Delta)
MythOverlayState m_overlayState
void ChangeAdjustFill(AdjustFillMode FillMode=kAdjustFill_Toggle)
void WindowResized(const QSize &Size)
MythCaptionsState m_captionsState
void ChangeOSDPositionUpdates(bool Enable)
void ToggleDetectLetterBox()
void ChangeTrack(uint Type, int Direction)
void SetTeletextPage(uint Page)
void RequestEmbedding(bool Embed, const QRect &Rect={}, const QStringList &Data={})
MythVisualiserState m_visualiserState
void HandleTeletextAction(const QString &Action, bool &Handled)
void RestartITV(uint Chanid, uint Cardid, bool IsLiveTV)
void PauseAudioUntilReady()
void ToggleMoveBottomLine()
void HandleITVAction(const QString &Action, bool &Handled)
void EnableTeletext(int Page=0x100)
MythVideoColourState m_videoColourState
void ChangeVolume(bool Direction, int Volume)
void ToggleCaptionsByType(uint Type)
MythVideoBoundsState m_videoBoundsState
void IsOSDVisible(bool &Visible)
void ChangeAudioOffset(std::chrono::milliseconds Delta, std::chrono::milliseconds Value=-9999ms)
void ChangeAllowForcedSubtitles(bool Allow)
void ChangePictureAttribute(PictureAttribute Attribute, bool Direction, int Value)
void EnableVisualiser(bool Enable, bool Toggle=false, const QString &Name=QString())
void ChangeUpmix(bool Enable, bool Toggle=false)
MythEditorState m_editorState
void ChangeOSDText(const QString &Window, const InfoMap &Map, OSDTimeout Timeout)
void SetTrack(uint Type, uint TrackNo)
This is the coordinating class of the Recorder Subsystem.
std::chrono::milliseconds milliseconds
SleepTimerInfo(QString String, std::chrono::milliseconds MilliSeconds)
QList< std::chrono::seconds > m_tvmChapterTimes
void ChannelEditXDSFill(InfoMap &Info)
void DoQueueTranscode(const QString &Profile)
void HandleOSDIdle(const QString &Action)
MythTVMenu m_playbackCompactMenu
bool SubtitleZoomHandleAction(const QStringList &Actions)
void VolumeChange(bool Up, int NewVolume=-1)
bool ManualZoomHandleAction(const QStringList &Actions)
PictureAttribute m_adjustingPictureAttribute
Picture attribute to modify (on arrow left or right)
static bool IsTVRunning()
Check whether media is currently playing.
volatile int m_endOfRecPromptTimerId
void ShowLCDChannelInfo()
bool HandleLCDTimerEvent()
void GetPlayerWriteLock() const
void ProcessNetworkControlCommand(const QString &Command)
InfoMap m_chanEditMap
Channel Editing initial map.
bool m_requestDelete
User wants last video deleted.
QList< QKeyEvent * > m_screenPressKeyMapLiveTV
QString GetTitleName(int Title)
int Playback(const ProgramInfo &ProgInfo)
bool GetJumpToProgram() const
This is set if the user asked MythTV to jump to the previous recording in the playlist.
volatile int m_endOfPlaybackTimerId
static const int kInitFFRWSpeed
bool TranslateKeyPressOrGesture(const QString &Context, QEvent *Event, QStringList &Actions, bool IsLiveTV, bool AllowJumps=true)
volatile int m_networkControlTimerId
QList< QKeyEvent * > m_screenPressKeyMapPlayback
bool HandleOSDCutpoint(const QString &Action)
bool DoPlayerSeekToFrame(uint64_t FrameNum)
void ShowOSDAlreadyEditing()
static QList< QKeyEvent * > ConvertScreenPressKeyMap(const QString &KeyList)
void PopPreviousChannel(bool ImmediateChange)
PlayerContext m_playerContext
static const std::chrono::milliseconds kSpeedChangeCheckFrequency
static const std::chrono::milliseconds kEndOfRecPromptCheckFrequency
void HandleStateChange()
Changes the state to the state on the front of the state change queue.
static void ToggleChannelFavorite()
static const std::chrono::milliseconds kErrorRecoveryCheckFrequency
bool MenuItemDisplayPlayback(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
int StartTimer(std::chrono::milliseconds Interval, int Line)
uint GetQueuedChanID() const
bool m_underNetworkControl
initial show started via by the network control interface
void SleepDialogTimeout()
std::chrono::milliseconds m_dbIdleTimeout
QString m_dbChannelFormat
QMap< QString, ProgramList > m_progLists
bool AudioSyncHandleAction(const QStringList &Actions)
void DoEditSchedule(int EditType=kScheduleProgramGuide, const QString &EditArg="")
bool MenuItemDisplay(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu) override
bool m_ignoreKeyPresses
should we ignore keypresses
volatile int m_lcdVolumeTimerId
void ShowOSDStopWatchingRecording()
static const std::chrono::milliseconds kSleepTimerDialogTimeout
void UpdateOSDStatus(const QString &Title, const QString &Desc, const QString &Value, int Type, const QString &Units, int Position=0, enum OSDTimeout Timeout=kOSDTimeout_Med)
uint m_queuedChanID
Queued ChanID (from EPG channel selector)
int m_sleepDialogTimerId
Timer for sleep dialog.
bool m_subtitleDelayAdjustment
True if subtitle delay is turned on.
MythDeque< QString > m_networkControlCommands
void RetrieveCast(const ProgramInfo &ProgInfo)
void HandleSaveLastPlayPosEvent()
MythTVMenu m_cutlistCompactMenu
uint m_initialChanID
Initial chanid override for Live TV.
void PlaybackLoop()
The main playback loop.
static EMBEDRETURNVOIDSCHEDIT RunScheduleEditorPtr
bool m_sigMonMode
Are we in signal monitoring mode?
bool HasQueuedChannel() const
void ClearInputQueues(bool Hideosd)
Clear channel key buffer of input keys.
static bool IsPaused()
Check whether playback is paused.
bool m_savedPause
saved pause state before embedding
bool GetAllowRerecord() const
Returns true if the user told Mythtv to allow re-recording of the show.
QVector< string_pair > m_guests
bool m_allowRerecord
User wants to rerecord the last video if deleted.
ChannelGroupList m_dbChannelGroups
QString GetRecordingGroup() const
void setUnderNetworkControl(bool setting)
void HandleEndOfRecordingExitPromptTimerEvent()
static EMBEDRETURNVOIDEPG RunProgramGuidePtr
static void SetFuncPtr(const char *Name, void *Pointer)
Import pointers to functions used to embed the TV window into other containers e.g.
bool GetEndOfRecording() const
This is set to true if the player reaches the end of the recording without the user explicitly exitin...
QString GetAngleName(int Angle)
bool ProcessKeypressOrGesture(QEvent *Event)
float DoTogglePauseStart()
MThreadPool * GetPosThreadPool()
void DoSwitchAngle(int Angle)
QVariant m_tvmJumprecBackHack
bool RequestNextRecorder(bool ShowDialogs, const ChannelInfoList &Selection=ChannelInfoList())
bool HandleJumpToProgramAction(const QStringList &Actions)
void FillOSDMenuJumpRec(const QString &Category="", int Level=0, const QString &Selected="")
static const std::chrono::milliseconds kVideoExitDialogTimeout
MThreadPool * m_posThreadPool
void SwitchInputs(uint ChanID=0, QString ChanNum="", uint InputID=0)
QMap< QString, AskProgramInfo > m_askAllowPrograms
QString m_queuedChanNum
Input key presses queued up so far to form a valid ChanNum.
bool DoPlayerSeek(float Time)
bool m_stretchAdjustment
True if time stretch is turned on.
void FillOSDMenuActorShows(const QString &actor, int person_id, const QString &category="")
bool m_asInputMode
Are we in Arbitrary seek input mode?
bool StartPlayer(TVState desiredState)
PictureAdjustType m_adjustingPicture
Picture attribute type to modify.
QString GetQueuedInput() const
static const uint kNextSource
void PlaybackMenuDeinit(const MythTVMenu &Menu)
bool LiveTV(bool ShowDialogs, const ChannelInfoList &Selection)
Starts LiveTV.
PlayerContext * GetPlayerContext()
Return a pointer to TV::m_playerContext.
bool m_subtitleZoomAdjustment
True if subtitle zoom is turned on.
volatile int m_videoExitDialogTimerId
std::chrono::milliseconds m_sleepTimerTimeout
Current sleep timeout in msec.
void ShowOSDPromptDeleteRecording(const QString &Title, bool Force=false)
void DoTogglePauseFinish(float Time, bool ShowOSD)
void DoJumpChapter(int Chapter)
void HandleEndOfPlaybackTimerEvent()
void UpdateOSDSignal(const QStringList &List)
Updates Signal portion of OSD...
bool MenuItemDisplayCutlist(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
bool HandleOSDVideoExit(const QString &Action)
bool m_dbRememberLastChannelGroup
static const std::vector< SleepTimerInfo > kSleepTimes
void HandleOSDAskAllow(const QString &Action)
volatile int m_speedChangeTimerId
bool m_ccInputMode
Are we in CC/Teletext page/stream selection mode?
void UpdateOSDTimeoutMessage()
void ForceNextStateNone()
void PauseLiveTV()
Used in ChangeChannel() to temporarily stop video output.
static EMBEDRETURNVOID RunPlaybackBoxPtr
void ShowOSDIdle()
After idleTimer has expired, display a dialogue warning the user that we will exit LiveTV unless they...
void GetPlayerReadLock() const
MythTimer m_keyRepeatTimer
Queue of unprocessed key presses.
void StartOsdNavigation()
static const std::chrono::milliseconds kEndOfPlaybackFirstCheckTimer
static const uint kPreviousSource
void HandleOSDAlreadyEditing(const QString &Action, bool WasPaused)
static EMBEDRETURNVOIDFINDER RunProgramFinderPtr
static int GetActiveChannelGroupId()
volatile int m_lcdTimerId
volatile int m_channelGroupId
QRect m_playerBounds
Prior GUI window bounds, for DoEditSchedule() and player exit().
QReadWriteLock m_playerLock
lock on player and playerActive changes
bool m_wantsToQuit
True if the user told MythTV to stop playback.
QRecursiveMutex m_askAllowLock
void PlaybackExiting(TV *Player)
void onApplicationStateChange(Qt::ApplicationState State)
bool DialogIsVisible(const QString &Dialog)
QVector< string_pair > m_guestStars
void UpdateOSDProgInfo(const char *WhichInfo)
Update and display the passed OSD set with programinfo.
static const uint kInputKeysMax
static bool StateIsLiveTV(TVState State)
bool StartRecorder(std::chrono::milliseconds MaxWait=-1ms)
Starts recorder, must be called before StartPlayer().
bool CreatePlayer(TVState State, bool Muted=false)
static bool StartTV(ProgramInfo *TVRec, uint Flags, const ChannelInfoList &Selection=ChannelInfoList())
Start playback of media.
void MenuLazyInit(void *Field)
volatile int m_asInputTimerId
bool event(QEvent *Event) override
This handles all standard events.
bool DoSetPauseState(bool Pause)
bool HandleTrackAction(const QString &Action)
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
void HandleLCDVolumeTimerEvent()
static bool IsTunable(uint ChanId)
void HandleOSDSleep(const QString &Action)
void HandlePseudoLiveTVTimerEvent()
bool m_audiosyncAdjustment
True if audiosync is turned on.
volatile int m_exitPlayerTimerId
std::array< QStringList, kTrackTypeCount > m_tvmTracks
bool m_savePosOnExit
False until first timer event.
QString GetQueuedChanNum() const
bool ProcessSmartChannel(QString &InputStr)
void StartChannelEditMode()
Starts channel editing mode.
static QStringList lastProgramStringList
void GetChapterTimes(QList< std::chrono::seconds > &Times)
bool TranslateGesture(const QString &Context, MythGestureEvent *Event, QStringList &Actions, bool IsLiveTV)
static bool StateIsPlaying(TVState State)
void StartProgramEditMode()
Starts Program Cut Map Editing mode.
bool SubtitleDelayHandleAction(const QStringList &Actions)
int GetQueuedInputAsInt(bool *OK=nullptr, int Base=10) const
int m_dbPlaybackExitPrompt
static void MenuStrings()
bool BrowseHandleAction(const QStringList &Actions)
void DoSkipCommercials(int Direction)
static TV * AcquireRelease(int &RefCount, bool Acquire, bool Create=false)
Statically create, destroy or check the existence of the TV instance.
void DoTogglePictureAttribute(PictureAdjustType Type)
bool ContextIsPaused(const char *File, int Location)
void ToggleOSD(bool IncludeStatusOSD)
Cycle through the available Info OSDs.
volatile int m_saveLastPlayPosTimerId
volatile int m_ccInputTimerId
bool HandleOSDChannelEdit(const QString &Action)
Processes channel editing key.
QMutex m_channelGroupLock
Lock necessary when modifying channel group variables.
void UnpauseLiveTV(bool Quietly=false)
Used in ChangeChannel() to restart video output.
void ReturnPlayerLock() const
std::vector< int > m_ffRewSpeeds
TvPlayWindow * m_myWindow
Our screen, if it exists.
void HandleOSDClosed(int OSDType)
bool eventFilter(QObject *Object, QEvent *Event) override
Prevent events from being sent to another object.
static bool StateIsRecording(TVState State)
void ShowOSDCutpoint(const QString &Type)
void DoArbSeek(ArbSeekWhence Whence, bool HonorCutlist)
void ReturnOSDLock() const
void SetBookmark(bool Clear=false)
PictureAttribute NextPictureAdjustType(PictureAdjustType Type, PictureAttribute Attr)
bool m_weDisabledGUI
true if this instance disabled MythUI drawing.
void UpdateOSDSeekMessage(const QString &Msg, enum OSDTimeout Timeout)
bool SeekHandleAction(const QStringList &Actions, bool IsDVD)
volatile int m_errorRecoveryTimerId
void PlaybackMenuShow(const MythTVMenu &Menu, const QDomNode &Node, const QDomNode &Selected)
void OSDDialogEvent(int Result, const QString &Text, QString Action)
void HandleVideoExitDialogTimerEvent()
void SetAutoCommercialSkip(CommSkipMode SkipMode=kCommSkipOff)
static const std::chrono::milliseconds kIdleTimerDialogTimeout
void HideOSDWindow(const char *window)
static const std::chrono::milliseconds kSaveLastPlayPosTimeout
bool m_dbEndOfRecExitPrompt
void AskAllowRecording(const QStringList &Msg, int Timeuntil, bool HasRec, bool HasLater)
void ShowPreviousChannel()
void UpdateChannelList(int GroupID)
update the channel list with channels from the selected channel group
static EMBEDRETURNVOIDPROGLIST RunProgramListPtr
void SetExitPlayer(bool SetIt, bool WantsTo)
std::array< int, kTrackTypeCount > m_tvmCurtrack
bool m_dbContinueEmbedded
void ChangeTimeStretch(int Dir, bool AllowEdit=true)
bool TimeStretchHandleAction(const QStringList &Actions)
static const std::chrono::milliseconds kEndOfPlaybackCheckFrequency
static EMBEDRETURNVOID RunViewScheduledPtr
bool FFRewHandleAction(const QStringList &Actions)
static int ConfiguredTunerCards()
If any cards are configured, return the number.
void ChannelEditAutoFill(InfoMap &Info)
Automatically fills in as much information as possible.
void SwitchSource(uint Direction)
void SetSpeedChangeTimer(std::chrono::milliseconds When, int Line)
void HandleOSDInfo(const QString &Action)
void AddKeyToInputQueue(char Key)
bool ActivePostQHandleAction(const QStringList &Actions)
int m_tvmFreeRecorderCount
QDateTime m_lastLockSeenTime
void DoSeekAbsolute(long long Seconds, bool HonorCutlist)
bool ActiveHandleAction(const QStringList &Actions, bool IsDVD, bool IsDVDStillFrame)
static const std::chrono::milliseconds kInputModeTimeout
void timerEvent(QTimerEvent *Event) override
MythMainWindow * m_mainWindow
QString m_queuedInput
Input key presses queued up so far...
ProgramInfo * m_lastProgram
last program played with this player
static QVector< uint > IsTunableOn(PlayerContext *Context, uint ChanId)
void DoTogglePause(bool ShowOSD)
bool IsSameProgram(const ProgramInfo *ProgInfo) const
MythTVMenu m_playbackMenu
void ScheduleStateChange()
volatile int m_signalMonitorTimerId
void OverrideScan(FrameScanType Scan)
void DoSwitchTitle(int Title)
void EditSchedule(int EditType=kScheduleProgramGuide, const QString &arg="")
int m_sleepTimerId
Timer for turning off playback.
void ChangeChannel(const ChannelInfoList &Options)
bool DiscMenuHandleAction(const QStringList &Actions) const
bool IsTunablePriv(uint ChanId)
uint m_dbAutoexpireDefault
uint m_sleepIndex
Index into sleep_times.
RemoteEncoder * m_switchToRec
Main recorder to use after a successful SwitchCards() call.
CommSkipMode m_tvmCurSkip
void ChangeFFRew(int Direction)
void ITVRestart(bool IsLive)
Restart the MHEG/MHP engine.
void SetManualZoom(bool ZoomON, const QString &Desc)
QElapsedTimer m_lockTimer
bool ToggleHandleAction(const QStringList &Actions, bool IsDVD)
bool m_endOfRecording
!player->IsPlaying() && StateIsPlaying()
void SetLastProgram(const ProgramInfo *ProgInfo)
QRecursiveMutex m_chanEditMapLock
Lock for chanEditMap and ddMap.
static const std::chrono::milliseconds kKeyRepeatTimeout
std::chrono::seconds GetTitleDuration(int Title)
void PrepareToExitPlayer(int Line)
void ShowNoRecorderDialog(NoRecorderMsg MsgType=kNoRecorders)
static void FillOSDMenuCastButton(MythOSDDialogData &dialog, const QVector< string_pair > &people)
bool HasQueuedInput() const
bool PictureAttributeHandleAction(const QStringList &Actions)
ProgramInfo * GetLastProgram() const
QVector< string_pair > m_actors
int m_idleDialogTimerId
Timer for idle dialog.
void Embed(bool Embed, QRect Rect={}, const QStringList &Data={})
void PrepToSwitchToRecordedProgram(const ProgramInfo &ProgInfo)
bool m_inPlaylist
show is part of a playlist
bool StartPlaying(std::chrono::milliseconds MaxWait=-1ms)
void HandleSpeedChangeTimerEvent()
void SetInPlayList(bool InPlayList)
bool Init()
Performs instance initialization, returns true on success.
void StopStuff(bool StopRingBuffer, bool StopPlayer, bool StopRecorder)
Can shut down the ringbuffers, the players, and in LiveTV it can shut down the recorders.
volatile int m_pseudoChangeChanTimerId
void FillOSDMenuCast(void)
bool m_dbUseChannelGroups
void customEvent(QEvent *Event) override
This handles all custom events.
volatile int m_queueInputTimerId
void ScheduleInputChange()
int m_idleTimerId
Timer for turning off playback after idle period.
void DoSeek(float Time, const QString &Msg, bool TimeIsOffset, bool HonorCutlist)
static const std::chrono::milliseconds kLCDTimeout
bool m_clearPosOnExit
False unless requested by user on playback exit.
const MythTVMenu & getMenuFromId(MenuTypeId id)
void ChangeSpeed(int Direction)
void ShowOSDMenu(bool isCompact=false)
ChannelInfoList m_channelGroupChannelList
void PlaybackMenuInit(const MythTVMenu &Menu)
bool CalcPlayerSliderPosition(osdInfo &info, bool paddedFields=false) const
Simple screen shown while the video player is starting up.
void UpdateProgress(void)
bool Create(void) override
static uint Parse(const QString &vbiformat)
int to_track_type(const QString &str)
@ kTrackTypeTeletextCaptions
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)
std::chrono::milliseconds millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static void showStatus(void)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythNotificationCenter * GetNotificationCenter(void)
MythMainWindow * GetMythMainWindow(void)
static QString GET_KEY(const QString &Context, const QString &Action)
static void REG_KEY(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
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 SendMythSystemPlayEvent(const QString &msg, const ProgramInfo *pginfo)
static MythThemedMenu * menu
StereoscopicMode ActionToStereoscopic(const QString &Action)
bool IsActionable(const QString &Action, const QStringList &Actions)
QHash< QString, QString > InfoMap
static constexpr const char * ACTION_SCREENSHOT
static constexpr const char * ACTION_LEFT
static constexpr const char * ACTION_DOWN
static constexpr const char * ACTION_TVPOWERON
static constexpr const char * ACTION_TVPOWEROFF
static constexpr const char * ACTION_RIGHT
static constexpr const char * ACTION_SELECT
static constexpr const char * ACTION_UP
static constexpr const char * ACTION_GETSTATUS
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
std::chrono::seconds secsInFuture(const QDateTime &future)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
MBASE_PUBLIC std::strong_ordering 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 | .
def scan(profile, smoonURL, gate)
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
static constexpr const char * OSD_WIN_BROWSE
static constexpr const char * OSD_DLG_EDITOR
static constexpr const char * OSD_DLG_INFO
static constexpr const char * OSD_WIN_PROGINFO
static constexpr const char * OSD_WIN_STATUS
@ kOSDFunctionalType_SubtitleZoomAdjust
@ kOSDFunctionalType_AudioSyncAdjust
@ kOSDFunctionalType_SubtitleDelayAdjust
@ kOSDFunctionalType_SmartForward
@ kOSDFunctionalType_Default
@ kOSDFunctionalType_TimeStretchAdjust
@ kOSDFunctionalType_PictureAdjust
static constexpr const char * OSD_DLG_SLEEP
static constexpr const char * OSD_DLG_CONFIRM
static constexpr const char * OSD_DLG_VIDEOEXIT
static constexpr const char * OSD_WIN_INPUT
static constexpr const char * OSD_DLG_CUTPOINT
static constexpr const char * OSD_DLG_EDITING
static constexpr const char * OSD_WIN_PROGEDIT
static constexpr const char * OSD_DLG_MENU
static constexpr const char * OSD_DLG_IDLE
static constexpr const char * OSD_DLG_ASKALLOW
static constexpr const char * OSD_DLG_NAVIGATE
static constexpr const char * OSD_WIN_MESSAGE
static constexpr const char * OSD_DLG_DELETE
std::deque< QString > StringDeque
std::vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
const QString kPlayerInUseID
const QString kRecorderInUseID
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
static eu8 clamp(eu8 value, eu8 low, eu8 high)
static void show(uint8_t *buf, int length)
std::vector< SignalMonitorValue > SignalMonitorList
QHash< QString, int > values
QString toTypeString(PictureAdjustType type)
QString StateToString(TVState state)
Returns a human readable QString representing a TVState.
QString toTitleString(PictureAdjustType type)
@ BROWSE_RIGHT
Fetch information on current channel in the future.
@ BROWSE_LEFT
Fetch information on current channel in the past.
@ BROWSE_UP
Fetch information on previous channel.
@ BROWSE_FAVORITE
Fetch information on the next favorite channel.
@ BROWSE_DOWN
Fetch information on next channel.
@ kAdjustingPicture_Playback
@ kAdjustingPicture_Recording
@ kAdjustingPicture_Channel
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
@ CHANNEL_DIRECTION_FAVORITE
TVState
TVState is an enumeration of the states used by TV and TVRec.
@ kState_WatchingDVD
Watching DVD is the state when we are watching a DVD.
@ kState_None
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
@ kState_Error
Error State, if we ever try to enter this state errored is set.
@ kState_WatchingPreRecorded
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
@ kState_WatchingBD
Watching BD is the state when we are watching a BD.
@ kState_ChangingState
This is a placeholder state which we never actually enter, but is returned by GetState() when we are ...
@ kState_WatchingVideo
Watching Video is the state when we are watching a video and is not a dvd or BD.
#define ACTION_TOGGLESUBS
#define ACTION_BOTTOMLINEMOVE
#define ACTION_TOGGLEEXTTEXT
#define ACTION_TOGGLEOSDDEBUG
#define ACTION_TOGGLEPGORDER
#define ACTION_ENABLEFORCEDSUBS
#define ACTION_TOGGLESLEEP
#define ACTION_NEXTSUBPAGE
#define ACTION_SWITCHANGLE
#define ACTION_DISABLEVISUALISATION
#define ACTION_JUMPTODVDCHAPTERMENU
#define ACTION_TOGGLESUBTITLEDELAY
#define ACTION_VIEWSCHEDULED
#define ACTION_ZOOMHORIZONTALIN
#define ACTION_TOGGELAUDIOSYNC
#define ACTION_ZOOMVERTICALIN
#define ACTION_TOGGLEVISUALISATION
#define ACTION_DISABLEEXTTEXT
#define ACTION_TOGGLEBACKGROUND
#define ACTION_ZOOMHORIZONTALOUT
#define ACTION_OSDNAVIGATION
#define ACTION_CHANNELSEARCH
#define ACTION_JUMPTODVDROOTMENU
#define ACTION_ENABLEEXTTEXT
#define ACTION_TOGGLERECORD
#define ACTION_SETCONTRAST
#define ACTION_LISTRECORDEDEPISODES
#define ACTION_BIGJUMPREW
#define ACTION_TOGGLECHANCONTROLS
#define ACTION_3DTOPANDBOTTOMDISCARD
#define ACTION_LOADCOMMSKIP
#define ACTION_SETBRIGHTNESS
#define ACTION_PREVSUBPAGE
#define ACTION_TOGGLESUBTITLEZOOM
#define ACTION_DISABLEUPMIX
#define ACTION_TOGGLEBOOKMARK
#define ACTION_ZOOMASPECTDOWN
#define ACTION_SWITCHTITLE
#define ACTION_3DSIDEBYSIDEDISCARD
#define ACTION_DISABLESUBS
#define ACTION_SEEKABSOLUTE
#define ACTION_JUMPTOPOPUPMENU
#define ACTION_ENABLESUBS
#define ACTION_PREVRECORDED
#define ACTION_BIGJUMPFWD
#define ACTION_JUMPCHAPTER
#define ACTION_EXITSHOWNOPROMPTS
#define ACTION_DISABLEFORCEDSUBS
#define ACTION_ZOOMASPECTUP
#define ACTION_MENUCOMPACT
#define ACTION_SETAUDIOSYNC
#define ACTION_ENABLEVISUALISATION
#define ACTION_ENABLEUPMIX
#define ACTION_TOGGLEUPMIX
#define ACTION_MENUYELLOW
#define ACTION_BOTTOMLINESAVE
#define ACTION_VOLUMEDOWN
#define ACTION_JUMPTODVDTITLEMENU
#define ACTION_TOGGLERECCONTROLS
#define ACTION_ZOOMVERTICALOUT
#define ACTION_SETBOOKMARK
#define ACTION_CHANNELDOWN
#define ACTION_ZOOMCOMMIT
static int comp_season_rev(const ProgramInfo *a, const ProgramInfo *b)
static QString add_spacer(const QString &chan, const QString &spacer)
#define BUTTON3(action, textActive, textInactive, isMenu)
#define BUTTON2(action, textActive, textInactive)
static void insert_map(InfoMap &infoMap, const InfoMap &newMap)
static bool comp_title(const ProgramInfo *a, const ProgramInfo *b)
static QString tv_i18n(const QString &msg)
static QString toCommaList(const QVector< uint > &list)
static uint get_chanid(const PlayerContext *ctx, uint cardid, const QString &channum)
#define BUTTON(action, text)
static int comp_originalAirDate_rev(const ProgramInfo *a, const ProgramInfo *b)
static bool SysEventHandleAction(MythMainWindow *MainWindow, QKeyEvent *e, const QStringList &actions)
#define TRANSITION(ASTATE, BSTATE)
void(*)(const ProgramInfo *, void *) EMBEDRETURNVOIDSCHEDIT
void(*)(void *, bool) EMBEDRETURNVOID
void(*)(uint, const QString &, const QDateTime, TV *, bool, bool, int) EMBEDRETURNVOIDEPG
void(*)(TV *, int, const QString &) EMBEDRETURNVOIDPROGLIST
@ kStartTVIgnoreLastPlayPos
@ kStartTVIgnoreProgStart
@ kStartTVByNetworkCommand
void(*)(TV *, bool, bool) EMBEDRETURNVOIDFINDER
NoRecorderMsg
Type of message displayed in ShowNoRecorderDialog()
@ kNoRecorders
No free recorders.
@ kNoCurrRec
No current recordings.
@ kNoTuners
No capture cards configured.
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
RemoteEncoder * RemoteGetExistingRecorder(const ProgramInfo *pginfo)
RemoteEncoder * RemoteRequestNextFreeRecorder(int inputid)
std::vector< InputInfo > RemoteRequestFreeInputInfo(uint excluded_input)
int RemoteGetFreeRecorderCount(void)
RemoteEncoder * RemoteRequestFreeRecorderFromList(const QStringList &qualifiedRecorders, uint excluded_input)
void RemoteCancelNextRecording(uint inputid, bool cancel)
PictureAttribute next_picattr(PictureAttributeSupported Supported, PictureAttribute Attribute)
QString GetZoomString(float HorizScale, float VertScale, QPoint Move)
@ kAdjustFill_AutoDetect_DefaultHalf
@ kAdjustFill_AutoDetect_DefaultOff
PictureAttributeSupported
@ kPictureAttributeSupported_Colour
@ kPictureAttributeSupported_Volume
@ kPictureAttributeSupported_Brightness
@ kPictureAttributeSupported_Hue
@ kPictureAttributeSupported_Contrast
@ kPictureAttributeSupported_None
@ kDisplayRawTextSubtitle
@ kDisplayNUVTeletextCaptions
@ kDisplayTeletextCaptions
@ kPictureAttribute_Range
@ kPictureAttribute_Contrast
@ kPictureAttribute_Brightness
@ kPictureAttribute_Volume
@ kPictureAttribute_Colour
QString ScanTypeToUserString(FrameScanType Scan, bool Forced=false)
@ kStereoscopicModeTopAndBottomDiscard
@ kStereoscopicModeSideBySideDiscard
@ kStereoscopicModeIgnore3D
PictureAttributeSupported toMask(PictureAttribute PictureAttribute)
bool OptionalCaptionEnabled(uint Captions)
Return whether any optional captions are enabled.