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