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