8#include <QCoreApplication>
53#define LOC QString("PlaybackBox: ")
54#define LOC_WARN QString("PlaybackBox Warning: ")
55#define LOC_ERR QString("PlaybackBox Error: ")
85 return (dt1 < dt2 ? 1 : -1);
98 return (dt1 > dt2 ? 1 : -1);
138 int eIndex = synd.indexOf(
'E');
139 if (synd.isEmpty() || !synd.startsWith(
'S') || (eIndex == -1))
147 bool okSeason {
false };
148 bool okEpisode {
false };
149 season = synd.mid(1, eIndex - 1).toInt(&okSeason);
150 episode = synd.mid(eIndex + 1).toInt(&okEpisode);
152 return okSeason && okEpisode;
165 if (a_season == 0 || b_season == 0)
167 if (a_season != b_season)
168 return (a_season < b_season ? 1 : -1);
169 if (a_episode == 0 && b_episode == 0)
171 return (a_episode < b_episode ? 1 : -1);
184 if (a_season == 0 || b_season == 0)
186 if (a_season != b_season)
187 return (a_season > b_season ? 1 : -1);
188 if (a_episode == 0 && b_episode == 0)
190 return (a_episode > b_episode ? 1 : -1);
266 QString sTitle = sortTitle.isEmpty()
267 ? title : sortTitle +
" - " + title;
296 sortprefix = QString(
"+%1").arg(1000 - recpriority, 3, 10, QChar(
'0'));
298 sortprefix = QString(
"-%1").arg(-recpriority, 3, 10, QChar(
'0'));
300 sTitle = sortprefix +
'-' + sTitle;
307 QString state(
"normal");
323 if ((state ==
"normal" || state ==
"running") &&
334 QString job =
"default";
347 job =
"commflagging";
367 const ProgramInfo &pginfo,
const QString &groupname)
370 if (groupname != pginfo.
GetTitle().toLower())
377 if (subtitle.trimmed().isEmpty())
387 list.push_back(QString() );
388 list.push_back(QString());
399 recordingID = list[0].toUInt();
405 if (recordingID == 0U) {
406 LOG(VB_GENERAL, LOG_ERR,
LOC +
"extract_one_del() invalid entry");
416 auto *pbb =
new PlaybackBox(mainStack,
"playbackbox", (
TV *)player, showTV);
430 m_groupDisplayName(
ProgramInfo::i18n(
"All Programs")),
431 m_recGroup(
"All Programs"),
432 m_watchGroupName(tr(
"Watch List")),
433 m_watchGroupLabel(m_watchGroupName.toLower()),
436 m_programInfoCache(this),
462 "DisplayGroupDefaultViewMask",
504 (displayCat &&
m_recGroup !=
"All Programs") ?
"category" :
"recgroup";
557 LOG(VB_GENERAL, LOG_ERR,
LOC +
558 "Theme is missing critical theme elements.");
619 "titlesubtitle|shortdate|starttime");
663 QString label = tr(
"Password for group '%1':").arg(newRecGroup);
701 const QString &grouplabel)
707 infoMap[
"title"] = grouplabel;
714 if (!groupname.isEmpty() && !
m_progLists[groupname].empty())
739 if (countInGroup >= 1)
742 float groupSize = 0.0;
744 for (
auto *
info : group)
748 uint64_t filesize =
info->GetFilesize();
755 groupSize += filesize;
759 desc = tr(
"There is/are %n recording(s) in this display "
760 "group, which consume(s) %1 GiB.",
"", countInGroup)
761 .arg(groupSize / 1024.0F / 1024.0F / 1024.0F, 0,
'f', 2);
765 desc = tr(
"There is no recording in this display group.");
768 infoMap[
"description"] = desc;
769 infoMap[
"rec_count"] = QString(
"%1").arg(countInGroup);
778 ratingState->
Reset();
798 bool force_preview_reload)
814 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
815 QString(
"UpdateUIListItem called with a title unknown "
816 "to us in m_recordingList\n\t\t\t%1")
823 "playlist",
"watched",
"preserve",
824 "cutlist",
"autoexpire",
"editing",
825 "bookmark",
"inuse",
"transcoded"
840 disp_flag_stat[8] = ((pginfo->
GetProgramFlags() & FL_TRANSCODED) != 0U);
842 for (
size_t i = 0; i <
disp_flags.size(); ++i)
848 bool is_sel,
bool force_preview_reload)
865 pginfo->ToMap(infoMap);
873 if (groupname == pginfo->GetTitle().toLower())
875 item->
SetText(tempSubTitle,
"titlesubtitle");
879 "titlesubtitlefull");
896 QString
rating = QString::number(pginfo->GetStars(10));
901 if (oldimgfile.isEmpty() || force_preview_reload)
908 pginfo->CalculateProgress(pginfo->QueryLastPlayPos());
910 pginfo->ToMap(infoMap);
944 if (arthost.isEmpty())
951 pginfo->GetInetRef(), pginfo->GetSeason(),
973 if (item->
GetText(
"is_item_initialized").isNull())
975 QMap<AudioProps, QString> audioFlags;
976 audioFlags[AUD_DOLBY] =
"dolby";
977 audioFlags[AUD_SURROUND] =
"surround";
978 audioFlags[AUD_STEREO] =
"stereo";
979 audioFlags[AUD_MONO] =
"mono";
981 QMap<VideoProps, QString> codecFlags;
982 codecFlags[VID_MPEG2] =
"mpeg2";
983 codecFlags[VID_AVC] =
"avc";
984 codecFlags[VID_HEVC] =
"hevc";
986 QMap<SubtitleProps, QString> subtitleFlags;
987 subtitleFlags[SUB_SIGNED] =
"deafsigned";
988 subtitleFlags[SUB_ONSCREEN] =
"onscreensub";
989 subtitleFlags[SUB_NORMAL] =
"subtitles";
990 subtitleFlags[SUB_HARDHEAR] =
"cc";
1000 pginfo->ToMap(infoMap);
1005 if (groupname == pginfo->GetTitle().toLower())
1007 item->
SetText(tempSubTitle,
"titlesubtitle");
1011 "titlesubtitlefull");
1016 item->
DisplayState(QString::number(pginfo->GetStars(10)),
1021 QMap<AudioProps, QString>::iterator ait;
1022 for (ait = audioFlags.begin(); ait != audioFlags.end(); ++ait)
1024 if (pginfo->GetAudioProperties() & ait.key())
1028 uint props = pginfo->GetVideoProperties();
1030 QMap<VideoProps, QString>::iterator cit;
1031 for (cit = codecFlags.begin(); cit != codecFlags.end(); ++cit)
1033 if (props & cit.key())
1040 if (props & VID_PROGRESSIVE)
1045 if (props & VID_1080)
1052 if (props & VID_1080)
1055 if (props & VID_720)
1057 if (!(props & (VID_4K | VID_1080 | VID_720)))
1059 if (props & VID_HDTV)
1061 else if (props & VID_WIDESCREEN)
1067 QMap<SubtitleProps, QString>::iterator sit;
1068 for (sit = subtitleFlags.begin(); sit != subtitleFlags.end(); ++sit)
1070 if (pginfo->GetSubtitleType() & sit.key())
1074 item->
DisplayState(pginfo->GetCategoryTypeString(),
"categorytype");
1077 item->
SetText(
"yes",
"is_item_initialized");
1094 const auto watchedPercent = pginfo->GetWatchedPercent();
1096 item->
SetProgress1(0, showProgress ? 100 : 0, watchedPercent);
1097 item->
SetProgress2(0, 100, pginfo->GetRecordedPercent());
1104 if (token.isEmpty())
1111 (
asAvailable == sel_pginfo->GetAvailableStatus()))
1127 if (list.size() < 5)
1129 LOG(VB_GENERAL, LOG_ERR,
"HandlePreviewEvent() -- too few args");
1130 for (
uint i = 0; i < (
uint) list.size(); i++)
1132 LOG(VB_GENERAL, LOG_INFO, QString(
"%1: %2")
1133 .arg(i).arg(list[i]));
1138 uint recordingID = list[0].toUInt();
1139 const QString& previewFile = list[1];
1140 const QString& message = list[2];
1143 for (
uint i = 4; i < (
uint) list.size(); i++)
1145 const QString& token = list[i];
1156 QString tokens(
"\n\t\t\ttokens: ");
1157 for (
uint i = 4; i < (
uint) list.size(); i++)
1158 tokens += list[i] +
", ";
1159 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1160 "Ignoring PREVIEW_SUCCESS, no matcing token" + tokens);
1164 if (previewFile.isEmpty())
1166 LOG(VB_GENERAL, LOG_ERR,
LOC +
1167 "Ignoring PREVIEW_SUCCESS, no preview file.");
1179 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1180 "Ignoring PREVIEW_SUCCESS, item no longer on screen.");
1185 LOG(VB_GUI, LOG_INFO,
LOC + QString(
"Loading preview %1,\n\t\t\tmsg %2")
1186 .arg(previewFile, message));
1188 item->
SetImage(previewFile,
"preview",
true);
1202 uint32_t flags = FL_NONE;
1207 QMap <QString, int>::iterator it;
1210 iconMap[
"commflagged"] = FL_COMMFLAG;
1211 iconMap[
"cutlist"] = FL_CUTLIST;
1212 iconMap[
"autoexpire"] = FL_AUTOEXP;
1213 iconMap[
"processing"] = FL_COMMPROCESSING;
1214 iconMap[
"editing"] = FL_EDITING;
1215 iconMap[
"bookmark"] = FL_BOOKMARK;
1216 iconMap[
"inuse"] = (FL_INUSERECORDING |
1219 iconMap[
"transcoded"] = FL_TRANSCODED;
1220 iconMap[
"watched"] = FL_WATCHED;
1221 iconMap[
"preserved"] = FL_PRESERVED;
1229 iconImage->
SetVisible((flags & (*it)) != 0U);
1243 iconMap[
"1dolby"] = AUD_DOLBY;
1244 iconMap[
"2surround"] = AUD_SURROUND;
1245 iconMap[
"3stereo"] = AUD_STEREO;
1249 bool haveIcon =
false;
1250 if (pginfo && iconState)
1265 if (iconState && !haveIcon)
1270 if (pginfo && iconState)
1275 if (props & VID_PROGRESSIVE)
1278 iconMap[
"hd1080p"] = VID_1080;
1283 iconMap[
"hd1080i"] = VID_1080;
1288 iconMap[
"widescreen"] = VID_WIDESCREEN;
1303 if (iconState && !haveIcon)
1306 iconMap[
"damaged"] = VID_DAMAGED;
1310 if (pginfo && iconState)
1325 if (iconState && !haveIcon)
1328 iconMap[
"deafsigned"] = SUB_SIGNED;
1329 iconMap[
"onscreensub"] = SUB_ONSCREEN;
1330 iconMap[
"subtitles"] = SUB_NORMAL;
1335 if (pginfo && iconState)
1350 if (iconState && !haveIcon)
1375 if (!freereportText && !usedProgress && !
GetChild(
"diskspacetotal") &&
1385 usageMap[
"diskspacetotal"] = locale.toString((freeSpaceTotal / 1024.0),
1387 usageMap[
"diskspaceused"] = locale.toString((freeSpaceUsed / 1024.0),
1389 usageMap[
"diskspacefree"] = locale.toString(
1390 ((freeSpaceTotal - freeSpaceUsed) / 1024.0),
1394 if (freeSpaceTotal > 0.0)
1395 perc = (100.0 * freeSpaceUsed) / freeSpaceTotal;
1397 usageMap[
"diskspacepercentused"] = QString::number((
int)perc);
1398 usageMap[
"diskspacepercentfree"] = QString::number(100 - (
int)perc);
1400 QString size = locale.toString(((freeSpaceTotal - freeSpaceUsed) / 1024.0),
1403 QString usestr = tr(
"%1% used, %2 GB free",
"Diskspace")
1404 .arg(QString::number((
int)perc),
1408 freereportText->
SetText(usestr);
1412 usedProgress->
SetTotal((
int)freeSpaceTotal);
1413 usedProgress->
SetUsed((
int)freeSpaceUsed);
1436 const QString& key = (*it);
1437 QString
tmp = (key ==
"All Programs") ?
"All" : key;
1444 QVariant::fromValue(key));
1448 item->SetText(name);
1460 int best_pref = INT_MAX;
1463 QStringList::iterator it;
1466 const QString& groupname = (*it);
1469 QVariant::fromValue(groupname.toLower()));
1471 int pref = groupPreferences.indexOf(groupname.toLower());
1472 if ((pref >= 0) && (pref < best_pref))
1479 QString displayName = groupname;
1480 if (displayName.isEmpty())
1489 item->SetText(groupname,
"groupname");
1490 item->SetText(displayName,
"name");
1491 item->SetText(displayName);
1493 int count =
m_progLists[groupname.toLower()].size();
1494 item->SetText(QString::number(count),
"reccount");
1511 QVariant::fromValue(Iqs->first));
1512 item->SetText(Iqs->first);
1520 QString newRecGroup = sel_item->
GetData().toString();
1536 if (!nextGroup.isEmpty())
1545 QString groupname = sel_item->
GetData().toString();
1546 QString grouplabel = sel_item->
GetText();
1560 ProgramMap::iterator pmit =
m_progLists.find(groupname);
1566 for (
auto & prog : progList)
1569 prog->GetAvailableStatus() ==
asDeleted)
1578 if (!progList.
empty())
1583 tr(
"There are no recordings available") :
1584 tr(
"There are no recordings in your current view");
1592 if (grouplabel.startsWith(
"Watch List") ||
1593 grouplabel.startsWith(
"All Programs"))
1600 if (pginfo ==
nullptr)
1614 if (!item->
GetText().isEmpty())
1623 QStringList &groupSelPref, QStringList &itemSelPref,
1624 QStringList &itemTopPref)
1630 groupSelPref.push_back(prefSelGroup->
GetData().toString());
1632 i < groupList->GetCount(); i++)
1636 groupSelPref.push_back(prefSelGroup->
GetData().toString());
1640 for (
int i = curPos; (i >= 0) && (i < recordingList->GetCount()); i++)
1644 itemSelPref.push_back(groupSelPref.front());
1645 itemSelPref.push_back(QString::number(pginfo->GetRecordingID()));
1647 for (
int i = curPos; (i >= 0) && (i < recordingList->GetCount()); i--)
1651 itemSelPref.push_back(groupSelPref.front());
1652 itemSelPref.push_back(QString::number(pginfo->GetRecordingID()));
1656 for (
int i = topPos + 1; i >= topPos - 1; i--)
1658 if (i >= 0 && i < recordingList->GetCount())
1664 itemTopPref.push_front(QString::number(pginfo->GetRecordingID()));
1665 itemTopPref.push_front(groupSelPref.front());
1669 itemTopPref.push_back(groupSelPref.front());
1670 itemTopPref.push_back(QString::number(pginfo->GetRecordingID()));
1680 const QStringList &groupSelPref,
const QStringList &itemSelPref,
1681 const QStringList &itemTopPref)
1686 if (!prefSelGroup ||
1687 !groupSelPref.contains(prefSelGroup->
GetData().toString()) ||
1688 !itemSelPref.contains(prefSelGroup->
GetData().toString()))
1694 QString groupname = prefSelGroup->
GetData().toString();
1698 for (
uint i = 0; i+1 < (
uint)itemSelPref.size(); i+=2)
1700 if (itemSelPref[i] != groupname)
1703 uint recordingID = itemSelPref[i+1].toUInt();
1708 if (pginfo && (pginfo->GetRecordingID() == recordingID))
1711 i = itemSelPref.size();
1719 for (
uint i = 0; i+1 < (
uint)itemTopPref.size(); i+=2)
1721 if (itemTopPref[i] != groupname)
1724 uint recordingID = itemTopPref[i+1].toUInt();
1729 if (pginfo && (pginfo->GetRecordingID() == recordingID))
1732 i = itemTopPref.size();
1741 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Reselect success (%1,%2)")
1742 .arg(sel).arg(top));
1749 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Reselect failure (%1,%2)")
1750 .arg(sel).arg(top));
1760 QStringList groupSelPref;
1761 QStringList itemSelPref;
1762 QStringList itemTopPref;
1764 groupSelPref, itemSelPref, itemTopPref))
1773 QMap<uint, AvailableStatusType> asCache;
1779 uint asRecordingID = prog->GetRecordingID();
1780 asCache[asRecordingID] = prog->GetAvailableStatus();
1799 bool isAllProgsGroup = (
m_recGroup ==
"All Programs");
1800 QMap<QString, QString> sortedList;
1801 QMap<int, QString> searchRule;
1802 QMap<int, QDateTime> recidLastEventTime;
1803 QMap<int, ProgramInfo*> recidWatchListProgram;
1814 query.
prepare(
"SELECT recordid,title FROM record "
1815 "WHERE search > 0 AND search != :MANUAL;");
1820 while (query.
next())
1822 QString tmpTitle = query.
value(1).toString();
1824 searchRule[query.
value(0).toInt()] = tmpTitle;
1830 bool isUnknownCategory = (
m_recGroup == tr(
"Unknown"));
1831 bool isDeletedGroup = (
m_recGroup ==
"Deleted");
1832 bool isLiveTvGroup = (
m_recGroup ==
"LiveTV");
1834 std::vector<ProgramInfo*> list;
1837 for (
auto *
p : list)
1839 if (
p->IsDeletePending())
1844 const QString& pRecgroup(
p->GetRecordingGroup());
1845 const bool isLiveTVProg(pRecgroup ==
"LiveTV");
1852 if (pRecgroup ==
"Deleted")
1856 if (!isDeletedGroup)
1861 !isLiveTvGroup && isLiveTVProg)
1870 else if (isCategoryFilter)
1873 if (isUnknownCategory ? !
p->GetCategory().isEmpty()
1878 else if (!isAllProgsGroup && pRecgroup !=
m_recGroup)
1883 if (
p->GetTitle().isEmpty())
1884 p->SetTitle(tr(
"_NO_TITLE_"));
1891 uint asRecordingID =
p->GetRecordingID();
1892 if (asCache.contains(asRecordingID))
1893 p->SetAvailableStatus(asCache[asRecordingID],
"UpdateUILists");
1899 QString tmpTitle = tr(
"Live TV");
1900 sortedList[tmpTitle.toLower()] = tmpTitle;
1902 m_progLists[tmpTitle.toLower()].setAutoDelete(
false);
1910 p->GetTitle(),
p->GetSortTitle(),
m_viewMask, titleSort,
1911 p->GetRecordingPriority());
1912 sTitle = sTitle.toLower();
1914 if (!sortedList.contains(sTitle))
1915 sortedList[sTitle] =
p->GetTitle();
1916 m_progLists[sortedList[sTitle].toLower()].push_front(
p);
1917 m_progLists[sortedList[sTitle].toLower()].setAutoDelete(
false);
1922 !pRecgroup.isEmpty() && !isLiveTVProg)
1924 sortedList[pRecgroup.toLower()] = pRecgroup;
1926 m_progLists[pRecgroup.toLower()].setAutoDelete(
false);
1932 QString catl =
p->GetCategory().toLower();
1933 sortedList[catl] =
p->GetCategory();
1939 !searchRule[
p->GetRecordingRuleID()].isEmpty() &&
1940 p->GetTitle() != searchRule[
p->GetRecordingRuleID()])
1942 QString tmpTitle = QString(
"(%1)")
1943 .arg(searchRule[
p->GetRecordingRuleID()]);
1944 sortedList[tmpTitle.toLower()] = tmpTitle;
1946 m_progLists[tmpTitle.toLower()].setAutoDelete(
false);
1950 !isLiveTVProg && pRecgroup !=
"Deleted")
1952 int rid =
p->GetRecordingRuleID();
1953 auto letIt = recidLastEventTime.find(rid);
1954 if (letIt == recidLastEventTime.end() || *letIt < p->GetLastModifiedTime())
1956 recidLastEventTime[rid] =
p->GetLastModifiedTime();
1962 LOG(VB_FILE, LOG_INFO, QString(
"Auto-expire off: %1")
1963 .arg(
p->GetTitle()));
1965 else if (
p->IsWatched())
1968 LOG(VB_FILE, LOG_INFO,
1969 QString(
"Marked as 'watched': %1")
1970 .arg(
p->GetTitle()));
1974 auto wlpIt = recidWatchListProgram.find(rid);
1975 if (wlpIt == recidWatchListProgram.end())
1977 recidWatchListProgram[rid] =
p;
1981 (*wlpIt)->SetRecordingPriority2(
wlEarlier);
1982 LOG(VB_FILE, LOG_INFO,
1983 QString(
"Not the earliest: %1")
1984 .arg((*wlpIt)->GetTitle()));
1986 recidWatchListProgram[rid] =
p;
1991 LOG(VB_FILE, LOG_INFO,
1992 QString(
"Not the earliest: %1")
1993 .arg(
p->GetTitle()));
2001 for (
auto *
p : std::as_const(recidWatchListProgram))
2010 if (sortedList.empty())
2012 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"SortedList is Empty");
2016 if (!isAllProgsGroup)
2028 if (episodeSort ==
"OrigAirDate")
2030 QMap<QString, ProgramList>::Iterator Iprog;
2033 if (!Iprog.key().isEmpty())
2035 std::stable_sort((*Iprog).begin(), (*Iprog).end(),
2042 else if (episodeSort ==
"Id")
2044 QMap<QString, ProgramList>::Iterator Iprog;
2047 if (!Iprog.key().isEmpty())
2049 std::stable_sort((*Iprog).begin(), (*Iprog).end(),
2056 else if (episodeSort ==
"Date")
2058 QMap<QString, ProgramList>::iterator it;
2061 if (!it.key().isEmpty())
2063 std::stable_sort((*it).begin(), (*it).end(),
2070 else if (episodeSort ==
"Season")
2072 QMap<QString, ProgramList>::iterator it;
2075 if (!it.key().isEmpty())
2077 std::stable_sort((*it).begin(), (*it).end(),
2088 query.
prepare(
"SELECT recordid, last_delete FROM record;");
2092 while (query.
next())
2094 int recid = query.
value(0).toInt();
2096 QDateTime last_delete =
2099 if (last_delete.isValid())
2101 auto it = recidLastEventTime.find(recid);
2102 if (it != recidLastEventTime.end() && last_delete > *it)
2104 recidLastEventTime[recid] = last_delete;
2113 int recid = (*pit)->GetRecordingRuleID();
2115 (*pit)->SetRecordingPriority2(recidLastEventTime[recid].toSecsSinceEpoch()/60);
2117 LOG(VB_FILE, LOG_INFO, QString(
" %1 %2 %3")
2120 .arg((*pit)->GetRecordingPriority2())
2121 .arg((*pit)->GetTitle()));
2135 (
std::find(sortedList.cbegin(), sortedList.cend(), tr(
"Live TV"))
2136 == sortedList.cend()))
2152 query.
prepare(
"SELECT distinct recgroup from recorded WHERE "
2153 "deletepending = 0 ORDER BY recgroup");
2157 while (query.
next())
2159 name = query.
value(0).toString();
2160 if (name !=
"Deleted" && name !=
"LiveTV" && !name.startsWith(
'.'))
2174 for (
auto it = sortedList.keyValueBegin();
2175 it != sortedList.keyValueEnd(); ++it)
2177 first = (*it).first.at(0).toUpper();
2198 groupSelPref, itemSelPref, itemTopPref);
2211 while (!
tmp.isEmpty())
2223 QCoreApplication::postEvent(
2237 const bool ignoreBookmark =
false;
2238 const bool ignoreProgStart =
false;
2239 const bool ignoreLastPlayPos =
false;
2240 const bool underNetworkControl =
false;
2242 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2243 underNetworkControl);
2256 const bool ignoreBookmark =
false;
2257 const bool ignoreProgStart =
true;
2258 const bool ignoreLastPlayPos =
true;
2259 const bool underNetworkControl =
false;
2261 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2262 underNetworkControl);
2275 const bool ignoreBookmark =
true;
2276 const bool ignoreProgStart =
true;
2277 const bool ignoreLastPlayPos =
true;
2278 const bool underNetworkControl =
false;
2280 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2281 underNetworkControl);
2294 const bool ignoreBookmark =
true;
2295 const bool ignoreProgStart =
true;
2296 const bool ignoreLastPlayPos =
false;
2297 const bool underNetworkControl =
false;
2299 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2300 underNetworkControl);
2304 bool ignoreBookmark,
2305 bool ignoreProgStart,
2306 bool ignoreLastPlayPos,
2307 bool underNetworkControl)
2311 Play(pginfo,
false, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos, underNetworkControl);
2358 LOG(VB_GENERAL, LOG_ERR, QString(
"deleteSelected(%1) -- failed ")
2360 QString(
"availability status: %1 ")
2361 .arg(pginfo->GetAvailableStatus()));
2364 tr(
"This recording is already being deleted"));
2366 else if (!pginfo->QueryIsDeleteCandidate())
2369 pginfo->QueryIsInUse(byWho);
2371 LOG(VB_GENERAL, LOG_ERR, QString(
"deleteSelected(%1) -- failed ")
2373 QString(
"delete candidate: %1 in use by %2")
2374 .arg(pginfo->QueryIsDeleteCandidate()).arg(byWho));
2376 if (byWho.isEmpty())
2379 tr(
"This recording is already being deleted"));
2384 tr(
"This recording is currently in use by:") +
"\n" +
2432 if (which ==
"groupmenu")
2452 else if (which ==
"actionmenu")
2466 QString label = tr(
"Group List Menu");
2507 bool inPlaylist,
bool ignoreBookmark,
bool ignoreProgStart,
2508 bool ignoreLastPlayPos,
bool underNetworkControl)
2510 bool playCompleted =
false;
2538 ignoreProgStart =
true;
2554 QCoreApplication::postEvent(
2561 return playCompleted;
2565 bool forceMetadataDelete)
2572 if (!forceMetadataDelete &&
2582 if (!forceMetadataDelete)
2587 forceMetadataDelete, forgetHistory);
2617 label = tr(
"Are you sure you want to delete:");
break;
2619 label = tr(
"Recording file does not exist.\n"
2620 "Are you sure you want to delete:");
2623 label = tr(
"Are you sure you want to stop:");
break;
2630 if (delItem !=
nullptr)
2680 tr(
"Yes, delete it and the remaining %1 list items")
2689 nullptr, !defaultIsYes);
2693 nullptr, !defaultIsYes);
2700 tr(
"No, and keep the remaining %1 list items")
2701 .arg(other_delete_cnt),
2721 tr(
"This recording is currently in "
2722 "use by:") +
"\n" + byWho);
2728 tr(
"This recording is currently "
2735 tr(
"This recording is currently being "
2736 "deleted and is unavailable"));
2741 tr(
"This recording has been "
2742 "deleted and is unavailable"));
2747 tr(
"The file for this recording can "
2753 tr(
"The file for this recording is "
2759 tr(
"This recording is not yet "
2766 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2767 "all items in the playlist",
"",
m_playList.size());
2779 menu->AddItem(tr(
"Toggle playlist for this Category/Title"),
2784 menu->AddItem(tr(
"Toggle playlist for this Group"),
2790 menu->AddItem(tr(
"Toggle playlist for this recording"),
2797 menu->AddItem(tr(
"Delete, and allow re-record"),
2805 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2806 "all items in the playlist",
"",
m_playList.size());
2823 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2824 "all items in the playlist",
"",
m_playList.size());
2830 QList<uint>::Iterator it;
2831 bool isTranscoding =
true;
2832 bool isFlagging =
true;
2833 bool isMetadataLookup =
true;
2834 bool isRunningUserJob1 =
true;
2835 bool isRunningUserJob2 =
true;
2836 bool isRunningUserJob3 =
true;
2837 bool isRunningUserJob4 =
true;
2847 isTranscoding =
false;
2855 isMetadataLookup =
false;
2859 isRunningUserJob1 =
false;
2863 isRunningUserJob2 =
false;
2867 isRunningUserJob3 =
false;
2871 isRunningUserJob4 =
false;
2872 if (!isTranscoding && !isFlagging && !isRunningUserJob1 &&
2873 !isRunningUserJob2 && !isRunningUserJob3 && !isRunningUserJob4)
2888 if (!isMetadataLookup)
2894 if (!command.isEmpty())
2898 if (!isRunningUserJob1)
2900 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2905 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2911 if (!command.isEmpty())
2915 if (!isRunningUserJob2)
2917 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2922 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2928 if (!command.isEmpty())
2932 if (!isRunningUserJob3)
2934 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2939 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2945 if (!command.isEmpty())
2949 if (!isRunningUserJob4)
2951 menu->AddItem(QString(
"%1 %2").arg(tr(
"Begin"), jobTitle),
2956 menu->AddItem(QString(
"%1 %2").arg(tr(
"Stop"), jobTitle),
3027 menu->AddItem(tr(
"Play from last played position"),
3030 menu->AddItem(tr(
"Play from bookmark"),
3032 menu->AddItem(tr(
"Play from beginning"),
3035 menu->AddItem(tr(
"Clear last played position"),
3051 tr(
"Disable Auto Expire") : tr(
"Enable Auto Expire");
3053 tr(
"Do not preserve this episode") : tr(
"Preserve this episode");
3074 menu->AddItem(tr(
"Edit Recording Schedule"),
3088static const std::array<const int,kMaxJobs>
kJobs
3119 const std::array<const bool,kMaxJobs> add
3129 const std::array<const QString,kMaxJobs*2> desc
3132 tr(
"Stop Transcoding"), tr(
"Begin Transcoding"),
3133 tr(
"Stop Commercial Detection"), tr(
"Begin Commercial Detection"),
3134 tr(
"Stop Metadata Lookup"), tr(
"Begin Metadata Lookup"),
3141 for (
size_t i = 0; i <
kMaxJobs; i++)
3146 QString stop_desc = desc[(i*2)+0];
3147 QString start_desc = desc[(i*2)+1];
3149 if (start_desc.toUInt())
3152 "UserJobDesc"+start_desc, tr(
"User Job") +
" #" + start_desc);
3153 stop_desc = tr(
"Stop") +
' ' + jobTitle;
3154 start_desc = tr(
"Begin") +
' ' + jobTitle;
3162 menu->AddItem((running) ? stop_desc : start_desc,
3163 kMySlots[(i * 2) + (running ? 0 : 1)], submenu);
3171 QString label = tr(
"Transcoding profiles");
3175 menu->AddItemV(tr(
"Default"), QVariant::fromValue(-1));
3176 menu->AddItemV(tr(
"Autodetect"), QVariant::fromValue(0));
3179 query.
prepare(
"SELECT r.name, r.id "
3180 "FROM recordingprofiles r, profilegroups p "
3181 "WHERE p.name = 'Transcoders' "
3182 "AND r.profilegroup = p.id "
3183 "AND r.name != 'RTjpeg/MPEG4' "
3184 "AND r.name != 'MPEG2' ");
3192 while (query.
next())
3194 QString transcoder_name = query.
value(0).toString();
3195 int transcoder_id = query.
value(1).toInt();
3198 if (transcoder_name ==
"High Quality")
3199 transcoder_name = tr(
"High Quality");
3200 else if (transcoder_name ==
"Medium Quality")
3201 transcoder_name = tr(
"Medium Quality");
3202 else if (transcoder_name ==
"Low Quality")
3203 transcoder_name = tr(
"Low Quality");
3205 menu->AddItemV(transcoder_name, QVariant::fromValue(transcoder_id));
3230 label = tr(
"Recording file cannot be found");
3232 label = tr(
"Recording file contains no data");
3234 tr(
"Recording Options");
3276 bool sameProgram =
false;
3363 QString timedate = QString(
"%1 - %2")
3377 return QString(
"\n%1%2\n%3").arg(title, extra, timedate);
3382 QList<uint>::Iterator it;
3440 QList<uint>::Iterator it;
3445 if (pginfo !=
nullptr)
3516 "",
"", jobHost, jobFlags);
3523 QList<uint>::Iterator it;
3558 QString forceDeleteStr(
"0");
3568 list.push_back(forceDeleteStr);
3569 list.push_back(forgetHistory ?
"1" :
"0");
3590 uint recordingID = 0;
3597 uint recordingID = 0;
3613 QCoreApplication::postEvent(
this, e);
3621 QString title = pginfo->
GetTitle().toLower();
3653 const QString& recgroup)
3656 std::array<ProgramList::iterator,2> _it {
3658 std::array<ProgramList::iterator,2> _end {
3661 if (recgroup !=
"LiveTV")
3663 swap( _it[0], _it[1]);
3664 swap(_end[0], _end[1]);
3667 for (
uint i = 0; i < 2; i++)
3670 const auto& end = _end[i];
3671 for (; it != end; ++it)
3673 if ((*it)->GetRecordingID() == recordingID)
3696 pginfo->SaveWatched(on);
3737 pginfo->SavePreserve(on);
3756 for (
auto *pl : std::as_const(
m_progLists[groupname]))
3758 if (pl && (pl->GetAvailableStatus() ==
asAvailable))
3832 QStringList tokens = command.simplified().split(
" ");
3834 if (tokens.size() >= 4 && (tokens[1] ==
"PLAY" || tokens[1] ==
"RESUME"))
3836 if (tokens.size() == 6 && tokens[2] ==
"PROGRAM")
3838 int clientID = tokens[5].toInt();
3840 LOG(VB_GENERAL, LOG_INFO,
LOC +
3841 QString(
"NetworkControl: Trying to %1 program '%2' @ '%3'")
3842 .arg(tokens[1], tokens[3], tokens[4]));
3846 LOG(VB_GENERAL, LOG_ERR,
LOC +
3847 "NetworkControl: Already playing");
3849 QString msg = QString(
3850 "NETWORK_CONTROL RESPONSE %1 ERROR: Unable to play, "
3851 "player is already playing another recording.")
3859 uint chanid = tokens[3].toUInt();
3865 QString msg = QString(
"NETWORK_CONTROL RESPONSE %1 OK")
3872 const bool ignoreBookmark = (tokens[1] ==
"PLAY");
3873 const bool ignoreProgStart =
true;
3874 const bool ignoreLastPlayPos =
true;
3875 const bool underNetworkControl =
true;
3876 PlayX(pginfo, ignoreBookmark, ignoreProgStart,
3877 ignoreLastPlayPos, underNetworkControl);
3881 QString message = QString(
"NETWORK_CONTROL RESPONSE %1 "
3882 "ERROR: Could not find recording for "
3884 .arg(tokens[5], tokens[3], tokens[4]);
3895 if ((event->key() == Qt::Key_LaunchMedia) &&
3896 (event->modifiers() ==
3897 (Qt::ShiftModifier |
3898 Qt::ControlModifier |
3901 Qt::KeypadModifier)))
3915 QStringList actions;
3919 for (
int i = 0; i < actions.size() && !handled; ++i)
3921 const QString&
action = actions[i];
3926 else if (
action ==
"MENU")
3930 else if (
action ==
"NEXTFAV")
3937 else if (
action ==
"TOGGLEFAV")
3963 if (!nextGroup.isEmpty())
3966 else if (
action ==
"NEXTVIEW")
3973 else if (
action ==
"PREVVIEW")
3988 else if (
action ==
"CHANGERECGROUP")
3992 else if (
action ==
"CHANGEGROUPVIEW")
3996 else if (
action ==
"EDIT")
4008 else if (
action ==
"CUSTOMEDIT")
4010 else if (
action ==
"GUIDE")
4012 else if (
action ==
"UPCOMING")
4041 QString resultid = dce->
GetId();
4043 if (resultid ==
"transcode" && dce->GetResult() >= 0)
4048 auto *me =
dynamic_cast<MythEvent *
>(event);
4052 const QString& message = me->
Message();
4054 if (message.startsWith(
"RECORDING_LIST_CHANGE"))
4056 QStringList tokens = message.simplified().split(
" ");
4057 uint recordingID = 0;
4058 if (tokens.size() >= 3)
4059 recordingID = tokens[2].toUInt();
4061 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
4071 else if (recordingID && (tokens[1] ==
"ADD"))
4080 else if (recordingID && (tokens[1] ==
"DELETE"))
4089 else if (message.startsWith(
"NETWORK_CONTROL"))
4091 QStringList tokens = message.simplified().split(
" ");
4092 if ((tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
4099 Qt::KeyboardModifiers modifiers =
4101 Qt::ControlModifier |
4105 auto *keyevent =
new QKeyEvent(QEvent::KeyPress,
4106 Qt::Key_LaunchMedia, modifiers);
4109 keyevent =
new QKeyEvent(QEvent::KeyRelease,
4110 Qt::Key_LaunchMedia, modifiers);
4114 else if (message.startsWith(
"UPDATE_FILE_SIZE"))
4116 QStringList tokens = message.simplified().split(
" ");
4117 if (tokens.size() >= 3)
4120 uint recordingID = tokens[1].toUInt();
4121 uint64_t filesize = tokens[2].toLongLong(&ok);
4127 recordingID, filesize,
4132 else if (message ==
"UPDATE_UI_LIST")
4142 else if (message.startsWith(
"UPDATE_UI_ITEM"))
4144 QStringList tokens = message.simplified().split(
" ");
4145 if (tokens.size() < 3)
4148 uint recordingID = tokens[1].toUInt();
4154 else if (message ==
"UPDATE_USAGE_UI")
4158 else if (message ==
"RECONNECT_SUCCESS")
4162 else if (message ==
"LOCAL_PBB_DELETE_RECORDINGS")
4165 for (
uint i = 0; i+2 < (
uint)me->ExtraDataList().size(); i+=3)
4167 uint recordingID = me->ExtraDataList()[i+0].toUInt();
4173 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4174 QString(
"LOCAL_PBB_DELETE_RECORDINGS - "
4175 "No matching recording %1")
4180 QString forceDeleteStr = me->ExtraDataList()[i+1];
4181 QString forgetHistoryStr = me->ExtraDataList()[i+2];
4184 list.push_back(forceDeleteStr);
4185 list.push_back(forgetHistoryStr);
4187 "LOCAL_PBB_DELETE_RECORDINGS");
4199 else if (message ==
"DELETE_SUCCESSES")
4203 else if (message ==
"DELETE_FAILURES")
4205 if (me->ExtraDataList().size() < 3)
4208 for (
uint i = 0; i+2 < (
uint)me->ExtraDataList().size(); i += 3)
4211 me->ExtraDataList()[i+0].toUInt());
4219 bool forceDelete = me->ExtraDataList()[1].toUInt() != 0U;
4228 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4229 "Delete failures not handled due to "
4230 "pre-existing popup.");
4237 else if (message ==
"PREVIEW_SUCCESS")
4241 else if (message ==
"PREVIEW_FAILED" && me->ExtraDataCount() >= 5)
4243 for (
uint i = 4; i < (
uint) me->ExtraDataCount(); i++)
4245 const QString& token = me->ExtraData(i);
4251 else if (message ==
"AVAILABILITY" && me->ExtraDataCount() == 8)
4253 static constexpr std::chrono::milliseconds kMaxUIWaitTime = 10s;
4254 QStringList list = me->ExtraDataList();
4255 uint recordingID = list[0].toUInt();
4258 uint64_t fs = list[3].toULongLong();
4260 tm.setHMS(list[4].toUInt(), list[5].toUInt(),
4261 list[6].toUInt(), list[7].toUInt());
4262 QTime now = QTime::currentTime();
4263 auto time_elapsed = std::chrono::milliseconds(tm.msecsTo(now));
4264 if (time_elapsed < 0ms)
4265 time_elapsed += 24h;
4276 if (time_elapsed >= kMaxUIWaitTime)
4285 (time_elapsed < kMaxUIWaitTime))
4295 const bool ignoreBookmark =
false;
4296 const bool ignoreProgStart =
false;
4297 const bool ignoreLastPlayPos =
true;
4298 const bool underNetworkControl =
false;
4300 ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
4301 underNetworkControl);
4309 QCoreApplication::postEvent(
4313 if (old_avail != availableStatus)
4316 else if ((message ==
"PLAY_PLAYLIST") && !
m_playListPlay.empty())
4330 const bool ignoreBookmark =
false;
4331 const bool ignoreProgStart =
true;
4332 const bool ignoreLastPlayPos =
true;
4333 const bool underNetworkControl =
false;
4335 Play(*pginfo,
true, ignoreBookmark, ignoreProgStart,
4336 ignoreLastPlayPos, underNetworkControl);
4338 else if ((message ==
"SET_PLAYBACK_URL") && (me->ExtraDataCount() == 2))
4340 uint recordingID = me->ExtraData(0).toUInt();
4343 info->SetPathname(me->ExtraData(1));
4345 else if ((message ==
"FOUND_ARTWORK") && (me->ExtraDataCount() >= 5))
4348 uint recordingID = me->ExtraData(3).toUInt();
4349 const QString& group = me->ExtraData(4);
4350 const QString& fn = me->ExtraData(5);
4364 else if (!group.isEmpty() &&
4374 else if (message ==
"EXIT_TO_MENU" ||
4375 message ==
"CANCEL_PLAYLIST")
4390 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4391 QString(
"Failed to remove %1, reloading list")
4400 groupname = sel_item->
GetData().toString();
4405 auto pit = (*git).begin();
4406 while (pit != (*git).end())
4408 if ((*pit)->GetRecordingID() == recordingID)
4410 if (!git.key().isEmpty() && git.key() == groupname)
4414 QVariant::fromValue(*pit));
4418 if (item_cur && (item_by_data == item_cur))
4428 pit = (*git).erase(pit);
4438 if (!groupname.isEmpty() && (git.key() == groupname))
4447 sel_item = next_item;
4450 groupname = sel_item->
GetData().toString();
4479 if (pginfo ==
nullptr)
4489 QCoreApplication::postEvent(
this,
new MythEvent(
"UPDATE_UI_LIST"));
4496 if (helpPopup->Create())
4506 if (viewPopup->Create())
4528 QStringList groupNames;
4529 QStringList displayNames;
4531 QStringList displayGroups;
4537 uint totalItems = 0;
4540 displayNames.append(QString(
"------- %1 -------").arg(tr(
"Groups")));
4541 groupNames.append(
"");
4544 query.
prepare(
"SELECT recgroup, COUNT(title) FROM recorded "
4545 "WHERE deletepending = 0 AND watched <= :WATCHED "
4546 "GROUP BY recgroup");
4550 while (query.
next())
4552 QString dispGroup = query.
value(0).toString();
4556 (dispGroup !=
"Deleted"))
4557 totalItems += items;
4559 groupNames.append(dispGroup);
4561 dispGroup = (dispGroup ==
"Default") ? tr(
"Default") : dispGroup;
4562 dispGroup = (dispGroup ==
"Deleted") ? tr(
"Deleted") : dispGroup;
4563 dispGroup = (dispGroup ==
"LiveTV") ? tr(
"Live TV") : dispGroup;
4565 displayNames.append(tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup));
4572 displayNames.push_front(tr(
"%1 [%n item(s)]",
nullptr, totalItems)
4574 groupNames.push_front(
"All Programs");
4578 query.
prepare(
"SELECT DISTINCT category, COUNT(title) FROM recorded "
4579 "WHERE deletepending = 0 AND watched <= :WATCHED "
4580 "GROUP BY category");
4584 int unknownCount = 0;
4585 while (query.
next())
4588 QString dispGroup = query.
value(0).toString();
4589 if (dispGroup.isEmpty())
4591 unknownCount += items;
4592 dispGroup = tr(
"Unknown");
4594 else if (dispGroup == tr(
"Unknown"))
4596 unknownCount += items;
4600 (dispGroup != tr(
"Unknown")))
4602 displayGroups += tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup);
4603 groups += dispGroup;
4609 if (unknownCount > 0)
4611 QString dispGroup = tr(
"Unknown");
4612 uint items = unknownCount;
4613 displayGroups += tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup);
4614 groups += dispGroup;
4621 displayNames.append(QString(
"------- %1 -------").arg(tr(
"Categories")));
4622 groupNames.append(
"");
4624 displayGroups.sort();
4625 QStringList::iterator it;
4626 for (it = displayGroups.begin(); it != displayGroups.end(); ++it)
4627 displayNames.append(*it);
4628 for (it = groups.begin(); it != groups.end(); ++it)
4629 groupNames.append(*it);
4631 QString label = tr(
"Change Filter");
4636 if (recGroupPopup->Create())
4648 delete recGroupPopup;
4665 QString newRecGroup = recGroup;
4667 if (newRecGroup.isEmpty())
4674 newRecGroup =
"Default";
4676 newRecGroup =
"All Programs";
4678 newRecGroup =
"LiveTV";
4680 newRecGroup =
"Deleted";
4712 query.
prepare(
"SELECT recgroup, password FROM recgroups "
4713 "WHERE password IS NOT NULL AND password <> '';");
4717 while (query.
next())
4719 QString recgroup = query.
value(0).toString();
4722 recgroup =
"Default";
4724 recgroup =
"All Programs";
4726 recgroup =
"LiveTV";
4728 recgroup =
"Deleted";
4756 "SELECT g.recgroup, COUNT(r.title) FROM recgroups g "
4757 "LEFT JOIN recorded r ON g.recgroupid=r.recgroupid AND r.deletepending = 0 "
4758 "WHERE g.recgroupid != 2 AND g.recgroupid != 3 "
4759 "GROUP BY g.recgroupid ORDER BY g.recgroup");
4761 QStringList displayNames(tr(
"Add New"));
4762 QStringList groupNames(
"addnewgroup");
4767 while (query.
next())
4769 QString dispGroup = query.
value(0).toString();
4770 groupNames.push_back(dispGroup);
4772 if (dispGroup ==
"Default")
4773 dispGroup = tr(
"Default");
4774 else if (dispGroup ==
"LiveTV")
4775 dispGroup = tr(
"Live TV");
4776 else if (dispGroup ==
"Deleted")
4777 dispGroup = tr(
"Deleted");
4779 displayNames.push_back(tr(
"%1 [%n item(s)]",
"", query.
value(1).toInt())
4783 QString label = tr(
"Select Recording Group") +
4789 if (rgChanger->Create())
4819 QStringList groupNames(tr(
"Default"));
4820 QStringList displayNames(
"Default");
4823 for (
const auto& name : std::as_const(list))
4825 displayNames.push_back(name);
4826 groupNames.push_back(name);
4829 QString label = tr(
"Select Playback Group") +
4835 if (pgChanger->Create())
4849 QList<uint>::Iterator it;
4854 if (tmpItem !=
nullptr)
4866 QList<uint>::Iterator it;
4871 if (tmpItem !=
nullptr)
4889 if (editMetadata->Create())
4897 delete editMetadata;
4902 const QString &newSubtitle,
4903 const QString &newDescription,
4904 const QString &newInetref,
4920 if (groupname == pginfo->GetTitle().toLower() &&
4921 newTitle != pginfo->GetTitle())
4927 QString tempSubTitle = newTitle;
4928 if (!newSubtitle.trimmed().isEmpty())
4929 tempSubTitle = QString(
"%1 - \"%2\"")
4930 .arg(tempSubTitle, newSubtitle);
4936 if (newSeason > 0 || newEpisode > 0)
4940 seasone = QString(
"s%1e%2")
4943 seasonx = QString(
"%1x%2")
4948 item->
SetText(tempSubTitle,
"titlesubtitle");
4949 item->
SetText(newTitle,
"title");
4950 item->
SetText(newSubtitle,
"subtitle");
4951 item->
SetText(newInetref,
"inetref");
4952 item->
SetText(seasonx,
"00x00");
4953 item->
SetText(seasone,
"s00e00");
4954 item->
SetText(season,
"season");
4955 item->
SetText(episode,
"episode");
4956 if (newDescription !=
nullptr)
4957 item->
SetText(newDescription,
"description");
4960 pginfo->SaveInetRef(newInetref);
4961 pginfo->SaveSeasonEpisode(newSeason, newEpisode);
4970 newRecGroup = newRecGroup.simplified();
4972 if (newRecGroup.isEmpty())
4975 if (newRecGroup ==
"addnewgroup")
4981 tr(
"New Recording Group"));
4986 if (newgroup->Create())
5006 if ((
p->GetRecordingGroup() ==
"LiveTV") &&
5007 (newRecGroup !=
"LiveTV"))
5009 p->SaveAutoExpire(defaultAutoExpire);
5011 else if ((
p->GetRecordingGroup() !=
"LiveTV") &&
5012 (newRecGroup ==
"LiveTV"))
5030 if ((
p->GetRecordingGroup() ==
"LiveTV") && (newRecGroup !=
"LiveTV"))
5031 p->SaveAutoExpire(defaultAutoExpire);
5032 else if ((
p->GetRecordingGroup() !=
"LiveTV") && (newRecGroup ==
"LiveTV"))
5045 if (newPlayGroup.isEmpty() || !tmpItem)
5048 if (newPlayGroup == tr(
"Default"))
5049 newPlayGroup =
"Default";
5053 QList<uint>::Iterator it;
5086 if (pwChanger->Create())
5102 query.
prepare(
"UPDATE recgroups SET password = :PASSWD WHERE "
5103 "recgroup = :RECGROUP");
5105 query.
bindValue(
":PASSWD", newPassword);
5111 if (newPassword.isEmpty())
5130 LOG(VB_GENERAL, LOG_ERR,
LOC +
5131 "Theme is missing 'groups' button list.");
5138 for (
int i = 0; i <
m_list.size(); ++i)
5141 QVariant::fromValue(
m_data.at(i)));
5161 if (item->
GetData().toString().isEmpty())
5164 QString group = item->
GetData().toString();
5272 LOG(VB_GENERAL, LOG_ERR,
LOC +
5273 "Window 'passwordchanger' is missing required elements.");
5336 LOG(VB_GENERAL, LOG_ERR,
LOC +
5337 "Window 'editmetadata' is missing required elements.");
5378 QString newRecDescription =
nullptr;
5379 QString newRecInetref =
nullptr;
5380 uint newRecSeason = 0;
5381 uint newRecEpisode = 0;
5388 if (newRecTitle.isEmpty())
5391 emit
result(newRecTitle, newRecSubtitle, newRecDescription,
5392 newRecInetref, newRecSeason, newRecEpisode);
5402 "recording online..."),
5430 lookup->SetSubtype(
type);
5432 lookup->SetAllowGeneric(
true);
5433 lookup->SetHandleImages(
false);
5441 lookup->SetAutomatic(
false);
5490 Qt::QueuedConnection);
5492 if (resultsdialog->Create())
5505 if (!mfsr || !mfsr->m_result)
5523 QString title = tr(
"No match found for this recording. You can "
5524 "try entering a TVDB/TMDB number, season, and "
5525 "episode manually.");
5529 if (okPopup->Create())
5545 LOG(VB_GENERAL, LOG_ERR,
LOC +
5546 "Window 'iconhelp' is missing required elements.");
5552 addItem(
"watched", tr(
"Recording has been watched"));
5553 addItem(
"commflagged", tr(
"Commercials are flagged"));
5554 addItem(
"cutlist", tr(
"An editing cutlist is present"));
5555 addItem(
"autoexpire", tr(
"The program is able to auto-expire"));
5556 addItem(
"processing", tr(
"Commercials are being flagged"));
5557 addItem(
"bookmark", tr(
"A bookmark is set"));
5559 addItem(
"inuse", tr(
"Recording is in use"));
5560 addItem(
"transcoded", tr(
"Recording has been transcoded"));
5563 addItem(
"mono", tr(
"Recording is in Mono"));
5564 addItem(
"stereo", tr(
"Recording is in Stereo"));
5565 addItem(
"surround", tr(
"Recording is in Surround Sound"));
5566 addItem(
"dolby", tr(
"Recording is in Dolby Surround Sound"));
5568 addItem(
"cc", tr(
"Recording is Closed Captioned"));
5569 addItem(
"subtitles", tr(
"Recording has Subtitles Available"));
5570 addItem(
"onscreensub", tr(
"Recording is Subtitled"));
5572 addItem(
"SD", tr(
"Recording is in Standard Definition"));
5573 addItem(
"widescreen", tr(
"Recording is Widescreen"));
5574 addItem(
"hdtv", tr(
"Recording is in High Definition"));
5575 addItem(
"hd720", tr(
"Recording is in 720p High Definition"));
5576 addItem(
"hd1080i", tr(
"Recording is in 1080i High Definition"));
5577 addItem(
"hd1080p", tr(
"Recording is in 1080p High Definition"));
5578 addItem(
"uhd4Ki", tr(
"Recording is in 4k(interlaced) UHD resolution"));
5579 addItem(
"uhd4Kp", tr(
"Recording is in 4k UHD resolution"));
5580 addItem(
"mpeg2", tr(
"Recording is using MPEG-2 codec"));
5581 addItem(
"avchd", tr(
"Recording is using AVC/H.264 codec"));
5582 addItem(
"hevc", tr(
"Recording is using HEVC/H.265 codec"));
5591 item->DisplayState(state,
"icons");
5596 QDateTime now = QDateTime::currentDateTime();
5600 QMap<int, JobQueueEntry> jobs;
5603 for (
const auto& job : std::as_const(jobs))
5605 m_jobs.insert(qMakePair(job.chanid, job.recstartts), job);
5612 const QDateTime &recstartts)
5615 QList<JobQueueEntry> values = m_jobs.values(qMakePair(chanid, recstartts));
5616 auto end = values.cend();
5617 for (
auto iter = values.cbegin(); iter != end; ++iter)
5619 if (iter->type == jobType)
5626 const QDateTime &recstartts)
5629 QList<JobQueueEntry> values = m_jobs.values(qMakePair(chanid, recstartts));
5630 auto end = values.cend();
5631 for (
auto iter = values.cbegin(); iter != end; ++iter)
5633 if (iter->type == jobType)
5640 const QDateTime &recstartts)
5642 return IsJobQueued(jobType, chanid, recstartts) ||
5643 IsJobRunning(jobType, chanid, recstartts);
bool Create(void) override
PlaybackBox * m_parentScreen
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
static const Type kEventType
bool Create(void) override
void AcceptItem(MythUIButtonListItem *item)
static bool ChangeJobCmds(int jobID, int newCmds)
static int GetJobsInQueue(QMap< int, JobQueueEntry > &jobs, int findJobs=JOB_LIST_NOT_DONE)
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 IsJobStatusQueued(int status)
static bool IsJobQueuedOrRunning(int jobType, uint chanid, const QDateTime &recstartts)
static bool IsJobStatusRunning(int status)
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 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.
Dialog asking for user confirmation.
void SaveBoolSetting(const QString &key, bool newValue)
void SaveSetting(const QString &key, int newValue)
QString GetSetting(const QString &key, const QString &defaultval="")
void dispatch(const MythEvent &event)
int GetNumSetting(const QString &key, int defaultval=0)
QString GetMasterHostName(void)
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
bool GetBoolSetting(const QString &key, bool defaultval=false)
static void DBError(const QString &where, const MSqlQuery &query)
Basic menu dialog, message and a list of options.
void Closed(QString, int)
bool Create(void) override
This class is used as a container for messages.
const QString & Message() const
static const Type kMythEventMessage
MythScreenStack * GetMainStack()
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void LoadInBackground(const QString &message="")
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
Dialog prompting the user to enter a text string.
bool Create(void) override
A checkbox widget supporting three check states - on,off,half and two conditions - selected and unsel...
void SetCheckState(MythUIStateType::StateType state)
virtual void SetTextFromMap(const InfoMap &infoMap)
virtual void ResetMap(const InfoMap &infoMap)
Image widget, displays a single image or multiple images in sequence.
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
void Reset(void) override
Reset the image back to the default defined in the theme.
void Set(int start, int total, int used)
A widget for offering a range of numerical values where only the the bounding values and interval are...
void SetRange(int low, int high, int step, uint pageMultiple=5)
Set the lower and upper bounds of the spinbox, the interval and page amount.
void SetValue(int val) override
int GetIntValue(void) const override
This widget is used for grouping other widgets for display when a particular named state is called.
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
bool DisplayState(const QString &name)
A text entry and edit widget.
void SetPassword(bool isPassword)
QString GetText(void) const
void SetText(const QString &text, bool moveCursor=true)
void SetMaxLength(int length)
All purpose text widget, displays a text string.
virtual void SetText(const QString &text)
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
virtual void SetVisible(bool visible)
void SetEnabled(bool enable)
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
MythUIButton * m_okButton
MythUITextEdit * m_newPasswordEdit
bool Create(void) override
MythUITextEdit * m_oldPasswordEdit
void OldPasswordChanged(void)
void result(const QString &)
static QStringList GetNames(void)
QString GetPreviewImage(const ProgramInfo &pginfo, bool check_availability=true)
void DeleteRecording(uint recordingID, bool forceDelete, bool forgetHistory)
QString LocateArtwork(const QString &inetref, uint season, VideoArtworkType type, const ProgramInfo *pginfo, const QString &groupname=nullptr)
void DeleteRecordings(const QStringList &list)
uint64_t GetFreeSpaceTotalMB(void) const
void StopRecording(const ProgramInfo &pginfo)
void CheckAvailability(const ProgramInfo &pginfo, CheckAvailabilityType cat=kCheckForCache)
void UndeleteRecording(uint recordingID)
void ForceFreeSpaceUpdate(void)
uint64_t GetFreeSpaceUsedMB(void) const
bool IsJobQueued(int jobType, uint chanid, const QDateTime &recstartts)
static constexpr std::chrono::milliseconds kInvalidateTimeMs
bool IsJobRunning(int jobType, uint chanid, const QDateTime &recstartts)
bool IsJobQueuedOrRunning(int jobType, uint chanid, const QDateTime &recstartts)
void stopPlaylistUserJob2()
MythUIImage * m_previewImage
void UpdateUIGroupList(const QStringList &groupPreferences)
~PlaybackBox(void) override
void setRecGroup(QString newRecGroup)
void stopPlaylistUserJob4()
QList< uint > m_playList
list of selected items "play list"
void changeProfileAndTranscode(int id)
QString extract_commflag_state(const ProgramInfo &pginfo)
void doPlaylistBeginUserJob4()
void toggleLiveTVView(bool setOn)
std::array< QTimer *, kNumArtImages > m_artTimer
QString extract_job_state(const ProgramInfo &pginfo)
void doPlaylistBeginUserJob3()
static std::array< PlaybackBoxCb, kMaxJobs *2 > kMySlots
bool Create(void) override
void doPlaylistBeginUserJob2()
void ShowActionPopup(const ProgramInfo &pginfo)
void saveViewChanges(void)
bool m_playingSomething
playingSomething is set to true iff a full screen recording is playing
void toggleTitleView(bool setOn)
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool IsUsageUIVisible(void) const
void updateRecGroup(MythUIButtonListItem *sel_item)
void stopPlaylistFlagging()
void SelectNextRecGroup(void)
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
QString m_watchGroupLabel
int m_allOrder
allOrder controls the ordering of the "All Programs" list
void ShowRecordedEpisodes()
void HandleRecordingAddEvent(const ProgramInfo &evinfo)
void ScheduleUpdateUIList(void)
void toggleWatchedView(bool setOn)
void ItemLoaded(MythUIButtonListItem *item)
void customEvent(QEvent *event) override
void PlaylistDelete(bool forgetHistory=false)
void doPlaylistWatchedSetOff()
void doPlaylistJobQueueJob(int jobType, int jobFlags=0)
void ItemVisible(MythUIButtonListItem *item)
void UpdateUIRecGroupList(void)
void saveRecMetadata(const QString &newTitle, const QString &newSubtitle, const QString &newDescription, const QString &newInetref, uint season, uint episode)
void ItemSelected(MythUIButtonListItem *item)
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
void DeleteIgnoreAllRemaining(void)
void toggleCategoryView(bool setOn)
void ShowDeletePopup(DeletePopupType type)
void ShowGroupPopup(void)
void stopPlaylistLookup()
QStringList m_playerSelectedNewShow
std::chrono::hours m_watchListBlackOut
adjust exclusion of a title from the Watch List after a delete
void doPlaylistExpireSetOn()
MythMenu * createStorageMenu()
QStringList m_delList
Recording[s] currently selected for deletion.
void ShowRecGroupChanger(bool use_playlist=false)
Used to change the recording group of a program or playlist.
ProgramInfo * FindProgramInUILists(const ProgramInfo &pginfo)
void showViewChanger(void)
void stopPlaylistUserJob3()
void togglePlayListItem(void)
MythUIProgressBar * m_watchedProgress
static QString CreateProgramInfoString(const ProgramInfo &pginfo)
QSet< QString > m_previewTokens
Outstanding preview image requests.
bool m_needUpdate
Does the recording list need to be refilled.
MythUIProgressBar * m_recordedProgress
void selected(MythUIButtonListItem *item)
void DeleteForceAllRemaining(void)
void processNetworkControlCommand(const QString &command)
MythMenu * createTranscodingProfilesMenu()
class PlaybackBox::PbbJobQueue m_jobQueue
void doBeginTranscoding()
void stopPlaylistUserJob1()
void stopPlaylistJobQueueJob(int jobType)
int m_progsInDB
total number of recordings in DB
void doPlaylistBeginUserJob1()
ProgramMap m_progLists
lists of programs by page
QStringList m_titleList
list of pages
void updateRecList(MythUIButtonListItem *sel_item)
MythMenu * createRecordingMenu()
static void * RunPlaybackBox(void *player, bool showTV)
MythUIText * m_noRecordingsText
MythScreenStack * m_popupStack
MythMenu * createPlaylistJobMenu()
void displayRecGroup(const QString &newRecGroup="")
static constexpr int kNumArtImages
QList< uint > m_playListPlay
list of items being played.
void toggleRecGroupView(bool setOn)
void showRecGroupPasswordChanger()
int m_watchListMaxAge
add 1 to the Watch List scord up to this many days
void doPlaylistExpireSetting(bool turnOn)
void setGroupFilter(const QString &newRecGroup)
void PlaylistDeleteForgetHistory(void)
void doAllowRerecord()
Callback function when Allow Re-record is pressed in Watch Recordings.
void doPlaylistWatchedSetOn()
std::deque< QString > m_networkControlCommands
void RemoveProgram(uint recordingID, bool forgetHistory, bool forceMetadataDelete)
void showMetadataEditor()
void deleteSelected(MythUIButtonListItem *item)
MythDialogBox * m_menuDialog
void popupClosed(const QString &which, int result)
void toggleWatchListView(bool setOn)
void groupSelectorClosed(void)
void togglePreserveEpisode()
void PlayFromLastPlayPos()
QString m_currentGroup
Group currently selected.
void doJobQueueJob(int jobType, int jobFlags=0)
void togglePlayListTitle(void)
void doPlaylistBeginLookup()
MythMenu * createPlaylistStorageMenu()
void ShowPlayGroupChanger(bool use_playlist=false)
Used to change the play group of a program or playlist.
bool m_watchListStart
use the Watch List as the initial view
PlaybackBox(MythScreenStack *parent, const QString &name, TV *player=nullptr, bool showTV=false)
MythMenu * createPlayFromMenu()
std::array< MythUIImage *, kNumArtImages > m_artImage
QString m_curGroupPassword
MythUIButtonList * m_recordingList
void HandleRecordingRemoveEvent(uint recordingID)
void ShowPlayGroupChangerNoPlaylist(void)
ProgramInfoCache m_programInfoCache
MythUIButtonList * m_groupList
void ShowRecGroupChangerNoPlaylist(void)
QMap< QString, QString > m_recGroupPwCache
MythMenu * createPlaylistMenu()
void checkPassword(const QString &password)
bool m_watchListAutoExpire
exclude recording not marked for auto-expire from the Watch List
QString getRecGroupPassword(const QString &recGroup)
void SetItemIcons(MythUIButtonListItem *item, ProgramInfo *pginfo)
void toggleSearchView(bool setOn)
bool Play(const ProgramInfo &rec, bool inPlaylist, bool ignoreBookmark, bool ignoreProgStart, bool ignoreLastPlayPos, bool underNetworkControl)
void playSelectedPlaylist(bool Random)
void PlayX(const ProgramInfo &pginfo, bool ignoreBookmark, bool ignoreProgStart, bool ignoreLastPlayPos, bool underNetworkControl)
void stopPlaylistTranscoding()
MythUIButtonList * m_groupAlphaList
void doPlaylistBeginFlagging()
void ShowRecGroupChangerUsePlaylist(void)
void processNetworkControlCommands(void)
void fillRecGroupPasswordCache(void)
void UpdateUIListItem(ProgramInfo *pginfo, bool force_preview_reload)
MythUIButtonList * m_recgroupList
void selectUIGroupsAlphabet(MythUIButtonListItem *item)
void doPlaylistBeginTranscoding()
void passwordClosed(void)
QMap< QString, QString > m_recGroupType
void ShowPlayGroupChangerUsePlaylist(void)
bool m_alwaysShowWatchedProgress
void updateGroupInfo(const QString &groupname, const QString &grouplabel)
void DeleteForgetHistory(void)
PlaybackBoxHelper m_helper
Main helper thread.
ProgramInfo * GetCurrentProgram(void) const override
void doPlaylistAllowRerecord()
void HandlePreviewEvent(const QStringList &list)
Updates the UI properties for a new preview file.
static void ShowAvailabilityPopup(const ProgramInfo &pginfo)
friend class PlaybackBoxListItem
void ShowMenu(void) override
void doPlaylistWatchedSetting(bool turnOn)
void doPlaylistExpireSetOff()
void doCreateTranscodingProfilesMenu()
QString m_artHostOverride
bool m_usingGroupSelector
void toggleView(PlaybackBox::ViewMask itemMask, bool setOn)
void setPlayGroup(QString newPlayGroup)
void updateIcons(const ProgramInfo *pginfo=nullptr)
void DisplayPopupMenu(void)
QString m_groupDisplayName
void PlaylistDeleteKeepHistory(void)
QMap< QString, QString > m_groupAlphabet
MythMenu * createJobMenu()
int m_listOrder
listOrder controls the ordering of the recordings in the list
void HandleUpdateItemEvent(uint recordingId, uint flags)
void SetRecGroupPassword(const QString &newPassword)
static void AddListener(QObject *listener)
Request notifications when a preview event is generated.
static void RemoveListener(QObject *listener)
Stop receiving notifications when a preview event is generated.
void GetOrdered(std::vector< ProgramInfo * > &list, bool newest_first=false)
void Add(const ProgramInfo &pginfo)
Adds a ProgramInfo to the cache.
bool Remove(uint recordingID)
Marks a ProgramInfo in the cache for deletion on the next call to Refresh().
bool IsLoadInProgress(void) const
void Refresh(void)
Refreshed the cache.
void UpdateFileSize(uint recordingID, uint64_t filesize, UpdateStates flags)
Updates a ProgramInfo in the cache.
void ScheduleLoad(bool updateUI=true)
ProgramInfoCache::UpdateStates Update(const ProgramInfo &pginfo)
Updates a ProgramInfo in the cache.
void WaitForLoadToComplete(void) const
ProgramInfo * GetRecordingInfo(uint recordingID) const
Holds information on recordings and videos.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
void SetAvailableStatus(AvailableStatusType status, const QString &where)
bool IsInUsePlaying(void) const
void SetFlagging(bool flagging)
bool HasPathname(void) const
bool QueryIsInUse(QStringList &byWho) const
Returns true if Program is in use.
uint GetVideoProperties(void) const
bool IsAutoExpirable(void) const
bool IsPreserved(void) const
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
QString GetCategoryTypeString(void) const
Returns catType as a string.
AutoExpireType QueryAutoExpire(void) const
Returns "autoexpire" field from "recorded" table.
uint GetEpisode(void) const
uint GetSubtitleType(void) const
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
QString GetProgramID(void) const
void SetEditing(bool editing)
QString GetRecordingGroup(void) const
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
uint GetRecordingID(void) const
QString GetInetRef(void) const
void SetRecordingStatus(RecStatus::Type status)
AvailableStatusType GetAvailableStatus(void) const
bool HasCutlist(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...
uint GetAudioProperties(void) const
QString GetHostname(void) const
virtual void SetFilesize(uint64_t sz)
void UpdateLastDelete(bool setTime) const
Set or unset the record.last_delete field.
bool IsBookmarkSet(void) const
QString GetSyndicatedEpisode(void) const
QString GetPlaybackGroup(void) const
QString GetDescription(void) const
QString GetTitle(void) const
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 GetSortTitle(void) const
static QString i18n(const QString &msg)
Translations for play,recording, & storage groups +.
QDate GetOriginalAirDate(void) const
int GetRecordingPriority2(void) const
virtual uint64_t GetFilesize(void) const
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.
bool IsWatched(void) const
bool IsPathSet(void) const
uint32_t GetProgramFlags(void) const
RecStatus::Type GetRecordingStatus(void) const
bool IsLastPlaySet(void) const
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
QString GetSubtitle(void) const
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
uint GetSeason(void) const
void SetPathname(const QString &pn)
Holds information on a TV Program one might wish to record.
void ApplyRecordPlayGroupChange(const QString &newplaygroup)
Sets the recording group, both in this RecordingInfo and in the database.
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
void ApplyRecordRecTitleChange(const QString &newTitle, const QString &newSubtitle, const QString &newDescription)
Sets the recording title, subtitle, and description both in this RecordingInfo and in the database.
void ApplyRecordRecGroupChange(const QString &newrecgroup)
Sets the recording group, both in this RecordingInfo and in the database.
static const QRegularExpression kReSearchTypeName
void ApplyTranscoderProfileChangeById(int id)
Internal representation of a recording rule, mirrors the record table.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
virtual void EditScheduled(void)
Creates a dialog for editing the recording schedule.
virtual void ShowDetails(void) const
Show the Program Details screen.
void customEvent(QEvent *event) override
virtual void EditCustom(void)
Creates a dialog for creating a custom recording rule.
virtual void ShowUpcomingScheduled(void) const
Show the upcoming recordings for this recording rule.
virtual void ShowGuide(void) const
Show the program guide.
virtual void ShowUpcoming(void) const
Show the upcoming recordings for this title.
virtual void ShowPrevious(void) const
Show the previous recordings for this recording rule.
void RequestEmbedding(bool Embed, const QRect &Rect={}, const QStringList &Data={})
QString GetRecordingGroup() const
static bool StartTV(ProgramInfo *TVRec, uint Flags, const ChannelInfoList &Selection=ChannelInfoList())
Start playback of media.
bool IsSameProgram(const ProgramInfo *ProgInfo) const
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
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)
static QMap< QString, QString > iconMap
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
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 ShowNotification(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
Convenience inline random number generator functions.
static MythThemedMenu * menu
QHash< QString, QString > InfoMap
static constexpr const char * ACTION_1
void run(const QString &name, Class *object, void(Class::*fn)())
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kDateTimeFull
Default local time.
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
@ kTime
Default local time.
@ kDateShort
Default local time.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
uint32_t MythRandom()
generate 32 random bits
QString intToPaddedString(int n, int width=2)
Creates a zero padded string representation of an integer.
def rating(profile, smoonURL, gate)
duration< CHRONO_TYPE, ratio< 86400 > > days
static bool comp_programid_less_than(const ProgramInfo *a, const ProgramInfo *b)
static int comp_season_rev(const ProgramInfo *a, const ProgramInfo *b)
static PlaybackBox::ViewMask m_viewMaskToggle(PlaybackBox::ViewMask mask, PlaybackBox::ViewMask toggle)
static bool save_position(const MythUIButtonList *groupList, const MythUIButtonList *recordingList, QStringList &groupSelPref, QStringList &itemSelPref, QStringList &itemTopPref)
static bool comp_season_less_than(const ProgramInfo *a, const ProgramInfo *b)
static const std::array< const uint, 3 > s_artDelay
static int comp_programid(const ProgramInfo *a, const ProgramInfo *b)
static int comp_recordDate_rev(const ProgramInfo *a, const ProgramInfo *b)
static bool comp_recpriority2_less_than(const ProgramInfo *a, const ProgramInfo *b)
static QString construct_sort_title(QString title, const QString &sortTitle, PlaybackBox::ViewMask viewmask, PlaybackBox::ViewTitleSort sortType, int recpriority)
static void push_onto_del(QStringList &list, const ProgramInfo &pginfo)
static int comp_season(const ProgramInfo *a, const ProgramInfo *b)
static bool extract_one_del(QStringList &list, uint &recordingID)
static bool comp_originalAirDate_less_than(const ProgramInfo *a, const ProgramInfo *b)
static int comp_recordDate(const ProgramInfo *a, const ProgramInfo *b)
static bool comp_programid_rev_less_than(const ProgramInfo *a, const ProgramInfo *b)
static bool comp_originalAirDate_rev_less_than(const ProgramInfo *a, const ProgramInfo *b)
static int comp_originalAirDate(const ProgramInfo *a, const ProgramInfo *b)
static bool comp_season_rev_less_than(const ProgramInfo *a, const ProgramInfo *b)
static void restore_position(MythUIButtonList *groupList, MythUIButtonList *recordingList, const QStringList &groupSelPref, const QStringList &itemSelPref, const QStringList &itemTopPref)
static bool retrieve_SeasonEpisode(int &season, int &episode, const ProgramInfo *prog)
static const std::array< const std::string, 9 > disp_flags
static bool comp_recordDate_rev_less_than(const ProgramInfo *a, const ProgramInfo *b)
static int comp_programid_rev(const ProgramInfo *a, const ProgramInfo *b)
static QString extract_subtitle(const ProgramInfo &pginfo, const QString &groupname)
static bool comp_recordDate_less_than(const ProgramInfo *a, const ProgramInfo *b)
static int comp_originalAirDate_rev(const ProgramInfo *a, const ProgramInfo *b)
static int comp_recpriority2(const ProgramInfo *a, const ProgramInfo *b)
static const std::array< const int, kMaxJobs > kJobs
static QString extract_main_state(const ProgramInfo &pginfo, const TV *player)
static const QString sLocation
static constexpr uint8_t kArtworkCoverTimeout
static constexpr uint8_t kArtworkBannerTimeout
static constexpr size_t kMaxJobs
static constexpr uint16_t kArtworkFanTimeout
@ kCheckForPlaylistAction
AutoDeleteDeque< ProgramInfo * > ProgramList
TVState
TVState is an enumeration of the states used by TV and TVRec.
@ kState_None
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
#define ACTION_VIEWSCHEDULED
#define ACTION_TOGGLERECORD
#define ACTION_LISTRECORDEDEPISODES
#define ACTION_PREVRECORDED
@ kStartTVIgnoreLastPlayPos
@ kStartTVIgnoreProgStart
@ kStartTVByNetworkCommand