Go to the documentation of this file.
30 LOG(VB_GENERAL, LOG_ERR,
"Cannot load 'Info buttonlist'");
41 QString table = (recorded) ?
"recordedrating" :
"programrating";
42 QString sel = QString(
43 "SELECT `system`, rating FROM %1 "
44 "WHERE chanid = :CHANID "
45 "AND starttime = :STARTTIME").arg(table);
58 QMap<QString,QString> main_ratings;
62 if (query.
value(0).toString().toLower() ==
"advisory")
64 advisory += query.
value(1).toString() +
", ";
67 main_ratings[query.
value(0).toString()] = query.
value(1).toString();
70 advisory = advisory.left(advisory.length() - 2);
72 if (main_ratings.empty())
75 if (!advisory.isEmpty())
76 advisory =
": " + advisory;
78 if (main_ratings.size() == 1)
80 return *main_ratings.begin() + advisory;
84 QMap<QString,QString>::const_iterator it;
85 for (it = main_ratings.cbegin(); it != main_ratings.cend(); ++it)
87 ratings += it.key() +
": " + *it +
", ";
90 return ratings +
"Advisory" + advisory;
125 for (
int i = 0; i < actions.size() && !handled; ++i)
127 const QString&
action = actions[i];
135 else if (
action ==
"DOWN")
163 using string_pair = QPair<QString, QString>;
164 QVector<string_pair> tests;
182 tests.append(qMakePair(QString(
"channel.recpriority"),
183 QString(
"channel.recpriority")));
184 tests.append(qMakePair(QString(
"capturecard.recpriority"),
185 QString(
"capturecard.recpriority")));
189 pwrpri = QString(
"(capturecard.cardid = record.prefinput) * %1")
191 tests.append(qMakePair(pwrpri, pwrpri));
195 pwrpri = QString(
"(program.hdtv > 0 OR "
196 "FIND_IN_SET('HDTV', program.videoprop) > 0) * %1")
198 tests.append(qMakePair(pwrpri, pwrpri));
203 (
"(FIND_IN_SET('WIDESCREEN', program.videoprop) > 0) * %1")
205 tests.append(qMakePair(pwrpri, pwrpri));
210 (
"(FIND_IN_SET('SIGNED', program.subtitletypes) > 0) * %1")
212 tests.append(qMakePair(pwrpri, pwrpri));
217 (
"(FIND_IN_SET('ONSCREEN', program.subtitletypes) > 0) * %1")
219 tests.append(qMakePair(pwrpri, pwrpri));
224 (
"(FIND_IN_SET('NORMAL', program.subtitletypes) > 0 OR "
225 "program.closecaptioned > 0 OR program.subtitled > 0) * %1")
227 tests.append(qMakePair(pwrpri, pwrpri));
232 (
"(FIND_IN_SET('HARDHEAR', program.subtitletypes) > 0 OR "
233 "FIND_IN_SET('HARDHEAR', program.audioprop) > 0) * %1")
235 tests.append(qMakePair(pwrpri, pwrpri));
240 (
"(FIND_IN_SET('VISUALIMPAIR', program.audioprop) > 0) * %1")
242 tests.append(qMakePair(pwrpri, pwrpri));
245 query.
prepare(
"SELECT recpriority, selectclause FROM powerpriority;");
255 int adj = query.
value(0).toInt();
258 QString sclause = query.
value(1).toString();
261 pwrpri = QString(
"(%1) * %2").arg(sclause)
262 .arg(query.
value(0).toInt());
263 pwrpri.replace(
"RECTABLE",
"record");
266 pwrpri += QString(
" AS powerpriority ");
268 tests.append(qMakePair(desc, pwrpri));
272 recmatch = QString(
"INNER JOIN record "
273 " ON ( record.recordid = %1 ) ")
276 for (
const auto & [label, csqlStart] : std::as_const(tests))
278 QString sqlStart = csqlStart;
279 query.
prepare(
"SELECT " + sqlStart.replace(
"program.",
"p.")
282 "INNER JOIN channel "
283 " ON ( channel.chanid = p.chanid ) "
284 "INNER JOIN capturecard "
285 " ON ( channel.sourceid = capturecard.sourceid AND "
286 " ( capturecard.schedorder <> 0 OR "
287 " capturecard.parentid = 0 ) ) ").arg(ptable)
289 "WHERE p.chanid = :CHANID AND"
290 " p.starttime = :STARTTIME ;");
295 adjustmsg = QString(
"%1 : ").arg(label);
298 int adj = query.
value(0).toInt();
301 adjustmsg += tr(
" MATCHED, adding %1").arg(adj);
306 adjustmsg += tr(
" not matched");
311 adjustmsg += tr(
" Query FAILED");
314 addItem(tr(
"Recording Priority Adjustment"), adjustmsg,
318 if (!tests.isEmpty())
319 addItem(tr(
"Priority Adjustment Total"), QString::number(total),
326 QString category_type;
329 QString syndicatedEpisodeNum;
332 QString title_pronounce;
340 bool recorded =
false;
352 QString ptable = recorded ?
"recordedprogram" :
"program";
356 query.
prepare(QString(
"SELECT category_type, airdate, stars,"
357 " partnumber, parttotal, audioprop+0, videoprop+0,"
358 " subtitletypes+0, syndicatedepisodenumber, generic,"
359 " showtype, colorcode, title_pronounce"
360 " FROM %1 WHERE chanid = :CHANID AND"
361 " starttime = :STARTTIME ;").arg(ptable));
368 category_type = query.
value(0).toString();
369 year = query.
value(1).toString();
370 stars = query.
value(2).toFloat();
371 partnumber = query.
value(3).toInt();
372 parttotal = query.
value(4).toInt();
373 audioprop = query.
value(5).toInt();
374 videoprop = query.
value(6).toInt();
375 subtype = query.
value(7).toInt();
376 syndicatedEpisodeNum = query.
value(8).toString();
377 generic = query.
value(9).toInt();
378 showtype = query.
value(10).toString();
379 colorcode = query.
value(11).toString();
380 title_pronounce = query.
value(12).toString();
397 category_type =
"movie";
399 category_type =
"series";
401 category_type =
"sports";
403 category_type =
"tvshow";
417 attr += tr(
"Part %1 of %2, ").arg(partnumber).arg(parttotal);
421 if (category_type ==
"movie")
430 attr += tr(
"%n star(s)",
"", roundf(stars * 10.0F)) +
", ";
432 if (!colorcode.isEmpty())
433 attr += colorcode +
", ";
435 if (audioprop & AUD_MONO)
436 attr += tr(
"Mono") +
", ";
437 if (audioprop & AUD_STEREO)
438 attr += tr(
"Stereo") +
", ";
439 if (audioprop & AUD_SURROUND)
440 attr += tr(
"Surround Sound") +
", ";
441 if (audioprop & AUD_DOLBY)
442 attr += tr(
"Dolby Sound") +
", ";
443 if (audioprop & AUD_HARDHEAR)
444 attr += tr(
"Audio for Hearing Impaired") +
", ";
445 if (audioprop & AUD_VISUALIMPAIR)
446 attr += tr(
"Audio for Visually Impaired") +
", ";
448 if (videoprop & VID_HDTV)
449 attr += tr(
"HDTV") +
", ";
450 if (videoprop & VID_WIDESCREEN)
451 attr += tr(
"Widescreen") +
", ";
452 if (videoprop & VID_AVC)
453 attr += tr(
"AVC/H.264") +
", ";
454 if (videoprop & VID_HEVC)
455 attr += tr(
"HEVC/H.265") +
", ";
456 if (videoprop & VID_720)
457 attr += tr(
"720p Resolution") +
", ";
459 if (videoprop & VID_PROGRESSIVE)
461 if (videoprop & VID_1080)
462 attr += tr(
"1080p Resolution") +
", ";
463 if (videoprop & VID_4K)
464 attr += tr(
"4K Resolution") +
", ";
468 if (videoprop & VID_1080)
469 attr += tr(
"1080i Resolution") +
", ";
470 if (videoprop & VID_4K)
471 attr += tr(
"4Ki Resolution") +
", ";
474 if (videoprop & VID_DAMAGED)
475 attr += tr(
"Damaged") +
", ";
477 if (subtype & SUB_HARDHEAR)
478 attr += tr(
"CC",
"Closed Captioned") +
", ";
479 if (subtype & SUB_NORMAL)
480 attr += tr(
"Subtitles Available") +
", ";
481 if (subtype & SUB_ONSCREEN)
482 attr += tr(
"Subtitled") +
", ";
483 if (subtype & SUB_SIGNED)
484 attr += tr(
"Deaf Signing") +
", ";
486 if (
generic && category_type ==
"series")
487 attr += tr(
"Unidentified Episode") +
", ";
489 attr += tr(
"Repeat") +
", ";
493 attr.truncate(attr.lastIndexOf(
','));
494 s +=
" (" + attr +
")";
502 QString execProducers;
508 QString commentators;
511 using string_pair = QPair<QString, QString>;
512 QVector<string_pair> actor_list;
513 QVector<string_pair> guest_star_list;
514 QVector<string_pair> guest_list;
520 table =
"recordedcredits";
524 query.
prepare(QString(
"SELECT role, people.name, roles.name FROM %1"
526 " LEFT JOIN people ON"
527 " credits.person = people.person"
528 " LEFT JOIN roles ON"
529 " credits.roleid = roles.roleid"
530 " WHERE credits.chanid = :CHANID"
531 " AND credits.starttime = :STARTTIME"
532 " ORDER BY role, priority;").arg(table));
537 if (query.
exec() && query.
size() > 0)
547 role = query.
value(0).toString();
563 pname = QString::fromUtf8(query.
value(1)
564 .toByteArray().constData());
565 character = QString::fromUtf8(query.
value(2)
566 .toByteArray().constData());
568 if (!character.isEmpty())
571 actor_list.append(qMakePair(pname, character));
572 else if (role ==
"guest_star")
573 guest_star_list.append(qMakePair(pname, character));
574 else if (role ==
"guest")
575 guest_list.append(qMakePair(pname, character));
580 plist.removeDuplicates();
582 actors = plist.join(
", ");
583 else if (rstr ==
"director")
584 directors = plist.join(
", ");
585 else if (rstr ==
"producer")
586 producers = plist.join(
", ");
587 else if (rstr ==
"executive_producer")
588 execProducers = plist.join(
", ");
589 else if (rstr ==
"writer")
590 writers = plist.join(
", ");
591 else if (rstr ==
"guest_star")
592 guestStars = plist.join(
", ");
593 else if (rstr ==
"host")
594 hosts = plist.join(
", ");
595 else if (rstr ==
"adapter")
596 adapters = plist.join(
", ");
597 else if (rstr ==
"presenter")
598 presenters = plist.join(
", ");
599 else if (rstr ==
"commentator")
600 commentators = plist.join(
", ");
601 else if (rstr ==
"guest")
602 guests = plist.join(
", ");
610 plist.removeDuplicates();
612 actors = plist.join(
", ");
613 else if (rstr ==
"director")
614 directors = plist.join(
", ");
615 else if (rstr ==
"producer")
616 producers = plist.join(
", ");
617 else if (rstr ==
"executive_producer")
618 execProducers = plist.join(
", ");
619 else if (rstr ==
"writer")
620 writers = plist.join(
", ");
621 else if (rstr ==
"guest_star")
622 guestStars = plist.join(
", ");
623 else if (rstr ==
"host")
624 hosts = plist.join(
", ");
625 else if (rstr ==
"adapter")
626 adapters = plist.join(
", ");
627 else if (rstr ==
"presenter")
628 presenters = plist.join(
", ");
629 else if (rstr ==
"commentator")
630 commentators = plist.join(
", ");
631 else if (rstr ==
"guest")
632 guests = plist.join(
", ");
639 if (!actor_list.isEmpty())
641 for (
const auto & [actor, role] : std::as_const(actor_list))
644 if (!guest_star_list.isEmpty())
646 for (
const auto & [actor, role] : std::as_const(guest_star_list))
649 if (!guest_list.isEmpty())
651 for (
const auto & [actor, role] : std::as_const(guest_list))
667 query.
prepare(
"SELECT genre FROM programgenres "
668 "WHERE chanid = :CHANID AND starttime = :STARTTIME "
669 "AND relevance <> '0' ORDER BY relevance;");
680 s += query.
value(0).toString();
686 if (!category_type.isEmpty())
691 if (!showtype.isEmpty())
716 addItem(tr(
"Syndicated Episode Number"), syndicatedEpisodeNum,
721 category_type !=
"movie")
731 QDateTime statusDate;
743 query.
prepare(
"SELECT recstatus, starttime "
744 "FROM oldrecorded WHERE duplicate > 0 AND "
746 "((programid <> '' AND programid = :PROGRAMID) OR "
747 " (title <> '' AND title = :TITLE AND "
748 " subtitle <> '' AND subtitle = :SUBTITLE AND "
749 " description <> '' AND description = :DECRIPTION));");
760 else if (query.
next())
790 if (statusDate.isValid())
796 QString recordingRule;
797 QString lastRecorded;
798 QString nextRecording;
799 QString averageTimeShift;
800 QString watchListScore;
801 QString watchListStatus;
802 QString searchPhrase;
809 if (record && !record->
m_title.isEmpty())
810 recordingRule += QString(
" \"%2\"").arg(record->
m_title);
812 query.
prepare(
"SELECT last_record, next_record, avg_delay "
813 "FROM record WHERE recordid = :RECORDID");
818 if (query.
value(0).toDateTime().isValid())
824 if (query.
value(1).toDateTime().isValid())
830 if (query.
value(2).toInt() > 0)
831 averageTimeShift = tr(
"%n hour(s)",
"",
832 query.
value(2).toInt());
845 watchListStatus = tr(
"Auto-expire off");
848 watchListStatus = tr(
"Marked as 'watched'");
851 watchListStatus = tr(
"Not the earliest episode");
854 watchListStatus = tr(
"Recently deleted episode");
869 QDateTime fdate(QDate(1970, 1, 1),QTime(12,0,0));
883 QString recordingHost;
884 QString recordingInput;
886 QString recordedPathname;
887 QString recordedFilename;
888 QString recordedFileSize;
889 QString recordingGroup;
890 QString storageGroup;
891 QString playbackGroup;
892 QString recordingProfile;
902 recordedFileSize = QString(
"%1 ")
904 recordedFileSize += tr(
"GB",
"GigaBytes");
906 query.
prepare(
"SELECT profile FROM recorded"
907 " WHERE chanid = :CHANID"
908 " AND starttime = :STARTTIME;");
922 recordingProfile = record ? record->
m_recProfile : tr(
"Unknown");
bool isActive(void) const
bool LoadByProgram(const ProgramInfo *proginfo)
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
virtual uint64_t GetFilesize(void) const
QString GetHostname(void) const
QString GetInputName(void) const
std::tuple< QString, QString, int > DataItem
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
void addItem(const QString &title, const QString &value, ProgInfoList::VisibleLevel level)
uint GetRecordingID(void) const
QVariant value(int i) const
QString GetCategory(void) const
static const QRegularExpression kReLeadingAnd
Internal representation of a recording rule, mirrors the record table.
bool Create(void) override
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QString GetRecordingGroup(void) const
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QString GetPathname(void) const
void PowerPriorities(const QString &ptable)
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
static QString getRatings(bool recorded, uint chanid, const QDateTime &startts)
bool IsRepeat(void) const
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
RecStatus::Type GetRecordingStatus(void) const
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
bool Create(bool focusable)
Initialise buttonlist from XML.
void Toggle(void)
Toggle infolist state. Focusable widgets toggle between Basic & Full info. Non-focusable widgets togg...
QString GetTitle(void) const
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetDescription(void) const
static void DBError(const QString &where, const MSqlQuery &query)
uint GetEpisodeTotal(void) const
void BuildFocusList(void)
def rating(profile, smoonURL, gate)
RecSearchType m_searchType
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
void Display(const DataList &data)
Build list of key:value buttons.
QString GetPlaybackGroup(void) const
uint GetFindID(void) const
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetSeriesID(void) const
static QString i18n(const QString &msg)
Translations for play,recording, & storage groups +.
int GetNumSetting(const QString &key, int defaultval=0)
QString GetStorageGroup(void) const
QDate GetOriginalAirDate(void) const
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
ProgInfoList::DataList m_data
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
RecordingType GetRecordingRuleType(void) const
uint GetEpisode(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
@ kAddYear
Add year to string if not included.
uint GetSeason(void) const
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
MythMainWindow * GetMythMainWindow(void)
@ kDateFull
Default local time.
QString GetProgramID(void) const
int GetRecordingPriority2(void) const
uint GetRecordingRuleID(void) const
QString GetBasename(void) const
bool Hide(void)
Remove infolist from display.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QString GetSubtitle(void) const