MythTV master
programrecpriority.cpp
Go to the documentation of this file.
1// C/C++ headers
2#include <algorithm>
3#include <compare>
4#include <vector> // For std::vector
5
6// QT headers
7#include <QChar> // Fix Qt6 GCC SFINAE warning
8#include <QDateTime>
9
10// MythTV headers
11#include "libmythbase/mythdb.h"
23
24// MythFrontend
25#include "proglist.h"
26#include "programrecpriority.h"
27#include "scheduleeditor.h"
28
30 const ProgramRecPriorityInfo &other, bool ignore_non_serialized_data)
31{
32 RecordingInfo::clone(other, ignore_non_serialized_data);
33
34 if (!ignore_non_serialized_data)
35 {
36 m_recType = other.m_recType;
38 m_recCount = other.m_recCount;
41 m_profile = other.m_profile;
44 }
45}
46
48 const RecordingInfo &other, bool ignore_non_serialized_data)
49{
50 RecordingInfo::clone(other, ignore_non_serialized_data);
51
52 if (!ignore_non_serialized_data)
53 {
55 m_matchCount = 0;
56 m_recCount = 0;
57 m_last_record = QDateTime();
58 m_avg_delay = 0;
59 m_profile.clear();
60 m_storageGroup.clear();
61 m_recordingGroup.clear();
62 }
63}
64
66 const ProgramInfo &other, bool ignore_non_serialized_data)
67{
68 RecordingInfo::clone(other, ignore_non_serialized_data);
69
70 if (!ignore_non_serialized_data)
71 {
73 m_matchCount = 0;
74 m_recCount = 0;
75 m_last_record = QDateTime();
76 m_avg_delay = 0;
77 m_profile.clear();
78 m_storageGroup.clear();
79 m_recordingGroup.clear();
80 }
81}
82
84{
86
88 m_matchCount = 0;
89 m_recCount = 0;
90 m_last_record = QDateTime();
91 m_avg_delay = 0;
92 m_profile.clear();
93 m_storageGroup.clear();
94 m_recordingGroup.clear();
95}
96
98 bool showrerecord, uint star_range,
99 uint date_format) const
100{
101 RecordingInfo::ToMap(progMap, showrerecord, star_range, date_format);
102 progMap["title"] = (m_title == "Default (Template)") ?
103 QObject::tr("Default (Template)") : m_title;
104 progMap["category"] = (m_category == "Default") ?
105 QObject::tr("Default") : m_category;
106 progMap["storagegroup"] = (m_storageGroup == "Default") ?
107 QObject::tr("Default") : m_storageGroup;
108 progMap["recordinggroup"] = (m_recordingGroup == "Default") ?
109 QObject::tr("Default") : m_recordingGroup;
110}
111
112// For the spaceship operator, the c++ standard library explicitly
113// requires '0' and not nullptr. NOLINTBEGIN(modernize-use-nullptr)
115{
116 public:
117 explicit TitleSort(bool reverse) : m_reverse(reverse) {}
118
120 const ProgramRecPriorityInfo *b) const
121 {
123 if (cmp == 0)
125 // sort higher recording priority before
126 if (cmp == 0)
127 cmp = b->GetRecordingPriority() <=> a->GetRecordingPriority();
128 // sort lower RecordingTypePrecedence before
129 if (cmp == 0)
131 // sort lower RecordingRuleID before
132 if (cmp == 0)
133 cmp = a->GetRecordingRuleID() <=> b->GetRecordingRuleID();
134
135 return m_reverse ? cmp > 0 : cmp < 0;
136 }
137
138 private:
139 bool m_reverse {false};
140};
141
143{
144 public:
145 explicit ProgramRecPrioritySort(bool reverse) : m_reverse(reverse) {}
146
148 const ProgramRecPriorityInfo *b) const
149 {
150 // sort higher recording priority before
151 auto cmp = b->GetRecordingPriority() <=> a->GetRecordingPriority();
152 // sort lower RecTypePrecedence before
153 if (cmp == 0)
155 // sort lower RecordingRuleID before
156 if (cmp == 0)
157 cmp = a->GetRecordingRuleID() <=> b->GetRecordingRuleID();
158
159 return m_reverse ? cmp > 0 : cmp < 0;
160 }
161
162 private:
163 bool m_reverse {false};
164};
165
167{
168 public:
169 explicit ProgramRecTypeSort(bool reverse) : m_reverse(reverse) {}
170
172 const ProgramRecPriorityInfo *b) const
173 {
174 // sort lower RecTypePrecedence before
176 // sort higher recording priority before
177 if (cmp == 0)
178 cmp = b->GetRecordingPriority() <=> a->GetRecordingPriority();
179 // sort lower RecordingRuleID before
180 if (cmp == 0)
181 cmp = a->GetRecordingRuleID() <=> b->GetRecordingRuleID();
182
183 return m_reverse ? cmp > 0 : cmp < 0;
184 }
185
186 private:
187 bool m_reverse {false};
188};
189
191{
192 public:
193 explicit ProgramCountSort(bool reverse) : m_reverse(reverse) {}
194
196 const ProgramRecPriorityInfo *b) const
197 {
198 // sort higher match count before
199 auto cmp = b->m_matchCount <=> a->m_matchCount;
200 // sort higher recCount before
201 if (cmp == 0)
202 cmp = b->m_recCount <=> a->m_recCount;
203 if (cmp == 0)
205 if (cmp == 0)
207
208 return m_reverse ? cmp > 0 : cmp < 0;
209 }
210
211 private:
212 bool m_reverse {false};
213};
214
216{
217 public:
218 explicit ProgramRecCountSort(bool reverse) : m_reverse(reverse) {}
219
221 const ProgramRecPriorityInfo *b) const
222 {
223 // sort higher recCount before
224 auto cmp = b->m_recCount <=> a->m_recCount;
225 // sort higher match count before
226 if (cmp == 0)
227 cmp = b->m_matchCount <=> a->m_matchCount;
228 if (cmp == 0)
230 if (cmp == 0)
232
233 return m_reverse ? cmp > 0 : cmp < 0;
234 }
235
236 private:
237 bool m_reverse {false};
238};
239
241{
242 public:
243 explicit ProgramLastRecordSort(bool reverse) : m_reverse(reverse) {}
244
246 const ProgramRecPriorityInfo *b) const
247 {
248 // sort later date time before
249 auto cmp = b->m_last_record.toMSecsSinceEpoch() <=> a->m_last_record.toMSecsSinceEpoch();
250 if (cmp == 0)
252 if (cmp == 0)
254
255 return m_reverse ? cmp > 0 : cmp < 0;
256 }
257
258 private:
259 bool m_reverse {false};
260};
261
263{
264 public:
265 explicit ProgramAvgDelaySort(bool reverse) : m_reverse(reverse) {}
266
268 const ProgramRecPriorityInfo *b) const
269 {
270 auto cmp = a->m_avg_delay <=> b->m_avg_delay;
271 if (cmp == 0)
273 if (cmp == 0)
275
276 return m_reverse ? cmp > 0 : cmp < 0;
277 }
278
279 private:
280 bool m_reverse {false};
281};
282// NOLINTEND(modernize-use-nullptr)
283
285
287 const QString &name)
288 : ScheduleCommon(parent, name)
289{
290 m_sortType = (SortType)gCoreContext->GetNumSetting("ProgramRecPrioritySorting",
291 (int)byTitle);
292 m_reverseSort = gCoreContext->GetBoolSetting("ProgramRecPriorityReverse", false);
293}
294
296{
297 if (!LoadWindowFromXML("schedule-ui.xml", "managerecrules", this))
298 return false;
299
300 m_programList = dynamic_cast<MythUIButtonList *> (GetChild("programs"));
301
302 m_schedInfoText = dynamic_cast<MythUIText *> (GetChild("scheduleinfo"));
303 m_recPriorityText = dynamic_cast<MythUIText *> (GetChild("recpriority"));
304 m_recPriorityBText = dynamic_cast<MythUIText *> (GetChild("recpriorityB"));
305 m_finalPriorityText = dynamic_cast<MythUIText *> (GetChild("finalpriority"));
306 m_lastRecordedText = dynamic_cast<MythUIText *> (GetChild("lastrecorded"));
307 m_lastRecordedDateText = dynamic_cast<MythUIText *> (GetChild("lastrecordeddate"));
308 m_lastRecordedTimeText = dynamic_cast<MythUIText *> (GetChild("lastrecordedtime"));
309 m_chanNameText = dynamic_cast<MythUIText *> (GetChild("channel"));
310 m_chanNumText = dynamic_cast<MythUIText *> (GetChild("channum"));
311 m_callSignText = dynamic_cast<MythUIText *> (GetChild("callsign"));
312 m_recProfileText = dynamic_cast<MythUIText *> (GetChild("recordingprofile"));
313
314 if (!m_programList)
315 {
316 LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
317 return false;
318 }
319
324
325 m_programList->SetLCDTitles(tr("Schedule Priorities"),
326 "rec_type|titlesubtitle|progpriority");
327 m_programList->SetSearchFields("titlesubtitle");
328
331
332 return true;
333}
334
336{
337 FillList();
338}
339
341{
342 SortList();
343}
344
346{
347 if (GetFocusWidget()->keyPressEvent(event))
348 return true;
349
350 QStringList actions;
351 bool handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, actions);
352
353 for (int i = 0; i < actions.size() && !handled; i++)
354 {
355 const QString& action = actions[i];
356 handled = true;
357
358 if (action == "RANKINC")
359 {
361 }
362 else if (action == "RANKDEC")
363 {
365 }
366 else if (action == "ESCAPE")
367 {
369 gCoreContext->SaveSetting("ProgramRecPrioritySorting",
370 (int)m_sortType);
371 gCoreContext->SaveSetting("ProgramRecPriorityReverse",
372 (int)m_reverseSort);
373 Close();
374 }
375 else if (action == "1")
376 {
377 if (m_sortType != byTitle)
378 {
380 m_reverseSort = false;
381 }
382 else
383 {
385 }
386 SortList();
387 }
388 else if (action == "2")
389 {
391 {
393 m_reverseSort = false;
394 }
395 else
396 {
398 }
399 SortList();
400 }
401 else if (action == "4")
402 {
403 if (m_sortType != byRecType)
404 {
406 m_reverseSort = false;
407 }
408 else
409 {
411 }
412 SortList();
413 }
414 else if (action == "5")
415 {
416 if (m_sortType != byCount)
417 {
419 m_reverseSort = false;
420 }
421 else
422 {
424 }
425 SortList();
426 }
427 else if (action == "6")
428 {
429 if (m_sortType != byRecCount)
430 {
432 m_reverseSort = false;
433 }
434 else
435 {
437 }
438 SortList();
439 }
440 else if (action == "7")
441 {
443 {
445 m_reverseSort = false;
446 }
447 else
448 {
450 }
451 SortList();
452 }
453 else if (action == "8")
454 {
455 if (m_sortType != byAvgDelay)
456 {
458 m_reverseSort = false;
459 }
460 else
461 {
463 }
464 SortList();
465 }
466 else if (action == "PREVVIEW" || action == "NEXTVIEW")
467 {
468 m_reverseSort = false;
469 if (m_sortType == byTitle)
471 else if (m_sortType == byRecPriority)
473 else
475 SortList();
476 }
477 else if (action == "SELECT" || action == "EDIT")
478 {
481 }
482 else if (action == "MENU")
483 {
484 showMenu();
485 }
486 else if (action == "CUSTOMEDIT")
487 {
489 EditCustom();
490 }
491 else if (action == "DELETE")
492 {
494 remove();
495 }
496 else if (action == "UPCOMING")
497 {
499 ShowUpcoming();
500 }
501 else if (action == "INFO" || action == "DETAILS")
502 {
503 ShowDetails();
504 }
505 else
506 {
507 handled = false;
508 }
509 }
510
511 if (!handled && MythScreenType::keyPressEvent(event))
512 handled = true;
513
514 return handled;
515}
516
518{
519 QString label = tr("Options");
520
521 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
522 auto *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
523
524 if (menuPopup->Create())
525 {
526 menuPopup->SetReturnEvent(this, "menu");
527
528 menuPopup->AddButton(tr("Increase Priority"));
529 menuPopup->AddButton(tr("Decrease Priority"));
530 menuPopup->AddButton(tr("Sort"), nullptr, true);
531 menuPopup->AddButton(tr("Program Details"));
532 menuPopup->AddButton(tr("Upcoming"));
533 menuPopup->AddButton(tr("Custom Edit"));
534 menuPopup->AddButton(tr("Delete Rule"));
535 menuPopup->AddButton(tr("New Template"));
536
537 popupStack->AddScreen(menuPopup);
538 }
539 else
540 {
541 delete menuPopup;
542 }
543}
544
546{
547 QString label = tr("Sort Options");
548
549 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
550 auto *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
551
552 if (menuPopup->Create())
553 {
554 menuPopup->SetReturnEvent(this, "sortmenu");
555
556 menuPopup->AddButton(tr("Reverse Sort Order"));
557 menuPopup->AddButton(tr("Sort By Title"));
558 menuPopup->AddButton(tr("Sort By Priority"));
559 menuPopup->AddButton(tr("Sort By Type"));
560 menuPopup->AddButton(tr("Sort By Count"));
561 menuPopup->AddButton(tr("Sort By Record Count"));
562 menuPopup->AddButton(tr("Sort By Last Recorded"));
563 menuPopup->AddButton(tr("Sort By Average Delay"));
564
565 popupStack->AddScreen(menuPopup);
566 }
567 else
568 {
569 delete menuPopup;
570 }
571}
572
574{
575 if (event->type() == DialogCompletionEvent::kEventType)
576 {
577 auto *dce = (DialogCompletionEvent*)event;
578
579 QString resultid = dce->GetId();
580 QString resulttext = dce->GetResultText();
581 int buttonnum = dce->GetResult();
582
583 if (resultid == "menu")
584 {
585 if (resulttext == tr("Increase Priority"))
586 {
588 }
589 else if (resulttext == tr("Decrease Priority"))
590 {
592 }
593 else if (resulttext == tr("Sort"))
594 {
595 showSortMenu();
596 }
597 else if (resulttext == tr("Program Details"))
598 {
599 ShowDetails();
600 }
601 else if (resulttext == tr("Upcoming"))
602 {
604 ShowUpcoming();
605 }
606 else if (resulttext == tr("Custom Edit"))
607 {
609 EditCustom();
610 }
611 else if (resulttext == tr("Delete Rule"))
612 {
614 remove();
615 }
616 else if (resulttext == tr("New Template"))
617 {
618 MythScreenStack *popupStack =
619 GetMythMainWindow()->GetStack("popup stack");
620 auto *textInput = new MythTextInputDialog(popupStack,
621 tr("Template Name"));
622 if (textInput->Create())
623 {
624 textInput->SetReturnEvent(this, "templatecat");
625 popupStack->AddScreen(textInput);
626 }
627 }
628 }
629 else if (resultid == "sortmenu")
630 {
631 if (resulttext == tr("Reverse Sort Order"))
632 {
634 SortList();
635 }
636 else if (resulttext == tr("Sort By Title"))
637 {
638 if (m_sortType != byTitle)
639 {
641 m_reverseSort = false;
642 }
643 else
644 {
646 }
647 SortList();
648 }
649 else if (resulttext == tr("Sort By Priority"))
650 {
652 {
654 m_reverseSort = false;
655 }
656 else
657 {
659 }
660 SortList();
661 }
662 else if (resulttext == tr("Sort By Type"))
663 {
664 if (m_sortType != byRecType)
665 {
667 m_reverseSort = false;
668 }
669 else
670 {
672 }
673 SortList();
674 }
675 else if (resulttext == tr("Sort By Count"))
676 {
677 if (m_sortType != byCount)
678 {
680 m_reverseSort = false;
681 }
682 else
683 {
685 }
686 SortList();
687 }
688 else if (resulttext == tr("Sort By Record Count"))
689 {
690 if (m_sortType != byRecCount)
691 {
693 m_reverseSort = false;
694 }
695 else
696 {
698 }
699 SortList();
700 }
701 else if (resulttext == tr("Sort By Last Recorded"))
702 {
704 {
706 m_reverseSort = false;
707 }
708 else
709 {
711 }
712 SortList();
713 }
714 else if (resulttext == tr("Sort By Average Delay"))
715 {
716 if (m_sortType != byAvgDelay)
717 {
719 m_reverseSort = false;
720 }
721 else
722 {
724 }
725 SortList();
726 }
727 }
728 else if (resultid == "deleterule")
729 {
730 auto *record = dce->GetData().value<RecordingRule *>();
731 if (record)
732 {
733 if (buttonnum > 0)
734 {
737
738 if (record->Delete() && item)
739 RemoveItemFromList(item);
740 else
741 LOG(VB_GENERAL, LOG_ERR,
742 "Failed to delete recording rule");
743 }
744 delete record;
745 }
746 }
747 else if (resultid == "templatecat")
748 {
749 newTemplate(resulttext);
750 }
751 else
752 {
754 }
755 }
756}
757
759{
760 if (!item)
761 return;
762
763 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo*>();
764 if (!pgRecInfo)
765 return;
766
767 auto *record = new RecordingRule();
768 record->m_recordID = pgRecInfo->GetRecordingRuleID();
769 if (record->m_searchType == kNoSearch)
770 record->LoadByProgram(pgRecInfo);
771
773 auto *schededit = new ScheduleEditor(mainStack, record);
774 if (schededit->Create())
775 {
776 mainStack->AddScreen(schededit);
779 }
780 else
781 {
782 delete schededit;
783 }
784}
785
787{
788 category = category.trimmed();
789 if (category.isEmpty())
790 return;
791
792 // Try to find an existing template and use it.
793 QMap<int, ProgramRecPriorityInfo>::Iterator it;
794 for (it = m_programData.begin(); it != m_programData.end(); ++it)
795 {
796 ProgramRecPriorityInfo *progInfo = &(*it);
797 if (progInfo->GetRecordingRuleType() == kTemplateRecord &&
798 category.compare(progInfo->GetCategory(),
799 Qt::CaseInsensitive) == 0)
800 {
801 m_programList->SetValueByData(QVariant::fromValue(progInfo));
803 return;
804 }
805 }
806
807 auto *record = new RecordingRule();
808 if (!record)
809 return;
810 record->MakeTemplate(category);
811
813 auto *schededit = new ScheduleEditor(mainStack, record);
814 if (schededit->Create())
815 {
816 mainStack->AddScreen(schededit);
819 }
820 else
821 {
822 delete schededit;
823 }
824}
825
827{
828 // Assumes that the current item didn't change, which isn't guaranteed
830 ProgramRecPriorityInfo *pgRecInfo = nullptr;
831 if (item)
832 pgRecInfo = item->GetData().value<ProgramRecPriorityInfo*>();
833
834 // If the recording id doesn't match, the user created a new
835 // template.
836 if (!pgRecInfo || recid != pgRecInfo->getRecordID())
837 {
838 RecordingRule record;
839 record.m_recordID = recid;
840 if (!record.Load() || record.m_type == kNotRecording)
841 return;
842
843 ProgramRecPriorityInfo progInfo;
844 progInfo.SetRecordingRuleID(record.m_recordID);
845 progInfo.SetRecordingRuleType(record.m_type);
846 progInfo.SetTitle(record.m_title, record.m_sortTitle);
847 progInfo.SetSubtitle(record.m_subtitle, record.m_sortSubtitle);
848 progInfo.SetCategory(record.m_category);
849 progInfo.SetRecordingPriority(record.m_recPriority);
850 progInfo.m_recType = record.m_type;
851 progInfo.m_recStatus = record.m_isInactive ?
853 progInfo.m_profile = record.m_recProfile;
854 progInfo.m_last_record = record.m_lastRecorded;
855 progInfo.m_storageGroup = record.m_storageGroup;
857
858 m_programData[recid] = progInfo;
860 record.m_recPriority;
861 SortList(&m_programData[recid]);
862
863 return;
864 }
865
866 // We need to refetch the recording priority values since the Advanced
867 // Recording Options page could've been used to change them
868
870 query.prepare("SELECT recpriority, type, inactive "
871 "FROM record "
872 "WHERE recordid = :RECORDID");
873 query.bindValue(":RECORDID", recid);
874 if (!query.exec())
875 {
876 MythDB::DBError("Get new recording priority query", query);
877 }
878 else if (query.next())
879 {
880 int recPriority = query.value(0).toInt();
881 int rectype = query.value(1).toInt();
882 int inactive = query.value(2).toInt();
883
884 // set the recording priorities of that program
885 pgRecInfo->SetRecordingPriority(recPriority);
886 pgRecInfo->m_recType = (RecordingType)rectype;
887 // also set the m_origRecPriorityData with new recording
888 // priority so we don't save to db again when we exit
890 pgRecInfo->GetRecordingPriority();
891 // also set the active/inactive state
892 pgRecInfo->m_recStatus = inactive ? RecStatus::Inactive : RecStatus::Unknown;
893
894 SortList();
895 }
896 else
897 {
898 RemoveItemFromList(item);
899 }
900
901 countMatches();
902}
903
905{
907 if (!item)
908 return;
909
910 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo*>();
911 if (!pgRecInfo ||
912 (pgRecInfo->m_recType == kTemplateRecord &&
913 pgRecInfo->GetCategory()
914 .compare("Default", Qt::CaseInsensitive) == 0))
915 {
916 return;
917 }
918
919 auto *record = new RecordingRule();
920 record->m_recordID = pgRecInfo->GetRecordingRuleID();
921 if (!record->Load())
922 {
923 delete record;
924 return;
925 }
926
927 QString message = tr("Delete '%1' %2 rule?")
928 .arg(record->m_title, toString(pgRecInfo->GetRecordingRuleType()));
929
930 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
931
932 auto *okPopup = new MythConfirmationDialog(popupStack, message, true);
933 okPopup->SetReturnEvent(this, "deleterule");
934 okPopup->SetData(QVariant::fromValue(record));
935
936 if (okPopup->Create())
937 popupStack->AddScreen(okPopup);
938 else
939 delete okPopup;
940}
941
943{
945 if (!item)
946 return;
947
948 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo*>();
949 if (pgRecInfo)
950 {
952
953 query.prepare("SELECT inactive "
954 "FROM record "
955 "WHERE recordid = :RECID");
956 query.bindValue(":RECID", pgRecInfo->GetRecordingRuleID());
957
958
959 if (!query.exec())
960 {
961 MythDB::DBError("ProgramRecPriority::deactivate()", query);
962 }
963 else if (query.next())
964 {
965 int inactive = query.value(0).toInt();
966 if (inactive)
967 inactive = 0;
968 else
969 inactive = 1;
970
971 query.prepare("UPDATE record "
972 "SET inactive = :INACTIVE "
973 "WHERE recordid = :RECID");
974 query.bindValue(":INACTIVE", inactive);
975 query.bindValue(":RECID", pgRecInfo->GetRecordingRuleID());
976
977 if (!query.exec())
978 {
980 "Update recording schedule inactive query", query);
981 }
982 else
983 {
985 QString("DeactivateRule %1 %2")
986 .arg(pgRecInfo->GetRecordingRuleID())
987 .arg(pgRecInfo->GetTitle()));
988 pgRecInfo->m_recStatus = inactive ? RecStatus::Inactive : RecStatus::Unknown;
989 item->DisplayState("disabled", "status");
990 }
991 }
992 }
993}
994
996{
998 if (!item)
999 return;
1000
1001 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo*>();
1002 if (!pgRecInfo)
1003 return;
1004
1005 // inc/dec recording priority
1006 int tempRecPriority = pgRecInfo->GetRecordingPriority() + howMuch;
1007 if (tempRecPriority > -100 && tempRecPriority < 100)
1008 {
1009 pgRecInfo->m_recPriority = tempRecPriority;
1010
1011 // order may change if sorting by recording priority, so resort
1013 {
1014 SortList();
1015 }
1016 else
1017 {
1018 // No need to re-fill the entire list, just update this entry
1019 int progRecPriority = pgRecInfo->GetRecordingPriority();
1020
1021 item->SetText(QString::number(progRecPriority), "progpriority");
1022 item->SetText(QString::number(progRecPriority), "recpriority");
1024 m_recPriorityText->SetText(QString::number(progRecPriority));
1025
1026 item->SetText(QString::number(progRecPriority), "recpriorityB");
1028 m_recPriorityBText->SetText(QString::number(progRecPriority));
1029
1030 item->SetText(QString::number(progRecPriority), "finalpriority");
1032 m_finalPriorityText->SetText(QString::number(progRecPriority));
1033 }
1034 }
1035}
1036
1038{
1039 QMap<int, ProgramRecPriorityInfo>::Iterator it;
1040
1041 for (it = m_programData.begin(); it != m_programData.end(); ++it)
1042 {
1043 ProgramRecPriorityInfo *progInfo = &(*it);
1044 int key = progInfo->GetRecordingRuleID();
1045
1046 // if this program's recording priority changed from when we entered
1047 // save new value out to db
1048 if (progInfo->GetRecordingPriority() != m_origRecPriorityData[key])
1050 progInfo->GetRecordingPriority());
1051 }
1052}
1053
1055{
1056 std::vector<ProgramInfo *> recordinglist;
1057
1058 m_programData.clear();
1059
1060 RemoteGetAllScheduledRecordings(recordinglist);
1061
1062 for (auto & pgiter : recordinglist)
1063 {
1064 ProgramInfo *progInfo = pgiter;
1065 m_programData[pgiter->GetRecordingRuleID()] =
1066 (*progInfo);
1067
1068 // save recording priority value in map so we don't have to
1069 // save all program's recording priority values when we exit
1070 m_origRecPriorityData[pgiter->GetRecordingRuleID()] =
1071 pgiter->GetRecordingPriority();
1072
1073 delete pgiter;
1074 }
1075
1076 // get recording types associated with each program from db
1077 // (hope this is ok to do here, it's so much lighter doing
1078 // it all at once than once per program)
1079
1080 MSqlQuery result(MSqlQuery::InitCon());
1081 result.prepare("SELECT recordid, title, chanid, starttime, startdate, "
1082 "type, inactive, last_record, avg_delay, profile, "
1083 "recgroup, storagegroup "
1084 "FROM record;");
1085
1086 if (!result.exec())
1087 {
1088 MythDB::DBError("Get program recording priorities query", result);
1089 }
1090
1091 countMatches();
1092 while (result.next()) {
1093 uint recordid = result.value(0).toUInt();
1094// QString title = result.value(1).toString();
1095// QString chanid = result.value(2).toString();
1096// QString tempTime = result.value(3).toString();
1097// QString tempDate = result.value(4).toString();
1098 RecordingType recType = (RecordingType)result.value(5).toInt();
1099 int inactive = result.value(6).toInt();
1100 QDateTime lastrec = MythDate::as_utc(result.value(7).toDateTime());
1101 int avgd = result.value(8).toInt();
1102 QString profile = result.value(9).toString();
1103 QString recordingGroup = result.value(10).toString();
1104 QString storageGroup = result.value(11).toString();
1105
1106 // find matching program in m_programData and set
1107 // recType
1108 QMap<int, ProgramRecPriorityInfo>::Iterator it;
1109 it = m_programData.find(recordid);
1110 if (it != m_programData.end())
1111 {
1112 ProgramRecPriorityInfo *progInfo = &(*it);
1113
1114 progInfo->m_recType = recType;
1115 progInfo->m_matchCount =
1116 m_listMatch[progInfo->GetRecordingRuleID()];
1117 progInfo->m_recCount =
1118 m_recMatch[progInfo->GetRecordingRuleID()];
1119 progInfo->m_last_record = lastrec;
1120 progInfo->m_avg_delay = avgd;
1121 progInfo->m_profile = profile;
1122 progInfo->m_recordingGroup = recordingGroup;
1123 progInfo->m_storageGroup = storageGroup;
1124
1125 if (inactive)
1126 progInfo->m_recStatus = RecStatus::Inactive;
1127 else if (m_conMatch[progInfo->GetRecordingRuleID()] > 0)
1128 progInfo->m_recStatus = RecStatus::Conflict;
1129 else if (m_nowMatch[progInfo->GetRecordingRuleID()] > 0)
1131 else if (m_recMatch[progInfo->GetRecordingRuleID()] > 0)
1133 else
1134 progInfo->m_recStatus = RecStatus::Unknown;
1135 }
1136 }
1137}
1138
1140{
1141 m_listMatch.clear();
1142 m_conMatch.clear();
1143 m_nowMatch.clear();
1144 m_recMatch.clear();
1145 ProgramList schedList;
1146 LoadFromScheduler(schedList);
1147 QDateTime now = MythDate::current();
1148
1149 for (auto *program : schedList)
1150 {
1151 const RecStatus::Type recstatus = (*program).GetRecordingStatus();
1152 const uint recordid = (*program).GetRecordingRuleID();
1153 if ((*program).GetRecordingEndTime() > now && recstatus != RecStatus::NotListed)
1154 {
1155 m_listMatch[recordid]++;
1156 if (recstatus == RecStatus::Conflict || recstatus == RecStatus::Offline)
1157 {
1158 m_conMatch[recordid]++;
1159 }
1160 else if (recstatus == RecStatus::WillRecord)
1161 {
1162 m_recMatch[recordid]++;
1163 }
1164 else if (recstatus == RecStatus::Recording)
1165 {
1166 m_nowMatch[recordid]++;
1167 m_recMatch[recordid]++;
1168 }
1169 }
1170 }
1171}
1172
1174{
1175 if (newCurrentItem)
1176 {
1177 m_currentItem = newCurrentItem;
1178 }
1179 else
1180 {
1182 if (item)
1184 item->GetData().value<ProgramRecPriorityInfo*>();
1185 }
1186
1187 QMap<int, ProgramRecPriorityInfo>::Iterator pit;
1188
1189 // copy m_programData into m_sortedProgram
1190 m_sortedProgram.clear();
1191 for (pit = m_programData.begin(); pit != m_programData.end(); ++pit)
1192 {
1193 ProgramRecPriorityInfo *progInfo = &(*pit);
1194 m_sortedProgram.push_back(progInfo);
1195 }
1196
1197 // sort m_sortedProgram
1198 switch (m_sortType)
1199 {
1200 case byTitle :
1201 std::ranges::sort(m_sortedProgram,
1203 break;
1204 case byRecPriority :
1205 std::ranges::sort(m_sortedProgram,
1207 break;
1208 case byRecType :
1209 std::ranges::sort(m_sortedProgram,
1211 break;
1212 case byCount :
1213 std::ranges::sort(m_sortedProgram,
1215 break;
1216 case byRecCount :
1217 std::ranges::sort(m_sortedProgram,
1219 break;
1220 case byLastRecord :
1221 std::ranges::sort(m_sortedProgram,
1223 break;
1224 case byAvgDelay :
1225 std::ranges::sort(m_sortedProgram,
1227 break;
1228 }
1229
1230 UpdateList();
1231}
1232
1234{
1237 .value<ProgramRecPriorityInfo*>();
1238
1240
1241 std::vector<ProgramRecPriorityInfo*>::iterator it;
1242 for (it = m_sortedProgram.begin(); it != m_sortedProgram.end(); ++it)
1243 {
1244 ProgramRecPriorityInfo *progInfo = *it;
1245
1246 auto *item = new MythUIButtonListItem(m_programList, "",
1247 QVariant::fromValue(progInfo));
1248
1249 int progRecPriority = progInfo->GetRecordingPriority();
1250
1251 if ((progInfo->m_recType == kSingleRecord ||
1252 progInfo->m_recType == kOverrideRecord ||
1253 progInfo->m_recType == kDontRecord) &&
1254 !(progInfo->GetSubtitle()).trimmed().isEmpty())
1255 {
1256 QString rating = QString::number(progInfo->GetStars(10));
1257
1258 item->DisplayState(rating, "ratingstate");
1259 }
1260 else
1261 {
1262 progInfo->m_subtitle.clear();
1263 }
1264
1265 QString state;
1266 if (progInfo->m_recType == kDontRecord ||
1267 (progInfo->m_recType != kTemplateRecord &&
1268 progInfo->m_recStatus == RecStatus::Inactive))
1269 state = "disabled";
1270 else if (m_conMatch[progInfo->GetRecordingRuleID()] > 0)
1271 state = "error";
1272 else if (m_recMatch[progInfo->GetRecordingRuleID()] > 0 ||
1273 progInfo->m_recType == kTemplateRecord)
1274 state = "normal";
1275 else if (m_nowMatch[progInfo->GetRecordingRuleID()] > 0)
1276 state = "running";
1277 else
1278 state = "warning";
1279
1280 InfoMap infoMap;
1281 progInfo->ToMap(infoMap);
1282 item->SetTextFromMap(infoMap, state);
1283
1284 QString subtitle;
1285 if (progInfo->m_subtitle != "(null)" &&
1286 (progInfo->m_recType == kSingleRecord ||
1287 progInfo->m_recType == kOverrideRecord ||
1288 progInfo->m_recType == kDontRecord))
1289 {
1290 subtitle = progInfo->m_subtitle;
1291 }
1292
1293 QString matchInfo;
1294 if (progInfo->GetRecordingStatus() == RecStatus::Inactive)
1295 {
1296 matchInfo = QString("%1 %2")
1297 .arg(m_listMatch[progInfo->GetRecordingRuleID()])
1298 .arg(RecStatus::toString(progInfo->GetRecordingStatus(),
1299 progInfo->GetRecordingRuleType()));
1300 }
1301 else
1302 {
1303 matchInfo = tr("Recording %1 of %2")
1304 .arg(m_recMatch[progInfo->GetRecordingRuleID()])
1305 .arg(m_listMatch[progInfo->GetRecordingRuleID()]);
1306 }
1307
1308 subtitle = QString("(%1) %2").arg(matchInfo, subtitle);
1309 item->SetText(subtitle, "scheduleinfo", state);
1310
1311 item->SetText(QString::number(progRecPriority), "progpriority", state);
1312 item->SetText(QString::number(progRecPriority), "finalpriority", state);
1313
1314 item->SetText(QString::number(progRecPriority), "recpriority", state);
1315 item->SetText(QString::number(progRecPriority), "recpriorityB", state);
1316
1317 QString tempDateTime = MythDate::toString(progInfo->m_last_record,
1320 item->SetText(tempDateTime, "lastrecorded", state);
1321 QString tempDate = MythDate::toString(progInfo->m_last_record,
1324 item->SetText(tempDate, "lastrecordeddate", state);
1325 QString tempTime = MythDate::toString(
1326 progInfo->m_last_record, MythDate::kTime);
1327 item->SetText(tempTime, "lastrecordedtime", state);
1328
1329 QString channame = progInfo->m_chanName;
1330 QString channum = progInfo->m_chanStr;
1331 QString callsign = progInfo->m_chanSign;
1332 if (progInfo->m_recType != kSingleRecord &&
1333 progInfo->m_recType != kOverrideRecord &&
1334 progInfo->m_recType != kDontRecord &&
1335 !(progInfo->GetRecordingRule()->m_filter & 1024) &&
1337 {
1338 channame = tr("Any");
1339 channum = tr("Any");
1340 callsign = tr("Any");
1341 }
1342 item->SetText(channame, "channel", state);
1343 item->SetText(channum, "channum", state);
1344 item->SetText(callsign, "callsign", state);
1345
1346 QString profile = progInfo->m_profile;
1347 if ((profile == "Default") || (profile == "Live TV") ||
1348 (profile == "High Quality") || (profile == "Low Quality"))
1349 profile = tr(profile.toUtf8().constData());
1350 item->SetText(profile, "recordingprofile", state);
1351 item->SetText(progInfo->m_recordingGroup, "recordinggroup", state);
1352 item->SetText(progInfo->m_storageGroup, "storagegroup", state);
1353 item->DisplayState(state, "status");
1354
1355 if (m_currentItem == progInfo)
1357 }
1358
1359 m_currentItem = nullptr;
1360
1361 MythUIText *norecordingText = dynamic_cast<MythUIText*>
1362 (GetChild("norecordings_info"));
1363
1364 if (norecordingText)
1365 norecordingText->SetVisible(m_programData.isEmpty());
1366}
1367
1368// Called whenever a new recording is selected from the list of
1369// recordings. This function updates the screen with the information
1370// on the newly selected recording.
1372{
1373 if (!item)
1374 return;
1375
1376 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo *>();
1377
1378 if (!pgRecInfo)
1379 return;
1380
1381 int progRecPriority = pgRecInfo->GetRecordingPriority();
1382
1383 QString subtitle;
1384 if (pgRecInfo->m_subtitle != "(null)" &&
1385 (pgRecInfo->m_recType == kSingleRecord ||
1386 pgRecInfo->m_recType == kOverrideRecord ||
1387 pgRecInfo->m_recType == kDontRecord))
1388 {
1389 subtitle = pgRecInfo->m_subtitle;
1390 }
1391
1392 QString matchInfo;
1393 if (pgRecInfo->GetRecordingStatus() == RecStatus::Inactive)
1394 {
1395 matchInfo = QString("%1 %2")
1396 .arg(m_listMatch[pgRecInfo->GetRecordingRuleID()])
1397 .arg(RecStatus::toString(pgRecInfo->GetRecordingStatus(),
1398 pgRecInfo->GetRecordingRuleType()));
1399 }
1400 else
1401 {
1402 matchInfo = tr("Recording %1 of %2")
1403 .arg(m_recMatch[pgRecInfo->GetRecordingRuleID()])
1404 .arg(m_listMatch[pgRecInfo->GetRecordingRuleID()]);
1405 }
1406
1407 subtitle = QString("(%1) %2").arg(matchInfo, subtitle);
1408
1409 InfoMap infoMap;
1410 pgRecInfo->ToMap(infoMap);
1411 SetTextFromMap(infoMap);
1412
1413 if (m_schedInfoText)
1414 m_schedInfoText->SetText(subtitle);
1415
1417 m_recPriorityText->SetText(QString::number(progRecPriority));
1418
1420 m_recPriorityBText->SetText(QString::number(progRecPriority));
1421
1423 m_finalPriorityText->SetText(QString::number(progRecPriority));
1424
1426 {
1427 QString tempDateTime = MythDate::toString(pgRecInfo->m_last_record,
1430 m_lastRecordedText->SetText(tempDateTime);
1431 }
1432
1434 {
1435 QString tempDate = MythDate::toString(pgRecInfo->m_last_record,
1439 }
1440
1442 {
1443 QString tempTime = MythDate::toString(
1444 pgRecInfo->m_last_record, MythDate::kTime);
1446 }
1447
1449 {
1450 QString channame = pgRecInfo->m_chanName;
1451 QString channum = pgRecInfo->m_chanStr;
1452 QString callsign = pgRecInfo->m_chanSign;
1453 if (pgRecInfo->m_recType != kSingleRecord &&
1454 pgRecInfo->m_recType != kOverrideRecord &&
1455 pgRecInfo->m_recType != kDontRecord &&
1456 !(pgRecInfo->GetRecordingRule()->m_filter & 1024) &&
1457 pgRecInfo->GetRecordingRule()->m_searchType != kManualSearch)
1458 {
1459 channame = tr("Any");
1460 channum = tr("Any");
1461 callsign = tr("Any");
1462 }
1463 if (m_chanNameText)
1464 m_chanNameText->SetText(channame);
1465 if (m_chanNumText)
1466 m_chanNumText->SetText(channum);
1467 if (m_callSignText)
1468 m_callSignText->SetText(callsign);
1469 }
1470
1471 if (m_recProfileText)
1472 {
1473 QString profile = pgRecInfo->m_profile;
1474 if ((profile == "Default") || (profile == "Live TV") ||
1475 (profile == "High Quality") || (profile == "Low Quality"))
1476 profile = tr(profile.toUtf8().constData());
1478 }
1479}
1480
1482{
1483 if (!item)
1484 return;
1485
1486 auto *pgRecInfo = item->GetData().value<ProgramRecPriorityInfo *>();
1487
1488 if (!pgRecInfo)
1489 return;
1490
1491 QMap<int, ProgramRecPriorityInfo>::iterator it;
1492 it = m_programData.find(pgRecInfo->GetRecordingRuleID());
1493 if (it != m_programData.end())
1494 m_programData.erase(it);
1495
1497}
1498
1500{
1502 return item ? item->GetData().value<ProgramRecPriorityInfo*>() : nullptr;
1503}
1504
1505#include "moc_programrecpriority.cpp"
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:40
static const Type kEventType
Definition: mythdialogbox.h:55
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:129
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:839
QVariant value(int i) const
Definition: mythdbcon.h:205
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:620
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:890
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:814
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:552
Dialog asking for user confirmation.
void SaveSetting(const QString &key, int newValue)
int GetNumSetting(const QString &key, int defaultval=0)
bool GetBoolSetting(const QString &key, bool defaultval=false)
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
Basic menu dialog, message and a list of options.
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)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void LoadInBackground(const QString &message="")
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
virtual void Close()
Dialog prompting the user to enter a text string.
void DisplayState(const QString &state, const QString &name)
void SetText(const QString &text, const QString &name="", const QString &state="")
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
void SetLCDTitles(const QString &title, const QString &columnList="")
MythUIButtonListItem * GetItemCurrent() const
void SetItemCurrent(MythUIButtonListItem *item)
void RemoveItem(MythUIButtonListItem *item)
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
void SetSearchFields(const QString &fields)
void itemClicked(MythUIButtonListItem *item)
void SetValueByData(const QVariant &data)
void itemSelected(MythUIButtonListItem *item)
virtual void SetTextFromMap(const InfoMap &infoMap)
All purpose text widget, displays a text string.
Definition: mythuitext.h:29
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
virtual void SetVisible(bool visible)
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:130
ProgramAvgDelaySort(bool reverse)
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
ProgramCountSort(bool reverse)
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
Holds information on recordings and videos.
Definition: programinfo.h:74
float GetStars(void) const
Definition: programinfo.h:453
uint GetRecordingRuleID(void) const
Definition: programinfo.h:460
void SetTitle(const QString &t, const QString &st=nullptr)
QString m_category
Definition: programinfo.h:785
void SetRecordingRuleType(RecordingType type)
Definition: programinfo.h:593
QString GetSortSubtitle(void) const
Definition: programinfo.h:371
void SetCategory(const QString &cat)
Definition: programinfo.h:546
QString m_title
Definition: programinfo.h:776
void SetRecordingRuleID(uint id)
Definition: programinfo.h:550
QString GetSortTitle(void) const
Definition: programinfo.h:369
QString m_chanStr
Definition: programinfo.h:791
int GetRecordingPriority(void) const
Definition: programinfo.h:451
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
QString m_chanSign
Definition: programinfo.h:792
QString m_chanName
Definition: programinfo.h:793
void SetRecordingPriority(int priority)
Definition: programinfo.h:548
QString m_subtitle
Definition: programinfo.h:778
RecStatus::Type GetRecordingStatus(void) const
Definition: programinfo.h:458
int8_t m_recStatus
Definition: programinfo.h:839
QString GetSubtitle(void) const
Definition: programinfo.h:370
QString GetCategory(void) const
Definition: programinfo.h:377
void SetSubtitle(const QString &st, const QString &sst=nullptr)
RecordingType GetRecordingRuleType(void) const
Definition: programinfo.h:462
ProgramLastRecordSort(bool reverse)
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
ProgramRecCountSort(bool reverse)
void clear(void) override
virtual void clone(const ProgramRecPriorityInfo &other, bool ignore_non_serialized_data=false)
void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const override
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
ProgramRecPrioritySort(bool reverse)
MythUIText * m_schedInfoText
ProgramInfo * GetCurrentProgram(void) const override
MythUIText * m_chanNameText
QMap< int, int > m_origRecPriorityData
void updateInfo(MythUIButtonListItem *item)
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
void edit(MythUIButtonListItem *item) const
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
MythUIText * m_lastRecordedTimeText
std::vector< ProgramRecPriorityInfo * > m_sortedProgram
void changeRecPriority(int howMuch)
ProgramRecPriority(MythScreenStack *parent, const QString &name)
QMap< int, int > m_nowMatch
MythUIText * m_callSignText
MythUIText * m_recPriorityBText
MythUIButtonList * m_programList
QMap< int, int > m_conMatch
QMap< int, int > m_listMatch
MythUIText * m_finalPriorityText
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
void newTemplate(QString category)
void customEvent(QEvent *event) override
MythUIText * m_lastRecordedDateText
MythUIText * m_chanNumText
MythUIText * m_lastRecordedText
void scheduleChanged(int recid)
MythUIText * m_recPriorityText
QMap< int, ProgramRecPriorityInfo > m_programData
bool Create(void) override
QMap< int, int > m_recMatch
ProgramRecPriorityInfo * m_currentItem
void RemoveItemFromList(MythUIButtonListItem *item)
void SortList(ProgramRecPriorityInfo *newCurrentItem=nullptr)
MythUIText * m_recProfileText
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
ProgramRecTypeSort(bool reverse)
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:36
static QString GetRecgroupString(uint recGroupID)
Temporary helper during transition from string to ID.
void clear(void) override
RecordingRule * GetRecordingRule(void)
Returns the "record" field, creating it if necessary.
int getRecordID(void)
Returns a record id, creating "record" it if necessary.
void ApplyRecordRecPriorityChange(int newrecpriority)
Sets recording priority of "record", creating "record" if it does not exist.
virtual void clone(const RecordingInfo &other, bool ignore_non_serialized_data=false)
Copies important fields from other RecordingInfo.
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:31
RecordingType m_type
QString m_sortSubtitle
Definition: recordingrule.h:82
QString m_category
Definition: recordingrule.h:84
RecSearchType m_searchType
unsigned m_filter
QString m_storageGroup
int m_recordID
Unique Recording Rule ID.
Definition: recordingrule.h:72
QString m_title
Definition: recordingrule.h:79
QString m_recProfile
bool m_isInactive
Recording rule is enabled?
Definition: recordingrule.h:76
QString m_subtitle
Definition: recordingrule.h:81
bool Load(bool asTemplate=false)
Load a single rule from the recorded table.
QDateTime m_lastRecorded
QString m_sortTitle
Definition: recordingrule.h:80
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 ShowUpcoming(void) const
Show the upcoming recordings for this title.
Construct a recording schedule.
void ruleSaved(int ruleId)
void ruleDeleted(int ruleId)
static void ReschedulePlace(const QString &why)
TitleSort(bool reverse)
bool operator()(const ProgramRecPriorityInfo *a, const ProgramRecPriorityInfo *b) const
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
unsigned int uint
Definition: compat.h:60
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:28
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
@ kDateTimeFull
Default local time.
Definition: mythdate.h:24
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:27
@ kDateFull
Default local time.
Definition: mythdate.h:20
@ kTime
Default local time.
Definition: mythdate.h:23
@ kAddYear
Add year to string if not included.
Definition: mythdate.h:26
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
MBASE_PUBLIC std::strong_ordering naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
This method chops the input a and b into pieces of digits and non-digits (a1.05 becomes a | 1 | .
Definition: stringutil.cpp:122
def rating(profile, smoonURL, gate)
Definition: scan.py:36
bool LoadFromScheduler(AutoDeleteDeque< TYPE * > &destination, bool &hasConflicts, const QString &altTable="", int recordid=-1)
Definition: programinfo.h:945
void RemoteGetAllScheduledRecordings(std::vector< ProgramInfo * > &scheduledlist)
int RecTypePrecedence(RecordingType rectype)
Converts a RecordingType to a simple integer so it's specificity can be compared to another.
@ kManualSearch
@ kNoSearch
RecordingType
@ kNotRecording
@ kOverrideRecord
@ kSingleRecord
@ kTemplateRecord
@ kDontRecord