MythTV  master
prevreclist.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Peter G Bennett <pbennett@mythtv.org>
3  *
4  * This file is part of MythTV.
5  *
6  * MythTV is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Public License as
8  * published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * MythTV is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MythTV. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "prevreclist.h"
21 
22 // C/C++
23 #include <algorithm>
24 #include <deque> // for _Deque_iterator, operator-, etc
25 #include <iterator> // for reverse_iterator
26 using namespace std;
27 
28 // QT
29 #include <QDateTime>
30 #include <QString>
31 
32 //MythTV
33 #include "mythcorecontext.h"
34 #include "mythdb.h"
35 #include "mythmiscutil.h"
36 #include "xmlparsebase.h"
37 #include "recordinginfo.h"
38 #include "recordingrule.h"
39 #include "scheduledrecording.h"
40 
41 // MythUI
42 #include "mythuitext.h"
43 #include "mythuibuttonlist.h"
44 #include "mythuibutton.h"
45 #include "mythscreenstack.h"
46 #include "mythmainwindow.h"
47 #include "mythuiutils.h" // for UIUtilE, UIUtilW
48 #include "mythdialogbox.h"
49 
50 #define LOC QString("PrevRecordedList: ")
51 
52 // flags for PrevRecSortFlags setting
53 static const int fTitleGroup = 1;
54 static const int fReverseSort = 2;
55 static const int fDefault = fReverseSort;
56 
58  QString title) :
59  ScheduleCommon(parent,"PrevRecordedList"),
60  m_recid(recid),
61  m_title(std::move(title))
62 {
63 
64  if (m_recid && !m_title.isEmpty())
65  {
66  m_where = QString(" AND ( recordid = %1 OR title = :MTITLE )")
67  .arg(m_recid);
68  }
69  else if (!m_title.isEmpty())
70  {
71  m_where = QString("AND title = :MTITLE ");
72  }
73  else if (m_recid)
74  {
75  m_where = QString("AND recordid = %1 ").arg(m_recid);
76  }
77  else
78  {
79  // Get sort options if this is not a filtered list
80  int flags = gCoreContext->GetNumSetting("PrevRecSortFlags",fDefault);
81  m_titleGroup = ((flags & fTitleGroup) != 0);
82  m_reverseSort = ((flags & fReverseSort) != 0);
83 
84  }
85 }
86 
88 {
89  if (m_where.isEmpty())
90  {
91  // Save sort setting if this is not a filtered list
92  int flags = 0;
93  if (m_titleGroup)
94  flags |= fTitleGroup;
95  if (m_reverseSort)
96  flags |= fReverseSort;
97  gCoreContext->SaveSetting("PrevRecSortFlags", flags);
98  }
100  m_showData.clear();
102 }
103 
105 {
106  if (!LoadWindowFromXML("schedule-ui.xml", "prevreclist", this))
107  return false;
108 
109  bool err = false;
110  UIUtilE::Assign(this, m_titleList, "titles", &err);
111  UIUtilE::Assign(this, m_showList, "shows", &err);
112  UIUtilW::Assign(this, m_help1Text, "help1text");
113  UIUtilW::Assign(this, m_help2Text, "help2text");
114  UIUtilW::Assign(this, m_curviewText, "curview");
115 
116  if (err)
117  {
118  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'prevreclist'");
119  return false;
120  }
121 
122  m_titleList->SetLCDTitles(tr("Programs"), "title");
123  m_showList->SetLCDTitles(tr("Episodes"), "startdate|parttitle");
124 
125  BuildFocusList();
126  gCoreContext->addListener(this);
127  m_loadShows = false;
129 
130  return true;
131 }
132 
134 {
135  gCoreContext->addListener(this);
142  connect(m_showList, SIGNAL(itemClicked(MythUIButtonListItem*)),
143  this, SLOT(ShowItemMenu()));
144 
145  UpdateTitleList();
146  updateInfo();
147 }
148 
149 // When m_loadShows is false we are loading the left hand
150 // button list, when it is true the right hand.
152 {
153  if (m_loadShows)
154  {
155  if (m_titleGroup)
157  else
158  LoadShowsByDate();
159  }
160  else
161  {
162  if (m_titleGroup)
163  LoadTitles();
164  else
165  LoadDates();
166  }
167  auto *slce = new ScreenLoadCompletionEvent(objectName());
168  QCoreApplication::postEvent(this, slce);
169 }
170 
171 static bool comp_sorttitle_lt(
172  const ProgramInfo *a, const ProgramInfo *b)
173 {
174  QString a_st = a->GetSortTitle();
175  QString b_st = b->GetSortTitle();
176  return naturalCompare(a_st,b_st) < 0;
177 }
178 
180  const ProgramInfo *a, const ProgramInfo *b)
181 {
182  QString a_st = a->GetSortTitle();
183  QString b_st = b->GetSortTitle();
184  return naturalCompare(b_st, a_st) < 0;
185 }
186 
187 static bool comp_sortdate_lt(
188  const ProgramInfo *a, const ProgramInfo *b)
189 {
190  return a->GetRecordingStartTime() < b->GetRecordingStartTime();
191 }
192 
194  const ProgramInfo *a, const ProgramInfo *b)
195 {
196  return b->GetRecordingStartTime() < a->GetRecordingStartTime();
197 }
198 
199 // Load a list of titles without subtitle or other info.
200 // each title can represent multiple recordings.
202 {
203  QString querystr = "SELECT DISTINCT title FROM oldrecorded "
204  "WHERE oldrecorded.future = 0 " + m_where;
205 
206  m_titleData.clear();
207 
208  MSqlQuery query(MSqlQuery::InitCon());
209  query.prepare(querystr);
210 
211  if (!m_title.isEmpty())
212  query.bindValue(":MTITLE", m_title);
213 
214  if (!query.exec())
215  {
216  MythDB::DBError("PrevRecordedList::LoadTitles", query);
217  return false;
218  }
219 
220  while (query.next())
221  {
222  QString title(query.value(0).toString());
223  auto *program = new ProgramInfo();
224  program->SetTitle(title);
225  m_titleData.push_back(program);
226  }
227  if (m_reverseSort)
228  {
229  std::stable_sort(m_titleData.begin(), m_titleData.end(),
231  }
232  else
233  {
234  std::stable_sort(m_titleData.begin(), m_titleData.end(),
236  }
237  return true;
238 }
239 
241 {
242  QString querystr = "SELECT DISTINCT "
243  "YEAR(CONVERT_TZ(starttime,'UTC','SYSTEM')), "
244  "MONTH(CONVERT_TZ(starttime,'UTC','SYSTEM')) "
245  "FROM oldrecorded "
246  "WHERE oldrecorded.future = 0 " + m_where;
247 
248  m_titleData.clear();
249 
250  MSqlQuery query(MSqlQuery::InitCon());
251  query.prepare(querystr);
252 
253  if (!m_title.isEmpty())
254  query.bindValue(":MTITLE", m_title);
255 
256  if (!query.exec())
257  {
258  MythDB::DBError("PrevRecordedList::LoadDates", query);
259  return false;
260  }
261 
262  // Create "Last two weeks" entry
263  // It is identified by bogus date of 0000/00
264 
265  auto *program = new ProgramInfo();
266  program->SetRecordingStartTime(QDateTime::currentDateTime());
267  program->SetTitle(tr("Last two weeks"), "0000/00");
268  m_titleData.push_back(program);
269 
270  while (query.next())
271  {
272  int year(query.value(0).toInt());
273  int month(query.value(1).toInt());
274  program = new ProgramInfo();
275  QDate startdate(year,month,1);
276  QDateTime starttime(startdate);
277  program->SetRecordingStartTime(starttime);
278  QString date = QString("%1/%2")
279  .arg(year,4,10,QChar('0')).arg(month,2,10,QChar('0'));
280  QLocale locale = gCoreContext->GetLocale()->ToQLocale();
281  QString title = QString("%1 %2").
282  arg(locale.monthName(month)).arg(year);
283  program->SetTitle(title, date);
284  m_titleData.push_back(program);
285  }
286  if (m_reverseSort)
287  {
288  std::stable_sort(m_titleData.begin(), m_titleData.end(),
290  }
291  else
292  {
293  std::stable_sort(m_titleData.begin(), m_titleData.end(),
295  }
296  return true;
297 }
298 
300 {
302 }
303 
305 {
307 }
308 
310  ProgramList *progData, bool isShows)
311 {
312  bnList->Reset();
313  for (auto *pg : *progData)
314  {
315  auto *item = new MythUIButtonListItem(bnList, "",
316  QVariant::fromValue(pg));
317  InfoMap infoMap;
318  pg->ToMap(infoMap,true);
319  QString state;
320  if (isShows)
321  {
322  QString partTitle;
323  if (m_titleGroup)
324  partTitle = infoMap["subtitle"];
325  else
326  partTitle = infoMap["titlesubtitle"];
327  infoMap["parttitle"] = partTitle;
328  state = RecStatus::toUIState(pg->GetRecordingStatus());
329  if ((state == "warning"))
330  state = "disabled";
331  }
332  else
333  infoMap["buttontext"] = infoMap["title"];
334 
335  item->SetTextFromMap(infoMap, state);
336  }
337 }
338 
340 {
341  if (m_help1Text)
342  m_help1Text->Reset();
343  if (m_help2Text)
344  m_help2Text->Reset();
345 
346  if (!m_showData.empty())
347  {
348  InfoMap infoMap;
349  m_showData[m_showList->GetCurrentPos()]->ToMap(infoMap,true);
350  SetTextFromMap(infoMap);
351  m_infoMap = infoMap;
352  }
353  else
354  {
356 
357  if (m_titleGroup)
358  {
359  m_titleList->SetLCDTitles(tr("Programs"), "title");
360  m_showList->SetLCDTitles(tr("Episodes"), "startdate|parttitle");
361  if (m_help1Text)
362  m_help1Text->SetText(tr("Select a program..."));
363  if (m_help2Text)
364  {
365  m_help2Text->SetText(tr(
366  "Select the title of the program you wish to find. "
367  "When finished return with the left arrow key. "
368  "To search by date press 1."));
369  }
370  if (m_curviewText)
371  {
372  if (m_reverseSort)
373  m_curviewText->SetText(tr("Reverse Title","Sort sequence"));
374  else
375  m_curviewText->SetText(tr("Title","Sort sequence"));
376  }
377  }
378  else
379  {
380  m_titleList->SetLCDTitles(tr("Dates"), "title");
381  m_showList->SetLCDTitles(tr("Programs"), "startdate|parttitle");
382  if (m_help1Text)
383  m_help1Text->SetText(tr("Select a month ..."));
384  if (m_help2Text)
385  {
386  m_help2Text->SetText(tr(
387  "Select a month to search. "
388  "When finished return with the left arrow key. "
389  "To search by title press 2."));
390  }
391  if (m_curviewText)
392  {
393  if (m_reverseSort)
394  m_curviewText->SetText(tr("Reverse Time","Sort sequence"));
395  else
396  m_curviewText->SetText(tr("Time","Sort sequence"));
397  }
398  }
399  }
400 }
401 
403 {
404  m_showData.clear();
405  m_showList->Reset();
406  updateInfo();
407 }
408 
410 {
411  m_loadShows = true;
413 }
414 
416 {
417  MSqlBindings bindings;
418  QString sql = " AND oldrecorded.title = :TITLE " + m_where;
419  uint selected = m_titleList->GetCurrentPos();
420  if (selected < m_titleData.size())
421  bindings[":TITLE"] = m_titleData[selected]->GetTitle();
422  else
423  bindings[":TITLE"] = "";
424  if (!m_title.isEmpty())
425  bindings[":MTITLE"] = m_title;
426  m_showData.clear();
427  LoadFromOldRecorded(m_showData, sql, bindings);
428 }
429 
431 {
432  MSqlBindings bindings;
433  int selected = m_titleList->GetCurrentPos();
434  QString sortTitle = m_titleData[selected]->GetSortTitle();
435  QStringList dateParts = sortTitle.split('/');
436  if (dateParts.size() != 2)
437  {
438  LOG(VB_GENERAL, LOG_ERR, LOC +
439  QString("Invalid sort Date: %1").arg(sortTitle));
440  return;
441  }
442  QString sortorder;
443  if (m_reverseSort)
444  sortorder = "DESC";
445  QString sql;
446  if (dateParts[0] == "0000")
447  sql = "AND TIMESTAMPDIFF(DAY, starttime, NOW()) < 14 ";
448  else
449  {
450  sql =
451  " AND YEAR(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :YEAR "
452  " AND MONTH(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :MONTH ";
453  bindings[":YEAR"] = dateParts[0];
454  bindings[":MONTH"] = dateParts[1];
455  }
456  sql = sql + m_where + QString(" ORDER BY starttime %1 ").arg(sortorder);
457  if (!m_title.isEmpty())
458  bindings[":MTITLE"] = m_title;
459  m_showData.clear();
460  LoadFromOldRecorded(m_showData, sql, bindings);
461 }
462 
464 {
465  if (!m_allowEvents)
466  return true;
467 
469  {
470  m_allowEvents = true;
471  return true;
472  }
473 
474  m_allowEvents = false;
475 
476  QStringList actions;
477  bool handled = GetMythMainWindow()->TranslateKeyPress(
478  "TV Frontend", e, actions);
479 
480  bool needUpdate = false;
481  for (uint i = 0; i < uint(actions.size()) && !handled; ++i)
482  {
483  QString action = actions[i];
484  handled = true;
485 
486  if (action == "CUSTOMEDIT")
487  EditCustom();
488  else if (action == "EDIT")
489  EditScheduled();
490  else if (action == "DELETE")
492  else if (action == "DETAILS" || action == "INFO")
493  ShowDetails();
494  else if (action == "GUIDE")
495  ShowGuide();
496  else if (action == "UPCOMING")
497  ShowUpcoming();
498  else if (action == "1")
499  {
500  if (m_titleGroup)
501  {
502  m_titleGroup = false;
503  m_reverseSort = true;
504  }
505  else
506  {
508  }
509  needUpdate = true;
510  }
511  else if (action == "2")
512  {
513  if (!m_titleGroup)
514  {
515  m_titleGroup = true;
516  m_reverseSort = false;
517  }
518  else
519  {
521  }
522  needUpdate = true;
523  }
524  else
525  {
526  handled = false;
527  }
528  }
529 
530  if (!handled && MythScreenType::keyPressEvent(e))
531  handled = true;
532 
533  if (needUpdate)
534  {
535  m_loadShows = false;
537  }
538 
539  m_allowEvents = true;
540 
541  return handled;
542 }
543 
545 {
546  auto *sortMenu = new MythMenu(tr("Sort Options"), this, "sortmenu");
547  sortMenu->AddItem(tr("Reverse Sort Order"));
548  sortMenu->AddItem(tr("Sort By Title"));
549  sortMenu->AddItem(tr("Sort By Time"));
550 
551  auto *menu = new MythMenu(tr("List Options"), this, "menu");
552 
553  menu->AddItem(tr("Sort"), nullptr, sortMenu);
554 
556  if (pi)
557  {
558  menu->AddItem(tr("Edit Schedule"), SLOT(EditScheduled()));
559  menu->AddItem(tr("Custom Edit"), SLOT(EditCustom()));
560  menu->AddItem(tr("Program Details"), SLOT(ShowDetails()));
561  menu->AddItem(tr("Upcoming"), SLOT(ShowUpcoming()));
562  menu->AddItem(tr("Channel Search"), SLOT(ShowChannelSearch()));
563  }
564  menu->AddItem(tr("Program Guide"), SLOT(ShowGuide()));
565  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
566  auto *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
567 
568  if (!menuPopup->Create())
569  {
570  delete menuPopup;
571  return;
572  }
573 
574  popupStack->AddScreen(menuPopup);
575 }
576 
578 {
579  auto *menu = new MythMenu(tr("Recording Options"), this, "menu");
580 
582  if (pi)
583  {
584  if (pi->IsDuplicate())
585  menu->AddItem(tr("Allow this episode to re-record"), SLOT(AllowRecord()));
586  else
587  menu->AddItem(tr("Never record this episode"), SLOT(PreventRecord()));
588  menu->AddItem(tr("Remove this episode from the list"),
589  SLOT(ShowDeleteOldEpisodeMenu()));
590  menu->AddItem(tr("Remove all episodes for this title"),
591  SLOT(ShowDeleteOldSeriesMenu()));
592  }
593  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
594  auto *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
595 
596  if (!menuPopup->Create())
597  {
598  delete menuPopup;
599  return;
600  }
601 
602  popupStack->AddScreen(menuPopup);
603 }
604 
605 void PrevRecordedList::customEvent(QEvent *event)
606 {
607  bool needUpdate = false;
608 
609  if (event->type() == DialogCompletionEvent::kEventType)
610  {
611  auto *dce = (DialogCompletionEvent*)(event);
612 
613  QString resultid = dce->GetId();
614  QString resulttext = dce->GetResultText();
615  int buttonnum = dce->GetResult();
616 
617  if (resultid == "sortmenu")
618  {
619  switch (buttonnum)
620  {
621  case 0:
623  needUpdate = true;
624  break;
625  case 1:
626  m_titleGroup = true;
627  m_reverseSort = false;
628  needUpdate = true;
629  break;
630  case 2:
631  m_titleGroup = false;
632  m_reverseSort = true;
633  needUpdate = true;
634  break;
635  }
636  }
637  else if (resultid == "deleterule")
638  {
639  auto *record = dce->GetData().value<RecordingRule *>();
640  if (record && buttonnum > 0 && !record->Delete())
641  {
642  LOG(VB_GENERAL, LOG_ERR, LOC +
643  "Failed to delete recording rule");
644  }
645  delete record;
646  }
647  else
648  {
650  }
651  }
652  else if (event->type() == ScreenLoadCompletionEvent::kEventType)
653  {
654  auto *slce = (ScreenLoadCompletionEvent*)(event);
655  QString id = slce->GetId();
656 
657  if (id == objectName())
658  {
659  // CloseBusyPopup(); // opened by LoadInBackground()
660  if (m_loadShows)
661  {
662  UpdateShowList();
663  CloseBusyPopup(); // opened by LoadInBackground()
664  }
665  else
666  {
667  UpdateTitleList();
668  m_showData.clear();
669  m_showList->Reset();
670  updateInfo();
671  CloseBusyPopup(); // opened by LoadInBackground()
673  }
674  }
675  }
676 
677  if (needUpdate)
678  {
679  m_loadShows = false;
681  }
682 }
683 
685 {
687  if (pi)
688  {
689  int pos = m_showList->GetCurrentPos();
690  RecordingInfo ri(*pi);
691  ri.ForgetHistory();
693  updateInfo();
695  }
696 }
697 
699 {
701  if (pi)
702  {
703  int pos = m_showList->GetCurrentPos();
704  RecordingInfo ri(*pi);
705  ri.SetDupHistory();
707  updateInfo();
709  }
710 }
711 
712 
714 {
715  int pos = m_showList->GetCurrentPos();
716  if (pos >= 0 && pos < (int) m_showData.size())
717  return m_showData[pos];
718  return nullptr;
719 }
720 
722 {
724 
725  if (!pi)
726  return;
727 
728  QString message = tr("Delete this episode of '%1' from the previously recorded history?").arg(pi->GetTitle());
729 
730  ShowOkPopup(message, this, SLOT(DeleteOldEpisode(bool)), true);
731 }
732 
734 {
736  if (!ok || !pi)
737  return;
738 
739  MSqlQuery query(MSqlQuery::InitCon());
740  query.prepare(
741  "DELETE FROM oldrecorded "
742  "WHERE chanid = :CHANID AND "
743  " starttime = :STARTTIME");
744  query.bindValue(":CHANID", pi->GetChanID());
745  query.bindValue(":STARTTIME", pi->GetScheduledStartTime());
746 
747  if (!query.exec())
748  MythDB::DBError("ProgLister::DeleteOldEpisode", query);
749 
750  ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode");
751 
752  // Delete the current item from both m_showData and m_showList.
753  auto it = m_showData.begin() + m_showList->GetCurrentPos();
754  m_showData.erase(it);
756  m_showList->RemoveItem(item);
757 }
758 
760 {
762 
763  if (!pi)
764  return;
765 
766  QString message = tr("Delete all episodes of '%1' from the previously recorded history?").arg(pi->GetTitle());
767 
768  ShowOkPopup(message, this, SLOT(DeleteOldSeries(bool)), true);
769 }
770 
772 {
774  if (!ok || !pi)
775  return;
776  QString title = pi->GetTitle();
777 
778  MSqlQuery query(MSqlQuery::InitCon());
779  query.prepare("DELETE FROM oldrecorded "
780  "WHERE title = :TITLE AND future = 0");
781  query.bindValue(":TITLE", title);
782  if (!query.exec())
783  MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query);
784 
785  // Set the programid to the special value of "**any**" which the
786  // scheduler recognizes to mean the entire series was deleted.
787  RecordingInfo tempri(*pi);
788  tempri.SetProgramID("**any**");
789  ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries");
790 
791  // Delete the matching items from both m_showData and m_showList.
792  int pos = 0;
793  auto it = m_showData.begin();
794  while (pos < (int)m_showData.size())
795  {
796  if ((*it)->GetTitle() == title)
797  {
798  LOG(VB_GENERAL, LOG_INFO, QString("Deleting %1 at pos %2")
799  .arg(title).arg(pos));
800  it = m_showData.erase(it);
802  m_showList->RemoveItem(item);
803  }
804  else
805  {
806  ++pos;
807  ++it;
808  }
809  }
810 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
iterator erase(iterator it)
ProgramList m_titleData
Definition: prevreclist.h:69
bool LoadTitles(void)
bool LoadDates(void)
ProgramInfo * GetCurrentProgram(void) const override
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
MythLocale * GetLocale(void) const
void push_back(T info)
QLocale ToQLocale() const
Definition: mythlocale.h:30
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
~PrevRecordedList() override
Definition: prevreclist.cpp:87
void LosingFocus()
MythConfirmationDialog * ShowOkPopup(const QString &message, QObject *parent, const char *slot, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
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)
void removeListener(QObject *listener)
Remove a listener to the observable.
static bool comp_sortdate_lt(const ProgramInfo *a, const ProgramInfo *b)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
void LoadShowsByTitle(void)
Basic menu dialog, message and a list of options.
PrevRecordedList(MythScreenStack *parent, uint recid=0, QString title=QString())
Definition: prevreclist.cpp:57
void showListLoseFocus(void)
QString GetTitle(void) const
Definition: programinfo.h:355
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:135
static bool comp_sortdate_lt_rev(const ProgramInfo *a, const ProgramInfo *b)
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
static const int fTitleGroup
Definition: prevreclist.cpp:53
void ShowMenu(void) override
MythScreenStack * GetStack(const QString &stackname)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
size_t size(void) const
virtual void ShowDetails(void) const
Show the Program Details screen.
InfoMap m_infoMap
Definition: prevreclist.h:80
void addListener(QObject *listener)
Add a listener to the observable.
MythUIButtonListItem * GetItemAt(int pos) const
void AllowRecord(void)
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
void SetDupHistory(void)
Set the duplicate flag in oldrecorded.
static MythThemedMenu * menu
Event that can be dispatched from a MythScreenType when it has completed loading.
bool Create(void) override
iterator begin(void)
void RemoveItem(MythUIButtonListItem *item)
void BuildFocusList(void)
static bool comp_sorttitle_lt(const ProgramInfo *a, const ProgramInfo *b)
static Type kEventType
Definition: mythdialogbox.h:57
static bool comp_sorttitle_lt_rev(const ProgramInfo *a, const ProgramInfo *b)
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:384
QVariant value(int i) const
Definition: mythdbcon.h:198
Holds information on recordings and videos.
Definition: programinfo.h:67
void LoadInBackground(const QString &message="")
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
void TakingFocus()
virtual void ShowGuide(void) const
Show the program guide.
void clear(void)
void UpdateList(MythUIButtonList *bnList, ProgramList *progData, bool isShows)
bool empty(void) const
void itemSelected(MythUIButtonListItem *item)
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
MythUIButtonList * m_titleList
Definition: prevreclist.h:70
MythUIText * m_help2Text
Definition: prevreclist.h:78
static void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
void updateInfo(void)
void DeleteOldEpisode(bool ok)
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:83
virtual void SetTextFromMap(const InfoMap &infoMap)
void DeleteOldSeries(bool ok)
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
unsigned int uint
Definition: compat.h:140
void PreventRecord(void)
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
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
virtual void EditCustom(void)
Creates a dialog for creating a custom recording rule.
static const int fDefault
Definition: prevreclist.cpp:55
void UpdateShowList(void)
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.
MythMainWindow * GetMythMainWindow(void)
virtual void ShowChannelSearch(void) const
Show the channel search.
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
static const int fReverseSort
Definition: prevreclist.cpp:54
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
int GetNumSetting(const QString &key, int defaultval=0)
MythUIText * m_curviewText
Definition: prevreclist.h:76
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
void ShowDeleteOldEpisodeMenu(void)
MythUIText * m_help1Text
Definition: prevreclist.h:77
void CloseBusyPopup(void)
void SetLCDTitles(const QString &title, const QString &columnList="")
QString GetSortTitle(void) const
Definition: programinfo.h:356
virtual void EditScheduled(void)
Creates a dialog for editing the recording schedule.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:366
static QString toUIState(Type recstatus)
Definition: recStatus.cpp:4
iterator end(void)
void ShowDeleteOldSeriesMenu(void)
void SetProgramID(const QString &id)
Definition: programinfo.h:520
void LoadShowsByDate(void)
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:398
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
void customEvent(QEvent *event) override
#define LOC
Definition: prevreclist.cpp:50
void SetItemCurrent(MythUIButtonListItem *item)
bool SetFocusWidget(MythUIType *widget=nullptr)
ProgramList m_showData
Definition: prevreclist.h:72
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
int GetCurrentPos() const
MythUIButtonList * m_showList
Definition: prevreclist.h:73
void UpdateTitleList(void)
void ShowItemMenu(void)
int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity)
virtual void ResetMap(const InfoMap &infoMap)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
void showListTakeFocus(void)
MythUIButtonListItem * GetItemCurrent() const
bool IsDuplicate(void) const
Definition: programinfo.h:481
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:41