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 <QString>
30 #include <QDateTime>
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  const QString &title) :
59  ScheduleCommon(parent,"PrevRecordedList"),
60  m_recid(recid),
61  m_title(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  }
168  new ScreenLoadCompletionEvent(objectName());
169  QCoreApplication::postEvent(this, slce);
170 }
171 
172 static bool comp_sorttitle_lt(
173  const ProgramInfo *a, const ProgramInfo *b)
174 {
175  QString a_st = a->GetSortTitle();
176  QString b_st = b->GetSortTitle();
177  return naturalCompare(a_st,b_st) < 0;
178 }
179 
181  const ProgramInfo *a, const ProgramInfo *b)
182 {
183  QString a_st = a->GetSortTitle();
184  QString b_st = b->GetSortTitle();
185  return naturalCompare(b_st, a_st) < 0;
186 }
187 
188 static bool comp_sortdate_lt(
189  const ProgramInfo *a, const ProgramInfo *b)
190 {
191  return a->GetRecordingStartTime() < b->GetRecordingStartTime();
192 }
193 
195  const ProgramInfo *a, const ProgramInfo *b)
196 {
197  return b->GetRecordingStartTime() < a->GetRecordingStartTime();
198 }
199 
200 // Load a list of titles without subtitle or other info.
201 // each title can represent multiple recordings.
203 {
204  QString querystr = "SELECT DISTINCT title FROM oldrecorded "
205  "WHERE oldrecorded.future = 0 " + m_where;
206 
207  m_titleData.clear();
208 
209  MSqlQuery query(MSqlQuery::InitCon());
210  query.prepare(querystr);
211 
212  if (!m_title.isEmpty())
213  query.bindValue(":MTITLE", m_title);
214 
215  if (!query.exec())
216  {
217  MythDB::DBError("PrevRecordedList::LoadTitles", query);
218  return false;
219  }
220 
221  while (query.next())
222  {
223  QString title(query.value(0).toString());
224  ProgramInfo *program = new ProgramInfo();
225  program->SetTitle(title);
226  m_titleData.push_back(program);
227  }
228  if (m_reverseSort)
229  std::stable_sort(m_titleData.begin(), m_titleData.end(),
231  else
232  std::stable_sort(m_titleData.begin(), m_titleData.end(),
234  return true;
235 }
236 
238 {
239  QString querystr = "SELECT DISTINCT "
240  "YEAR(CONVERT_TZ(starttime,'UTC','SYSTEM')), "
241  "MONTH(CONVERT_TZ(starttime,'UTC','SYSTEM')) "
242  "FROM oldrecorded "
243  "WHERE oldrecorded.future = 0 " + m_where;
244 
245  m_titleData.clear();
246 
247  MSqlQuery query(MSqlQuery::InitCon());
248  query.prepare(querystr);
249 
250  if (!m_title.isEmpty())
251  query.bindValue(":MTITLE", m_title);
252 
253  if (!query.exec())
254  {
255  MythDB::DBError("PrevRecordedList::LoadDates", query);
256  return false;
257  }
258 
259  // Create "Last two weeks" entry
260  // It is identified by bogus date of 0000/00
261 
262  ProgramInfo *program = new ProgramInfo();
263  program->SetRecordingStartTime(QDateTime::currentDateTime());
264  program->SetTitle(tr("Last two weeks"), "0000/00");
265  m_titleData.push_back(program);
266 
267  while (query.next())
268  {
269  int year(query.value(0).toInt());
270  int month(query.value(1).toInt());
271  program = new ProgramInfo();
272  QDate startdate(year,month,1);
273  QDateTime starttime(startdate);
274  program->SetRecordingStartTime(starttime);
275  QString date = QString("%1/%2")
276  .arg(year,4,10,QChar('0')).arg(month,2,10,QChar('0'));
277  QLocale locale = gCoreContext->GetLocale()->ToQLocale();
278  QString title = QString("%1 %2").
279  arg(locale.monthName(month)).arg(year);
280  program->SetTitle(title, date);
281  m_titleData.push_back(program);
282  }
283  if (m_reverseSort)
284  std::stable_sort(m_titleData.begin(), m_titleData.end(),
286  else
287  std::stable_sort(m_titleData.begin(), m_titleData.end(),
289  return true;
290 }
291 
293 {
295 }
296 
298 {
300 }
301 
303  ProgramList *progData, bool isShows)
304 {
305  bnList->Reset();
306  for (size_t i = 0; i < progData->size(); ++i)
307  {
308  MythUIButtonListItem *item =
309  new MythUIButtonListItem(bnList, "", QVariant::fromValue((*progData)[i]));
310  InfoMap infoMap;
311  (*progData)[i]->ToMap(infoMap,true);
312  QString state;
313  if (isShows)
314  {
315  QString partTitle;
316  if (m_titleGroup)
317  partTitle = infoMap["subtitle"];
318  else
319  partTitle = infoMap["titlesubtitle"];
320  infoMap["parttitle"] = partTitle;
321  state = RecStatus::toUIState((*progData)[i]->GetRecordingStatus());
322  if ((state == "warning"))
323  state = "disabled";
324  }
325  else
326  infoMap["buttontext"] = infoMap["title"];
327 
328  item->SetTextFromMap(infoMap, state);
329  }
330 }
331 
333 {
334  if (m_help1Text)
335  m_help1Text->Reset();
336  if (m_help2Text)
337  m_help2Text->Reset();
338 
339  if (!m_showData.empty())
340  {
341  InfoMap infoMap;
342  m_showData[m_showList->GetCurrentPos()]->ToMap(infoMap,true);
343  SetTextFromMap(infoMap);
344  m_infoMap = infoMap;
345  }
346  else
347  {
349 
350  if (m_titleGroup)
351  {
352  m_titleList->SetLCDTitles(tr("Programs"), "title");
353  m_showList->SetLCDTitles(tr("Episodes"), "startdate|parttitle");
354  if (m_help1Text)
355  m_help1Text->SetText(tr("Select a program..."));
356  if (m_help2Text)
357  m_help2Text->SetText(tr(
358  "Select the title of the program you wish to find. "
359  "When finished return with the left arrow key. "
360  "To search by date press 1."));
361  if (m_curviewText)
362  {
363  if (m_reverseSort)
364  m_curviewText->SetText(tr("Reverse Title","Sort sequence"));
365  else
366  m_curviewText->SetText(tr("Title","Sort sequence"));
367  }
368  }
369  else
370  {
371  m_titleList->SetLCDTitles(tr("Dates"), "title");
372  m_showList->SetLCDTitles(tr("Programs"), "startdate|parttitle");
373  if (m_help1Text)
374  m_help1Text->SetText(tr("Select a month ..."));
375  if (m_help2Text)
376  m_help2Text->SetText(tr(
377  "Select a month to search. "
378  "When finished return with the left arrow key. "
379  "To search by title press 2."));
380  if (m_curviewText)
381  {
382  if (m_reverseSort)
383  m_curviewText->SetText(tr("Reverse Time","Sort sequence"));
384  else
385  m_curviewText->SetText(tr("Time","Sort sequence"));
386  }
387  }
388  }
389 }
390 
392 {
393  m_showData.clear();
394  m_showList->Reset();
395  updateInfo();
396 }
397 
399 {
400  m_loadShows = true;
402 }
403 
405 {
406  MSqlBindings bindings;
407  QString sql = " AND oldrecorded.title = :TITLE " + m_where;
408  uint selected = m_titleList->GetCurrentPos();
409  if (selected < m_titleData.size())
410  bindings[":TITLE"] = m_titleData[selected]->GetTitle();
411  else
412  bindings[":TITLE"] = "";
413  if (!m_title.isEmpty())
414  bindings[":MTITLE"] = m_title;
415  m_showData.clear();
416  LoadFromOldRecorded(m_showData, sql, bindings);
417 }
418 
420 {
421  MSqlBindings bindings;
422  int selected = m_titleList->GetCurrentPos();
423  QString sortTitle = m_titleData[selected]->GetSortTitle();
424  QStringList dateParts = sortTitle.split('/');
425  if (dateParts.size() != 2)
426  {
427  LOG(VB_GENERAL, LOG_ERR, LOC +
428  QString("Invalid sort Date: %1").arg(sortTitle));
429  return;
430  }
431  QString sortorder;
432  if (m_reverseSort)
433  sortorder = "DESC";
434  QString sql;
435  if (dateParts[0] == "0000")
436  sql = "AND TIMESTAMPDIFF(DAY, starttime, NOW()) < 14 ";
437  else
438  {
439  sql =
440  " AND YEAR(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :YEAR "
441  " AND MONTH(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :MONTH ";
442  bindings[":YEAR"] = dateParts[0];
443  bindings[":MONTH"] = dateParts[1];
444  }
445  sql = sql + m_where + QString(" ORDER BY starttime %1 ").arg(sortorder);
446  if (!m_title.isEmpty())
447  bindings[":MTITLE"] = m_title;
448  m_showData.clear();
449  LoadFromOldRecorded(m_showData, sql, bindings);
450 }
451 
453 {
454  if (!m_allowEvents)
455  return true;
456 
458  {
459  m_allowEvents = true;
460  return true;
461  }
462 
463  m_allowEvents = false;
464 
465  QStringList actions;
466  bool handled = GetMythMainWindow()->TranslateKeyPress(
467  "TV Frontend", e, actions);
468 
469  bool needUpdate = false;
470  for (uint i = 0; i < uint(actions.size()) && !handled; ++i)
471  {
472  QString action = actions[i];
473  handled = true;
474 
475  if (action == "CUSTOMEDIT")
476  EditCustom();
477  else if (action == "EDIT")
478  EditScheduled();
479  else if (action == "DELETE")
481  else if (action == "DETAILS" || action == "INFO")
482  ShowDetails();
483  else if (action == "GUIDE")
484  ShowGuide();
485  else if (action == "UPCOMING")
486  ShowUpcoming();
487  else if (action == "1")
488  {
489  if (m_titleGroup)
490  {
491  m_titleGroup = false;
492  m_reverseSort = true;
493  }
494  else
495  {
497  }
498  needUpdate = true;
499  }
500  else if (action == "2")
501  {
502  if (!m_titleGroup)
503  {
504  m_titleGroup = true;
505  m_reverseSort = false;
506  }
507  else
508  {
510  }
511  needUpdate = true;
512  }
513  else
514  {
515  handled = false;
516  }
517  }
518 
519  if (!handled && MythScreenType::keyPressEvent(e))
520  handled = true;
521 
522  if (needUpdate)
523  {
524  m_loadShows = false;
526  }
527 
528  m_allowEvents = true;
529 
530  return handled;
531 }
532 
534 {
535  MythMenu *sortMenu = new MythMenu(tr("Sort Options"), this, "sortmenu");
536  sortMenu->AddItem(tr("Reverse Sort Order"));
537  sortMenu->AddItem(tr("Sort By Title"));
538  sortMenu->AddItem(tr("Sort By Time"));
539 
540  MythMenu *menu = new MythMenu(tr("List Options"), this, "menu");
541 
542  menu->AddItem(tr("Sort"), nullptr, sortMenu);
543 
545  if (pi)
546  {
547  menu->AddItem(tr("Edit Schedule"), SLOT(EditScheduled()));
548  menu->AddItem(tr("Custom Edit"), SLOT(EditCustom()));
549  menu->AddItem(tr("Program Details"), SLOT(ShowDetails()));
550  menu->AddItem(tr("Upcoming"), SLOT(ShowUpcoming()));
551  menu->AddItem(tr("Channel Search"), SLOT(ShowChannelSearch()));
552  }
553  menu->AddItem(tr("Program Guide"), SLOT(ShowGuide()));
554  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
555  MythDialogBox *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
556 
557  if (!menuPopup->Create())
558  {
559  delete menuPopup;
560  return;
561  }
562 
563  popupStack->AddScreen(menuPopup);
564 }
565 
567 {
568  MythMenu *menu = new MythMenu(tr("Recording Options"), this, "menu");
569 
571  if (pi)
572  {
573  if (pi->IsDuplicate())
574  menu->AddItem(tr("Allow this episode to re-record"), SLOT(AllowRecord()));
575  else
576  menu->AddItem(tr("Never record this episode"), SLOT(PreventRecord()));
577  menu->AddItem(tr("Remove this episode from the list"),
578  SLOT(ShowDeleteOldEpisodeMenu()));
579  menu->AddItem(tr("Remove all episodes for this title"),
580  SLOT(ShowDeleteOldSeriesMenu()));
581  }
582  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
583  MythDialogBox *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
584 
585  if (!menuPopup->Create())
586  {
587  delete menuPopup;
588  return;
589  }
590 
591  popupStack->AddScreen(menuPopup);
592 }
593 
594 void PrevRecordedList::customEvent(QEvent *event)
595 {
596  bool needUpdate = false;
597 
598  if (event->type() == DialogCompletionEvent::kEventType)
599  {
601 
602  QString resultid = dce->GetId();
603  QString resulttext = dce->GetResultText();
604  int buttonnum = dce->GetResult();
605 
606  if (resultid == "sortmenu")
607  {
608  switch (buttonnum)
609  {
610  case 0:
612  needUpdate = true;
613  break;
614  case 1:
615  m_titleGroup = true;
616  m_reverseSort = false;
617  needUpdate = true;
618  break;
619  case 2:
620  m_titleGroup = false;
621  m_reverseSort = true;
622  needUpdate = true;
623  break;
624  }
625  }
626  else if (resultid == "deleterule")
627  {
628  RecordingRule *record =
629  dce->GetData().value<RecordingRule *>();
630  if (record && buttonnum > 0 && !record->Delete())
631  {
632  LOG(VB_GENERAL, LOG_ERR, LOC +
633  "Failed to delete recording rule");
634  }
635  delete record;
636  }
637  else
638  {
640  }
641  }
642  else if (event->type() == ScreenLoadCompletionEvent::kEventType)
643  {
645  QString id = slce->GetId();
646 
647  if (id == objectName())
648  {
649  // CloseBusyPopup(); // opened by LoadInBackground()
650  if (m_loadShows)
651  {
652  UpdateShowList();
653  CloseBusyPopup(); // opened by LoadInBackground()
654  }
655  else
656  {
657  UpdateTitleList();
658  m_showData.clear();
659  m_showList->Reset();
660  updateInfo();
661  CloseBusyPopup(); // opened by LoadInBackground()
663  }
664  }
665  }
666 
667  if (needUpdate)
668  {
669  m_loadShows = false;
671  }
672 }
673 
675 {
677  if (pi)
678  {
679  int pos = m_showList->GetCurrentPos();
680  RecordingInfo ri(*pi);
681  ri.ForgetHistory();
683  updateInfo();
685  }
686 }
687 
689 {
691  if (pi)
692  {
693  int pos = m_showList->GetCurrentPos();
694  RecordingInfo ri(*pi);
695  ri.SetDupHistory();
697  updateInfo();
699  }
700 }
701 
702 
704 {
705  int pos = m_showList->GetCurrentPos();
706  if (pos >= 0 && pos < (int) m_showData.size())
707  return m_showData[pos];
708  return nullptr;
709 }
710 
712 {
714 
715  if (!pi)
716  return;
717 
718  QString message = tr("Delete this episode of '%1' from the previously recorded history?").arg(pi->GetTitle());
719 
720  ShowOkPopup(message, this, SLOT(DeleteOldEpisode(bool)), true);
721 }
722 
724 {
726  if (!ok || !pi)
727  return;
728 
729  MSqlQuery query(MSqlQuery::InitCon());
730  query.prepare(
731  "DELETE FROM oldrecorded "
732  "WHERE chanid = :CHANID AND "
733  " starttime = :STARTTIME");
734  query.bindValue(":CHANID", pi->GetChanID());
735  query.bindValue(":STARTTIME", pi->GetScheduledStartTime());
736 
737  if (!query.exec())
738  MythDB::DBError("ProgLister::DeleteOldEpisode", query);
739 
740  ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode");
741 
742  // Delete the current item from both m_showData and m_showList.
745  m_showData.erase(it);
747  m_showList->RemoveItem(item);
748 }
749 
751 {
753 
754  if (!pi)
755  return;
756 
757  QString message = tr("Delete all episodes of '%1' from the previously recorded history?").arg(pi->GetTitle());
758 
759  ShowOkPopup(message, this, SLOT(DeleteOldSeries(bool)), true);
760 }
761 
763 {
765  if (!ok || !pi)
766  return;
767  QString title = pi->GetTitle();
768 
769  MSqlQuery query(MSqlQuery::InitCon());
770  query.prepare("DELETE FROM oldrecorded "
771  "WHERE title = :TITLE AND future = 0");
772  query.bindValue(":TITLE", title);
773  if (!query.exec())
774  MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query);
775 
776  // Set the programid to the special value of "**any**" which the
777  // scheduler recognizes to mean the entire series was deleted.
778  RecordingInfo tempri(*pi);
779  tempri.SetProgramID("**any**");
780  ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries");
781 
782  // Delete the matching items from both m_showData and m_showList.
783  int pos = 0;
785  while (pos < (int)m_showData.size())
786  {
787  if ((*it)->GetTitle() == title)
788  {
789  LOG(VB_GENERAL, LOG_INFO, QString("Deleting %1 at pos %2")
790  .arg(title).arg(pos));
791  it = m_showData.erase(it);
793  m_showList->RemoveItem(item);
794  }
795  else
796  {
797  ++pos;
798  ++it;
799  }
800  }
801 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
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:863
MythLocale * GetLocale(void) const
void push_back(T info)
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
void LosingFocus()
bool Delete(bool sendSig=true)
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.
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.
void showListLoseFocus(void)
QString GetTitle(void) const
Definition: programinfo.h:353
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:136
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)
unsigned int uint
Definition: compat.h:140
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.
const QLocale ToQLocale() const
Definition: mythlocale.h:30
void SetDupHistory(void)
Set the duplicate flag in oldrecorded.
static MythThemedMenu * menu
static QString toUIState(Type)
Definition: recStatus.cpp:4
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:50
static bool comp_sorttitle_lt_rev(const ProgramInfo *a, const ProgramInfo *b)
unsigned char b
Definition: ParseText.cpp:329
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:382
QVariant value(int i) const
Definition: mythdbcon.h:198
Holds information on recordings and videos.
Definition: programinfo.h:66
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
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.
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
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:84
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
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
void PreventRecord(void)
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:32
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 customEvent(QEvent *) override
void UpdateShowList(void)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void AddItem(const QString &title, QVariant data=0, MythMenu *subMenu=nullptr, bool selected=false, bool checked=false)
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...
void SetTitle(const QString &t, const QString &st=nullptr)
static const int fReverseSort
Definition: prevreclist.cpp:54
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:807
bool keyPressEvent(QKeyEvent *) override
Key event handler.
void ShowDeleteOldEpisodeMenu(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
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:354
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:364
iterator end(void)
void ShowDeleteOldSeriesMenu(void)
void SetProgramID(const QString &id)
Definition: programinfo.h:518
void LoadShowsByDate(void)
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
void SetRecordingStartTime(const QDateTime &dt)
Definition: programinfo.h:510
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:396
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
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
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:37
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
void showListTakeFocus(void)
PrevRecordedList(MythScreenStack *parent, uint recid=0, const QString &title=QString())
Definition: prevreclist.cpp:57
MythUIButtonListItem * GetItemCurrent() const
void LoadInBackground(QString message="")
bool Create(void) override
bool IsDuplicate(void) const
Definition: programinfo.h:479