MythTV  master
proglist.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <algorithm>
3 #include <deque> // for _Deque_iterator, operator-, etc
4 #include <functional>
5 #include <iterator> // for reverse_iterator
6 #include <utility>
7 
8 // Qt
9 #include <QCoreApplication>
10 #include <QLocale>
11 
12 // MythTV
14 #include "libmythbase/mythdate.h"
15 #include "libmythbase/mythdb.h"
16 #include "libmythbase/stringutil.h"
17 #include "libmythtv/channelinfo.h"
18 #include "libmythtv/channelutil.h"
22 #include "libmythtv/tv_actions.h" // for ACTION_CHANNELSEARCH
26 #include "libmythui/mythuitext.h"
27 
28 // MythFrontend
29 #include "proglist.h"
30 
31 #define LOC QString("ProgLister: ")
32 #define LOC_WARN QString("ProgLister, Warning: ")
33 #define LOC_ERR QString("ProgLister, Error: ")
34 
36  QString view, QString extraArg,
37  QDateTime selectedTime) :
38  ScheduleCommon(parent, "ProgLister"),
39  m_type(pltype),
40  m_extraArg(std::move(extraArg)),
41  m_startTime(MythDate::current()),
42  m_searchTime(m_startTime),
43  m_selectedTime(std::move(selectedTime)),
44  m_channelOrdering(gCoreContext->GetSetting("ChannelOrdering", "channum")),
45  m_view(std::move(view))
46 {
47  if (pltype == plMovies)
48  {
50  query.prepare("SELECT COUNT(*) FROM program WHERE stars > 0");
51 
52  if (query.exec() && query.next())
53  {
54  if (query.value(0).toInt() == 0) // No ratings in database
55  {
56  m_curView = 0; // Show All
57  m_allowViewDialog = false;
58  }
59  }
60  }
61 
62  switch (pltype)
63  {
67  case plPowerSearch:
68  case plSQLSearch:
70  default: m_searchType = kNoSearch; break;
71  }
72 }
73 
74 // previously recorded ctor
76  MythScreenStack *parent, uint recid, QString title) :
77  ScheduleCommon(parent, "PreviousList"),
78  m_type(plPreviouslyRecorded),
79  m_recid(recid),
80  m_title(std::move(title)),
81  m_startTime(MythDate::current()),
82  m_searchTime(m_startTime),
83  m_channelOrdering(gCoreContext->GetSetting("ChannelOrdering", "channum")),
84  m_view("reverse time"),
85  m_reverseSort(true)
86 {
87 }
88 
90 {
91  m_itemList.clear();
94 }
95 
97 {
98  if (!LoadWindowFromXML("schedule-ui.xml", "programlist", this))
99  return false;
100 
101  bool err = false;
102  UIUtilW::Assign(this, m_curviewText, "curview", &err);
103  UIUtilE::Assign(this, m_progList, "proglist", &err);
104  UIUtilW::Assign(this, m_schedText, "sched", &err);
105  UIUtilW::Assign(this, m_messageText, "msg", &err);
106  UIUtilW::Assign(this, m_positionText, "position", &err);
107 
108  if (err)
109  {
110  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'programlist'");
111  return false;
112  }
113 
116 
119 
122 
124  {
127  }
128  else
129  {
131  this, qOverload<MythUIButtonListItem*>(&ProgLister::EditRecording));
132  }
133 
134  m_progList->SetLCDTitles(tr("Program List"), "title|channel|shortstarttimedate");
135  m_progList->SetSearchFields("titlesubtitle");
136 
137  BuildFocusList();
138 
139  QString value;
140  switch (m_type)
141  {
142  case plTitle: value = tr("Program Listings"); break;
143  case plNewListings: value = tr("New Title Search"); break;
144  case plTitleSearch: value = tr("Title Search"); break;
145  case plKeywordSearch: value = tr("Keyword Search"); break;
146  case plPeopleSearch: value = tr("People Search"); break;
147  case plStoredSearch: value = tr("Stored Search"); break;
148  case plPowerSearch:
149  case plSQLSearch: value = tr("Power Search"); break;
150  case plRecordid: value = tr("Rule Search"); break;
151  case plCategory: value = tr("Category Search"); break;
152  case plChannel: value = tr("Channel Search"); break;
153  case plMovies: value = tr("Movie Search"); break;
154  case plTime: value = tr("Time Search"); break;
155  case plPreviouslyRecorded: value = tr("Previously Recorded"); break;
156  default: value = tr("Unknown Search"); break;
157  }
158 
159  if (m_schedText)
160  m_schedText->SetText(value);
161 
162  gCoreContext->addListener(this);
163 
165 
166  return true;
167 }
168 
170 {
171  if (m_viewList.isEmpty() || m_curView < 0)
173 
174  FillItemList(false, false);
175 
176  auto *slce = new ScreenLoadCompletionEvent(objectName());
177  QCoreApplication::postEvent(this, slce);
178 }
179 
180 bool ProgLister::keyPressEvent(QKeyEvent *e)
181 {
182  if (!m_allowEvents)
183  return true;
184 
186  {
187  m_allowEvents = true;
188  return true;
189  }
190 
191  m_allowEvents = false;
192 
193  QStringList actions;
194  bool handled = GetMythMainWindow()->TranslateKeyPress(
195  "TV Frontend", e, actions);
196 
197  bool needUpdate = false;
198  for (uint i = 0; i < uint(actions.size()) && !handled; ++i)
199  {
200  QString action = actions[i];
201  handled = true;
202 
203  if (action == "PREVVIEW")
205  else if (action == "NEXTVIEW")
207  else if (action == "CUSTOMEDIT")
208  EditCustom();
209  else if (action == "EDIT")
210  EditScheduled();
211  else if (action == "DELETE")
213  else if (action == "UPCOMING" && m_type != plTitle)
214  ShowUpcoming();
215  else if (action == "PREVRECORDED" && m_type != plPreviouslyRecorded)
216  ShowPrevious();
217  else if (action == "DETAILS" || action == "INFO")
218  ShowDetails();
219  else if (action == "GUIDE")
220  ShowGuide();
221  else if (action == ACTION_CHANNELSEARCH && m_type != plChannel)
223  else if (action == "TOGGLERECORD")
224  QuickRecord();
225  else if (action == "1")
226  {
227  if (m_titleSort)
228  {
229  m_titleSort = false;
231  }
232  else
233  {
235  }
236  needUpdate = true;
237  }
238  else if (action == "2")
239  {
240  if (!m_titleSort)
241  {
242  m_titleSort = true;
243  m_reverseSort = false;
244  }
245  else
246  {
248  }
249  needUpdate = true;
250  }
251  else
252  {
253  handled = false;
254  }
255  }
256 
257  if (!handled && MythScreenType::keyPressEvent(e))
258  handled = true;
259 
260  if (needUpdate)
262 
263  m_allowEvents = true;
264 
265  return handled;
266 }
267 
269 {
270  auto *sortMenu = new MythMenu(tr("Sort Options"), this, "sortmenu");
271  sortMenu->AddItem(tr("Reverse Sort Order"));
272  sortMenu->AddItem(tr("Sort By Title"));
273  sortMenu->AddItem(tr("Sort By Time"));
274 
275  auto *menu = new MythMenu(tr("Options"), this, "menu");
276 
278  {
279  menu->AddItem(tr("Choose Search Phrase..."), &ProgLister::ShowChooseViewMenu);
280  }
281 
282  menu->AddItem(tr("Sort"), nullptr, sortMenu);
283 
285  menu->AddItem(tr("Record"), &ProgLister::QuickRecord);
286 
287  menu->AddItem(tr("Edit Schedule"), qOverload<>(&ProgLister::EditScheduled));
288  menu->AddItem(tr("Program Details"), &ProgLister::ShowDetails);
289  menu->AddItem(tr("Program Guide"), &ProgLister::ShowGuide);
290  if (m_type != plChannel)
291  menu->AddItem(tr("Channel Search"), &ProgLister::ShowChannelSearch);
292  if (m_type != plTitle)
293  menu->AddItem(tr("Upcoming"), qOverload<>(&ProgLister::ShowUpcoming));
295  menu->AddItem(tr("Previously Recorded"), qOverload<>(&ProgLister::ShowPrevious));
296  menu->AddItem(tr("Custom Edit"), &ProgLister::EditCustom);
297 
300  {
301  if (pi && pi->GetRecordingRuleID())
302  menu->AddItem(tr("Delete Rule"), &ProgLister::ShowDeleteRuleMenu);
303  }
304  else
305  {
306  menu->AddItem(
307  tr("Delete Episode"), &ProgLister::ShowDeleteOldEpisodeMenu);
308  }
309 
310  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
311  auto *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
312 
313  if (!menuPopup->Create())
314  {
315  delete menuPopup;
316  return;
317  }
318 
319  popupStack->AddScreen(menuPopup);
320 }
321 
323 {
324  if (m_type == plTime && !m_viewList.empty() && !m_viewTextList.empty())
325  {
326  m_searchTime = m_searchTime.addSecs(-3600);
327  m_curView = 0;
332  return;
333  }
334 
335  if (m_viewList.size() <= 1)
336  return;
337 
338  m_curView--;
339  if (m_curView < 0)
340  m_curView = m_viewList.size() - 1;
341 
343 }
344 
346 {
347  if (m_type == plTime && !m_viewList.empty() && !m_viewTextList.empty())
348  {
349  m_searchTime = m_searchTime.addSecs(3600);
350  m_curView = 0;
355 
356  return;
357  }
358 
359  if (m_viewList.size() <= 1)
360  return;
361 
362  m_curView++;
363  if (m_curView >= m_viewList.size())
364  m_curView = 0;
365 
367 }
368 
369 void ProgLister::UpdateKeywordInDB(const QString &text, const QString &oldValue)
370 {
371  int oldview = m_viewList.indexOf(oldValue);
372  int newview = m_viewList.indexOf(text);
373 
374  if (newview >= 0 && newview == oldview)
375  return;
376 
377  if (oldview >= 0)
378  {
379  QString qphrase = m_viewList[oldview];
380 
381  MSqlQuery query(MSqlQuery::InitCon());
382  query.prepare("DELETE FROM keyword "
383  "WHERE phrase = :PHRASE AND searchtype = :TYPE;");
384  query.bindValue(":PHRASE", qphrase);
385  query.bindValue(":TYPE", m_searchType);
386  if (!query.exec())
387  {
389  "ProgLister::updateKeywordInDB -- delete", query);
390  }
391  m_viewList.removeAll(qphrase);
392  m_viewTextList.removeAll(qphrase);
393  }
394 
395  if (newview < 0)
396  {
397  const QString& qphrase = text;
398 
399  MSqlQuery query(MSqlQuery::InitCon());
400  query.prepare("REPLACE INTO keyword (phrase, searchtype)"
401  "VALUES(:PHRASE, :TYPE );");
402  query.bindValue(":PHRASE", qphrase);
403  query.bindValue(":TYPE", m_searchType);
404  if (!query.exec())
405  {
407  "ProgLister::updateKeywordInDB -- replace", query);
408  }
409  m_viewList.push_back(qphrase);
410  m_viewTextList.push_back(qphrase);
411  }
412 }
413 
415 {
416  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
417  MythScreenType *screen = nullptr;
418 
419  switch (m_type)
420  {
421  case plChannel:
422  case plCategory:
423  case plMovies:
424  case plNewListings:
425  case plStoredSearch:
426  {
427  if (m_viewList.empty())
428  return;
429 
430  QString msg;
431  switch (m_type)
432  {
433  case plMovies: msg = tr("Select Rating"); break;
434  case plChannel: msg = tr("Select Channel"); break;
435  case plCategory: msg = tr("Select Category"); break;
436  case plNewListings: msg = tr("Select List"); break;
437  case plStoredSearch: msg = QString("%1\n%2")
438  .arg(tr("Select a search stored from"),
439  tr("Custom Record")); break;
440  default: // silence warning
441  break;
442  }
443 
444  auto *dialog = new MythUISearchDialog(
445  popupStack, msg, m_viewTextList, true, "");
446  if (!dialog)
447  return;
448  connect(dialog, &MythUISearchDialog::haveResult,
450  screen = dialog;
451  break;
452  }
453  case plTitleSearch:
454  case plKeywordSearch:
455  case plPeopleSearch:
456  {
457  auto *dialog = new PhrasePopup(
458  popupStack, this, m_searchType, m_viewTextList,
459  (m_curView >= 0) ? m_viewList[m_curView] : QString());
460  if (!dialog)
461  return;
462  connect(dialog, &PhrasePopup::haveResult,
464  screen = dialog;
465  break;
466  }
467  case plPowerSearch:
468  {
469  auto *dialog = new PowerSearchPopup(
470  popupStack, this, m_searchType, m_viewTextList,
471  (m_curView >= 0) ? m_viewList[m_curView] : QString());
472  if (!dialog)
473  return;
474  connect(dialog, &PowerSearchPopup::haveResult,
476  screen = dialog;
477  break;
478  }
479  case plTime:
480  {
481  QString message = tr("Start search from date and time");
482  int flags = (MythTimeInputDialog::kDay |
485  auto *dialog = new MythTimeInputDialog(popupStack, message, flags);
486  if (!dialog)
487  return;
488  connect(dialog, &MythTimeInputDialog::haveResult,
490  screen = dialog;
491  break;
492  }
493  case plRecordid:
495  case plUnknown:
496  case plTitle:
497  case plSQLSearch:
498  break;
499  }
500 
501  if (!screen)
502  {
503  LOG(VB_GENERAL, LOG_WARNING, LOC + "No menu");
504  return;
505  }
506 
507  if (!screen->Create())
508  {
509  delete screen;
510  return;
511  }
512 
513  popupStack->AddScreen(screen);
514 }
515 
516 void ProgLister::SetViewFromTime(QDateTime searchTime)
517 {
518  if (m_viewList.empty() || m_viewTextList.empty())
519  return;
520 
521  m_searchTime = std::move(searchTime);
522  m_curView = 0;
526 
528 }
529 
530 void ProgLister::SetViewFromList(const QString& item)
531 {
532  m_curView = m_viewTextList.indexOf(item);
533  if (m_curView >= 0)
535 }
536 
538  const QString &qphrase, QString &output, MSqlBindings &bindings)
539 {
540  output.clear();
541 
542  QStringList field = qphrase.split(':');
543  if (field.size() != 6)
544  {
545  LOG(VB_GENERAL, LOG_ERR, LOC + "Power search should have 6 fields," +
546  QString("\n\t\t\tnot %1 (%2)") .arg(field.size()).arg(qphrase));
547  return false;
548  };
549 
550  static const std::array<QString,6> kBindingList
551  {
552  ":POWERTITLE",
553  ":POWERSUB",
554  ":POWERDESC",
555  ":POWERCATTYPE",
556  ":POWERGENRE",
557  ":POWERCALLSIGN",
558  };
559 
560  static const std::array<QString,6> kOutputList
561  {
562  "program.title LIKE :POWERTITLE ",
563  "program.subtitle LIKE :POWERSUB ",
564  "program.description LIKE :POWERDESC ",
565  "program.category_type = :POWERCATTYPE ",
566  "programgenres.genre = :POWERGENRE ",
567  "channel.callsign = :POWERCALLSIGN ",
568  };
569 
570  for (uint i = 0; i < (uint) field.size(); i++)
571  {
572  if (field[i].isEmpty())
573  continue;
574 
575  if (!output.isEmpty())
576  output += "\nAND ";
577 
578  output += kOutputList[i];
579  bindings[kBindingList[i]] =
580  (!kOutputList[i].contains("=")) ?
581  QString('%') + field[i] + QString('%') : field[i];
582  }
583 
584  return output.contains("programgenres");
585 }
586 
588 {
589  int pos = m_progList->GetCurrentPos();
590  if (pos >= 0 && pos < (int) m_itemList.size())
591  return m_itemList[pos];
592  return nullptr;
593 }
594 
596 {
599  else
601 }
602 
604 {
606 
607  if (!pi || !pi->GetRecordingRuleID())
608  return;
609 
610  auto *record = new RecordingRule();
611  if (!record->LoadByProgram(pi))
612  {
613  delete record;
614  return;
615  }
616 
617  QString message = tr("Delete '%1' %2 rule?")
618  .arg(record->m_title, toString(pi->GetRecordingRuleType()));
619 
620  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
621 
622  auto *okPopup = new MythConfirmationDialog(
623  popupStack, message, true);
624 
625  okPopup->SetReturnEvent(this, "deleterule");
626  okPopup->SetData(QVariant::fromValue(record));
627 
628  if (okPopup->Create())
629  popupStack->AddScreen(okPopup);
630  else
631  delete okPopup;
632 }
633 
635 {
637 
638  if (!pi)
639  return;
640 
641  QString message = tr("Delete this episode of '%1'?").arg(pi->GetTitle());
642 
643  ShowOkPopup(message, this, &ProgLister::DeleteOldEpisode, true);
644 }
645 
647 {
649  if (!ok || !pi)
650  return;
651 
652  MSqlQuery query(MSqlQuery::InitCon());
653  query.prepare(
654  "DELETE FROM oldrecorded "
655  "WHERE chanid = :CHANID AND "
656  " starttime = :STARTTIME");
657  query.bindValue(":CHANID", pi->GetChanID());
658  query.bindValue(":STARTTIME", pi->GetScheduledStartTime());
659 
660  if (!query.exec())
661  MythDB::DBError("ProgLister::DeleteOldEpisode", query);
662 
663  ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode");
664  FillItemList(true);
665 }
666 
668 {
670 
671  if (!pi)
672  return;
673 
674  QString message = tr("Delete all episodes of '%1'?").arg(pi->GetTitle());
675 
676  ShowOkPopup(message, this, &ProgLister::DeleteOldSeries, true);
677 }
678 
680 {
682  if (!ok || !pi)
683  return;
684 
685  MSqlQuery query(MSqlQuery::InitCon());
686  query.prepare("DELETE FROM oldrecorded "
687  "WHERE title = :TITLE AND future = 0");
688  query.bindValue(":TITLE", pi->GetTitle());
689  if (!query.exec())
690  MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query);
691 
692  // Set the programid to the special value of "**any**" which the
693  // scheduler recognizes to mean the entire series was deleted.
694  RecordingInfo tempri(*pi);
695  tempri.SetProgramID("**any**");
696  ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries");
697  FillItemList(true);
698 }
699 
701 {
703 
704  if (!pi)
705  return;
706 
707  QString message = pi->toString(ProgramInfo::kTitleSubtitle, " - ");
708 
709  if (!pi->GetDescription().isEmpty())
710  message += "\n\n" + pi->GetDescription();
711 
712  message += "\n\n\n" + tr("NOTE: removing items from this list will not "
713  "delete any recordings.");
714 
715  QString title = tr("Previously Recorded");
716 
717  auto *menu = new MythMenu(title, message, this, "deletemenu");
718  if (pi->IsDuplicate())
719  menu->AddItem(tr("Allow this episode to re-record"));
720  else
721  menu->AddItem(tr("Never record this episode"));
722  menu->AddItem(tr("Remove this episode from the list"));
723  menu->AddItem(tr("Remove all episodes for this title"));
724  menu->AddItem(tr("Cancel"));
725 
727  auto *menuPopup = new MythDialogBox(menu, mainStack, "deletepopup", true);
728 
729  if (menuPopup->Create())
730  mainStack->AddScreen(menuPopup);
731  else
732  delete menuPopup;
733 }
734 
735 void ProgLister::FillViewList(const QString &view)
736 {
737  m_viewList.clear();
738  m_viewTextList.clear();
739 
740  if (m_type == plChannel) // list by channel
741  {
743  0, true, "channum, chanid");
745 
746  for (auto & channel : channels)
747  {
748  QString chantext = channel.GetFormatted(ChannelInfo::kChannelShort);
749 
750  m_viewList.push_back(QString::number(channel.m_chanId));
751  m_viewTextList.push_back(chantext);
752  }
753 
754  if (!view.isEmpty())
755  m_curView = m_viewList.indexOf(view);
756  }
757  else if (m_type == plCategory) // list by category
758  {
759  QDateTime query_starttime = m_startTime.addSecs(50 -
760  m_startTime.time().second());
761  MSqlQuery query(MSqlQuery::InitCon());
762  query.prepare("SELECT g1.genre, g2.genre "
763  "FROM program "
764  "JOIN programgenres g1 ON "
765  " program.chanid = g1.chanid AND "
766  " program.starttime = g1.starttime "
767  "LEFT JOIN programgenres g2 ON "
768  " g1.chanid = g2.chanid AND "
769  " g1.starttime = g2.starttime "
770  "WHERE program.endtime > :PGILSTART "
771  "GROUP BY g1.genre, g2.genre;");
772  query.bindValue(":PGILSTART", query_starttime);
773 
774  m_useGenres = false;
775 
776  if (query.exec())
777  {
778  QString lastGenre1;
779 
780  while (query.next())
781  {
782  m_useGenres = true;
783 
784  QString genre1 = query.value(0).toString();
785  if (genre1.isEmpty())
786  continue;
787 
788  if (genre1 != lastGenre1)
789  {
790  m_viewList.push_back(genre1);
791  m_viewTextList.push_back(genre1);
792  lastGenre1 = genre1;
793  }
794 
795  QString genre2 = query.value(1).toString();
796  if (genre2.isEmpty() || genre2 == genre1)
797  continue;
798 
799  m_viewList.push_back(genre1 + ":/:" + genre2);
800  m_viewTextList.push_back(" " + genre1 + " / " + genre2);
801  }
802  }
803 
804  if (!m_useGenres)
805  {
806  query.prepare("SELECT category "
807  "FROM program "
808  "WHERE program.endtime > :PGILSTART "
809  "GROUP BY category");
810  query.bindValue(":PGILSTART", query_starttime);
811 
812  if (query.exec())
813  {
814  while (query.next())
815  {
816  QString category = query.value(0).toString();
817  if (category.isEmpty())
818  continue;
819  category = query.value(0).toString();
820  m_viewList.push_back(category);
821  m_viewTextList.push_back(category);
822  }
823  }
824  }
825 
826  if (!view.isEmpty())
827  m_curView = m_viewList.indexOf(view);
828  }
829  else if (m_type == plTitleSearch || m_type == plKeywordSearch ||
831  {
832  MSqlQuery query(MSqlQuery::InitCon());
833  query.prepare("SELECT phrase FROM keyword "
834  "WHERE searchtype = :SEARCHTYPE;");
835  query.bindValue(":SEARCHTYPE", m_searchType);
836 
837  if (query.exec())
838  {
839  while (query.next())
840  {
841  /* The keyword.phrase column uses utf8_bin collation, so
842  * Qt uses QString::fromAscii() for toString(). Explicitly
843  * convert the value using QString::fromUtf8() to prevent
844  * corruption. */
845  QString phrase = QString::fromUtf8(query.value(0)
846  .toByteArray().constData());
847  if (phrase.isEmpty())
848  continue;
849  m_viewList.push_back(phrase);
850  m_viewTextList.push_back(phrase);
851  }
852  }
853 
854  if (!view.isEmpty())
855  {
856  m_curView = m_viewList.indexOf(view);
857 
858  if (m_curView < 0)
859  {
860  const QString& qphrase = view;
861 
862  MSqlQuery query2(MSqlQuery::InitCon());
863  query2.prepare("REPLACE INTO keyword (phrase, searchtype)"
864  "VALUES(:VIEW, :SEARCHTYPE );");
865  query2.bindValue(":VIEW", qphrase);
866  query2.bindValue(":SEARCHTYPE", m_searchType);
867  if (!query2.exec())
868  MythDB::DBError("ProgLister::FillViewList -- "
869  "replace keyword", query2);
870 
871  m_viewList.push_back(qphrase);
872  m_viewTextList.push_back(qphrase);
873 
874  m_curView = m_viewList.size() - 1;
875  }
876  }
877  else
878  {
879  m_curView = -1;
880  }
881  }
882  else if (m_type == plTitle)
883  {
884  if (!view.isEmpty())
885  {
886  m_viewList.push_back(view);
887  m_viewTextList.push_back(view);
888  m_curView = 0;
889  }
890  else
891  {
892  m_curView = -1;
893  }
894  }
895  else if (m_type == plNewListings)
896  {
897  m_viewList.push_back("all");
898  m_viewTextList.push_back(tr("All"));
899 
900  m_viewList.push_back("premieres");
901  m_viewTextList.push_back(tr("Premieres"));
902 
903  m_viewList.push_back("movies");
904  m_viewTextList.push_back(tr("Movies"));
905 
906  m_viewList.push_back("series");
907  m_viewTextList.push_back(tr("Series"));
908 
909  m_viewList.push_back("specials");
910  m_viewTextList.push_back(tr("Specials"));
911 
912  if (!view.isEmpty())
913  m_curView = m_viewList.indexOf(view);
914  }
915  else if (m_type == plMovies)
916  {
917  m_viewList.push_back(">= 0.0");
918  m_viewTextList.push_back(tr("All"));
919  m_viewList.push_back("= 0.0");
920  m_viewTextList.push_back(tr("Unrated"));
921  m_viewList.push_back(QString(">= %1").arg((10 - 0.5) / 10.0 - 0.001));
922  m_viewTextList.push_back(tr("%n star(s)", "", 10));
923  for (int i = 9; i > 0; i--)
924  {
925  float stars = (i - 0.5 ) / 10.0 - 0.001;
926  m_viewList.push_back(QString(">= %1").arg(stars));
927  m_viewTextList.push_back(tr("%n star(s) and above", "", i));
928  }
929 
930  if (!view.isEmpty())
931  m_curView = m_viewList.indexOf(view);
932  }
933  else if (m_type == plTime)
934  {
935  m_curView = 0;
938  m_viewTextList.push_back(m_viewList[m_curView]);
939  }
940  else if (m_type == plSQLSearch)
941  {
942  m_curView = 0;
943  m_viewList.push_back(view);
944  m_viewTextList.push_back(tr("Power Recording Rule"));
945  }
946  else if (m_type == plRecordid)
947  {
948  m_curView = 0;
949 
950  MSqlQuery query(MSqlQuery::InitCon());
951  query.prepare("SELECT title FROM record "
952  "WHERE recordid = :RECORDID");
953  query.bindValue(":RECORDID", view);
954 
955  if (query.exec() && query.next())
956  {
957  QString title = query.value(0).toString();
958  m_viewList.push_back(view);
959  m_viewTextList.push_back(title);
960  }
961  }
962  else if (m_type == plStoredSearch) // stored searches
963  {
964  MSqlQuery query(MSqlQuery::InitCon());
965  query.prepare("SELECT rulename FROM customexample "
966  "WHERE search > 0 ORDER BY rulename;");
967 
968  if (query.exec())
969  {
970  while (query.next())
971  {
972  QString rulename = query.value(0).toString();
973  if (rulename.isEmpty() || rulename.trimmed().isEmpty())
974  continue;
975  rulename = query.value(0).toString();
976  m_viewList.push_back(rulename);
977  m_viewTextList.push_back(rulename);
978  }
979  }
980  if (!view.isEmpty())
981  m_curView = m_viewList.indexOf(view);
982  }
983  else if (m_type == plPreviouslyRecorded) // previously recorded
984  {
985  m_viewList.push_back("sort by time");
986  m_viewTextList.push_back(tr("Time"));
987 
988  m_viewList.push_back("reverse time");
989  m_viewTextList.push_back(tr("Reverse Time"));
990 
991  m_viewList.push_back("sort by title");
992  m_viewTextList.push_back(tr("Title"));
993 
994  m_viewList.push_back("reverse title");
995  m_viewTextList.push_back(tr("Reverse Title"));
996 
997  if (!view.isEmpty())
998  m_curView = m_viewList.indexOf(view);
999  }
1000 
1001  if (m_curView >= m_viewList.size())
1002  m_curView = m_viewList.size() - 1;
1003 }
1004 
1005 static bool plTitleSort(const ProgramInfo *a, const ProgramInfo *b)
1006 {
1007  if (a->GetSortTitle() != b->GetSortTitle())
1008  return StringUtil::naturalCompare(a->GetSortTitle(), b->GetSortTitle()) < 0;
1009  if (a->GetSortSubtitle() != b->GetSortSubtitle())
1011 
1012  if (a->GetRecordingStatus() == b->GetRecordingStatus())
1013  return a->GetScheduledStartTime() < b->GetScheduledStartTime();
1014 
1018  return true;
1022  return false;
1023 
1026  return true;
1029  return false;
1030 
1031  return a->GetScheduledStartTime() < b->GetScheduledStartTime();
1032 };
1033 
1034 static bool plPrevTitleSort(const ProgramInfo *a, const ProgramInfo *b)
1035 {
1036  if (a->GetSortTitle() != b->GetSortTitle())
1037  return StringUtil::naturalCompare(a->GetSortTitle(), b->GetSortTitle()) < 0;
1038  if (a->GetSortSubtitle() != b->GetSortSubtitle())
1040 
1041  if (a->GetProgramID() != b->GetProgramID())
1042  return a->GetProgramID() < b->GetProgramID();
1043 
1044  return a->GetScheduledStartTime() < b->GetScheduledStartTime();
1045 };
1046 
1047 static bool plTimeSort(const ProgramInfo *a, const ProgramInfo *b)
1048 {
1050  return (a->GetChanID() < b->GetChanID());
1051 
1052  return (a->GetScheduledStartTime() < b->GetScheduledStartTime());
1053 };
1054 
1055 void ProgLister::FillItemList(bool restorePosition, bool updateDisp)
1056 {
1058  {
1059  if (!m_titleSort)
1060  {
1061  if (!m_reverseSort)
1062  m_curView = 0;
1063  else
1064  m_curView = 1;
1065  }
1066  else
1067  {
1068  if (!m_reverseSort)
1069  m_curView = 2;
1070  else
1071  m_curView = 3;
1072  }
1073  }
1074 
1075  if (m_curView < 0)
1076  return;
1077 
1078  QString where;
1079  QString qphrase = m_viewList[m_curView];
1080 
1081  MSqlBindings bindings;
1082 
1084  bindings[":PGILSTART"] =
1085  m_startTime.addSecs(50 - m_startTime.time().second());
1086 
1087  if (m_type == plTitle) // per title listings
1088  {
1089  where = "WHERE channel.deleted IS NULL "
1090  " AND channel.visible > 0 "
1091  " AND program.endtime > :PGILSTART "
1092  " AND (program.title = :PGILPHRASE0 OR "
1093  " (program.seriesid <> '' AND "
1094  " program.seriesid = :PGILPHRASE1)) ";
1095  bindings[":PGILPHRASE0"] = qphrase;
1096  bindings[":PGILPHRASE1"] = m_extraArg;
1097  }
1098  else if (m_type == plNewListings) // what's new list
1099  {
1100  where = "LEFT JOIN oldprogram ON "
1101  " oldprogram.oldtitle = program.title "
1102  "WHERE channel.deleted IS NULL "
1103  " AND channel.visible > 0 "
1104  " AND program.endtime > :PGILSTART "
1105  " AND oldprogram.oldtitle IS NULL "
1106  " AND program.manualid = 0 ";
1107 
1108  if (qphrase == "premieres")
1109  {
1110  where += " AND ( ";
1111  where += " ( program.originalairdate = DATE(";
1112  where += " CONVERT_TZ(program.starttime, 'Etc/UTC', 'SYSTEM'))";
1113  where += " AND (program.category = 'Special' ";
1114  where += " OR program.programid LIKE 'EP%0001')) ";
1115  where += " OR (program.category_type='movie' ";
1116  where += " AND program.stars > 0.5 ";
1117  where += " AND program.airdate >= YEAR(NOW()) - 2) ";
1118  where += " ) ";
1119  }
1120  else if (qphrase == "movies")
1121  {
1122  where += " AND program.category_type = 'movie' ";
1123  }
1124  else if (qphrase == "series")
1125  {
1126  where += " AND program.category_type = 'series' ";
1127  }
1128  else if (qphrase == "specials")
1129  {
1130  where += " AND program.category_type = 'tvshow' ";
1131  }
1132  else
1133  {
1134  where += " AND (program.category_type <> 'movie' ";
1135  where += " OR program.airdate >= YEAR(NOW()) - 3) ";
1136  }
1137  }
1138  else if (m_type == plTitleSearch) // keyword search
1139  {
1140  where = "WHERE channel.deleted IS NULL "
1141  " AND channel.visible > 0 "
1142  " AND program.endtime > :PGILSTART "
1143  " AND program.title LIKE :PGILLIKEPHRASE0 ";
1144  bindings[":PGILLIKEPHRASE0"] = QString("%") + qphrase + '%';
1145  }
1146  else if (m_type == plKeywordSearch) // keyword search
1147  {
1148  where = "WHERE channel.deleted IS NULL "
1149  " AND channel.visible > 0 "
1150  " AND program.endtime > :PGILSTART "
1151  " AND (program.title LIKE :PGILLIKEPHRASE1 "
1152  " OR program.subtitle LIKE :PGILLIKEPHRASE2 "
1153  " OR program.description LIKE :PGILLIKEPHRASE3 ) ";
1154  bindings[":PGILLIKEPHRASE1"] = QString("%") + qphrase + '%';
1155  bindings[":PGILLIKEPHRASE2"] = QString("%") + qphrase + '%';
1156  bindings[":PGILLIKEPHRASE3"] = QString("%") + qphrase + '%';
1157  }
1158  else if (m_type == plPeopleSearch) // people search
1159  {
1160  where = ", people, credits "
1161  "WHERE channel.deleted IS NULL "
1162  " AND channel.visible > 0 "
1163  " AND program.endtime > :PGILSTART "
1164  " AND people.name LIKE :PGILPHRASE1 "
1165  " AND credits.person = people.person "
1166  " AND program.chanid = credits.chanid "
1167  " AND program.starttime = credits.starttime";
1168  bindings[":PGILPHRASE1"] = qphrase;
1169  }
1170  else if (m_type == plPowerSearch) // complex search
1171  {
1172  QString powerWhere;
1173  MSqlBindings powerBindings;
1174 
1175  bool genreflag = PowerStringToSQL(qphrase, powerWhere, powerBindings);
1176 
1177  if (!powerWhere.isEmpty())
1178  {
1179  if (genreflag)
1180  {
1181  where = QString("LEFT JOIN programgenres ON "
1182  "program.chanid = programgenres.chanid AND "
1183  "program.starttime = programgenres.starttime ");
1184  }
1185 
1186  where += QString("WHERE channel.deleted IS NULL "
1187  " AND channel.visible > 0 "
1188  " AND program.endtime > :PGILSTART "
1189  " AND ( ") + powerWhere + " ) ";
1190  MSqlAddMoreBindings(bindings, powerBindings);
1191  }
1192  }
1193  else if (m_type == plSQLSearch) // complex search
1194  {
1195  qphrase.remove(RecordingInfo::kReLeadingAnd);
1196  where = QString("WHERE channel.deleted iS NULL "
1197  " AND channel.visible > 0 "
1198  " AND program.endtime > :PGILSTART "
1199  " AND ( %1 ) ").arg(qphrase);
1200  if (!m_extraArg.isEmpty())
1201  where = m_extraArg + ' ' + where;
1202  }
1203  else if (m_type == plChannel) // list by channel
1204  {
1205  where = "WHERE channel.deleted IS NULL "
1206  " AND channel.visible > 0 "
1207  " AND program.endtime > :PGILSTART "
1208  " AND channel.chanid = :PGILPHRASE2 ";
1209  bindings[":PGILPHRASE2"] = qphrase;
1210  }
1211  else if (m_type == plCategory) // list by category
1212  {
1213  if (!m_useGenres)
1214  {
1215  where = "WHERE channel.deleted IS NULL "
1216  " AND channel.visible > 0 "
1217  " AND program.endtime > :PGILSTART "
1218  " AND program.category = :PGILPHRASE3 ";
1219  bindings[":PGILPHRASE3"] = qphrase;
1220  }
1221  else if (m_viewList[m_curView].indexOf(":/:") < 0)
1222  {
1223  where = "JOIN programgenres g ON "
1224  " program.chanid = g.chanid AND "
1225  " program.starttime = g.starttime AND "
1226  " genre = :PGILPHRASE4 "
1227  "WHERE channel.deleted IS NULL "
1228  " AND channel.visible > 0 "
1229  " AND program.endtime > :PGILSTART ";
1230  bindings[":PGILPHRASE4"] = qphrase;
1231  }
1232  else
1233  {
1234  where = "JOIN programgenres g1 ON "
1235  " program.chanid = g1.chanid AND "
1236  " program.starttime = g1.starttime AND "
1237  " g1.genre = :GENRE1 "
1238  "JOIN programgenres g2 ON "
1239  " program.chanid = g2.chanid AND "
1240  " program.starttime = g2.starttime AND "
1241  " g2.genre = :GENRE2 "
1242  "WHERE channel.deleted IS NULL "
1243  " AND channel.visible > 0 "
1244  " AND program.endtime > :PGILSTART ";
1245  bindings[":GENRE1"] = m_viewList[m_curView].section(":/:", 0, 0);
1246  bindings[":GENRE2"] = m_viewList[m_curView].section(":/:", 1, 1);
1247  }
1248  }
1249  else if (m_type == plMovies) // list movies
1250  {
1251  where = "WHERE channel.deleted IS NULL "
1252  " AND channel.visible > 0 "
1253  " AND program.endtime > :PGILSTART "
1254  " AND program.category_type = 'movie' "
1255  " AND program.stars " + qphrase + ' ';
1256  }
1257  else if (m_type == plTime) // list by time
1258  {
1259  QDateTime searchTime(m_searchTime);
1260  searchTime.setTime(QTime(searchTime.time().hour(), 0, 0));
1261  bindings[":PGILSEARCHTIME1"] = searchTime;
1262  where = "WHERE channel.deleted IS NULL "
1263  " AND channel.visible > 0 "
1264  " AND program.starttime >= :PGILSEARCHTIME1 ";
1265  if (m_titleSort)
1266  {
1267  where += " AND program.starttime < DATE_ADD(:PGILSEARCHTIME2, "
1268  "INTERVAL '1' HOUR) ";
1269  bindings[":PGILSEARCHTIME2"] = bindings[":PGILSEARCHTIME1"];
1270  }
1271  }
1272  else if (m_type == plRecordid) // list by recordid
1273  {
1274  where = "JOIN recordmatch ON "
1275  " (program.starttime = recordmatch.starttime "
1276  " AND program.chanid = recordmatch.chanid) "
1277  "WHERE channel.deleted IS NULL "
1278  " AND channel.visible > 0 "
1279  " AND program.endtime > :PGILSTART "
1280  " AND recordmatch.recordid = :PGILPHRASE5 ";
1281  bindings[":PGILPHRASE5"] = qphrase;
1282  }
1283  else if (m_type == plStoredSearch) // stored search
1284  {
1285  MSqlQuery query(MSqlQuery::InitCon());
1286  query.prepare("SELECT fromclause, whereclause FROM customexample "
1287  "WHERE rulename = :RULENAME;");
1288  query.bindValue(":RULENAME", qphrase);
1289 
1290  if (query.exec() && query.next())
1291  {
1292  QString fromc = query.value(0).toString();
1293  QString wherec = query.value(1).toString();
1294 
1295  where = QString("WHERE channel.deleted IS NULL "
1296  " AND channel.visible > 0 "
1297  " AND program.endtime > :PGILSTART "
1298  " AND ( %1 ) ").arg(wherec);
1299  if (!fromc.isEmpty())
1300  where = fromc + ' ' + where;
1301  }
1302  }
1303  else if (m_type == plPreviouslyRecorded)
1304  {
1305  if (m_recid && !m_title.isEmpty())
1306  {
1307  where = QString("AND ( recordid = %1 OR title = :MTITLE )")
1308  .arg(m_recid);
1309  bindings[":MTITLE"] = m_title;
1310  }
1311  else if (!m_title.isEmpty())
1312  {
1313  where = QString("AND title = :MTITLE ");
1314  bindings[":MTITLE"] = m_title;
1315  }
1316  else if (m_recid)
1317  {
1318  where = QString("AND recordid = %1 ").arg(m_recid);
1319  }
1320  }
1321 
1322  ProgramInfo selected;
1323  const ProgramInfo *selectedP = (restorePosition) ? GetCurrentProgram() : nullptr;
1324  if (selectedP)
1325  {
1326  selected = *selectedP;
1327  selectedP = &selected;
1328  }
1329 
1330  // Save a copy of m_itemList so that deletion of the ProgramInfo
1331  // objects can be deferred until background processing of old
1332  // ProgramInfo objects has completed.
1335  m_itemList.setAutoDelete(false);
1336  m_itemList.clear();
1337  m_itemList.setAutoDelete(true);
1338 
1340  {
1341  LoadFromOldRecorded(m_itemList, where, bindings);
1342  }
1343  else
1344  {
1346  LoadFromProgram(m_itemList, where, bindings, m_schedList);
1347  }
1348 
1349  if (m_type == plNewListings || m_titleSort)
1350  {
1353  {
1354  // Prune to one per title
1355  QString curtitle;
1356  auto it = m_itemList.begin();
1357  while (it != m_itemList.end())
1358  {
1359  if ((*it)->GetSortTitle() != curtitle)
1360  {
1361  curtitle = (*it)->GetSortTitle();
1362  ++it;
1363  }
1364  else
1365  {
1366  it = m_itemList.erase(it);
1367  }
1368  }
1369  }
1370  }
1371 
1372  if (!m_titleSort)
1374 
1375  if (updateDisp)
1376  UpdateDisplay(selectedP);
1377 }
1378 
1380 {
1381  if (!m_titleSort)
1382  return kTimeSort;
1384  return kPrevTitleSort;
1385  return kTitleSort;
1386 }
1387 
1388 void ProgLister::SortList(SortBy sortby, bool reverseSort)
1389 {
1390  if (reverseSort)
1391  {
1392  if (kTimeSort == sortby)
1393  {
1394  std::stable_sort(m_itemList.rbegin(), m_itemList.rend(), plTimeSort);
1395  }
1396  else if (kPrevTitleSort == sortby)
1397  {
1398  std::stable_sort(m_itemList.rbegin(), m_itemList.rend(),
1399  plPrevTitleSort);
1400  }
1401  else
1402  {
1403  std::stable_sort(m_itemList.rbegin(), m_itemList.rend(), plTitleSort);
1404  }
1405  }
1406  else
1407  {
1408  if (kTimeSort == sortby)
1409  {
1410  std::stable_sort(m_itemList.begin(), m_itemList.end(), plTimeSort);
1411  }
1412  else if (kPrevTitleSort == sortby)
1413  {
1414  std::stable_sort(m_itemList.begin(), m_itemList.end(),plPrevTitleSort);
1415  }
1416  else
1417  {
1418  std::stable_sort(m_itemList.begin(), m_itemList.end(), plTitleSort);
1419  }
1420  }
1421 }
1422 
1424 {
1425  InfoMap infoMap;
1426  ProgramInfo pginfo;
1427  pginfo.ToMap(infoMap);
1428  ResetMap(infoMap);
1429 
1430  if (m_positionText)
1431  m_positionText->Reset();
1432 }
1433 
1435 {
1436  int offset = 0;
1437 
1438  if (selected)
1440 
1441  m_progList->Reset();
1442 
1443  if (m_messageText)
1445 
1447 
1448  if (m_curviewText && m_curView >= 0)
1450 
1451  UpdateButtonList();
1452 
1453  if (selected)
1454  RestoreSelection(selected, offset);
1455  else if (m_selectedTime.isValid())
1456  {
1457  size_t i = 0;
1458  for (i = 0; i < m_itemList.size(); ++i)
1459  {
1460  if (m_selectedTime <= m_itemList[i]->GetScheduledStartTime())
1461  break;
1462  }
1464  m_selectedTime = QDateTime();
1465  }
1466 }
1467 
1469  int selectedOffset)
1470 {
1471  using ProgramInfoSortFn = bool (*)(const ProgramInfo *a, const ProgramInfo *b);
1472  ProgramInfoSortFn comp { nullptr };
1473  if (!m_titleSort)
1474  comp = plTimeSort;
1475  else if (m_type == plPreviouslyRecorded)
1476  comp = plPrevTitleSort;
1477  else
1478  comp = plTitleSort;
1479 
1480  int i = 0;
1481  for (i = m_itemList.size() - 2; i >= 0; i--)
1482  {
1483  bool dobreak = false;
1484  if (m_reverseSort)
1485  dobreak = comp(selected, m_itemList[i]);
1486  else
1487  dobreak = comp(m_itemList[i], selected);
1488  if (dobreak)
1489  break;
1490  }
1491 
1492  m_progList->SetItemCurrent(i + 1, i + 1 - selectedOffset);
1493 }
1494 
1496 {
1497  auto *pginfo = item->GetData().value<ProgramInfo*>();
1498 
1499  if (item->GetText("is_item_initialized").isNull())
1500  {
1501  InfoMap infoMap;
1502  pginfo->ToMap(infoMap);
1503 
1504  QString state = RecStatus::toUIState(pginfo->GetRecordingStatus());
1505  if ((state == "warning") && (plPreviouslyRecorded == m_type))
1506  state = "disabled";
1507 
1508  item->SetTextFromMap(infoMap, state);
1509 
1510  if (m_type == plTitle)
1511  {
1512  QString tempSubTitle = pginfo->GetSubtitle();
1513  if (tempSubTitle.trimmed().isEmpty())
1514  tempSubTitle = pginfo->GetTitle();
1515  item->SetText(tempSubTitle, "titlesubtitle", state);
1516  }
1517 
1518  item->DisplayState(QString::number(pginfo->GetStars(10)),
1519  "ratingstate");
1520 
1521  item->DisplayState(state, "status");
1522 
1523  // Mark this button list item as initialized.
1524  item->SetText("yes", "is_item_initialized");
1525  }
1526 }
1527 
1529 {
1530  for (auto *it : m_itemList)
1531  new MythUIButtonListItem(m_progList, "", QVariant::fromValue(it));
1533 
1534  if (m_positionText)
1535  {
1537  tr("%1 of %2", "Current position in list where %1 is the "
1538  "position, %2 is the total count")
1539  .arg(QLocale::system().toString(m_progList->IsEmpty() ? 0 : m_progList->GetCurrentPos() + 1),
1540  QLocale::system().toString(m_progList->GetCount())));
1541  }
1542 }
1543 
1545 {
1546  if (!item)
1547  {
1549  return;
1550  }
1551 
1552  auto *pginfo = item->GetData().value<ProgramInfo*> ();
1553  if (!pginfo)
1554  {
1556  return;
1557  }
1558 
1559  InfoMap infoMap;
1560  pginfo->ToMap(infoMap);
1561  SetTextFromMap(infoMap);
1562 
1563  if (m_positionText)
1564  {
1566  tr("%1 of %2", "Current position in list where %1 is the "
1567  "position, %2 is the total count")
1568  .arg(QLocale::system().toString(m_progList->IsEmpty() ? 0 : m_progList->GetCurrentPos() + 1),
1569  QLocale::system().toString(m_progList->GetCount())));
1570  }
1571 
1572  MythUIStateType *ratingState = dynamic_cast<MythUIStateType*>
1573  (GetChild("ratingstate"));
1574 
1575  if (ratingState)
1576  {
1577  QString rating = QString::number(pginfo->GetStars(10));
1578  ratingState->DisplayState(rating);
1579  }
1580 }
1581 
1582 void ProgLister::customEvent(QEvent *event)
1583 {
1584  bool needUpdate = false;
1585 
1586  if (event->type() == DialogCompletionEvent::kEventType)
1587  {
1588  auto *dce = (DialogCompletionEvent*)(event);
1589 
1590  QString resultid = dce->GetId();
1591 // QString resulttext = dce->GetResultText();
1592  int buttonnum = dce->GetResult();
1593 
1594  if (resultid == "sortmenu")
1595  {
1596  switch (buttonnum)
1597  {
1598  case 0:
1600  needUpdate = true;
1601  break;
1602  case 1:
1603  m_titleSort = true;
1604  m_reverseSort = false;
1605  needUpdate = true;
1606  break;
1607  case 2:
1608  m_titleSort = false;
1610  needUpdate = true;
1611  break;
1612  }
1613  }
1614  else if (resultid == "deletemenu")
1615  {
1616  switch (buttonnum)
1617  {
1618  case 0:
1619  {
1621  if (pi)
1622  {
1623  RecordingInfo ri(*pi);
1624  if (ri.IsDuplicate())
1625  ri.ForgetHistory();
1626  else
1627  ri.SetDupHistory();
1628  *pi = ri;
1629  }
1630  break;
1631  }
1632  case 1:
1634  break;
1635  case 2:
1637  break;
1638  }
1639  }
1640  else if (resultid == "deleterule")
1641  {
1642  auto *record = dce->GetData().value<RecordingRule *>();
1643  if (record && buttonnum > 0 && !record->Delete())
1644  {
1645  LOG(VB_GENERAL, LOG_ERR, LOC +
1646  "Failed to delete recording rule");
1647  }
1648  delete record;
1649  }
1650  else
1651  {
1653  }
1654  }
1655  else if (event->type() == ScreenLoadCompletionEvent::kEventType)
1656  {
1657  auto *slce = (ScreenLoadCompletionEvent*)(event);
1658  QString id = slce->GetId();
1659 
1660  if (id == objectName())
1661  {
1662  CloseBusyPopup(); // opened by LoadInBackground()
1663  UpdateDisplay();
1664 
1665  if (m_curView < 0 && m_type != plPreviouslyRecorded)
1667  }
1668  }
1669  else if (event->type() == MythEvent::MythEventMessage)
1670  {
1671  auto *me = dynamic_cast<MythEvent *>(event);
1672  if (me == nullptr)
1673  return;
1674 
1675  const QString& message = me->Message();
1676 
1677  if (m_allowViewDialog && message == "CHOOSE_VIEW")
1679  else if (message == "SCHEDULE_CHANGE")
1680  needUpdate = true;
1681  }
1682 
1683  if (needUpdate)
1684  FillItemList(true);
1685 }
ProgramInfo::GetSortTitle
QString GetSortTitle(void) const
Definition: programinfo.h:362
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:101
MythScreenType::LoadInBackground
void LoadInBackground(const QString &message="")
Definition: mythscreentype.cpp:286
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:807
ProgLister::Load
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
Definition: proglist.cpp:169
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:315
RecStatus::toUIState
static QString toUIState(RecStatus::Type recstatus)
Definition: recordingstatus.cpp:5
MythUIButtonList::GetTopItemPos
int GetTopItemPos(void) const
Definition: mythuibuttonlist.h:240
bool
bool
Definition: pxsup2dast.c:30
MythUISearchDialog
Provide a dialog to quickly find an entry in a list.
Definition: mythdialogbox.h:399
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MythEvent::MythEventMessage
static Type MythEventMessage
Definition: mythevent.h:79
plPeopleSearch
@ plPeopleSearch
Definition: proglist.h:20
ProgLister::m_progList
MythUIButtonList * m_progList
Definition: proglist.h:130
MythTimeInputDialog::kHours
@ kHours
Definition: mythdialogbox.h:458
ProgramInfo::IsDuplicate
bool IsDuplicate(void) const
Definition: programinfo.h:488
mythuitext.h
LoadFromScheduler
bool LoadFromScheduler(AutoDeleteDeque< TYPE * > &destination, bool &hasConflicts, const QString &altTable="", int recordid=-1)
Definition: programinfo.h:912
MythUIText::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:82
ProgLister::DeleteOldEpisode
void DeleteOldEpisode(bool ok)
Definition: proglist.cpp:646
mythdb.h
ProgLister::GetSortBy
SortBy GetSortBy(void) const
Definition: proglist.cpp:1379
MythUIButtonListItem::DisplayState
void DisplayState(const QString &state, const QString &name)
Definition: mythuibuttonlist.cpp:3563
ChannelInfo::kChannelShort
@ kChannelShort
Definition: channelinfo.h:49
MythUIComposite::ResetMap
virtual void ResetMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:28
ProgLister::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: proglist.cpp:180
MythTimeInputDialog::kDay
@ kDay
Definition: mythdialogbox.h:454
ProgLister::kTitleSort
@ kTitleSort
Definition: proglist.h:88
ScheduleCommon::customEvent
void customEvent(QEvent *event) override
Definition: schedulecommon.cpp:481
RecStatus::Tuning
@ Tuning
Definition: recordingstatus.h:22
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:133
RecordingInfo::ForgetHistory
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
Definition: recordinginfo.cpp:1461
plChannel
@ plChannel
Definition: proglist.h:26
plUnknown
@ plUnknown
Definition: proglist.h:16
ProgLister::m_viewList
QStringList m_viewList
Definition: proglist.h:111
MythUISearchDialog::haveResult
void haveResult(QString)
MSqlAddMoreBindings
void MSqlAddMoreBindings(MSqlBindings &output, MSqlBindings &addfrom)
Add the entries in addfrom to the map in output.
Definition: mythdbcon.cpp:960
DialogCompletionEvent::kEventType
static Type kEventType
Definition: mythdialogbox.h:57
AutoDeleteDeque::clear
void clear(void)
Definition: autodeletedeque.h:40
ProgLister::m_allowEvents
bool m_allowEvents
Definition: proglist.h:122
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
ProgramInfo::kTitleSubtitle
@ kTitleSubtitle
Definition: programinfo.h:509
AutoDeleteDeque::empty
bool empty(void) const
Definition: autodeletedeque.h:66
ProgLister::m_searchTime
QDateTime m_searchTime
Definition: proglist.h:103
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MythScreenStack
Definition: mythscreenstack.h:16
MythScreenType::Create
virtual bool Create(void)
Definition: mythscreentype.cpp:266
plCategory
@ plCategory
Definition: proglist.h:25
RecordingInfo::kReLeadingAnd
static const QRegularExpression kReLeadingAnd
Definition: recordinginfo.h:200
RecordingRule
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:28
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:608
ProgLister::ShowOldRecordedMenu
void ShowOldRecordedMenu(void)
Definition: proglist.cpp:700
ScheduleCommon::ShowGuide
virtual void ShowGuide(void) const
Show the program guide.
Definition: schedulecommon.cpp:132
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythuistatetype.h
ProgLister::m_viewTextList
QStringList m_viewTextList
Definition: proglist.h:112
ProgramInfo::SetProgramID
void SetProgramID(const QString &id)
Definition: programinfo.h:533
MythUIButtonList::SetSearchFields
void SetSearchFields(const QString &fields)
Definition: mythuibuttonlist.h:254
ScreenLoadCompletionEvent::kEventType
static Type kEventType
Definition: mythscreentype.h:33
kKeywordSearch
@ kKeywordSearch
Definition: recordingtypes.h:83
ProgLister::PhrasePopup
friend class PhrasePopup
Definition: proglist.h:35
ProgLister::SwitchToPreviousView
void SwitchToPreviousView(void)
Definition: proglist.cpp:322
mythuibuttonlist.h
ProgLister::ShowDeleteRuleMenu
void ShowDeleteRuleMenu(void)
Definition: proglist.cpp:603
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1652
ScheduleCommon::ShowDetails
virtual void ShowDetails(void) const
Show the Program Details screen.
Definition: schedulecommon.cpp:27
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:95
ProgLister::SortList
void SortList(SortBy sortby, bool reverseSort)
Definition: proglist.cpp:1388
ScheduleCommon::EditRecording
virtual void EditRecording(bool may_watch_now=false)
Creates a dialog for editing the recording status, blocking until user leaves dialog.
Definition: schedulecommon.cpp:274
LOC
#define LOC
Definition: proglist.cpp:31
ScheduleCommon::EditScheduled
virtual void EditScheduled(void)
Creates a dialog for editing the recording schedule.
Definition: schedulecommon.cpp:166
proglist.h
ProgLister::kTimeSort
@ kTimeSort
Definition: proglist.h:88
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:113
ProgLister::UpdateKeywordInDB
void UpdateKeywordInDB(const QString &text, const QString &oldValue)
Definition: proglist.cpp:369
ProgLister::kPrevTitleSort
@ kPrevTitleSort
Definition: proglist.h:88
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3268
ChannelUtil::SortChannels
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
Definition: channelutil.cpp:2300
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
ProgLister::DeleteOldSeries
void DeleteOldSeries(bool ok)
Definition: proglist.cpp:679
AutoDeleteDeque::begin
iterator begin(void)
Definition: autodeletedeque.h:50
plTitleSort
static bool plTitleSort(const ProgramInfo *a, const ProgramInfo *b)
Definition: proglist.cpp:1005
RecStatus::WillRecord
@ WillRecord
Definition: recordingstatus.h:31
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
AutoDeleteDeque::setAutoDelete
void setAutoDelete(bool auto_delete)
Definition: autodeletedeque.h:72
ProgLister::m_itemListSave
ProgramList m_itemListSave
Definition: proglist.h:115
plPreviouslyRecorded
@ plPreviouslyRecorded
Definition: proglist.h:30
ScheduleCommon::ShowPrevious
virtual void ShowPrevious(void) const
Show the previous recordings for this recording rule.
Definition: schedulecommon.cpp:248
ProgLister::m_reverseSort
bool m_reverseSort
Definition: proglist.h:124
MythUIButtonList::IsEmpty
bool IsEmpty() const
Definition: mythuibuttonlist.cpp:1668
mythdate.h
ProgLister::PowerSearchPopup
friend class PowerSearchPopup
Definition: proglist.h:37
AutoDeleteDeque::rend
reverse_iterator rend(void)
Definition: autodeletedeque.h:57
plTitleSearch
@ plTitleSearch
Definition: proglist.h:18
ProgListType
ProgListType
Definition: proglist.h:15
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:390
ProgLister::m_startTime
QDateTime m_startTime
Definition: proglist.h:102
MythUIButtonList::itemLoaded
void itemLoaded(MythUIButtonListItem *item)
ScheduleCommon::EditCustom
virtual void EditCustom(void)
Creates a dialog for creating a custom recording rule.
Definition: schedulecommon.cpp:202
ProgramInfo::GetRecordingStatus
RecStatus::Type GetRecordingStatus(void) const
Definition: programinfo.h:447
ProgLister::ShowMenu
void ShowMenu(void) override
Definition: proglist.cpp:268
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1104
kPowerSearch
@ kPowerSearch
Definition: recordingtypes.h:81
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:238
tv_actions.h
ProgLister::m_schedText
MythUIText * m_schedText
Definition: proglist.h:127
ProgLister::UpdateButtonList
void UpdateButtonList(void)
Definition: proglist.cpp:1528
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
MythUIButtonList::LoadInBackground
void LoadInBackground(int start=0, int pageSize=20)
Definition: mythuibuttonlist.cpp:2756
menu
static MythThemedMenu * menu
Definition: mythtv-setup.cpp:58
ProgramInfo::GetTitle
QString GetTitle(void) const
Definition: programinfo.h:361
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:540
ProgramInfo::GetDescription
QString GetDescription(void) const
Definition: programinfo.h:365
ProgLister::HandleSelected
void HandleSelected(MythUIButtonListItem *item)
Definition: proglist.cpp:1544
ProgLister::m_curView
int m_curView
Definition: proglist.h:110
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
ProgLister::HandleVisible
void HandleVisible(MythUIButtonListItem *item)
Definition: proglist.cpp:1495
ProgLister::FillViewList
void FillViewList(const QString &view)
Definition: proglist.cpp:735
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
hardwareprofile.scan.rating
def rating(profile, smoonURL, gate)
Definition: scan.py:39
StringUtil::naturalCompare
MBASE_PUBLIC int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
This method chops the input a and b into pieces of digits and non-digits (a1.05 becomes a | 1 | .
Definition: stringutil.cpp:160
RecStatus::Failing
@ Failing
Definition: recordingstatus.h:18
ACTION_CHANNELSEARCH
#define ACTION_CHANNELSEARCH
Definition: tv_actions.h:28
ProgLister::m_selectedTime
QDateTime m_selectedTime
Definition: proglist.h:104
stringutil.h
ProgLister::m_recid
uint m_recid
Definition: proglist.h:99
MythUIComposite::SetTextFromMap
virtual void SetTextFromMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:9
ScheduleCommon
Definition: schedulecommon.h:15
ProgramInfo::toString
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
Definition: programinfo.cpp:1934
ProgramInfo::ToMap
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
Definition: programinfo.cpp:1542
ProgLister::FillItemList
void FillItemList(bool restorePosition, bool updateDisp=true)
Definition: proglist.cpp:1055
scheduledrecording.h
plPowerSearch
@ plPowerSearch
Definition: proglist.h:21
ProgLister::SetViewFromTime
void SetViewFromTime(QDateTime searchTime)
Definition: proglist.cpp:516
ScheduledRecording::RescheduleCheck
static void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
Definition: scheduledrecording.h:23
ProgLister::PowerStringToSQL
static bool PowerStringToSQL(const QString &qphrase, QString &output, MSqlBindings &bindings)
Definition: proglist.cpp:537
MythUIButtonList::SetLCDTitles
void SetLCDTitles(const QString &title, const QString &columnList="")
Definition: mythuibuttonlist.cpp:3034
kNoSearch
@ kNoSearch
Definition: recordingtypes.h:80
MythTimeInputDialog::haveResult
void haveResult(QDateTime time)
plTitle
@ plTitle
Definition: proglist.h:17
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3665
ChannelUtil::GetChannels
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
Definition: channelutil.h:243
uint
unsigned int uint
Definition: compat.h:79
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
AutoDeleteDeque::end
iterator end(void)
Definition: autodeletedeque.h:51
MythUIButtonList::itemVisible
void itemVisible(MythUIButtonListItem *item)
ProgLister::GetCurrentProgram
ProgramInfo * GetCurrentProgram(void) const override
Definition: proglist.cpp:587
ProgramInfo::GetSortSubtitle
QString GetSortSubtitle(void) const
Definition: programinfo.h:364
ProgLister::m_curviewText
MythUIText * m_curviewText
Definition: proglist.h:128
kTitleSearch
@ kTitleSearch
Definition: recordingtypes.h:82
plStoredSearch
@ plStoredSearch
Definition: proglist.h:29
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
ProgLister::SetViewFromList
void SetViewFromList(const QString &item)
Definition: proglist.cpp:530
channelutil.h
MythUIButtonListItem::SetTextFromMap
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
Definition: mythuibuttonlist.cpp:3285
RecStatus::Pending
@ Pending
Definition: recordingstatus.h:17
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3315
ProgLister::m_title
QString m_title
Definition: proglist.h:100
ScreenLoadCompletionEvent
Event that can be dispatched from a MythScreenType when it has completed loading.
Definition: mythscreentype.h:25
channelinfo.h
plPrevTitleSort
static bool plPrevTitleSort(const ProgramInfo *a, const ProgramInfo *b)
Definition: proglist.cpp:1034
ProgLister::m_allowViewDialog
bool m_allowViewDialog
Definition: proglist.h:133
recordinginfo.h
ProgLister::~ProgLister
~ProgLister() override
Definition: proglist.cpp:89
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
ProgramInfo::GetRecordingRuleType
RecordingType GetRecordingRuleType(void) const
Definition: programinfo.h:451
MythMenu
Definition: mythdialogbox.h:99
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:404
ProgLister::m_positionText
MythUIText * m_positionText
Definition: proglist.h:129
RecStatus::Recording
@ Recording
Definition: recordingstatus.h:30
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:272
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:695
ProgLister::ShowChooseViewMenu
void ShowChooseViewMenu(void)
Definition: proglist.cpp:414
ProgLister::ClearCurrentProgramInfo
void ClearCurrentProgramInfo(void)
Definition: proglist.cpp:1423
plTime
@ plTime
Definition: proglist.h:27
MythDate
Definition: mythdate.cpp:11
ProgLister::m_itemList
ProgramList m_itemList
Definition: proglist.h:114
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:883
std
Definition: mythchrono.h:23
LoadFromProgram
bool LoadFromProgram(ProgramList &destination, const QString &where, const QString &groupBy, const QString &orderBy, const MSqlBindings &bindings, const ProgramList &schedList)
Definition: programinfo.cpp:5642
ProgLister::m_searchType
RecSearchType m_searchType
Definition: proglist.h:107
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
plTimeSort
static bool plTimeSort(const ProgramInfo *a, const ProgramInfo *b)
Definition: proglist.cpp:1047
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:132
ProgLister::m_type
ProgListType m_type
Definition: proglist.h:98
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1108
ScheduleCommon::ShowUpcoming
virtual void ShowUpcoming(void) const
Show the upcoming recordings for this title.
Definition: schedulecommon.cpp:67
ScheduleCommon::QuickRecord
virtual void QuickRecord(void)
Create a kSingleRecord or bring up recording dialog.
Definition: schedulecommon.cpp:147
PowerSearchPopup::haveResult
void haveResult(QString item)
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:116
plMovies
@ plMovies
Definition: proglist.h:24
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1554
build_compdb.action
action
Definition: build_compdb.py:9
ProgLister::m_schedList
ProgramList m_schedList
Definition: proglist.h:116
ProgLister::m_channelOrdering
QString m_channelOrdering
Definition: proglist.h:105
ProgLister::ProgLister
ProgLister(MythScreenStack *parent, ProgListType pltype, QString view, QString extraArg, QDateTime selectedTime=QDateTime())
Definition: proglist.cpp:35
ProgLister::Create
bool Create(void) override
Definition: proglist.cpp:96
ProgLister::m_extraArg
QString m_extraArg
Definition: proglist.h:101
AutoDeleteDeque::rbegin
reverse_iterator rbegin(void)
Definition: autodeletedeque.h:56
LoadFromOldRecorded
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
Definition: programinfo.cpp:5830
plRecordid
@ plRecordid
Definition: proglist.h:28
ProgLister::ShowDeleteOldEpisodeMenu
void ShowDeleteOldEpisodeMenu(void)
Definition: proglist.cpp:634
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:320
ProgLister::RestoreSelection
void RestoreSelection(const ProgramInfo *selected, int selectedOffset)
Definition: proglist.cpp:1468
MythTimeInputDialog::kFutureDates
@ kFutureDates
Definition: mythdialogbox.h:462
ScheduleCommon::ShowChannelSearch
virtual void ShowChannelSearch(void) const
Show the channel search.
Definition: schedulecommon.cpp:113
plSQLSearch
@ plSQLSearch
Definition: proglist.h:22
ProgramInfo::GetProgramID
QString GetProgramID(void) const
Definition: programinfo.h:436
plNewListings
@ plNewListings
Definition: proglist.h:23
ProgLister::customEvent
void customEvent(QEvent *event) override
Definition: proglist.cpp:1582
ProgLister::SwitchToNextView
void SwitchToNextView(void)
Definition: proglist.cpp:345
AutoDeleteDeque::erase
iterator erase(iterator it)
Definition: autodeletedeque.h:34
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:23
ProgramInfo::GetRecordingRuleID
uint GetRecordingRuleID(void) const
Definition: programinfo.h:449
PhrasePopup::haveResult
void haveResult(QString item)
ProgLister::ShowDeleteItemMenu
void ShowDeleteItemMenu(void)
Definition: proglist.cpp:595
recordingrule.h
ProgLister::SortBy
SortBy
Definition: proglist.h:88
MythTimeInputDialog
Definition: mythdialogbox.h:443
ProgLister::ShowDeleteOldSeriesMenu
void ShowDeleteOldSeriesMenu(void)
Definition: proglist.cpp:667
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:50
ProgLister::m_titleSort
bool m_titleSort
Definition: proglist.h:123
ProgLister::UpdateDisplay
void UpdateDisplay(const ProgramInfo *selected=nullptr)
Definition: proglist.cpp:1434
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:563
output
#define output
Definition: synaesthesia.cpp:220
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
kPeopleSearch
@ kPeopleSearch
Definition: recordingtypes.h:84
MythScreenType::CloseBusyPopup
void CloseBusyPopup(void)
Definition: mythscreentype.cpp:338
MythUIStateType
This widget is used for grouping other widgets for display when a particular named state is called....
Definition: mythuistatetype.h:22
AutoDeleteDeque::size
size_t size(void) const
Definition: autodeletedeque.h:67
MythUIStateType::DisplayState
bool DisplayState(const QString &name)
Definition: mythuistatetype.cpp:84
ProgLister::m_view
QString m_view
Definition: proglist.h:109
plKeywordSearch
@ plKeywordSearch
Definition: proglist.h:19
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:832
ProgLister::m_useGenres
bool m_useGenres
Definition: proglist.h:125
RecordingInfo::SetDupHistory
void SetDupHistory(void)
Set the duplicate flag in oldrecorded.
Definition: recordinginfo.cpp:1644
ProgLister::m_messageText
MythUIText * m_messageText
Definition: proglist.h:131
ChannelInfoList
std::vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:131