7 #include <QCoreApplication>
55 #define LOC QString("PlaybackBox: ")
56 #define LOC_WARN QString("PlaybackBox Warning: ")
57 #define LOC_ERR QString("PlaybackBox Error: ")
87 return (dt1 < dt2 ? 1 : -1);
100 return (dt1 > dt2 ? 1 : -1);
206 static const std::array<const uint,3>
s_artDelay
225 QString sTitle = sortTitle.isEmpty()
226 ? title : sortTitle +
" - " + title;
255 sortprefix = QString(
"+%1").arg(1000 - recpriority, 3, 10, QChar(
'0'));
257 sortprefix = QString(
"-%1").arg(-recpriority, 3, 10, QChar(
'0'));
259 sTitle = sortprefix +
'-' + sTitle;
266 QString state(
"normal");
282 if ((state ==
"normal" || state ==
"running") &&
293 QString job =
"default";
306 job =
"commflagging";
326 const ProgramInfo &pginfo,
const QString &groupname)
329 if (groupname != pginfo.
GetTitle().toLower())
336 if (subtitle.trimmed().isEmpty())
346 list.push_back(QString() );
347 list.push_back(QString());
358 recordingID = list[0].toUInt();
364 if (recordingID == 0U) {
365 LOG(VB_GENERAL, LOG_ERR,
LOC +
"extract_one_del() invalid entry");
375 auto *pbb =
new PlaybackBox(mainStack,
"playbackbox", (
TV *)player, showTV);
389 m_groupDisplayName(
ProgramInfo::i18n(
"All Programs")),
390 m_recGroup(
"All Programs"),
391 m_watchGroupName(tr(
"Watch List")),
392 m_watchGroupLabel(m_watchGroupName.toLower()),
395 m_programInfoCache(this),
421 "DisplayGroupDefaultViewMask",
463 (displayCat &&
m_recGroup !=
"All Programs") ?
"category" :
"recgroup";
513 LOG(VB_GENERAL, LOG_ERR,
LOC +
514 "Theme is missing critical theme elements.");
568 "titlesubtitle|shortdate|starttime");
611 QString label = tr(
"Password for group '%1':").arg(newRecGroup);
649 const QString &grouplabel)
655 infoMap[
"title"] = grouplabel;
662 if (!groupname.isEmpty() && !
m_progLists[groupname].empty())
687 if (countInGroup >= 1)
690 float groupSize = 0.0;
692 for (
auto *info : group)
696 uint64_t filesize = info->GetFilesize();
703 groupSize += filesize;
707 desc = tr(
"There is/are %n recording(s) in this display "
708 "group, which consume(s) %1 GiB.",
"", countInGroup)
709 .arg(groupSize / 1024.0F / 1024.0F / 1024.0F, 0,
'f', 2);
713 desc = tr(
"There is no recording in this display group.");
716 infoMap[
"description"] = desc;
717 infoMap[
"rec_count"] = QString(
"%1").arg(countInGroup);
726 ratingState->
Reset();
746 bool force_preview_reload)
762 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
763 QString(
"UpdateUIListItem called with a title unknown "
764 "to us in m_recordingList\n\t\t\t%1")
769 static const std::array<const std::string,9>
disp_flags
771 "playlist",
"watched",
"preserve",
772 "cutlist",
"autoexpire",
"editing",
773 "bookmark",
"inuse",
"transcoded"
788 disp_flag_stat[8] = ((pginfo->
GetProgramFlags() & FL_TRANSCODED) != 0U);
790 for (
size_t i = 0; i <
disp_flags.size(); ++i)
796 bool is_sel,
bool force_preview_reload)
813 pginfo->ToMap(infoMap);
821 if (groupname == pginfo->GetTitle().toLower())
823 item->
SetText(tempSubTitle,
"titlesubtitle");
827 "titlesubtitlefull");
844 QString
rating = QString::number(pginfo->GetStars(10));
849 if (oldimgfile.isEmpty() || force_preview_reload)
856 pginfo->CalculateProgress(pginfo->QueryLastPlayPos());
858 pginfo->ToMap(infoMap);
892 if (arthost.isEmpty())
899 pginfo->GetInetRef(), pginfo->GetSeason(),
921 if (item->
GetText(
"is_item_initialized").isNull())
923 QMap<AudioProps, QString> audioFlags;
924 audioFlags[AUD_DOLBY] =
"dolby";
925 audioFlags[AUD_SURROUND] =
"surround";
926 audioFlags[AUD_STEREO] =
"stereo";
927 audioFlags[AUD_MONO] =
"mono";
929 QMap<VideoProps, QString> codecFlags;
930 codecFlags[VID_MPEG2] =
"mpeg2";
931 codecFlags[VID_AVC] =
"avc";
932 codecFlags[VID_HEVC] =
"hevc";
934 QMap<SubtitleProps, QString> subtitleFlags;
935 subtitleFlags[SUB_SIGNED] =
"deafsigned";
936 subtitleFlags[SUB_ONSCREEN] =
"onscreensub";
937 subtitleFlags[SUB_NORMAL] =
"subtitles";
938 subtitleFlags[SUB_HARDHEAR] =
"cc";
948 pginfo->ToMap(infoMap);
953 if (groupname == pginfo->GetTitle().toLower())
955 item->
SetText(tempSubTitle,
"titlesubtitle");
959 "titlesubtitlefull");
964 item->
DisplayState(QString::number(pginfo->GetStars(10)),
969 QMap<AudioProps, QString>::iterator ait;
970 for (ait = audioFlags.begin(); ait != audioFlags.end(); ++ait)
972 if (pginfo->GetAudioProperties() & ait.key())
976 uint props = pginfo->GetVideoProperties();
978 QMap<VideoProps, QString>::iterator cit;
979 for (cit = codecFlags.begin(); cit != codecFlags.end(); ++cit)
981 if (props & cit.key())
988 if (props & VID_PROGRESSIVE)
993 if (props & VID_1080)
1000 if (props & VID_1080)
1003 if (props & VID_720)
1005 if (!(props & (VID_4K | VID_1080 | VID_720)))
1007 if (props & VID_HDTV)
1009 else if (props & VID_WIDESCREEN)
1015 QMap<SubtitleProps, QString>::iterator sit;
1016 for (sit = subtitleFlags.begin(); sit != subtitleFlags.end(); ++sit)
1018 if (pginfo->GetSubtitleType() & sit.key())
1022 item->
DisplayState(pginfo->GetCategoryTypeString(),
"categorytype");
1025 item->
SetText(
"yes",
"is_item_initialized");
1043 pginfo->GetWatchedPercent());
1044 item->
SetProgress2(0, 100, pginfo->GetRecordedPercent());
1051 if (token.isEmpty())
1058 (
asAvailable == sel_pginfo->GetAvailableStatus()))
1074 if (list.size() < 5)
1076 LOG(VB_GENERAL, LOG_ERR,
"HandlePreviewEvent() -- too few args");
1077 for (
uint i = 0; i < (
uint) list.size(); i++)
1079 LOG(VB_GENERAL, LOG_INFO, QString(
"%1: %2")
1080 .arg(i).arg(list[i]));
1085 uint recordingID = list[0].toUInt();
1086 const QString& previewFile = list[1];
1087 const QString& message = list[2];
1090 for (
uint i = 4; i < (
uint) list.size(); i++)
1092 const QString& token = list[i];
1103 QString tokens(
"\n\t\t\ttokens: ");
1104 for (
uint i = 4; i < (
uint) list.size(); i++)
1105 tokens += list[i] +
", ";
1106 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1107 "Ignoring PREVIEW_SUCCESS, no matcing token" + tokens);
1111 if (previewFile.isEmpty())
1113 LOG(VB_GENERAL, LOG_ERR,
LOC +
1114 "Ignoring PREVIEW_SUCCESS, no preview file.");
1126 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1127 "Ignoring PREVIEW_SUCCESS, item no longer on screen.");
1132 LOG(VB_GUI, LOG_INFO,
LOC + QString(
"Loading preview %1,\n\t\t\tmsg %2")
1133 .arg(previewFile, message));
1135 item->
SetImage(previewFile,
"preview",
true);
1149 uint32_t flags = FL_NONE;
1154 QMap <QString, int>::iterator it;
1157 iconMap[
"commflagged"] = FL_COMMFLAG;
1158 iconMap[
"cutlist"] = FL_CUTLIST;
1159 iconMap[
"autoexpire"] = FL_AUTOEXP;
1160 iconMap[
"processing"] = FL_COMMPROCESSING;
1161 iconMap[
"editing"] = FL_EDITING;
1162 iconMap[
"bookmark"] = FL_BOOKMARK;
1163 iconMap[
"inuse"] = (FL_INUSERECORDING |
1166 iconMap[
"transcoded"] = FL_TRANSCODED;
1167 iconMap[
"watched"] = FL_WATCHED;
1168 iconMap[
"preserved"] = FL_PRESERVED;
1176 iconImage->
SetVisible((flags & (*it)) != 0U);
1190 iconMap[
"1dolby"] = AUD_DOLBY;
1191 iconMap[
"2surround"] = AUD_SURROUND;
1192 iconMap[
"3stereo"] = AUD_STEREO;
1196 bool haveIcon =
false;
1197 if (pginfo && iconState)
1212 if (iconState && !haveIcon)
1216 if (pginfo && iconState)
1222 if (props & VID_PROGRESSIVE)
1225 iconMap[
"hd1080p"] = VID_1080;
1230 iconMap[
"hd1080i"] = VID_1080;
1235 iconMap[
"widescreen"] = VID_WIDESCREEN;
1254 iconMap[
"damaged"] = VID_DAMAGED;
1258 if (pginfo && iconState)
1273 if (iconState && !haveIcon)
1276 iconMap[
"deafsigned"] = SUB_SIGNED;
1277 iconMap[
"onscreensub"] = SUB_ONSCREEN;
1278 iconMap[
"subtitles"] = SUB_NORMAL;
1283 if (pginfo && iconState)
1298 if (iconState && !haveIcon)
1323 if (!freereportText && !usedProgress && !
GetChild(
"diskspacetotal") &&
1333 usageMap[
"diskspacetotal"] = locale.toString((freeSpaceTotal / 1024.0),
1335 usageMap[
"diskspaceused"] = locale.toString((freeSpaceUsed / 1024.0),
1337 usageMap[
"diskspacefree"] = locale.toString(
1338 ((freeSpaceTotal - freeSpaceUsed) / 1024.0),
1342 if (freeSpaceTotal > 0.0)
1343 perc = (100.0 * freeSpaceUsed) / freeSpaceTotal;
1345 usageMap[
"diskspacepercentused"] = QString::number((
int)perc);
1346 usageMap[
"diskspacepercentfree"] = QString::number(100 - (
int)perc);
1348 QString size = locale.toString(((freeSpaceTotal - freeSpaceUsed) / 1024.0),
1351 QString usestr = tr(
"%1% used, %2 GB free",
"Diskspace")
1352 .arg(QString::number((
int)perc),
1356 freereportText->
SetText(usestr);
1360 usedProgress->
SetTotal((
int)freeSpaceTotal);
1361 usedProgress->
SetUsed((
int)freeSpaceUsed);
1384 QString key = (*it);
1385 QString
tmp = (key ==
"All Programs") ?
"All" : key;
1392 QVariant::fromValue(key));
1396 item->SetText(name);
1406 int best_pref = INT_MAX;
1408 QStringList::iterator it;
1411 QString groupname = (*it);
1414 QVariant::fromValue(groupname.toLower()));
1416 int pref = groupPreferences.indexOf(groupname.toLower());
1417 if ((pref >= 0) && (pref < best_pref))
1424 QString displayName = groupname;
1425 if (displayName.isEmpty())
1434 item->SetText(groupname,
"groupname");
1435 item->SetText(displayName,
"name");
1436 item->SetText(displayName);
1438 int count =
m_progLists[groupname.toLower()].size();
1439 item->SetText(QString::number(count),
"reccount");
1454 QString newRecGroup = sel_item->
GetData().toString();
1470 if (!nextGroup.isEmpty())
1479 QString groupname = sel_item->
GetData().toString();
1480 QString grouplabel = sel_item->
GetText();
1495 ProgramMap::iterator pmit =
m_progLists.find(groupname);
1501 for (
auto & prog : progList)
1504 prog->GetAvailableStatus() ==
asDeleted)
1513 if (!progList.empty())
1518 tr(
"There are no recordings available") :
1519 tr(
"There are no recordings in your current view");
1528 QStringList &groupSelPref, QStringList &itemSelPref,
1529 QStringList &itemTopPref)
1535 groupSelPref.push_back(prefSelGroup->
GetData().toString());
1537 i < groupList->GetCount(); i++)
1541 groupSelPref.push_back(prefSelGroup->
GetData().toString());
1545 for (
int i = curPos; (i >= 0) && (i < recordingList->GetCount()); i++)
1549 itemSelPref.push_back(groupSelPref.front());
1550 itemSelPref.push_back(QString::number(pginfo->GetRecordingID()));
1552 for (
int i = curPos; (i >= 0) && (i < recordingList->GetCount()); i--)
1556 itemSelPref.push_back(groupSelPref.front());
1557 itemSelPref.push_back(QString::number(pginfo->GetRecordingID()));
1561 for (
int i = topPos + 1; i >= topPos - 1; i--)
1563 if (i >= 0 && i < recordingList->GetCount())
1569 itemTopPref.push_front(QString::number(pginfo->GetRecordingID()));
1570 itemTopPref.push_front(groupSelPref.front());
1574 itemTopPref.push_back(groupSelPref.front());
1575 itemTopPref.push_back(QString::number(pginfo->GetRecordingID()));
1585 const QStringList &groupSelPref,
const QStringList &itemSelPref,
1586 const QStringList &itemTopPref)
1591 if (!prefSelGroup ||
1592 !groupSelPref.contains(prefSelGroup->
GetData().toString()) ||
1593 !itemSelPref.contains(prefSelGroup->
GetData().toString()))
1599 QString groupname = prefSelGroup->
GetData().toString();
1603 for (
uint i = 0; i+1 < (
uint)itemSelPref.size(); i+=2)
1605 if (itemSelPref[i] != groupname)
1608 uint recordingID = itemSelPref[i+1].toUInt();
1613 if (pginfo && (pginfo->GetRecordingID() == recordingID))
1616 i = itemSelPref.size();
1624 for (
uint i = 0; i+1 < (
uint)itemTopPref.size(); i+=2)
1626 if (itemTopPref[i] != groupname)
1629 uint recordingID = itemTopPref[i+1].toUInt();
1634 if (pginfo && (pginfo->GetRecordingID() == recordingID))
1637 i = itemTopPref.size();
1646 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Reselect success (%1,%2)")
1647 .arg(sel).arg(top));
1654 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Reselect failure (%1,%2)")
1655 .arg(sel).arg(top));
1665 QStringList groupSelPref;
1666 QStringList itemSelPref;
1667 QStringList itemTopPref;
1669 groupSelPref, itemSelPref, itemTopPref))
1678 QMap<uint, AvailableStatusType> asCache;
1684 uint asRecordingID = prog->GetRecordingID();
1685 asCache[asRecordingID] = prog->GetAvailableStatus();
1704 bool isAllProgsGroup = (
m_recGroup ==
"All Programs");
1705 QMap<QString, QString> sortedList;
1706 QMap<int, QString> searchRule;
1707 QMap<int, QDateTime> recidLastEventTime;
1708 QMap<int, ProgramInfo*> recidWatchListProgram;
1719 query.
prepare(
"SELECT recordid,title FROM record "
1720 "WHERE search > 0 AND search != :MANUAL;");
1725 while (query.
next())
1727 QString tmpTitle = query.
value(1).toString();
1729 searchRule[query.
value(0).toInt()] = tmpTitle;
1735 bool isUnknownCategory = (
m_recGroup == tr(
"Unknown"));
1736 bool isDeletedGroup = (
m_recGroup ==
"Deleted");
1737 bool isLiveTvGroup = (
m_recGroup ==
"LiveTV");
1739 std::vector<ProgramInfo*> list;
1742 for (
auto *
p : list)
1744 if (
p->IsDeletePending())
1749 const QString& pRecgroup(
p->GetRecordingGroup());
1750 const bool isLiveTVProg(pRecgroup ==
"LiveTV");
1757 if (pRecgroup ==
"Deleted")
1761 if (!isDeletedGroup)
1766 !isLiveTvGroup && isLiveTVProg)
1775 else if (isCategoryFilter)
1778 if (isUnknownCategory ? !
p->GetCategory().isEmpty()
1783 else if (!isAllProgsGroup && pRecgroup !=
m_recGroup)
1786 if (
p->GetTitle().isEmpty())
1787 p->SetTitle(tr(
"_NO_TITLE_"));
1794 uint asRecordingID =
p->GetRecordingID();
1795 if (asCache.contains(asRecordingID))
1796 p->SetAvailableStatus(asCache[asRecordingID],
"UpdateUILists");
1802 QString tmpTitle = tr(
"Live TV");
1803 sortedList[tmpTitle.toLower()] = tmpTitle;
1805 m_progLists[tmpTitle.toLower()].setAutoDelete(
false);
1813 p->GetTitle(),
p->GetSortTitle(),
m_viewMask, titleSort,
1814 p->GetRecordingPriority());
1815 sTitle = sTitle.toLower();
1817 if (!sortedList.contains(sTitle))
1818 sortedList[sTitle] =
p->GetTitle();
1819 m_progLists[sortedList[sTitle].toLower()].push_front(
p);
1820 m_progLists[sortedList[sTitle].toLower()].setAutoDelete(
false);
1825 !pRecgroup.isEmpty() && !isLiveTVProg)
1827 sortedList[pRecgroup.toLower()] = pRecgroup;
1829 m_progLists[pRecgroup.toLower()].setAutoDelete(
false);
1835 QString catl =
p->GetCategory().toLower();
1836 sortedList[catl] =
p->GetCategory();
1842 !searchRule[
p->GetRecordingRuleID()].isEmpty() &&
1843 p->GetTitle() != searchRule[
p->GetRecordingRuleID()])
1845 QString tmpTitle = QString(
"(%1)")
1846 .arg(searchRule[
p->GetRecordingRuleID()]);
1847 sortedList[tmpTitle.toLower()] = tmpTitle;
1849 m_progLists[tmpTitle.toLower()].setAutoDelete(
false);
1853 !isLiveTVProg && pRecgroup !=
"Deleted")
1855 int rid =
p->GetRecordingRuleID();
1856 auto letIt = recidLastEventTime.find(rid);
1857 if (letIt == recidLastEventTime.end() || *letIt < p->GetLastModifiedTime())
1859 recidLastEventTime[rid] =
p->GetLastModifiedTime();
1865 LOG(VB_FILE, LOG_INFO, QString(
"Auto-expire off: %1")
1866 .arg(
p->GetTitle()));
1868 else if (
p->IsWatched())
1871 LOG(VB_FILE, LOG_INFO,
1872 QString(
"Marked as 'watched': %1")
1873 .arg(
p->GetTitle()));
1877 auto wlpIt = recidWatchListProgram.find(rid);
1878 if (wlpIt == recidWatchListProgram.end())
1880 recidWatchListProgram[rid] =
p;
1884 (*wlpIt)->SetRecordingPriority2(
wlEarlier);
1885 LOG(VB_FILE, LOG_INFO,
1886 QString(
"Not the earliest: %1")
1887 .arg((*wlpIt)->GetTitle()));
1889 recidWatchListProgram[rid] =
p;
1894 LOG(VB_FILE, LOG_INFO,
1895 QString(
"Not the earliest: %1")
1896 .arg(
p->GetTitle()));
1904 for (
auto *
p : qAsConst(recidWatchListProgram))
1913 if (sortedList.empty())
1915 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"SortedList is Empty");
1919 if (!isAllProgsGroup)
1931 if (episodeSort ==
"OrigAirDate")
1933 QMap<QString, ProgramList>::Iterator Iprog;
1936 if (!Iprog.key().isEmpty())
1938 std::stable_sort((*Iprog).begin(), (*Iprog).end(),
1945 else if (episodeSort ==
"Id")
1947 QMap<QString, ProgramList>::Iterator Iprog;
1950 if (!Iprog.key().isEmpty())
1952 std::stable_sort((*Iprog).begin(), (*Iprog).end(),
1959 else if (episodeSort ==
"Date")
1961 QMap<QString, ProgramList>::iterator it;
1964 if (!it.key().isEmpty())
1966 std::stable_sort((*it).begin(), (*it).end(),
1973 else if (episodeSort ==
"Season")
1975 QMap<QString, ProgramList>::iterator it;
1978 if (!it.key().isEmpty())
1980 std::stable_sort((*it).begin(), (*it).end(),
1991 query.
prepare(
"SELECT recordid, last_delete FROM record;");
1995 while (query.
next())
1997 int recid = query.
value(0).toInt();
1999 QDateTime last_delete =
2002 if (last_delete.isValid())
2004 auto it = recidLastEventTime.find(recid);
2005 if (it != recidLastEventTime.end() && last_delete > *it)
2007 recidLastEventTime[recid] = last_delete;
2016 int recid = (*pit)->GetRecordingRuleID();
2018 (*pit)->SetRecordingPriority2(recidLastEventTime[recid].toSecsSinceEpoch()/60);
2020 LOG(VB_FILE, LOG_INFO, QString(
" %1 %2 %3")
2023 .arg((*pit)->GetRecordingPriority2())
2024 .arg((*pit)->GetTitle()));
2038 (
std::find(sortedList.cbegin(), sortedList.cend(), tr(
"Live TV"))
2039 == sortedList.cend()))
2055 query.
prepare(
"SELECT distinct recgroup from recorded WHERE "
2056 "deletepending = 0 ORDER BY recgroup");
2060 while (query.
next())
2062 name = query.
value(0).toString();
2063 if (name !=
"Deleted" && name !=
"LiveTV" && !name.startsWith(
'.'))
2092 groupSelPref, itemSelPref, itemTopPref);
2105 while (!
tmp.isEmpty())
2117 QCoreApplication::postEvent(
2131 const bool ignoreBookmark =
false;
2132 const bool ignoreProgStart =
false;
2133 const bool ignoreLastPlayPos =
false;
2134 const bool underNetworkControl =
false;
2136 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2137 underNetworkControl);
2150 const bool ignoreBookmark =
false;
2151 const bool ignoreProgStart =
true;
2152 const bool ignoreLastPlayPos =
true;
2153 const bool underNetworkControl =
false;
2155 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2156 underNetworkControl);
2169 const bool ignoreBookmark =
true;
2170 const bool ignoreProgStart =
true;
2171 const bool ignoreLastPlayPos =
true;
2172 const bool underNetworkControl =
false;
2174 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2175 underNetworkControl);
2188 const bool ignoreBookmark =
true;
2189 const bool ignoreProgStart =
true;
2190 const bool ignoreLastPlayPos =
false;
2191 const bool underNetworkControl =
false;
2193 PlayX(*pginfo, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
2194 underNetworkControl);
2198 bool ignoreBookmark,
2199 bool ignoreProgStart,
2200 bool ignoreLastPlayPos,
2201 bool underNetworkControl)
2205 Play(pginfo,
false, ignoreBookmark, ignoreProgStart, ignoreLastPlayPos, underNetworkControl);
2252 LOG(VB_GENERAL, LOG_ERR, QString(
"deleteSelected(%1) -- failed ")
2254 QString(
"availability status: %1 ")
2255 .arg(pginfo->GetAvailableStatus()));
2258 tr(
"This recording is already being deleted"));
2260 else if (!pginfo->QueryIsDeleteCandidate())
2263 pginfo->QueryIsInUse(byWho);
2265 LOG(VB_GENERAL, LOG_ERR, QString(
"deleteSelected(%1) -- failed ")
2267 QString(
"delete candidate: %1 in use by %2")
2268 .arg(pginfo->QueryIsDeleteCandidate()).arg(byWho));
2270 if (byWho.isEmpty())
2273 tr(
"This recording is already being deleted"));
2278 tr(
"This recording is currently in use by:") +
"\n" +
2326 if (which ==
"groupmenu")
2346 else if (which ==
"actionmenu")
2358 QString label = tr(
"Group List Menu");
2399 bool inPlaylist,
bool ignoreBookmark,
bool ignoreProgStart,
2400 bool ignoreLastPlayPos,
bool underNetworkControl)
2402 bool playCompleted =
false;
2430 ignoreProgStart =
true;
2446 QCoreApplication::postEvent(
2453 return playCompleted;
2457 bool forceMetadataDelete)
2464 if (!forceMetadataDelete &&
2474 if (!forceMetadataDelete)
2479 forceMetadataDelete, forgetHistory);
2509 label = tr(
"Are you sure you want to delete:");
break;
2511 label = tr(
"Recording file does not exist.\n"
2512 "Are you sure you want to delete:");
2515 label = tr(
"Are you sure you want to stop:");
break;
2570 tr(
"Yes, delete it and the remaining %1 list items")
2579 nullptr, !defaultIsYes);
2583 nullptr, !defaultIsYes);
2590 tr(
"No, and keep the remaining %1 list items")
2591 .arg(other_delete_cnt),
2611 tr(
"This recording is currently in "
2612 "use by:") +
"\n" + byWho);
2618 tr(
"This recording is currently "
2625 tr(
"This recording is currently being "
2626 "deleted and is unavailable"));
2631 tr(
"This recording has been "
2632 "deleted and is unavailable"));
2637 tr(
"The file for this recording can "
2643 tr(
"The file for this recording is "
2649 tr(
"This recording is not yet "
2656 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2657 "all items in the playlist",
"",
m_playList.size());
2669 menu->AddItem(tr(
"Toggle playlist for this Category/Title"),
2674 menu->AddItem(tr(
"Toggle playlist for this Group"),
2679 menu->AddItem(tr(
"Toggle playlist for this recording"),
2685 menu->AddItem(tr(
"Delete, and allow re-record"),
2693 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2694 "all items in the playlist",
"",
m_playList.size());
2711 QString label = tr(
"There is %n item(s) in the playlist. Actions affect "
2712 "all items in the playlist",
"",
m_playList.size());
2718 QList<uint>::Iterator it;
2719 bool isTranscoding =
true;
2720 bool isFlagging =
true;
2721 bool isMetadataLookup =
true;
2722 bool isRunningUserJob1 =
true;
2723 bool isRunningUserJob2 =
true;
2724 bool isRunningUserJob3 =
true;
2725 bool isRunningUserJob4 =
true;
2735 isTranscoding =
false;
2743 isMetadataLookup =
false;
2747 isRunningUserJob1 =
false;
2751 isRunningUserJob2 =
false;
2755 isRunningUserJob3 =
false;
2759 isRunningUserJob4 =
false;
2760 if (!isTranscoding && !isFlagging && !isRunningUserJob1 &&
2761 !isRunningUserJob2 && !isRunningUserJob3 && !isRunningUserJob4)
2776 if (!isMetadataLookup)
2782 if (!command.isEmpty())
2786 if (!isRunningUserJob1)
2788 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2793 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2799 if (!command.isEmpty())
2803 if (!isRunningUserJob2)
2805 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2810 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2816 if (!command.isEmpty())
2820 if (!isRunningUserJob3)
2822 menu->AddItem(tr(
"Begin") +
' ' + jobTitle,
2827 menu->AddItem(tr(
"Stop") +
' ' + jobTitle,
2833 if (!command.isEmpty())
2837 if (!isRunningUserJob4)
2839 menu->AddItem(QString(
"%1 %2").arg(tr(
"Begin"), jobTitle),
2844 menu->AddItem(QString(
"%1 %2").arg(tr(
"Stop"), jobTitle),
2911 menu->AddItem(tr(
"Play from last played position"),
2914 menu->AddItem(tr(
"Play from bookmark"),
2916 menu->AddItem(tr(
"Play from beginning"),
2919 menu->AddItem(tr(
"Clear last played position"),
2935 tr(
"Disable Auto Expire") : tr(
"Enable Auto Expire");
2937 tr(
"Do not preserve this episode") : tr(
"Preserve this episode");
2958 menu->AddItem(tr(
"Edit Recording Schedule"),
2972 static const std::array<const int,kMaxJobs>
kJobs
3003 const std::array<const bool,kMaxJobs> add
3013 const std::array<const QString,kMaxJobs*2> desc
3016 tr(
"Stop Transcoding"), tr(
"Begin Transcoding"),
3017 tr(
"Stop Commercial Detection"), tr(
"Begin Commercial Detection"),
3018 tr(
"Stop Metadata Lookup"), tr(
"Begin Metadata Lookup"),
3025 for (
size_t i = 0; i <
kMaxJobs; i++)
3030 QString stop_desc = desc[i*2+0];
3031 QString start_desc = desc[i*2+1];
3033 if (start_desc.toUInt())
3036 "UserJobDesc"+start_desc, tr(
"User Job") +
" #" + start_desc);
3037 stop_desc = tr(
"Stop") +
' ' + jobTitle;
3038 start_desc = tr(
"Begin") +
' ' + jobTitle;
3046 menu->AddItem((running) ? stop_desc : start_desc,
3047 kMySlots[i * 2 + (running ? 0 : 1)], submenu);
3055 QString label = tr(
"Transcoding profiles");
3059 menu->AddItemV(tr(
"Default"), QVariant::fromValue(-1));
3060 menu->AddItemV(tr(
"Autodetect"), QVariant::fromValue(0));
3063 query.
prepare(
"SELECT r.name, r.id "
3064 "FROM recordingprofiles r, profilegroups p "
3065 "WHERE p.name = 'Transcoders' "
3066 "AND r.profilegroup = p.id "
3067 "AND r.name != 'RTjpeg/MPEG4' "
3068 "AND r.name != 'MPEG2' ");
3076 while (query.
next())
3078 QString transcoder_name = query.
value(0).toString();
3079 int transcoder_id = query.
value(1).toInt();
3082 if (transcoder_name ==
"High Quality")
3083 transcoder_name = tr(
"High Quality");
3084 else if (transcoder_name ==
"Medium Quality")
3085 transcoder_name = tr(
"Medium Quality");
3086 else if (transcoder_name ==
"Low Quality")
3087 transcoder_name = tr(
"Low Quality");
3089 menu->AddItemV(transcoder_name, QVariant::fromValue(transcoder_id));
3114 tr(
"Recording file cannot be found") :
3116 tr(
"Recording file contains no data") :
3117 tr(
"Recording Options");
3159 bool sameProgram =
false;
3246 QString timedate = QString(
"%1 - %2")
3260 return QString(
"\n%1%2\n%3").arg(title, extra, timedate);
3265 QList<uint>::Iterator it;
3323 QList<uint>::Iterator it;
3328 if (pginfo !=
nullptr)
3399 "",
"", jobHost, jobFlags);
3406 QList<uint>::Iterator it;
3441 QString forceDeleteStr(
"0");
3451 list.push_back(forceDeleteStr);
3452 list.push_back(forgetHistory ?
"1" :
"0");
3473 uint recordingID = 0;
3480 uint recordingID = 0;
3496 QCoreApplication::postEvent(
this, e);
3504 QString title = pginfo->
GetTitle().toLower();
3536 const QString& recgroup)
3539 std::array<ProgramList::iterator,2> _it {
3541 std::array<ProgramList::iterator,2> _end {
3544 if (recgroup !=
"LiveTV")
3546 swap( _it[0], _it[1]);
3547 swap(_end[0], _end[1]);
3550 for (
uint i = 0; i < 2; i++)
3554 for (; it != end; ++it)
3556 if ((*it)->GetRecordingID() == recordingID)
3579 pginfo->SaveWatched(on);
3620 pginfo->SavePreserve(on);
3641 if (pl && (pl->GetAvailableStatus() ==
asAvailable))
3715 QStringList tokens = command.simplified().split(
" ");
3717 if (tokens.size() >= 4 && (tokens[1] ==
"PLAY" || tokens[1] ==
"RESUME"))
3719 if (tokens.size() == 6 && tokens[2] ==
"PROGRAM")
3721 int clientID = tokens[5].toInt();
3723 LOG(VB_GENERAL, LOG_INFO,
LOC +
3724 QString(
"NetworkControl: Trying to %1 program '%2' @ '%3'")
3725 .arg(tokens[1], tokens[3], tokens[4]));
3729 LOG(VB_GENERAL, LOG_ERR,
LOC +
3730 "NetworkControl: Already playing");
3732 QString msg = QString(
3733 "NETWORK_CONTROL RESPONSE %1 ERROR: Unable to play, "
3734 "player is already playing another recording.")
3742 uint chanid = tokens[3].toUInt();
3748 QString msg = QString(
"NETWORK_CONTROL RESPONSE %1 OK")
3755 const bool ignoreBookmark = (tokens[1] ==
"PLAY");
3756 const bool ignoreProgStart =
true;
3757 const bool ignoreLastPlayPos =
true;
3758 const bool underNetworkControl =
true;
3759 PlayX(pginfo, ignoreBookmark, ignoreProgStart,
3760 ignoreLastPlayPos, underNetworkControl);
3764 QString message = QString(
"NETWORK_CONTROL RESPONSE %1 "
3765 "ERROR: Could not find recording for "
3767 .arg(tokens[5], tokens[3], tokens[4]);
3778 if ((event->key() == Qt::Key_LaunchMedia) &&
3779 (event->modifiers() ==
3780 (Qt::ShiftModifier |
3781 Qt::ControlModifier |
3784 Qt::KeypadModifier)))
3798 QStringList actions;
3802 for (
int i = 0; i < actions.size() && !handled; ++i)
3804 QString
action = actions[i];
3809 else if (
action ==
"MENU")
3813 else if (
action ==
"NEXTFAV")
3820 else if (
action ==
"TOGGLEFAV")
3846 if (!nextGroup.isEmpty())
3849 else if (
action ==
"NEXTVIEW")
3856 else if (
action ==
"PREVVIEW")
3871 else if (
action ==
"CHANGERECGROUP")
3873 else if (
action ==
"CHANGEGROUPVIEW")
3875 else if (
action ==
"EDIT")
3885 else if (
action ==
"CUSTOMEDIT")
3887 else if (
action ==
"GUIDE")
3889 else if (
action ==
"UPCOMING")
3916 QString resultid = dce->
GetId();
3918 if (resultid ==
"transcode" && dce->GetResult() >= 0)
3923 auto *me =
dynamic_cast<MythEvent *
>(event);
3927 const QString& message = me->
Message();
3929 if (message.startsWith(
"RECORDING_LIST_CHANGE"))
3931 QStringList tokens = message.simplified().split(
" ");
3932 uint recordingID = 0;
3933 if (tokens.size() >= 3)
3934 recordingID = tokens[2].toUInt();
3936 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
3946 else if (recordingID && (tokens[1] ==
"ADD"))
3955 else if (recordingID && (tokens[1] ==
"DELETE"))
3964 else if (message.startsWith(
"NETWORK_CONTROL"))
3966 QStringList tokens = message.simplified().split(
" ");
3967 if ((tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
3974 Qt::KeyboardModifiers modifiers =
3976 Qt::ControlModifier |
3980 auto *keyevent =
new QKeyEvent(QEvent::KeyPress,
3981 Qt::Key_LaunchMedia, modifiers);
3984 keyevent =
new QKeyEvent(QEvent::KeyRelease,
3985 Qt::Key_LaunchMedia, modifiers);
3989 else if (message.startsWith(
"UPDATE_FILE_SIZE"))
3991 QStringList tokens = message.simplified().split(
" ");
3992 if (tokens.size() >= 3)
3995 uint recordingID = tokens[1].toUInt();
3996 uint64_t filesize = tokens[2].toLongLong(&ok);
4002 recordingID, filesize,
4007 else if (message ==
"UPDATE_UI_LIST")
4017 else if (message.startsWith(
"UPDATE_UI_ITEM"))
4019 QStringList tokens = message.simplified().split(
" ");
4020 if (tokens.size() < 3)
4023 uint recordingID = tokens[1].toUInt();
4029 else if (message ==
"UPDATE_USAGE_UI")
4033 else if (message ==
"RECONNECT_SUCCESS")
4037 else if (message ==
"LOCAL_PBB_DELETE_RECORDINGS")
4040 for (
uint i = 0; i+2 < (
uint)me->ExtraDataList().size(); i+=3)
4042 uint recordingID = me->ExtraDataList()[i+0].toUInt();
4048 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4049 QString(
"LOCAL_PBB_DELETE_RECORDINGS - "
4050 "No matching recording %1")
4055 QString forceDeleteStr = me->ExtraDataList()[i+1];
4056 QString forgetHistoryStr = me->ExtraDataList()[i+2];
4059 list.push_back(forceDeleteStr);
4060 list.push_back(forgetHistoryStr);
4062 "LOCAL_PBB_DELETE_RECORDINGS");
4074 else if (message ==
"DELETE_SUCCESSES")
4078 else if (message ==
"DELETE_FAILURES")
4080 if (me->ExtraDataList().size() < 3)
4083 for (
uint i = 0; i+2 < (
uint)me->ExtraDataList().size(); i += 3)
4086 me->ExtraDataList()[i+0].toUInt());
4094 bool forceDelete = me->ExtraDataList()[1].toUInt() != 0U;
4103 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4104 "Delete failures not handled due to "
4105 "pre-existing popup.");
4112 else if (message ==
"PREVIEW_SUCCESS")
4116 else if (message ==
"PREVIEW_FAILED" && me->ExtraDataCount() >= 5)
4118 for (
uint i = 4; i < (
uint) me->ExtraDataCount(); i++)
4120 const QString& token = me->ExtraData(i);
4126 else if (message ==
"AVAILABILITY" && me->ExtraDataCount() == 8)
4128 static constexpr std::chrono::milliseconds kMaxUIWaitTime = 10s;
4129 QStringList list = me->ExtraDataList();
4130 uint recordingID = list[0].toUInt();
4133 uint64_t fs = list[3].toULongLong();
4135 tm.setHMS(list[4].toUInt(), list[5].toUInt(),
4136 list[6].toUInt(), list[7].toUInt());
4137 QTime now = QTime::currentTime();
4138 auto time_elapsed = std::chrono::milliseconds(tm.msecsTo(now));
4139 if (time_elapsed < 0ms)
4140 time_elapsed += 24h;
4151 if (time_elapsed >= kMaxUIWaitTime)
4160 (time_elapsed < kMaxUIWaitTime))
4170 const bool ignoreBookmark =
false;
4171 const bool ignoreProgStart =
false;
4172 const bool ignoreLastPlayPos =
true;
4173 const bool underNetworkControl =
false;
4175 ignoreBookmark, ignoreProgStart, ignoreLastPlayPos,
4176 underNetworkControl);
4184 QCoreApplication::postEvent(
4188 if (old_avail != availableStatus)
4191 else if ((message ==
"PLAY_PLAYLIST") && !
m_playListPlay.empty())
4205 const bool ignoreBookmark =
false;
4206 const bool ignoreProgStart =
true;
4207 const bool ignoreLastPlayPos =
true;
4208 const bool underNetworkControl =
false;
4210 Play(*pginfo,
true, ignoreBookmark, ignoreProgStart,
4211 ignoreLastPlayPos, underNetworkControl);
4213 else if ((message ==
"SET_PLAYBACK_URL") && (me->ExtraDataCount() == 2))
4215 uint recordingID = me->ExtraData(0).toUInt();
4220 else if ((message ==
"FOUND_ARTWORK") && (me->ExtraDataCount() >= 5))
4223 uint recordingID = me->ExtraData(3).toUInt();
4224 const QString& group = me->ExtraData(4);
4225 const QString& fn = me->ExtraData(5);
4239 else if (!group.isEmpty() &&
4249 else if (message ==
"EXIT_TO_MENU" ||
4250 message ==
"CANCEL_PLAYLIST")
4263 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4264 QString(
"Failed to remove %1, reloading list")
4273 groupname = sel_item->
GetData().toString();
4278 auto pit = (*git).begin();
4279 while (pit != (*git).end())
4281 if ((*pit)->GetRecordingID() == recordingID)
4283 if (!git.key().isEmpty() && git.key() == groupname)
4287 QVariant::fromValue(*pit));
4291 if (item_cur && (item_by_data == item_cur))
4301 pit = (*git).erase(pit);
4311 if (!groupname.isEmpty() && (git.key() == groupname))
4320 sel_item = next_item;
4323 groupname = sel_item->
GetData().toString();
4352 if (pginfo ==
nullptr)
4362 QCoreApplication::postEvent(
this,
new MythEvent(
"UPDATE_UI_LIST"));
4369 if (helpPopup->Create())
4379 if (viewPopup->Create())
4399 QStringList groupNames;
4400 QStringList displayNames;
4402 QStringList displayGroups;
4408 uint totalItems = 0;
4411 displayNames.append(QString(
"------- %1 -------").arg(tr(
"Groups")));
4412 groupNames.append(
"");
4415 query.
prepare(
"SELECT recgroup, COUNT(title) FROM recorded "
4416 "WHERE deletepending = 0 AND watched <= :WATCHED "
4417 "GROUP BY recgroup");
4421 while (query.
next())
4423 QString dispGroup = query.
value(0).toString();
4427 (dispGroup !=
"Deleted"))
4428 totalItems += items;
4430 groupNames.append(dispGroup);
4432 dispGroup = (dispGroup ==
"Default") ? tr(
"Default") : dispGroup;
4433 dispGroup = (dispGroup ==
"Deleted") ? tr(
"Deleted") : dispGroup;
4434 dispGroup = (dispGroup ==
"LiveTV") ? tr(
"Live TV") : dispGroup;
4436 displayNames.append(tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup));
4443 displayNames.push_front(tr(
"%1 [%n item(s)]",
nullptr, totalItems)
4445 groupNames.push_front(
"All Programs");
4449 query.
prepare(
"SELECT DISTINCT category, COUNT(title) FROM recorded "
4450 "WHERE deletepending = 0 AND watched <= :WATCHED "
4451 "GROUP BY category");
4455 int unknownCount = 0;
4456 while (query.
next())
4459 QString dispGroup = query.
value(0).toString();
4460 if (dispGroup.isEmpty())
4462 unknownCount += items;
4463 dispGroup = tr(
"Unknown");
4465 else if (dispGroup == tr(
"Unknown"))
4466 unknownCount += items;
4469 (dispGroup != tr(
"Unknown")))
4471 displayGroups += tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup);
4472 groups += dispGroup;
4478 if (unknownCount > 0)
4480 QString dispGroup = tr(
"Unknown");
4481 uint items = unknownCount;
4482 displayGroups += tr(
"%1 [%n item(s)]",
nullptr, items).arg(dispGroup);
4483 groups += dispGroup;
4490 displayNames.append(QString(
"------- %1 -------").arg(tr(
"Categories")));
4491 groupNames.append(
"");
4493 displayGroups.sort();
4494 QStringList::iterator it;
4495 for (it = displayGroups.begin(); it != displayGroups.end(); ++it)
4496 displayNames.append(*it);
4497 for (it = groups.begin(); it != groups.end(); ++it)
4498 groupNames.append(*it);
4500 QString label = tr(
"Change Filter");
4505 if (recGroupPopup->Create())
4516 delete recGroupPopup;
4532 QString newRecGroup = recGroup;
4534 if (newRecGroup.isEmpty())
4541 newRecGroup =
"Default";
4543 newRecGroup =
"All Programs";
4545 newRecGroup =
"LiveTV";
4547 newRecGroup =
"Deleted";
4579 query.
prepare(
"SELECT recgroup, password FROM recgroups "
4580 "WHERE password IS NOT NULL AND password <> '';");
4584 while (query.
next())
4586 QString recgroup = query.
value(0).toString();
4589 recgroup =
"Default";
4591 recgroup =
"All Programs";
4593 recgroup =
"LiveTV";
4595 recgroup =
"Deleted";
4621 "SELECT g.recgroup, COUNT(r.title) FROM recgroups g "
4622 "LEFT JOIN recorded r ON g.recgroupid=r.recgroupid AND r.deletepending = 0 "
4623 "WHERE g.recgroupid != 2 AND g.recgroupid != 3 "
4624 "GROUP BY g.recgroupid ORDER BY g.recgroup");
4626 QStringList displayNames(tr(
"Add New"));
4627 QStringList groupNames(
"addnewgroup");
4632 while (query.
next())
4634 QString dispGroup = query.
value(0).toString();
4635 groupNames.push_back(dispGroup);
4637 if (dispGroup ==
"Default")
4638 dispGroup = tr(
"Default");
4639 else if (dispGroup ==
"LiveTV")
4640 dispGroup = tr(
"Live TV");
4641 else if (dispGroup ==
"Deleted")
4642 dispGroup = tr(
"Deleted");
4644 displayNames.push_back(tr(
"%1 [%n item(s)]",
"", query.
value(1).toInt())
4648 QString label = tr(
"Select Recording Group") +
4654 if (rgChanger->Create())
4680 QStringList groupNames(tr(
"Default"));
4681 QStringList displayNames(
"Default");
4684 for (
const auto& name : qAsConst(list))
4686 displayNames.push_back(name);
4687 groupNames.push_back(name);
4690 QString label = tr(
"Select Playback Group") +
4696 if (pgChanger->Create())
4708 QList<uint>::Iterator it;
4713 if (tmpItem !=
nullptr)
4725 QList<uint>::Iterator it;
4730 if (tmpItem !=
nullptr)
4748 if (editMetadata->Create())
4755 delete editMetadata;
4759 const QString &newSubtitle,
4760 const QString &newDescription,
4761 const QString &newInetref,
4777 if (groupname == pginfo->GetTitle().toLower() &&
4778 newTitle != pginfo->GetTitle())
4784 QString tempSubTitle = newTitle;
4785 if (!newSubtitle.trimmed().isEmpty())
4786 tempSubTitle = QString(
"%1 - \"%2\"")
4787 .arg(tempSubTitle, newSubtitle);
4793 if (newSeason > 0 || newEpisode > 0)
4797 seasone = QString(
"s%1e%2")
4800 seasonx = QString(
"%1x%2")
4805 item->
SetText(tempSubTitle,
"titlesubtitle");
4806 item->
SetText(newTitle,
"title");
4807 item->
SetText(newSubtitle,
"subtitle");
4808 item->
SetText(newInetref,
"inetref");
4809 item->
SetText(seasonx,
"00x00");
4810 item->
SetText(seasone,
"s00e00");
4811 item->
SetText(season,
"season");
4812 item->
SetText(episode,
"episode");
4813 if (newDescription !=
nullptr)
4814 item->
SetText(newDescription,
"description");
4817 pginfo->SaveInetRef(newInetref);
4818 pginfo->SaveSeasonEpisode(newSeason, newEpisode);
4827 newRecGroup = newRecGroup.simplified();
4829 if (newRecGroup.isEmpty())
4832 if (newRecGroup ==
"addnewgroup")
4838 tr(
"New Recording Group"));
4843 if (newgroup->Create())
4863 if ((
p->GetRecordingGroup() ==
"LiveTV") &&
4864 (newRecGroup !=
"LiveTV"))
4866 p->SaveAutoExpire(defaultAutoExpire);
4868 else if ((
p->GetRecordingGroup() !=
"LiveTV") &&
4869 (newRecGroup ==
"LiveTV"))
4887 if ((
p->GetRecordingGroup() ==
"LiveTV") && (newRecGroup !=
"LiveTV"))
4888 p->SaveAutoExpire(defaultAutoExpire);
4889 else if ((
p->GetRecordingGroup() !=
"LiveTV") && (newRecGroup ==
"LiveTV"))
4902 if (newPlayGroup.isEmpty() || !tmpItem)
4905 if (newPlayGroup == tr(
"Default"))
4906 newPlayGroup =
"Default";
4910 QList<uint>::Iterator it;
4943 if (pwChanger->Create())
4957 query.
prepare(
"UPDATE recgroups SET password = :PASSWD WHERE "
4958 "recgroup = :RECGROUP");
4960 query.
bindValue(
":PASSWD", newPassword);
4966 if (newPassword.isEmpty())
4985 LOG(VB_GENERAL, LOG_ERR,
LOC +
4986 "Theme is missing 'groups' button list.");
4993 for (
int i = 0; i <
m_list.size(); ++i)
4996 QVariant::fromValue(
m_data.at(i)));
5016 if (item->
GetData().toString().isEmpty())
5019 QString group = item->
GetData().toString();
5127 LOG(VB_GENERAL, LOG_ERR,
LOC +
5128 "Window 'passwordchanger' is missing required elements.");
5191 LOG(VB_GENERAL, LOG_ERR,
LOC +
5192 "Window 'editmetadata' is missing required elements.");
5233 QString newRecDescription =
nullptr;
5234 QString newRecInetref =
nullptr;
5235 uint newRecSeason = 0;
5236 uint newRecEpisode = 0;
5243 if (newRecTitle.isEmpty())
5246 emit
result(newRecTitle, newRecSubtitle, newRecDescription,
5247 newRecInetref, newRecSeason, newRecEpisode);
5257 "recording online..."),
5285 lookup->SetSubtype(
type);
5287 lookup->SetAllowGeneric(
true);
5288 lookup->SetHandleImages(
false);
5296 lookup->SetAutomatic(
false);
5345 Qt::QueuedConnection);
5347 if (resultsdialog->Create())
5360 if (!mfsr || !mfsr->m_result)
5378 QString title = tr(
"No match found for this recording. You can "
5379 "try entering a TVDB/TMDB number, season, and "
5380 "episode manually.");
5384 if (okPopup->Create())
5400 LOG(VB_GENERAL, LOG_ERR,
LOC +
5401 "Window 'iconhelp' is missing required elements.");
5407 addItem(
"watched", tr(
"Recording has been watched"));
5408 addItem(
"commflagged", tr(
"Commercials are flagged"));
5409 addItem(
"cutlist", tr(
"An editing cutlist is present"));
5410 addItem(
"autoexpire", tr(
"The program is able to auto-expire"));
5411 addItem(
"processing", tr(
"Commercials are being flagged"));
5412 addItem(
"bookmark", tr(
"A bookmark is set"));
5414 addItem(
"inuse", tr(
"Recording is in use"));
5415 addItem(
"transcoded", tr(
"Recording has been transcoded"));
5418 addItem(
"mono", tr(
"Recording is in Mono"));
5419 addItem(
"stereo", tr(
"Recording is in Stereo"));
5420 addItem(
"surround", tr(
"Recording is in Surround Sound"));
5421 addItem(
"dolby", tr(
"Recording is in Dolby Surround Sound"));
5423 addItem(
"cc", tr(
"Recording is Closed Captioned"));
5424 addItem(
"subtitles", tr(
"Recording has Subtitles Available"));
5425 addItem(
"onscreensub", tr(
"Recording is Subtitled"));
5427 addItem(
"SD", tr(
"Recording is in Standard Definition"));
5428 addItem(
"widescreen", tr(
"Recording is Widescreen"));
5429 addItem(
"hdtv", tr(
"Recording is in High Definition"));
5430 addItem(
"hd720", tr(
"Recording is in 720p High Definition"));
5431 addItem(
"hd1080i", tr(
"Recording is in 1080i High Definition"));
5432 addItem(
"hd1080p", tr(
"Recording is in 1080p High Definition"));
5433 addItem(
"uhd4Ki", tr(
"Recording is in 4k(interlaced) UHD resolution"));
5434 addItem(
"uhd4Kp", tr(
"Recording is in 4k UHD resolution"));
5435 addItem(
"mpeg2", tr(
"Recording is using MPEG-2 codec"));
5436 addItem(
"avchd", tr(
"Recording is using AVC/H.264 codec"));
5437 addItem(
"hevc", tr(
"Recording is using HEVC/H.265 codec"));
5446 item->DisplayState(state,
"icons");
5451 QDateTime now = QDateTime::currentDateTime();
5455 QMap<int, JobQueueEntry> jobs;
5458 for (
const auto& job : qAsConst(jobs))
5460 m_jobs.insert(qMakePair(job.chanid, job.recstartts), job);
5467 const QDateTime &recstartts)
5470 QList<JobQueueEntry> values = m_jobs.values(qMakePair(chanid, recstartts));
5471 auto end = values.cend();
5472 for (
auto iter = values.cbegin(); iter != end; ++iter)
5474 if (iter->type == jobType)
5481 const QDateTime &recstartts)
5484 QList<JobQueueEntry> values = m_jobs.values(qMakePair(chanid, recstartts));
5485 auto end = values.cend();
5486 for (
auto iter = values.cbegin(); iter != end; ++iter)
5488 if (iter->type == jobType)
5495 const QDateTime &recstartts)
5497 return IsJobQueued(jobType, chanid, recstartts) ||
5498 IsJobRunning(jobType, chanid, recstartts);