MythTV  master
scheduleeditor.cpp
Go to the documentation of this file.
1 
2 #include "scheduleeditor.h"
3 
4 // QT
5 #include <QString>
6 #include <QHash>
7 #include <QCoreApplication>
8 
9 // Libmyth
10 #include "mythcorecontext.h"
11 #include "storagegroup.h"
12 #include "programtypes.h"
13 #include "recordingtypes.h"
14 
15 // Libmythtv
16 #include "playgroup.h"
17 #include "tv_play.h"
18 #include "recordingprofile.h"
19 #include "cardutil.h"
20 
21 // Libmythui
22 #include "mythmainwindow.h"
23 #include "mythuihelper.h"
24 #include "mythuibuttonlist.h"
25 #include "mythuibutton.h"
26 #include "mythuitext.h"
27 #include "mythuiimage.h"
28 #include "mythuistatetype.h"
29 #include "mythuispinbox.h"
30 #include "mythuicheckbox.h"
31 #include "mythdialogbox.h"
32 #include "mythprogressdialog.h"
33 #include "mythuifilebrowser.h"
34 #include "mythuimetadataresults.h"
35 #include "mythuiimageresults.h"
36 #include "videoutils.h"
37 #include "mythuiutils.h"
38 #include "mythtypes.h"
39 
40 #include "metadataimagehelper.h"
41 
42 // Mythfrontend
43 #include "proglist.h"
44 #include "viewschedulediff.h"
45 
46 #define ENUM_TO_QVARIANT(a) qVariantFromValue(static_cast<int>(a))
47 
48 //static const QString _Location = QObject::tr("Schedule Editor");
49 
50 // Define the strings inserted into the recordfilter table in the
51 // database. This should make them available to the translators.
52 static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor", "New episode"));
53 static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor", "Identifiable episode"));
54 static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor", "First showing"));
55 static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor", "Prime time"));
56 static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor", "Commercial free"));
57 static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor", "High definition"));
58 static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor", "This episode"));
59 static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor", "This series"));
60 static QString fs8(QT_TRANSLATE_NOOP("SchedFilterEditor", "This time"));
61 static QString fs9(QT_TRANSLATE_NOOP("SchedFilterEditor", "This day and time"));
62 static QString fs10(QT_TRANSLATE_NOOP("SchedFilterEditor", "This channel"));
63 static QString fs11(QT_TRANSLATE_NOOP("SchedFilterEditor", "No episodes"));
64 
65 void *ScheduleEditor::RunScheduleEditor(ProgramInfo *proginfo, void *player)
66 {
67  RecordingRule *rule = new RecordingRule();
68  rule->LoadByProgram(proginfo);
69 
71  ScheduleEditor *se = new ScheduleEditor(mainStack, rule,
72  static_cast<TV*>(player));
73 
74  if (se->Create())
75  mainStack->AddScreen(se, (player == NULL));
76  else
77  delete se;
78 
79  return NULL;
80 }
81 
88  RecordingInfo *recInfo, TV *player)
89  : ScheduleCommon(parent, "ScheduleEditor"),
90  SchedOptMixin(*this, NULL), FilterOptMixin(*this, NULL),
91  StoreOptMixin(*this, NULL), PostProcMixin(*this, NULL),
92  m_recInfo(new RecordingInfo(*recInfo)), m_recordingRule(NULL),
94  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
97  m_previewButton(NULL), m_metadataButton(NULL),
98  m_filtersButton(NULL),
99  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
100 {
107 }
108 
110  RecordingRule *recRule, TV *player)
111  : ScheduleCommon(parent, "ScheduleEditor"),
112  SchedOptMixin(*this, recRule),
113  FilterOptMixin(*this, recRule),
114  StoreOptMixin(*this, recRule),
115  PostProcMixin(*this, recRule),
116  m_recInfo(NULL), m_recordingRule(recRule),
117  m_sendSig(false),
118  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
119  m_schedOptButton(NULL), m_storeOptButton(NULL),
120  m_postProcButton(NULL), m_schedInfoButton(NULL),
121  m_previewButton(NULL), m_metadataButton(NULL),
122  m_filtersButton(NULL),
123  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
124 {
125 }
126 
128 {
129  delete m_recordingRule;
130 
131  // if we have a player, we need to tell we are done
132  if (m_player)
133  {
134  QString message = QString("VIEWSCHEDULED_EXITING");
135  qApp->postEvent(m_player, new MythEvent(message));
136  }
137 }
138 
140 {
141  if (!LoadWindowFromXML("schedule-ui.xml", "scheduleeditor", this))
142  return false;
143 
144  bool err = false;
145 
146  UIUtilE::Assign(this, m_rulesList, "rules", &err);
147 
148  UIUtilW::Assign(this, m_schedOptButton, "schedoptions");
149  UIUtilW::Assign(this, m_storeOptButton, "storeoptions");
150  UIUtilW::Assign(this, m_postProcButton, "postprocessing");
151  UIUtilW::Assign(this, m_metadataButton, "metadata");
152  UIUtilW::Assign(this, m_schedInfoButton, "schedinfo");
153  UIUtilW::Assign(this, m_previewButton, "preview");
154  UIUtilW::Assign(this, m_filtersButton, "filters");
155 
156  SchedOptMixin::Create(&err);
158  StoreOptMixin::Create(&err);
159  PostProcMixin::Create(&err);
160 
161  UIUtilW::Assign(this, m_cancelButton, "cancel");
162  UIUtilE::Assign(this, m_saveButton, "save", &err);
163 
164  if (err)
165  {
166  LOG(VB_GENERAL, LOG_ERR, "ScheduleEditor, theme is missing "
167  "required elements");
168  return false;
169  }
170 
171  connect(m_rulesList, SIGNAL(itemSelected(MythUIButtonListItem *)),
173 
174  if (m_schedOptButton)
175  connect(m_schedOptButton, SIGNAL(Clicked()), SLOT(ShowSchedOpt()));
176  if (m_filtersButton)
177  connect(m_filtersButton, SIGNAL(Clicked()), SLOT(ShowFilters()));
178  if (m_storeOptButton)
179  connect(m_storeOptButton, SIGNAL(Clicked()), SLOT(ShowStoreOpt()));
180  if (m_postProcButton)
181  connect(m_postProcButton, SIGNAL(Clicked()), SLOT(ShowPostProc()));
182  if (m_schedInfoButton)
183  connect(m_schedInfoButton, SIGNAL(Clicked()), SLOT(ShowSchedInfo()));
184  if (m_previewButton)
185  connect(m_previewButton, SIGNAL(Clicked()), SLOT(ShowPreview()));
186  if (m_metadataButton)
187  connect(m_metadataButton, SIGNAL(Clicked()), SLOT(ShowMetadataOptions()));
188 
189  if (m_cancelButton)
190  connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
191  connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
192 
193  if (m_schedInfoButton)
195  if (m_previewButton)
197 
198  if (m_dupmethodList)
199  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
201  if (m_filtersList)
202  connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
204  if (m_maxepSpin)
205  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
207  if (m_recgroupList)
208  connect(m_recgroupList, SIGNAL(LosingFocus()),
209  SLOT(PromptForRecGroup()));
210  if (m_transcodeCheck)
211  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
212  SLOT(TranscodeChanged(bool)));
213 
214  BuildFocusList();
215 
216  if (!m_recordingRule->IsLoaded())
217  {
218  if (m_recInfo)
220  else if (m_recordingRule->m_recordID)
222 
223  if (!m_recordingRule->IsLoaded())
224  {
225  LOG(VB_GENERAL, LOG_ERR,
226  "ScheduleEditor::Create() - Failed to load recording rule");
227  return false;
228  }
229  }
230 
231  if (m_player)
232  m_player->StartEmbedding(QRect());
233 
234  return true;
235 }
236 
238 {
239  if (m_child)
240  m_child->Close();
241 
242  // don't fade the screen if we are returning to the player
243  if (m_player)
244  GetScreenStack()->PopScreen(this, false);
245  else
246  GetScreenStack()->PopScreen(this, true);
247 }
248 
250 {
255 
256  if (!m_loaded)
257  {
258  // Copy this now, it will change briefly after the first item
259  // is inserted into the list by design of
260  // MythUIButtonList::itemSelected()
262 
263  // Rules List
265  {
267  .compare("Default", Qt::CaseInsensitive) != 0)
268  {
270  tr("Delete this recording rule template"),
272  }
276  }
277  else if (m_recordingRule->m_isOverride)
278  {
280  tr("Record this showing with normal options"),
288  }
289  else
290  {
291  bool hasChannel = !m_recordingRule->m_station.isEmpty();
292  bool isManual = (m_recordingRule->m_searchType == kManualSearch);
293 
297  if (hasChannel)
301  if (!isManual)
305  if (!hasChannel || isManual)
309  if (!hasChannel || isManual)
313  if (!isManual)
317  }
318 
320  }
322 
323  InfoMap progMap;
324 
325  m_recordingRule->ToMap(progMap);
326 
327  if (m_recInfo)
328  m_recInfo->ToMap(progMap);
329 
330  SetTextFromMap(progMap);
331 
332  m_loaded = true;
333 }
334 
336 {
338  Load();
339  emit templateLoaded();
340 }
341 
343 {
344  if (!item)
345  return;
346 
347  m_recordingRule->m_type = static_cast<RecordingType>
348  (item->GetData().toInt());
349 
350  bool isScheduled = (m_recordingRule->m_type != kNotRecording &&
352 
353  if (m_schedOptButton)
354  m_schedOptButton->SetEnabled(isScheduled);
355  if (m_filtersButton)
356  m_filtersButton->SetEnabled(isScheduled);
357  if (m_storeOptButton)
358  m_storeOptButton->SetEnabled(isScheduled);
359  if (m_postProcButton)
360  m_postProcButton->SetEnabled(isScheduled);
361  if (m_metadataButton)
362  m_metadataButton->SetEnabled(isScheduled &&
364 
369 }
370 
372 {
374 }
375 
377 {
379 }
380 
382 {
384 }
385 
387 {
389 }
390 
392 {
394 }
395 
397 {
398  if (m_child)
399  m_child->Close();
400 
402  {
403  int recid = m_recordingRule->m_recordID;
404  DeleteRule();
405  if (recid)
406  emit ruleDeleted(recid);
407  Close();
408  return;
409  }
410 
415  m_recordingRule->Save(true);
417 
418  Close();
419 }
420 
422 {
424 }
425 
427 {
430  return;
431 
432  if (m_child)
433  m_child->Close();
434 
436 
438  SchedOptEditor *schedoptedit = new SchedOptEditor(mainStack, *this,
440  if (!schedoptedit->Create())
441  {
442  delete schedoptedit;
443  return;
444  }
445 
447  m_child = schedoptedit;
448  mainStack->AddScreen(schedoptedit);
449 }
450 
452 {
455  return;
456 
457  if (m_child)
458  m_child->Close();
459 
461 
463  StoreOptEditor *storeoptedit = new StoreOptEditor(mainStack, *this,
465  if (!storeoptedit->Create())
466  {
467  delete storeoptedit;
468  return;
469  }
470 
472  m_child = storeoptedit;
473  mainStack->AddScreen(storeoptedit);
474 }
475 
477 {
480  return;
481 
482  if (m_child)
483  m_child->Close();
484 
486 
488  PostProcEditor *ppedit = new PostProcEditor(mainStack, *this,
490  if (!ppedit->Create())
491  {
492  delete ppedit;
493  return;
494  }
495 
497  m_child = ppedit;
498  mainStack->AddScreen(ppedit);
499 }
500 
502 {
504  return;
505 
506  QString label = tr("Schedule Information");
507 
508  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
509  MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
510 
511  if (menuPopup->Create())
512  {
513  menuPopup->SetReturnEvent(this, "schedinfo");
514 
515  if (m_recInfo)
516  menuPopup->AddButton(tr("Program Details"));
517  menuPopup->AddButton(tr("Upcoming Episodes"));
518  menuPopup->AddButton(tr("Upcoming Recordings"));
520  menuPopup->AddButton(tr("Previously Recorded"));
521 
522  popupStack->AddScreen(menuPopup);
523  }
524  else
525  delete menuPopup;
526 }
527 
528 bool ScheduleEditor::keyPressEvent(QKeyEvent *event)
529 {
530  if (GetFocusWidget()->keyPressEvent(event))
531  return true;
532 
533  bool handled = false;
534  QStringList actions;
535  handled = GetMythMainWindow()->
536  TranslateKeyPress("TV Frontend", event, actions);
537 
538  for (int i = 0; i < actions.size() && !handled; i++)
539  {
540  QString action = actions[i];
541  handled = true;
542 
543  if (action == "MENU")
544  showMenu();
545  else if (action == "INFO")
546  ShowDetails();
547  else if (action == "GUIDE")
548  ShowGuide();
549  else if (action == "UPCOMING")
551  else if (action == "PREVVIEW")
553  else if (action == "NEXTVIEW")
554  ShowNextView();
555  else
556  handled = false;
557  }
558 
559  if (!handled && MythScreenType::keyPressEvent(event))
560  handled = true;
561 
562  return handled;
563 }
564 
565 void ScheduleEditor::customEvent(QEvent *event)
566 {
567  if (event->type() == DialogCompletionEvent::kEventType)
568  {
570 
571  QString resultid = dce->GetId();
572  QString resulttext = dce->GetResultText();
573 
574  if (resultid == "menu")
575  {
576  if (resulttext == tr("Main Options"))
577  m_child->Close();
578  if (resulttext == tr("Schedule Options"))
579  ShowSchedOpt();
580  else if (resulttext == tr("Filter Options"))
581  ShowFilters();
582  else if (resulttext == tr("Storage Options"))
583  ShowStoreOpt();
584  else if (resulttext == tr("Post Processing"))
585  ShowPostProc();
586  else if (resulttext == tr("Metadata Options"))
588  else if (resulttext == tr("Use Template"))
590  else if (resulttext == tr("Schedule Info"))
591  ShowSchedInfo();
592  else if (resulttext == tr("Preview Changes"))
593  ShowPreview();
594  }
595  else if (resultid == "templatemenu")
596  {
597  LoadTemplate(resulttext);
598  }
599  else if (resultid == "schedinfo")
600  {
601  if (resulttext == tr("Program Details"))
602  ShowDetails();
603  else if (resulttext == tr("Upcoming Episodes"))
605  else if (resulttext == tr("Upcoming Recordings"))
607  else if (resulttext == tr("Previously Recorded"))
610  }
611  else if (resultid == "newrecgroup")
612  {
613  int groupID = CreateRecordingGroup(resulttext);
614  StoreOptMixin::SetRecGroup(groupID, resulttext);
615  }
616  }
617 }
618 
620 {
622  return;
623 
624  // No rule? Search by title
625  if (m_recordingRule->m_recordID <= 0)
626  {
628  return;
629  }
630 
632  ProgLister *pl = new ProgLister(mainStack, plRecordid,
633  QString::number(m_recordingRule->m_recordID),
634  "");
635 
636  if (pl->Create())
637  mainStack->AddScreen(pl);
638  else
639  delete pl;
640 }
641 
643 {
645  return;
646 
647  // Existing rule and search? Search by rule
648  if (m_recordingRule->m_recordID > 0 &&
651 
652  QString title = m_recordingRule->m_title;
653 
655  title.remove(QRegExp(" \\(.*\\)$"));
656 
658 }
659 
661 {
663  return;
664 
665  if (m_child)
666  {
667  m_child->Save();
668  if (m_view == kSchedOptView)
670  else if (m_view == kStoreOptView)
672  else if (m_view == kPostProcView)
674  }
675 
680 
681  QString ttable = "record_tmp";
682  m_recordingRule->UseTempTable(true, ttable);
683 
685  ViewScheduleDiff *vsd = new ViewScheduleDiff(mainStack, ttable,
688  if (vsd->Create())
689  mainStack->AddScreen(vsd);
690  else
691  delete vsd;
692 
694 }
695 
697 {
701  return;
702 
703  if (m_child)
704  m_child->Close();
705 
707  MetadataOptions *rad = new MetadataOptions(mainStack, *this,
709  if (!rad->Create())
710  {
711  delete rad;
712  return;
713  }
714 
716  m_child = rad;
717  mainStack->AddScreen(rad);
718 }
719 
721 {
724  return;
725 
726  if (m_child)
727  m_child->Close();
728 
730 
732  SchedFilterEditor *schedfilteredit = new SchedFilterEditor(mainStack,
733  *this, *m_recordingRule, m_recInfo);
734  if (!schedfilteredit->Create())
735  {
736  delete schedfilteredit;
737  return;
738  }
739 
741  m_child = schedfilteredit;
742  mainStack->AddScreen(schedfilteredit);
743 }
744 
746 {
749  return;
750 
753  else if (m_view == kMainView)
754  ShowPostProc();
755  else if (m_view == kSchedOptView)
756  m_child->Close();
757  else if (m_view == kFilterView)
758  ShowSchedOpt();
759  else if (m_view == kStoreOptView)
760  ShowFilters();
761  else if (m_view == kPostProcView)
762  ShowStoreOpt();
763  else if (m_view == kMetadataView)
764  ShowPostProc();
765 }
766 
768 {
771  return;
772 
773  if (m_view == kMainView)
774  ShowSchedOpt();
775  else if (m_view == kSchedOptView)
776  ShowFilters();
777  else if (m_view == kFilterView)
778  ShowStoreOpt();
779  else if (m_view == kStoreOptView)
780  ShowPostProc();
783  else if (m_view == kPostProcView)
784  m_child->Close();
785  else if (m_view == kMetadataView)
786  m_child->Close();
787 }
788 
790 {
791  if (m_view == kSchedOptView)
793  else if (m_view == kFilterView)
795  else if (m_view == kStoreOptView)
797  else if (m_view == kPostProcView)
799 
800  m_child = NULL;
801  m_view = kMainView;
802 }
803 
805 {
806  QString label = tr("Options");
807  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
808  MythDialogBox *menuPopup =
809  new MythDialogBox(label, popupStack, "menuPopup");
810 
812  RecordingType type = static_cast<RecordingType>(item->GetData().toInt());
813  bool isScheduled = (type != kNotRecording && type != kDontRecord);
814 
815  if (menuPopup->Create())
816  {
817  menuPopup->SetReturnEvent(this, "menu");
818  if (m_view != kMainView)
819  menuPopup->AddButton(tr("Main Options"));
820  if (isScheduled && m_view != kSchedOptView)
821  menuPopup->AddButton(tr("Schedule Options"));
822  if (isScheduled && m_view != kFilterView)
823  menuPopup->AddButton(tr("Filter Options"));
824  if (isScheduled && m_view != kStoreOptView)
825  menuPopup->AddButton(tr("Storage Options"));
826  if (isScheduled && m_view != kPostProcView)
827  menuPopup->AddButton(tr("Post Processing"));
828  if (isScheduled && !m_recordingRule->m_isTemplate &&
830  menuPopup->AddButton(tr("Metadata Options"));
832  menuPopup->AddButton(tr("Schedule Info"));
834  menuPopup->AddButton(tr("Preview Changes"));
835  menuPopup->AddButton(tr("Use Template"));
836  popupStack->AddScreen(menuPopup);
837  }
838  else
839  {
840  delete menuPopup;
841  }
842 }
843 
845 {
846  QStringList templates = RecordingRule::GetTemplateNames();
847  if (templates.empty())
848  {
849  ShowOkPopup(tr("No templates available"));
850  return;
851  }
852 
853  QString label = tr("Template Options");
854  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
855  MythDialogBox *menuPopup =
856  new MythDialogBox(label, popupStack, "menuPopup");
857 
858  if (menuPopup->Create())
859  {
860  menuPopup->SetReturnEvent(this, "templatemenu");
861  while (!templates.empty())
862  {
863  QString name = templates.front();
864  if (name == "Default")
865  menuPopup->AddButton(tr("Default"));
866  else
867  menuPopup->AddButton(name);
868  templates.pop_front();
869  }
870  popupStack->AddScreen(menuPopup);
871  }
872  else
873  {
874  delete menuPopup;
875  }
876 }
877 
879 
885  ScheduleEditor &editor, RecordingRule &rule,
886  RecordingInfo *recInfo)
887  : MythScreenType(parent, name),
888  m_editor(&editor), m_recordingRule(&rule), m_recInfo(recInfo),
889  m_backButton(NULL), m_saveButton(NULL), m_previewButton(NULL)
890 {
891 }
892 
894 {
895 }
896 
897 bool SchedEditChild::keyPressEvent(QKeyEvent *event)
898 {
899  if (GetFocusWidget()->keyPressEvent(event))
900  return true;
901 
902  bool handled = false;
903  QStringList actions;
904  handled = GetMythMainWindow()->
905  TranslateKeyPress("TV Frontend", event, actions);
906 
907  for (int i = 0; i < actions.size() && !handled; i++)
908  {
909  QString action = actions[i];
910  handled = true;
911 
912  if (action == "MENU")
913  m_editor->showMenu();
914  else if (action == "INFO")
916  else if (action == "UPCOMING")
918  if (action == "ESCAPE")
919  Close();
920  else if (action == "PREVVIEW")
922  else if (action == "NEXTVIEW")
924  else
925  handled = false;
926  }
927 
928  if (!handled && MythScreenType::keyPressEvent(event))
929  handled = true;
930 
931  return handled;
932 }
933 
935  const QString &xmlfile, const QString &winname, bool isTemplate)
936 {
937  if (!LoadWindowFromXML(xmlfile, winname, this))
938  return false;
939 
940  UIUtilW::Assign(this, m_backButton, "back");
941  UIUtilW::Assign(this, m_saveButton, "save");
942  UIUtilW::Assign(this, m_previewButton, "preview");
943 
944  connect(this, SIGNAL(Closing()), m_editor, SLOT(ChildClosing()));
945  connect(m_editor, SIGNAL(templateLoaded()), SLOT(Load()));
946 
947  if (m_backButton)
948  connect(m_backButton, SIGNAL(Clicked()), SLOT(Close()));
949  if (m_saveButton)
950  connect(m_saveButton, SIGNAL(Clicked()), m_editor, SLOT(Save()));
951  if (m_previewButton)
952  connect(m_previewButton, SIGNAL(Clicked()),
953  m_editor, SLOT(ShowPreview()));
954 
955  if (m_previewButton)
956  m_previewButton->SetEnabled(!isTemplate);
957 
958  return true;
959 }
960 
962 {
963  InfoMap progMap;
964 
965  m_recordingRule->ToMap(progMap);
966 
967  if (m_recInfo)
968  m_recInfo->ToMap(progMap);
969 
970  SetTextFromMap(progMap);
971 }
972 
974 {
975  Save();
976  emit Closing();
978 }
979 
981 
988  ScheduleEditor &editor,
989  RecordingRule &rule,
990  RecordingInfo *recInfo)
991  : SchedEditChild(parent, "ScheduleOptionsEditor", editor, rule, recInfo),
992  SchedOptMixin(*this, &rule, &editor), m_filtersButton(NULL)
993 {
994 }
995 
997 {
998 }
999 
1001 {
1003  "schedule-ui.xml", "scheduleoptionseditor",
1005  {
1006  return false;
1007  }
1008 
1009  bool err = false;
1010 
1011  SchedOptMixin::Create(&err);
1012 
1013  UIUtilW::Assign(this, m_filtersButton, "filters");
1014 
1015  if (err)
1016  {
1017  LOG(VB_GENERAL, LOG_ERR, "SchedOptEditor, theme is missing "
1018  "required elements");
1019  return false;
1020  }
1021 
1022  if (m_dupmethodList)
1023  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
1025 
1026  if (m_filtersButton)
1027  connect(m_filtersButton, SIGNAL(Clicked()),
1028  m_editor, SLOT(ShowFilters()));
1029 
1030  BuildFocusList();
1031 
1032  return true;
1033 }
1034 
1036 {
1038  SetTextFromMaps();
1039 }
1040 
1042 {
1044 }
1045 
1047 {
1049 }
1050 
1052 
1059  ScheduleEditor &editor,
1060  RecordingRule &rule,
1061  RecordingInfo *recInfo)
1062  : SchedEditChild(parent, "ScheduleFilterEditor", editor, rule, recInfo),
1063  FilterOptMixin(*this, &rule, &editor)
1064 {
1065 }
1066 
1068 {
1069 }
1070 
1072 {
1074  "schedule-ui.xml", "schedulefiltereditor",
1076  {
1077  return false;
1078  }
1079 
1080  bool err = false;
1081 
1082  FilterOptMixin::Create(&err);
1083 
1084  if (err)
1085  {
1086  LOG(VB_GENERAL, LOG_ERR, "SchedFilterEditor, theme is missing "
1087  "required elements");
1088  return false;
1089  }
1090 
1091  connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
1093 
1094  BuildFocusList();
1095 
1096  return true;
1097 }
1098 
1100 {
1102  SetTextFromMaps();
1103 }
1104 
1106 {
1108 }
1109 
1111 {
1113 }
1114 
1116 
1123  ScheduleEditor &editor,
1124  RecordingRule &rule,
1125  RecordingInfo *recInfo)
1126  : SchedEditChild(parent, "StorageOptionsEditor", editor, rule, recInfo),
1127  StoreOptMixin(*this, &rule, &editor)
1128 {
1129 }
1130 
1132 {
1133 }
1134 
1136 {
1138  "schedule-ui.xml", "storageoptionseditor",
1140  {
1141  return false;
1142  }
1143 
1144  bool err = false;
1145 
1146  StoreOptMixin::Create(&err);
1147 
1148  if (err)
1149  {
1150  LOG(VB_GENERAL, LOG_ERR, "StoreOptEditor, theme is missing "
1151  "required elements");
1152  return false;
1153  }
1154 
1155  if (m_maxepSpin)
1156  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
1158  if (m_recgroupList)
1159  connect(m_recgroupList, SIGNAL(LosingFocus()),
1160  SLOT(PromptForRecGroup()));
1161 
1162  BuildFocusList();
1163 
1164  return true;
1165 }
1166 
1168 {
1170  SetTextFromMaps();
1171 }
1172 
1174 {
1176 }
1177 
1179 {
1181 }
1182 
1183 void StoreOptEditor::customEvent(QEvent *event)
1184 {
1185  if (event->type() == DialogCompletionEvent::kEventType)
1186  {
1188 
1189  QString resultid = dce->GetId();
1190  QString resulttext = dce->GetResultText();
1191 
1192  if (resultid == "newrecgroup")
1193  {
1194  int groupID = CreateRecordingGroup(resulttext);
1195  StoreOptMixin::SetRecGroup(groupID, resulttext);
1196  }
1197  }
1198 }
1199 
1201 {
1203 }
1204 
1206 
1213  ScheduleEditor &editor,
1214  RecordingRule &rule,
1215  RecordingInfo *recInfo)
1216  : SchedEditChild(parent, "PostProcOptionsEditor", editor, rule, recInfo),
1217  PostProcMixin(*this, &rule, &editor)
1218 {
1219 }
1220 
1222 {
1223 }
1224 
1226 {
1228  "schedule-ui.xml", "postproceditor",
1230  {
1231  return false;
1232  }
1233 
1234  bool err = false;
1235 
1236  PostProcMixin::Create(&err);
1237 
1238  if (err)
1239  {
1240  LOG(VB_GENERAL, LOG_ERR, "PostProcEditor, theme is missing "
1241  "required elements");
1242  return false;
1243  }
1244 
1245  if (m_transcodeCheck)
1246  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
1247  SLOT(TranscodeChanged(bool)));
1248 
1249  BuildFocusList();
1250 
1251  return true;
1252 }
1253 
1255 {
1257  SetTextFromMaps();
1258 }
1259 
1261 {
1263 }
1264 
1266 {
1268 }
1269 
1271 
1278  ScheduleEditor &editor,
1279  RecordingRule &rule,
1280  RecordingInfo *recInfo)
1281  : SchedEditChild(parent, "MetadataOptions", editor, rule, recInfo),
1282  m_busyPopup(NULL), m_fanart(NULL), m_coverart(NULL),
1283  m_banner(NULL), m_inetrefEdit(NULL), m_seasonSpin(NULL),
1284  m_episodeSpin(NULL), m_queryButton(NULL), m_localFanartButton(NULL),
1285  m_localCoverartButton(NULL), m_localBannerButton(NULL),
1286  m_onlineFanartButton(NULL), m_onlineCoverartButton(NULL),
1287  m_onlineBannerButton(NULL)
1288 {
1289  m_popupStack = GetMythMainWindow()->GetStack("popup stack");
1290 
1291  m_metadataFactory = new MetadataFactory(this);
1292  m_imageLookup = new MetadataDownload(this);
1294 
1297 }
1298 
1300 {
1301  if (m_imageLookup)
1302  {
1303  m_imageLookup->cancel();
1304  delete m_imageLookup;
1305  m_imageLookup = NULL;
1306  }
1307 
1308  if (m_imageDownload)
1309  {
1311  delete m_imageDownload;
1312  m_imageDownload = NULL;
1313  }
1314 }
1315 
1317 {
1319  "schedule-ui.xml", "metadataoptions",
1321  {
1322  return false;
1323  }
1324 
1325  bool err = false;
1326 
1327  UIUtilE::Assign(this, m_inetrefEdit, "inetref_edit", &err);
1328  UIUtilE::Assign(this, m_seasonSpin, "season_spinbox", &err);
1329  UIUtilE::Assign(this, m_episodeSpin, "episode_spinbox", &err);
1330  UIUtilE::Assign(this, m_queryButton, "query_button", &err);
1331  UIUtilE::Assign(this, m_localFanartButton, "local_fanart_button", &err);
1332  UIUtilE::Assign(this, m_localCoverartButton, "local_coverart_button", &err);
1333  UIUtilE::Assign(this, m_localBannerButton, "local_banner_button", &err);
1334  UIUtilE::Assign(this, m_onlineFanartButton, "online_fanart_button", &err);
1335  UIUtilE::Assign(this, m_onlineCoverartButton, "online_coverart_button", &err);
1336  UIUtilE::Assign(this, m_onlineBannerButton, "online_banner_button", &err);
1337  UIUtilW::Assign(this, m_fanart, "fanart");
1338  UIUtilW::Assign(this, m_coverart, "coverart");
1339  UIUtilW::Assign(this, m_banner, "banner");
1340 
1341  if (err)
1342  {
1343  LOG(VB_GENERAL, LOG_ERR, "MetadataOptions, theme is missing "
1344  "required elements");
1345  return false;
1346  }
1347 
1348  connect(m_queryButton, SIGNAL(Clicked()),
1349  SLOT(PerformQuery()));
1350  connect(m_localFanartButton, SIGNAL(Clicked()),
1351  SLOT(SelectLocalFanart()));
1352  connect(m_localCoverartButton, SIGNAL(Clicked()),
1353  SLOT(SelectLocalCoverart()));
1354  connect(m_localBannerButton, SIGNAL(Clicked()),
1355  SLOT(SelectLocalBanner()));
1356  connect(m_onlineFanartButton, SIGNAL(Clicked()),
1357  SLOT(SelectOnlineFanart()));
1358  connect(m_onlineCoverartButton, SIGNAL(Clicked()),
1359  SLOT(SelectOnlineCoverart()));
1360  connect(m_onlineBannerButton, SIGNAL(Clicked()),
1361  SLOT(SelectOnlineBanner()));
1362 
1363  connect(m_seasonSpin, SIGNAL(itemSelected(MythUIButtonListItem*)),
1364  SLOT(ValuesChanged()));
1365 
1366  // InetRef
1368 
1369  // Season
1370  m_seasonSpin->SetRange(0,9999,1,5);
1372 
1373  // Episode
1374  m_episodeSpin->SetRange(0,9999,1,10);
1376 
1377  if (m_coverart)
1378  {
1380  m_coverart->Load();
1381  }
1382 
1383  if (m_fanart)
1384  {
1386  m_fanart->Load();
1387  }
1388 
1389  if (m_banner)
1390  {
1392  m_banner->Load();
1393  }
1394 
1395  BuildFocusList();
1396 
1397  return true;
1398 }
1399 
1401 {
1402  SetTextFromMaps();
1403 }
1404 
1406 {
1407  if (m_busyPopup)
1408  return;
1409 
1410  QString message = title;
1411 
1412  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
1413  "metaoptsdialog");
1414 
1415  if (m_busyPopup->Create())
1417 }
1418 
1420 {
1421  CreateBusyDialog(tr("Trying to manually find this "
1422  "recording online..."));
1423 
1425 
1426  lookup->SetAutomatic(false);
1427  m_metadataFactory->Lookup(lookup);
1428 }
1429 
1431 {
1432  QueryComplete(lookup);
1433 }
1434 
1437 {
1438  QString msg = tr("Downloading selected artwork...");
1439  CreateBusyDialog(msg);
1440 
1441  MetadataLookup *lookup = new MetadataLookup();
1442 
1443  lookup->SetType(kMetadataVideo);
1445  lookup->SetAutomatic(true);
1446  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1447 
1448  ArtworkMap downloads;
1449  downloads.insert(type, info);
1450  lookup->SetDownloads(downloads);
1451  lookup->SetAllowOverwrites(true);
1452  lookup->SetTitle(m_recordingRule->m_title);
1454  lookup->SetInetref(m_inetrefEdit->GetText());
1455  lookup->SetSeason(m_seasonSpin->GetIntValue());
1456  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1457 
1458  m_imageDownload->addDownloads(lookup);
1459 }
1460 
1462 {
1463  if (!CanSetArtwork())
1464  return;
1465 
1466  QString url = generate_file_url("Fanart",
1468  "");
1469  FindImagePopup(url,"",*this, "fanart");
1470 }
1471 
1473 {
1474  if (!CanSetArtwork())
1475  return;
1476 
1477  QString url = generate_file_url("Coverart",
1479  "");
1480  FindImagePopup(url,"",*this, "coverart");
1481 }
1482 
1484 {
1485  if (!CanSetArtwork())
1486  return;
1487 
1488  QString url = generate_file_url("Banners",
1490  "");
1491  FindImagePopup(url,"",*this, "banner");
1492 }
1493 
1495 {
1497 }
1498 
1500 {
1502 }
1503 
1505 {
1507 }
1508 
1510 {
1511  // Season
1512  if (m_seasonSpin)
1514 
1515  // Episode
1516  if (m_episodeSpin)
1518 
1519  // InetRef
1520  if (m_inetrefEdit)
1522 }
1523 
1525 {
1526  if (!lookup)
1527  return;
1528 
1529  // InetRef
1530  m_inetrefEdit->SetText(lookup->GetInetref());
1531 
1532  // Season
1533  m_seasonSpin->SetValue(lookup->GetSeason());
1534 
1535  // Episode
1536  m_episodeSpin->SetValue(lookup->GetEpisode());
1537 
1538  InfoMap metadataMap;
1539  lookup->toMap(metadataMap);
1540  SetTextFromMap(metadataMap);
1541 }
1542 
1544  const QString &prefixAlt,
1545  QObject &inst,
1546  const QString &returnEvent)
1547 {
1548  QString fp;
1549 
1550  if (prefix.startsWith("myth://"))
1551  fp = prefix;
1552  else
1553  fp = prefix.isEmpty() ? prefixAlt : prefix;
1554 
1555  MythScreenStack *popupStack =
1556  GetMythMainWindow()->GetStack("popup stack");
1557 
1558  MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, fp);
1560  if (fb->Create())
1561  {
1562  fb->SetReturnEvent(&inst, returnEvent);
1563  popupStack->AddScreen(fb);
1564  }
1565  else
1566  delete fb;
1567 }
1568 
1570 {
1571  QStringList ret;
1572 
1573  QList<QByteArray> exts = QImageReader::supportedImageFormats();
1574  for (QList<QByteArray>::iterator p = exts.begin(); p != exts.end(); ++p)
1575  {
1576  ret.append(QString("*.").append(*p));
1577  }
1578 
1579  return ret;
1580 }
1581 
1583 {
1584  if (m_inetrefEdit->GetText().isEmpty())
1585  {
1586  ShowOkPopup(tr("You must set a reference number "
1587  "on this rule to set artwork. For items "
1588  "without a metadata source, you can set "
1589  "any unique value."));
1590  return false;
1591  }
1592 
1593  return true;
1594 }
1595 
1597 {
1598  MetadataLookup *lookup = new MetadataLookup();
1599  lookup->SetStep(kLookupSearch);
1600  lookup->SetType(mtype);
1602 
1603  if (type == kUnknownVideo)
1604  {
1606  (m_seasonSpin->GetIntValue() == 0 &&
1607  m_episodeSpin->GetIntValue() == 0))
1608  {
1609  lookup->SetSubtype(kProbableMovie);
1610  }
1611  else
1612  {
1614  }
1615  }
1616  else
1617  {
1618  // we could determine the type from the inetref
1619  lookup->SetSubtype(type);
1620  }
1621  lookup->SetAllowGeneric(true);
1622  lookup->SetHandleImages(false);
1624  lookup->SetTitle(m_recordingRule->m_title);
1626  lookup->SetInetref(m_inetrefEdit->GetText());
1628  lookup->SetSeason(m_seasonSpin->GetIntValue());
1629  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1630 
1631  return lookup;
1632 }
1633 
1635 {
1636  if (!CanSetArtwork())
1637  return;
1638 
1639  QString msg = tr("Searching for available artwork...");
1640  CreateBusyDialog(msg);
1641 
1643 
1644  lookup->SetAutomatic(true);
1645  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1646  m_imageLookup->addLookup(lookup);
1647 }
1648 
1650 {
1651  if (!lookup)
1652  return;
1653 
1654  if (m_busyPopup)
1655  {
1656  m_busyPopup->Close();
1657  m_busyPopup = NULL;
1658  }
1659 
1660  VideoArtworkType type = lookup->GetData().value<VideoArtworkType>();
1661  ArtworkList list = lookup->GetArtwork(type);
1662 
1663  if (list.isEmpty())
1664  {
1665  MythWarningNotification n(tr("No image found"), tr("Schedule Editor"));
1667  return;
1668  }
1669 
1670  ImageSearchResultsDialog *resultsdialog =
1671  new ImageSearchResultsDialog(m_popupStack, list, type);
1672 
1673  connect(resultsdialog, SIGNAL(haveResult(ArtworkInfo, VideoArtworkType)),
1675 
1676  if (resultsdialog->Create())
1677  m_popupStack->AddScreen(resultsdialog);
1678 }
1679 
1681 {
1682  if (!lookup)
1683  return;
1684 
1685  DownloadMap map = lookup->GetDownloads();
1686 
1687  if (map.isEmpty())
1688  return;
1689 
1690  for (DownloadMap::const_iterator i = map.begin(); i != map.end(); ++i)
1691  {
1692  VideoArtworkType type = i.key();
1693  ArtworkInfo info = i.value();
1694 
1695  if (type == kArtworkCoverart)
1696  m_artworkMap.replace(kArtworkCoverart, info);
1697  else if (type == kArtworkFanart)
1698  m_artworkMap.replace(kArtworkFanart, info);
1699  else if (type == kArtworkBanner)
1700  m_artworkMap.replace(kArtworkBanner, info);
1701  }
1702 
1705 
1706  ValuesChanged();
1707 }
1708 
1710 {
1713 
1714  if (m_coverart)
1715  {
1717  m_coverart->Load();
1718  }
1719 
1720  if (m_fanart)
1721  {
1723  m_fanart->Load();
1724  }
1725 
1726  if (m_banner)
1727  {
1729  m_banner->Load();
1730  }
1731 }
1732 
1733 void MetadataOptions::customEvent(QEvent *levent)
1734 {
1735  if (levent->type() == MetadataFactoryMultiResult::kEventType)
1736  {
1737  if (m_busyPopup)
1738  {
1739  m_busyPopup->Close();
1740  m_busyPopup = NULL;
1741  }
1742 
1743  MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
1744 
1745  if (!mfmr)
1746  return;
1747 
1748  MetadataLookupList list = mfmr->results;
1749 
1750  if (list.count() > 1)
1751  {
1752  int yearindex = -1;
1753 
1754  for (int p = 0; p != list.size(); ++p)
1755  {
1756  if (!m_recordingRule->m_seriesid.isEmpty() &&
1757  m_recordingRule->m_seriesid == (list[p])->GetTMSref())
1758  {
1759  MetadataLookup *lookup = list[p];
1760  QueryComplete(lookup);
1761  return;
1762  }
1763  else if (m_recInfo &&
1765  (list[p])->GetYear() != 0 &&
1766  m_recInfo->GetYearOfInitialRelease() == (list[p])->GetYear())
1767  {
1768  if (yearindex > -1)
1769  {
1770  LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite "
1771  "match could be found based on year alone.");
1772  yearindex = -2;
1773  }
1774  else if (yearindex == -1)
1775  {
1776  LOG(VB_GENERAL, LOG_INFO, "Matched based on year. ");
1777  yearindex = p;
1778  }
1779  }
1780  }
1781 
1782  if (yearindex > -1)
1783  {
1784  MetadataLookup *lookup = list[yearindex];
1785  QueryComplete(lookup);
1786  return;
1787  }
1788 
1789  LOG(VB_GENERAL, LOG_INFO, "Falling through to selection dialog.");
1790  MetadataResultsDialog *resultsdialog =
1792 
1793  connect(resultsdialog, SIGNAL(haveResult(RefCountHandler<MetadataLookup>)),
1795  Qt::QueuedConnection);
1796 
1797  if (resultsdialog->Create())
1798  m_popupStack->AddScreen(resultsdialog);
1799  }
1800  }
1801  else if (levent->type() == MetadataFactorySingleResult::kEventType)
1802  {
1803  if (m_busyPopup)
1804  {
1805  m_busyPopup->Close();
1806  m_busyPopup = NULL;
1807  }
1808 
1809  MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
1810 
1811  if (!mfsr)
1812  return;
1813 
1814  MetadataLookup *lookup = mfsr->result;
1815 
1816  if (!lookup)
1817  return;
1818 
1819  QueryComplete(lookup);
1820  }
1821  else if (levent->type() == MetadataFactoryNoResult::kEventType)
1822  {
1823  if (m_busyPopup)
1824  {
1825  m_busyPopup->Close();
1826  m_busyPopup = NULL;
1827  }
1828 
1829  MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
1830 
1831  if (!mfnr)
1832  return;
1833 
1834  QString title = tr("No match found for this recording. You can "
1835  "try entering a TVDB/TMDB number, season, and "
1836  "episode manually.");
1837 
1838  MythConfirmationDialog *okPopup =
1839  new MythConfirmationDialog(m_popupStack, title, false);
1840 
1841  if (okPopup->Create())
1842  m_popupStack->AddScreen(okPopup);
1843  }
1844  else if (levent->type() == MetadataLookupEvent::kEventType)
1845  {
1846  if (m_busyPopup)
1847  {
1848  m_busyPopup->Close();
1849  m_busyPopup = NULL;
1850  }
1851 
1852  MetadataLookupEvent *lue = (MetadataLookupEvent *)levent;
1853 
1854  MetadataLookupList lul = lue->lookupList;
1855 
1856  if (lul.isEmpty())
1857  return;
1858 
1859  if (lul.count() >= 1)
1860  {
1861  OnArtworkSearchDone(lul[0]);
1862  }
1863  }
1864  else if (levent->type() == MetadataLookupFailure::kEventType)
1865  {
1866  if (m_busyPopup)
1867  {
1868  m_busyPopup->Close();
1869  m_busyPopup = NULL;
1870  }
1871 
1873 
1874  MetadataLookupList lul = luf->lookupList;
1875 
1876  if (lul.size())
1877  {
1878  QString title = tr("This number, season, and episode combination "
1879  "does not appear to be valid (or the site may "
1880  "be down). Check your information and try "
1881  "again.");
1882 
1883  MythConfirmationDialog *okPopup =
1884  new MythConfirmationDialog(m_popupStack, title, false);
1885 
1886  if (okPopup->Create())
1887  m_popupStack->AddScreen(okPopup);
1888  }
1889  }
1890  else if (levent->type() == ImageDLEvent::kEventType)
1891  {
1892  if (m_busyPopup)
1893  {
1894  m_busyPopup->Close();
1895  m_busyPopup = NULL;
1896  }
1897 
1898  ImageDLEvent *ide = (ImageDLEvent *)levent;
1899 
1900  MetadataLookup *lookup = ide->item;
1901 
1902  if (!lookup)
1903  return;
1904 
1905  HandleDownloadedImages(lookup);
1906  }
1907  else if (levent->type() == ImageDLFailureEvent::kEventType)
1908  {
1909  if (m_busyPopup)
1910  {
1911  m_busyPopup->Close();
1912  m_busyPopup = NULL;
1913  }
1914  MythErrorNotification n(tr("Failed to retrieve image(s)"),
1915  tr("Schedule Editor"),
1916  tr("Check logs"));
1918  }
1919  else if (levent->type() == DialogCompletionEvent::kEventType)
1920  {
1921  DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent);
1922 
1923  const QString resultid = dce->GetId();
1924  ArtworkInfo info;
1925  info.url = dce->GetResultText();
1926 
1927  if (resultid == "coverart")
1928  {
1929  m_artworkMap.replace(kArtworkCoverart, info);
1930  }
1931  else if (resultid == "fanart")
1932  {
1933  m_artworkMap.replace(kArtworkFanart, info);
1934  }
1935  else if (resultid == "banner")
1936  {
1937  m_artworkMap.replace(kArtworkBanner, info);
1938  }
1939 
1942 
1943  ValuesChanged();
1944  }
1945 
1946 }
1947 
1949 
1956  SchedOptMixin *other)
1957  : m_prioritySpin(NULL), m_startoffsetSpin(NULL), m_endoffsetSpin(NULL),
1958  m_dupmethodList(NULL), m_dupscopeList(NULL), m_inputList(NULL),
1959  m_ruleactiveCheck(NULL), m_newrepeatList(NULL),
1960  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false),
1961  m_haveRepeats(gCoreContext->GetNumSetting("HaveRepeats", 0))
1962 {
1963 }
1964 
1965 void SchedOptMixin::Create(bool *err)
1966 {
1967  if (!m_rule)
1968  return;
1969 
1970  if (m_other && !m_other->m_prioritySpin)
1971  UIUtilE::Assign(m_screen, m_prioritySpin, "priority", err);
1972  else
1973  UIUtilW::Assign(m_screen, m_prioritySpin, "priority");
1974 
1976  UIUtilE::Assign(m_screen, m_startoffsetSpin, "startoffset", err);
1977  else
1978  UIUtilW::Assign(m_screen, m_startoffsetSpin, "startoffset");
1979 
1980  if (m_other && !m_other->m_endoffsetSpin)
1981  UIUtilE::Assign(m_screen, m_endoffsetSpin, "endoffset", err);
1982  else
1983  UIUtilW::Assign(m_screen, m_endoffsetSpin, "endoffset");
1984 
1985  if (m_other && !m_other->m_dupmethodList)
1986  UIUtilE::Assign(m_screen, m_dupmethodList, "dupmethod", err);
1987  else
1988  UIUtilW::Assign(m_screen, m_dupmethodList, "dupmethod");
1989 
1990  if (m_other && !m_other->m_dupscopeList)
1991  UIUtilE::Assign(m_screen, m_dupscopeList, "dupscope", err);
1992  else
1993  UIUtilW::Assign(m_screen, m_dupscopeList, "dupscope");
1994 
1995  if (m_other && !m_other->m_inputList)
1996  UIUtilE::Assign(m_screen, m_inputList, "input", err);
1997  else
1999 
2001  UIUtilE::Assign(m_screen, m_ruleactiveCheck, "ruleactive", err);
2002  else
2003  UIUtilW::Assign(m_screen, m_ruleactiveCheck, "ruleactive");
2004 
2005  UIUtilW::Assign(m_screen, m_newrepeatList, "newrepeat");
2006 }
2007 
2009 {
2010  if (!m_rule)
2011  return;
2012 
2013  // Priority
2014  if (m_prioritySpin)
2015  {
2016  if (!m_loaded)
2017  m_prioritySpin->SetRange(-99,99,1,5);
2019  }
2020 
2021  // Start Offset
2022  if (m_startoffsetSpin)
2023  {
2024  if (!m_loaded)
2025  m_startoffsetSpin->SetRange(480,-480,1,10);
2027  }
2028 
2029  // End Offset
2030  if (m_endoffsetSpin)
2031  {
2032  if (!m_loaded)
2033  m_endoffsetSpin->SetRange(-480,480,1,10);
2035  }
2036 
2037  // Duplicate Match Type
2038  if (m_dupmethodList)
2039  {
2040  if (!m_loaded)
2041  {
2043 
2059 
2060  m_rule->m_dupMethod = dupMethod;
2061  }
2063  }
2064 
2065  // Duplicate Matching Scope
2066  if (m_dupscopeList)
2067  {
2068  if (!m_loaded)
2069  {
2079  if (m_haveRepeats && !m_newrepeatList &&
2081  {
2085  }
2086  }
2088  }
2089 
2090  // Preferred Input
2091  if (m_inputList)
2092  {
2093  if (!m_loaded)
2094  {
2096  QObject::tr("Use any available input"),
2097  qVariantFromValue(0));
2098 
2099  vector<uint> inputids = CardUtil::GetSchedInputList();
2100  for (uint i = 0; i < inputids.size(); ++i)
2101  {
2103  QObject::tr("Prefer input %1")
2104  .arg(CardUtil::GetDisplayName(inputids[i])), inputids[i]);
2105  }
2106  }
2108  }
2109 
2110  // Active/Disabled
2111  if (m_ruleactiveCheck)
2112  {
2114  }
2115 
2116  // Record new and repeat
2117  if (m_newrepeatList)
2118  {
2119  if (!m_loaded)
2120  {
2122  QObject::tr("Record new and repeat "
2123  "episodes"), ENUM_TO_QVARIANT(0));
2125  QObject::tr("Record new episodes only"),
2127  }
2129  (m_rule->m_dupIn & kDupsNewEpi));
2130  }
2131 
2132  m_loaded = true;
2133 
2134  RuleChanged();
2135 }
2136 
2138 {
2139  if (!m_rule)
2140  return;
2141 
2142  if (m_prioritySpin)
2144  if (m_startoffsetSpin)
2146  if (m_endoffsetSpin)
2148  if (m_dupmethodList)
2149  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2150  (m_dupmethodList->GetDataValue().toInt());
2151  if (m_dupscopeList)
2152  {
2153  int mask = ((m_other && m_other->m_newrepeatList) ||
2154  m_newrepeatList) ? kDupsInAll : ~0;
2155  int val = ((m_rule->m_dupIn & ~mask) |
2156  m_dupscopeList->GetDataValue().toInt());
2157  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2158  }
2159  if (m_inputList)
2161  if (m_ruleactiveCheck)
2163  if (m_newrepeatList)
2164  {
2165  int val = ((m_rule->m_dupIn & ~kDupsNewEpi) |
2166  m_newrepeatList->GetDataValue().toInt());
2167  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2168  }
2169 }
2170 
2172 {
2173  if (!m_rule)
2174  return;
2175 
2176  bool isScheduled = (m_rule->m_type != kNotRecording &&
2177  m_rule->m_type != kDontRecord);
2178  bool isSingle = (m_rule->m_type == kSingleRecord ||
2180 
2181  if (m_prioritySpin)
2182  m_prioritySpin->SetEnabled(isScheduled);
2183  if (m_startoffsetSpin)
2184  m_startoffsetSpin->SetEnabled(isScheduled);
2185  if (m_endoffsetSpin)
2186  m_endoffsetSpin->SetEnabled(isScheduled);
2187  if (m_dupmethodList)
2188  m_dupmethodList->SetEnabled(isScheduled && !isSingle);
2189  if (m_dupscopeList)
2190  m_dupscopeList->SetEnabled(isScheduled && !isSingle &&
2192  if (m_inputList)
2193  m_inputList->SetEnabled(isScheduled);
2194  if (m_ruleactiveCheck)
2195  m_ruleactiveCheck->SetEnabled(isScheduled);
2196  if (m_newrepeatList)
2197  m_newrepeatList->SetEnabled(isScheduled && !isSingle && m_haveRepeats);
2198 }
2199 
2201 {
2202  if (!item || !m_rule)
2203  return;
2204 
2205  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2206  (item->GetData().toInt());
2207 
2208  if (m_dupscopeList)
2210 }
2211 
2213 
2220  FilterOptMixin *other)
2221  : m_filtersList(NULL), m_activeFiltersList(NULL),
2222  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2223 {
2224 }
2225 
2226 void FilterOptMixin::Create(bool *err)
2227 {
2228  if (!m_rule)
2229  return;
2230 
2231  if (m_other && !m_other->m_filtersList)
2232  UIUtilE::Assign(m_screen, m_filtersList, "filters", err);
2233  else
2234  UIUtilW::Assign(m_screen, m_filtersList, "filters");
2235 
2236  UIUtilW::Assign(m_screen, m_activeFiltersList, "activefilters");
2237  if (m_activeFiltersList)
2239 }
2240 
2242 {
2243  if (!m_rule)
2244  return;
2245 
2246  if (!m_loaded)
2247  {
2248  MSqlQuery query(MSqlQuery::InitCon());
2249 
2250  query.prepare("SELECT filterid, description, newruledefault "
2251  "FROM recordfilter ORDER BY filterid");
2252 
2253  if (query.exec())
2254  {
2255  while (query.next())
2256  {
2257  m_descriptions << QObject::tr(query.value(1).toString()
2258  .toUtf8().constData());
2259  }
2260  }
2261  m_loaded = true;
2262  }
2263 
2264  if (m_activeFiltersList)
2266 
2267  MythUIButtonListItem *button;
2268  QStringList::iterator Idesc;
2269  int idx;
2270  bool active;
2271  bool not_empty = m_filtersList && !m_filtersList->IsEmpty();
2272  for (Idesc = m_descriptions.begin(), idx = 0;
2273  Idesc != m_descriptions.end(); ++Idesc, ++idx)
2274  {
2275  active = m_rule->m_filter & (1 << idx);
2276  if (m_filtersList)
2277  {
2278  if (not_empty)
2279  button = m_filtersList->GetItemAt(idx);
2280  else
2281  button = new MythUIButtonListItem(m_filtersList, *Idesc, idx);
2282  button->setCheckable(true);
2285  }
2286  if (active && m_activeFiltersList)
2287  {
2288  /* Create a simple list of active filters the theme can
2289  use for informational purposes. */
2291  *Idesc, idx);
2292  button->setCheckable(false);
2293  }
2294  }
2295 
2297  {
2299  QObject::tr("None"), idx);
2300  button->setCheckable(false);
2301  }
2302 
2303  RuleChanged();
2304 }
2305 
2307 {
2308  if (!m_rule || !m_filtersList)
2309  return;
2310 
2311  // Iterate through button list, and build the mask
2312  MythUIButtonListItem *button;
2313  uint32_t filter_mask = 0;
2314  int idx, end;
2315 
2316  end = m_filtersList->GetCount();
2317  for (idx = 0; idx < end; ++idx)
2318  {
2319  if ((button = m_filtersList->GetItemAt(idx)) &&
2321  filter_mask |= (1 << button->GetData().value<uint32_t>());
2322  }
2323  m_rule->m_filter = filter_mask;
2324 }
2325 
2327 {
2328  if (!m_rule)
2329  return;
2330 
2331  bool enabled = m_rule->m_type != kNotRecording &&
2333  if (m_filtersList)
2334  m_filtersList->SetEnabled(enabled);
2335  if (m_activeFiltersList)
2336  m_activeFiltersList->SetEnabled(enabled);
2337 }
2338 
2340 {
2344 }
2345 
2346 
2348 
2355  StoreOptMixin *other)
2356  : m_recprofileList(NULL), m_recgroupList(NULL), m_storagegroupList(NULL),
2357  m_playgroupList(NULL), m_maxepSpin(NULL), m_maxbehaviourList(NULL),
2358  m_autoexpireCheck(NULL),
2359  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2360 {
2361 }
2362 
2363 void StoreOptMixin::Create(bool *err)
2364 {
2365  if (!m_rule)
2366  return;
2367 
2368  if (m_other && !m_other->m_recprofileList)
2369  UIUtilE::Assign(m_screen, m_recprofileList, "recprofile", err);
2370  else
2371  UIUtilW::Assign(m_screen, m_recprofileList, "recprofile");
2372 
2373  if (m_other && !m_other->m_recgroupList)
2374  UIUtilE::Assign(m_screen, m_recgroupList, "recgroup", err);
2375  else
2376  UIUtilW::Assign(m_screen, m_recgroupList, "recgroup");
2377 
2379  UIUtilE::Assign(m_screen, m_storagegroupList, "storagegroup", err);
2380  else
2381  UIUtilW::Assign(m_screen, m_storagegroupList, "storagegroup");
2382 
2383  if (m_other && !m_other->m_playgroupList)
2384  UIUtilE::Assign(m_screen, m_playgroupList, "playgroup", err);
2385  else
2386  UIUtilW::Assign(m_screen, m_playgroupList, "playgroup");
2387 
2388  if (m_other && !m_other->m_maxepSpin)
2389  UIUtilE::Assign(m_screen, m_maxepSpin, "maxepisodes", err);
2390  else
2391  UIUtilW::Assign(m_screen, m_maxepSpin, "maxepisodes");
2392 
2394  UIUtilE::Assign(m_screen, m_maxbehaviourList, "maxnewest", err);
2395  else
2397 
2399  UIUtilE::Assign(m_screen, m_autoexpireCheck, "autoexpire", err);
2400  else
2401  UIUtilW::Assign(m_screen, m_autoexpireCheck, "autoexpire");
2402 }
2403 
2405 {
2406  if (!m_rule)
2407  return;
2408 
2409  QString label;
2410  QStringList groups;
2411  QStringList::Iterator it;
2412  MSqlQuery query(MSqlQuery::InitCon());
2413 
2414  // Recording Profile
2415  if (m_recprofileList)
2416  {
2417  if (!m_loaded)
2418  {
2419  label = QObject::tr("Record using the %1 profile");
2420 
2422  label.arg(QObject::tr("Default")),
2423  qVariantFromValue(QString("Default")));
2424  // LiveTV profile - it's for LiveTV not scheduled recordings??
2426  label.arg(QObject::tr("LiveTV")),
2427  qVariantFromValue(QString("LiveTV")));
2429  label.arg(QObject::tr("High Quality")),
2430  qVariantFromValue(QString("High Quality")));
2432  label.arg(QObject::tr("Low Quality")),
2433  qVariantFromValue(QString("Low Quality")));
2434  }
2436  }
2437 
2438  // Recording Group
2439  if (m_recgroupList)
2440  {
2441  if (!m_loaded)
2442  {
2443  label = QObject::tr("Include in the \"%1\" recording group");
2445  QObject::tr("Create a new recording group"),
2446  qVariantFromValue(QString("__NEW_GROUP__")));
2447 
2448  query.prepare("SELECT recgroupid, recgroup FROM recgroups "
2449  "WHERE recgroup <> 'Deleted' AND "
2450  " recgroup <> 'LiveTV' "
2451  "ORDER BY special DESC, recgroup ASC"); // Special groups first
2452  if (query.exec())
2453  {
2454  while (query.next())
2455  {
2456  int id = query.value(0).toInt();
2457  QString name = query.value(1).toString();
2458 
2459  if (name == "Default")
2460  name = QObject::tr("Default");
2461  new MythUIButtonListItem(m_recgroupList, label.arg(name),
2462  qVariantFromValue(id));
2463  }
2464  }
2465 
2466  }
2468  }
2469 
2470  // Storage Group
2471  if (m_storagegroupList)
2472  {
2473  if (!m_loaded)
2474  {
2475  label = QObject::tr("Store in the \"%1\" storage group");
2477  label.arg(QObject::tr("Default")),
2478  qVariantFromValue(QString("Default")));
2479 
2481  for (it = groups.begin(); it != groups.end(); ++it)
2482  {
2483  if ((*it).compare("Default", Qt::CaseInsensitive) != 0)
2485  label.arg(*it), qVariantFromValue(*it));
2486  }
2487  }
2489  }
2490 
2491  // Playback Group
2492  if (m_playgroupList)
2493  {
2494  if (!m_loaded)
2495  {
2496  label = QObject::tr("Use \"%1\" playback group settings");
2498  label.arg(QObject::tr("Default")),
2499  qVariantFromValue(QString("Default")));
2500 
2501  groups = PlayGroup::GetNames();
2502  for (it = groups.begin(); it != groups.end(); ++it)
2503  {
2504  new MythUIButtonListItem(m_playgroupList, label.arg(*it),
2505  qVariantFromValue(*it));
2506  }
2507  }
2509  }
2510 
2511  // Max Episodes
2512  if (m_maxepSpin)
2513  {
2514  if (!m_loaded)
2515  {
2516  int maxEpisodes = m_rule->m_maxEpisodes;
2517  m_maxepSpin->SetRange(0,100,1,5);
2518  m_rule->m_maxEpisodes = maxEpisodes;
2519  }
2521  }
2522 
2523  // Max Episode Behaviour
2524  if (m_maxbehaviourList)
2525  {
2526  if (!m_loaded)
2527  {
2529  QObject::tr("Don't record if this would exceed the max "
2530  "episodes"), qVariantFromValue(false));
2532  QObject::tr("Delete oldest if this would exceed the max "
2533  "episodes"), qVariantFromValue(true));
2534  }
2536  }
2537 
2538  // Auto-Expire
2539  if (m_autoexpireCheck)
2540  {
2542  }
2543 
2544  m_loaded = true;
2545 
2546  RuleChanged();
2547 }
2548 
2550 {
2551  if (!m_rule)
2552  return;
2553 
2554  if (m_recprofileList)
2556 
2557  if (m_recgroupList)
2558  {
2559  // If the user selected 'Create a new regroup' but failed to enter a
2560  // name when prompted, restore the original value
2561  if (m_recgroupList->GetDataValue().toString() == "__NEW_GROUP__")
2564  }
2565 
2566  if (m_storagegroupList)
2568 
2569  if (m_playgroupList)
2571 
2572  if (m_maxepSpin)
2574 
2575  if (m_maxbehaviourList)
2577 
2578  if (m_autoexpireCheck)
2580 }
2581 
2583 {
2584  if (!m_rule)
2585  return;
2586 
2587  bool isScheduled = (m_rule->m_type != kNotRecording &&
2588  m_rule->m_type != kDontRecord);
2589  bool isSingle = (m_rule->m_type == kSingleRecord ||
2591 
2592  if (m_recprofileList)
2593  m_recprofileList->SetEnabled(isScheduled);
2594  if (m_recgroupList)
2595  m_recgroupList->SetEnabled(isScheduled);
2596  if (m_storagegroupList)
2597  m_storagegroupList->SetEnabled(isScheduled);
2598  if (m_playgroupList)
2599  m_playgroupList->SetEnabled(isScheduled);
2600  if (m_maxepSpin)
2601  m_maxepSpin->SetEnabled(isScheduled && !isSingle);
2602  if (m_maxbehaviourList)
2603  m_maxbehaviourList->SetEnabled(isScheduled && !isSingle &&
2604  m_rule->m_maxEpisodes != 0);
2605  if (m_autoexpireCheck)
2606  m_autoexpireCheck->SetEnabled(isScheduled);
2607 }
2608 
2610 {
2611  if (!item || !m_rule)
2612  return;
2613 
2614  m_rule->m_maxEpisodes = item->GetData().toInt();
2615 
2616  if (m_maxbehaviourList)
2618 }
2619 
2621 {
2622  if (!m_rule)
2623  return;
2624 
2625  if (m_recgroupList->GetDataValue().toString() != "__NEW_GROUP__")
2626  return;
2627 
2628  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2629 
2630  QString label =
2631  QObject::tr("New Recording group name: ");
2632 
2633  MythTextInputDialog *textDialog =
2634  new MythTextInputDialog(popupStack, label,
2635  static_cast<InputFilter>(FilterSymbols | FilterPunct));
2636 
2637  textDialog->SetReturnEvent(m_screen, "newrecgroup");
2638 
2639  if (textDialog->Create())
2640  popupStack->AddScreen(textDialog, false);
2641 }
2642 
2643 void StoreOptMixin::SetRecGroup(int recgroupID, QString recgroup)
2644 {
2645  if (!m_rule || recgroupID <= 0)
2646  return;
2647 
2648  if (m_recgroupList)
2649  {
2650  recgroup = recgroup.trimmed();
2651  if (recgroup.isEmpty())
2652  return;
2653 
2654  QString label = QObject::tr("Include in the \"%1\" recording group");
2655  MythUIButtonListItem *item =
2656  new MythUIButtonListItem(m_recgroupList, label.arg(recgroup),
2657  qVariantFromValue(recgroup));
2659 
2660  if (m_other && m_other->m_recgroupList)
2661  {
2663  label.arg(recgroup), qVariantFromValue(recgroupID));
2665  }
2666  }
2667 }
2668 
2669 int StoreOptMixin::CreateRecordingGroup(const QString& groupName)
2670 {
2671  int groupID = -1;
2672  MSqlQuery query(MSqlQuery::InitCon());
2673 
2674  query.prepare("INSERT INTO recgroups SET recgroup = :NAME, "
2675  "displayname = :DISPLAYNAME");
2676  query.bindValue(":NAME", groupName);
2677  query.bindValue(":DISPLAYNAME", groupName);
2678 
2679  if (query.exec())
2680  groupID = query.lastInsertId().toInt();
2681 
2682  if (groupID <= 0)
2683  LOG(VB_GENERAL, LOG_ERR, QString("Could not create recording group (%1). "
2684  "Does it already exist?").arg(groupName));
2685 
2686  return groupID;
2687 }
2688 
2690 
2697  PostProcMixin *other)
2698  : m_commflagCheck(NULL), m_transcodeCheck(NULL),
2699  m_transcodeprofileList(NULL), m_userjob1Check(NULL),
2700  m_userjob2Check(NULL), m_userjob3Check(NULL), m_userjob4Check(NULL),
2701  m_metadataLookupCheck(NULL),
2702  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2703 {
2704 }
2705 
2706 void PostProcMixin::Create(bool *err)
2707 {
2708  if (!m_rule)
2709  return;
2710 
2711  if (m_other && !m_other->m_commflagCheck)
2712  UIUtilE::Assign(m_screen, m_commflagCheck, "autocommflag", err);
2713  else
2714  UIUtilW::Assign(m_screen, m_commflagCheck, "autocommflag");
2715 
2716  if (m_other && !m_other->m_transcodeCheck)
2717  UIUtilE::Assign(m_screen, m_transcodeCheck, "autotranscode", err);
2718  else
2719  UIUtilW::Assign(m_screen, m_transcodeCheck, "autotranscode");
2720 
2722  UIUtilE::Assign(m_screen, m_transcodeprofileList, "transcodeprofile", err);
2723  else
2724  UIUtilW::Assign(m_screen, m_transcodeprofileList, "transcodeprofile");
2725 
2726  if (m_other && !m_other->m_userjob1Check)
2727  UIUtilE::Assign(m_screen, m_userjob1Check, "userjob1", err);
2728  else
2730 
2731  if (m_other && !m_other->m_userjob2Check)
2732  UIUtilE::Assign(m_screen, m_userjob2Check, "userjob2", err);
2733  else
2735 
2736  if (m_other && !m_other->m_userjob3Check)
2737  UIUtilE::Assign(m_screen, m_userjob3Check, "userjob3", err);
2738  else
2740 
2741  if (m_other && !m_other->m_userjob4Check)
2742  UIUtilE::Assign(m_screen, m_userjob4Check, "userjob4", err);
2743  else
2745 
2746  UIUtilW::Assign(m_screen, m_metadataLookupCheck, "metadatalookup");
2747 }
2748 
2750 {
2751  if (!m_rule)
2752  return;
2753 
2754  // Auto-commflag
2755  if (m_commflagCheck)
2756  {
2758  }
2759 
2760  // Auto-transcode
2761  if (m_transcodeCheck)
2762  {
2764  }
2765 
2766  // Transcode Method
2768  {
2769  if (!m_loaded)
2770  {
2771  QMap<int, QString> profiles = RecordingProfile::GetTranscodingProfiles();
2772  QMap<int, QString>::iterator it;
2773  for (it = profiles.begin(); it != profiles.end(); ++it)
2774  {
2776  qVariantFromValue(it.key()));
2777  }
2778  }
2780  }
2781 
2782  // User Job #1
2783  if (m_userjob1Check)
2784  {
2785  if (!m_loaded)
2786  {
2787  MythUIText *userjob1Text = NULL;
2788  UIUtilW::Assign(m_screen, userjob1Text, "userjob1text");
2789  if (userjob1Text)
2790  userjob1Text->SetText(QObject::tr("Run '%1'")
2791  .arg(gCoreContext->GetSetting("UserJobDesc1", "User Job 1")));
2792  }
2794  }
2795 
2796  // User Job #2
2797  if (m_userjob2Check)
2798  {
2799  if (!m_loaded)
2800  {
2801  MythUIText *userjob2Text = NULL;
2802  UIUtilW::Assign(m_screen, userjob2Text, "userjob2text");
2803  if (userjob2Text)
2804  userjob2Text->SetText(QObject::tr("Run '%1'")
2805  .arg(gCoreContext->GetSetting("UserJobDesc2", "User Job 2")));
2806  }
2808  }
2809 
2810  // User Job #3
2811  if (m_userjob3Check)
2812  {
2813  if (!m_loaded)
2814  {
2815  MythUIText *userjob3Text = NULL;
2816  UIUtilW::Assign(m_screen, userjob3Text, "userjob3text");
2817  if (userjob3Text)
2818  userjob3Text->SetText(QObject::tr("Run '%1'")
2819  .arg(gCoreContext->GetSetting("UserJobDesc3", "User Job 3")));
2820  }
2822  }
2823 
2824  // User Job #4
2825  if (m_userjob4Check)
2826  {
2827  if (!m_loaded)
2828  {
2829  MythUIText *userjob4Text = NULL;
2830  UIUtilW::Assign(m_screen, userjob4Text, "userjob4text");
2831  if (userjob4Text)
2832  userjob4Text->SetText(QObject::tr("Run '%1'")
2833  .arg(gCoreContext->GetSetting("UserJobDesc4", "User Job 4")));
2834  }
2836  }
2837 
2838  // Auto Metadata Lookup
2840  {
2842  }
2843 
2844  m_loaded = true;
2845 
2846  RuleChanged();
2847 }
2848 
2850 {
2851  if (!m_rule)
2852  return;
2853 
2854  if (m_commflagCheck)
2856  if (m_transcodeCheck)
2860  if (m_userjob1Check)
2862  if (m_userjob2Check)
2864  if (m_userjob3Check)
2866  if (m_userjob4Check)
2871 }
2872 
2874 {
2875  if (!m_rule)
2876  return;
2877 
2878  bool isScheduled = (m_rule->m_type != kNotRecording &&
2879  m_rule->m_type != kDontRecord);
2880 
2881  if (m_commflagCheck)
2882  m_commflagCheck->SetEnabled(isScheduled);
2883  if (m_transcodeCheck)
2884  m_transcodeCheck->SetEnabled(isScheduled);
2886  m_transcodeprofileList->SetEnabled(isScheduled &&
2888  if (m_userjob1Check)
2889  m_userjob1Check->SetEnabled(isScheduled);
2890  if (m_userjob2Check)
2891  m_userjob2Check->SetEnabled(isScheduled);
2892  if (m_userjob3Check)
2893  m_userjob3Check->SetEnabled(isScheduled);
2894  if (m_userjob4Check)
2895  m_userjob4Check->SetEnabled(isScheduled);
2897  m_metadataLookupCheck->SetEnabled(isScheduled);
2898 }
2899 
2901 {
2902  if (!m_rule)
2903  return;
2904 
2905  m_rule->m_autoTranscode = enable;
2906 
2909 }
QString m_subtitle
Definition: recordingrule.h:76
MetadataFactory * m_metadataFactory
MythScreenType * m_screen
void Create(bool *err)
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:798
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=NULL)
Definition: mythuiutils.h:27
MythUICheckBox * m_commflagCheck
void SetTitle(const QString &title)
void SetHandleImages(bool handle)
void MaxEpisodesChanged(MythUIButtonListItem *)
static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor", "Prime time"))
MythScreenStack * GetScreenStack() const
Select post-processing options.
void ruleDeleted(int ruleId)
void showUpcomingByTitle(void)
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:897
static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor", "This episode"))
ArtworkList GetArtwork(VideoArtworkType type) const
MythUICheckBox * m_ruleactiveCheck
void RuleChanged(void)
void DupMethodChanged(MythUIButtonListItem *)
void SetSubtitle(const QString &subtitle)
MetadataLookupList results
void SetAutomatic(bool autom)
#define ENUM_TO_QVARIANT(a)
void UseTempTable(bool usetemp, QString table="record_tmp")
MythUISpinBox * m_endoffsetSpin
bool StartEmbedding(const QRect &)
Definition: tv_play.cpp:8587
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...
ScheduleEditor(MythScreenStack *parent, RecordingInfo *recinfo, TV *player=NULL)
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
bool LoadByProgram(const ProgramInfo *proginfo)
MythUIButton * m_localFanartButton
Dialog asking for user confirmation.
Select schedule filters.
void ToggleSelected(MythUIButtonListItem *item)
void LosingFocus()
void SetEnabled(bool enable)
Select artwork and inetref for recordings.
bool Delete(bool sendSig=true)
virtual bool keyPressEvent(QKeyEvent *event)
Key event handler.
void TranscodeChanged(bool enable)
RecordingRule * m_recordingRule
MythScreenType * m_screen
MythUIButtonList * m_filtersList
MythConfirmationDialog * ShowOkPopup(const QString &message, QObject *parent, const char *slot, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
void showUpcomingByRule(void)
All purpose text widget, displays a text string.
Definition: mythuitext.h:28
static QString fs8(QT_TRANSLATE_NOOP("SchedFilterEditor", "This time"))
MetadataType
virtual void ShowUpcoming(void) const
Show the upcoming recordings for this title.
ArtworkMap m_artworkMap
MythUISpinBox * m_prioritySpin
PostProcEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
void ToMap(InfoMap &infoMap) const
enum RecordingDupInTypes RecordingDupInType
void templateLoaded(void)
virtual void Close(void)
void SetInetref(const QString &inetref)
MetadataLookupList lookupList
void FindImagePopup(const QString &prefix, const QString &prefixAlt, QObject &inst, const QString &returnEvent)
void SetData(QVariant data)
void MaxEpisodesChanged(MythUIButtonListItem *)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
void SetAllowOverwrites(bool allow)
MythUIButtonList * m_playgroupList
void TranscodeChanged(bool enable)
LookupType GuessLookupType(ProgramInfo *pginfo)
Basic menu dialog, message and a list of options.
void SetRule(RecordingRule *rule)
void Create(bool *err)
void SetReturnEvent(QObject *retobject, const QString &resultid)
VideoArtworkType
static QString fs9(QT_TRANSLATE_NOOP("SchedFilterEditor", "This day and time"))
MythUICheckBox * m_userjob4Check
MythUIButton * m_filtersButton
QString m_storageGroup
static QStringList getRecordingsGroups(void)
virtual bool Create(void)
bool SetArtwork(const QString &inetref, uint season, const QString &host, const QString &coverart, const QString &fanart, const QString &banner)
QString m_station
Definition: recordingrule.h:93
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:166
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
void ToggleSelected(MythUIButtonListItem *item)
void Load(void)
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
MythScreenStack * GetStack(const QString &stackname)
static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor", "Commercial free"))
RecordingInfo * m_recInfo
void CreateBusyDialog(QString title)
unsigned int uint
Definition: compat.h:136
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
RecordingType m_type
Definition: recordingrule.h:99
MythScreenStack * GetMainStack()
MythUIButton * m_schedOptButton
virtual void ShowDetails(void) const
Show the Program Details screen.
void showTemplateMenu(void)
SchedEditChild * m_child
RecordingDupMethodType m_dupMethod
void ShowSchedInfo(void)
MythUIButtonListItem * GetItemAt(int pos) const
static vector< uint > GetSchedInputList(void)
Definition: cardutil.cpp:2108
Select schedule options.
static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor", "This series"))
static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor", "First showing"))
void SetRule(RecordingRule *rule)
SchedEditChild(MythScreenStack *parent, const QString &name, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
void customEvent(QEvent *event)
MythUITextEdit * m_inetrefEdit
void DeleteRule(void)
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Mixin for schedule options.
static QString fs10(QT_TRANSLATE_NOOP("SchedFilterEditor", "This channel"))
void BuildFocusList(void)
static Type kEventType
Definition: mythdialogbox.h:50
MetadataLookup * item
RecordingRule * m_recordingRule
MetadataLookup * CreateLookup(MetadataType mtype)
MythUICheckBox * m_metadataLookupCheck
MythUIImage * m_fanart
uint GetSeason() const
void SetStep(LookupStep step)
RecordingDupMethodType
void SetNameFilter(QStringList filter)
QVariant value(int i) const
Definition: mythdbcon.h:182
void MaxEpisodesChanged(MythUIButtonListItem *)
virtual void Close()
MythUIButton * m_cancelButton
void setCheckable(bool flag)
MythScreenType * m_screen
MythUIButton * m_onlineFanartButton
void AddButton(const QString &title, QVariant data=0, bool newMenu=false, bool setCurrent=false)
bool Save(bool sendSig=true)
uint GetEpisode() const
Holds information on recordings and videos.
Definition: programinfo.h:66
void SetRange(int low, int high, int step, uint pageMultiple=5)
Set the lower and upper bounds of the spinbox, the interval and page amount.
RecordingRule * m_rule
void OnArtworkSearchDone(MetadataLookup *lookup)
bool GetBooleanCheckState(void) const
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Select storage options.
void toMap(InfoMap &map)
MythUIButton * m_metadataButton
void SetValueByData(QVariant data)
MythUICheckBox * m_transcodeCheck
This class is used as a container for messages.
Definition: mythevent.h:15
void DupMethodChanged(MythUIButtonListItem *)
MythUIButton * m_saveButton
void Reset()
Reset the widget to it&#39;s original state, should not reset changes made by the theme.
RecordingRule * m_rule
virtual void Load(void)=0
virtual void ShowGuide(void) const
Show the program guide.
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:83
virtual void ShowPrevious(void) const
Show the previous recordings for this recording rule.
MythUIButtonList * m_storagegroupList
void FilterChanged(MythUIButtonListItem *)
void ruleSaved(int ruleId)
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:924
static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor", "Identifiable episode"))
Mixin for Filters.
MythUIButton * m_filtersButton
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MythUIImage * m_coverart
void customEvent(QEvent *event)
void SetAllowGeneric(bool allow)
Construct a recording schedule.
bool m_autoMetadataLookup
QString GetSetting(const QString &key, const QString &defaultval="")
void RuleChanged(void)
MythUICheckBox * m_autoexpireCheck
void SetReturnEvent(QObject *retobject, const QString &resultid)
void addDownloads(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_downloadList takes ownership of the ...
QString m_playGroup
void Create(bool *err)
MythUIButtonList * m_inputList
MythUIButton * m_backButton
static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor", "High definition"))
void ShowPostProc(void)
StoreOptEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
MythUIButton * m_schedInfoButton
virtual void SetTextFromMap(const InfoMap &infoMap)
Control TV playback.
Definition: tv_play.h:290
QString GetMasterHostName(void)
RecordingRule * m_rule
QVariant GetDataValue() const
MythUIButton * m_saveButton
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
virtual bool CreateEditChild(const QString &xmlfile, const QString &winname, bool isTemplate)
Mixin for storage options.
void SetRule(RecordingRule *rule)
void Closing(void)
uint GetSeason(void) const
Definition: programinfo.h:346
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:555
void FindNetArt(VideoArtworkType type)
MythUIBusyDialog * m_busyPopup
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:31
void SetDownloads(ArtworkMap map)
void SetRecGroup(int recgroupID, QString recgroup)
QString GetInetref() const
const char * name
Definition: ParseText.cpp:339
void ShowSchedOpt(void)
void ShowFilters(void)
FilterOptMixin * m_other
void ShowMetadataOptions(void)
QString m_seriesid
Definition: recordingrule.h:87
MythUIButton * m_localBannerButton
MythUIButton * m_previewButton
static void * RunScheduleEditor(ProgramInfo *proginfo, void *player=NULL)
Callback.
CheckState state() const
void SetSeason(uint season)
RecordingRule * m_rule
MythUIButtonList * m_newrepeatList
RecordingInfo * m_recInfo
void PromptForRecGroup(void)
MythUIButton * m_postProcButton
void SetCollectionref(const QString &collectionref)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
RecordingDupInType m_dupIn
bool keyPressEvent(QKeyEvent *event)
Key event handler.
void ChildClosing(void)
void SetText(const QString &text, bool moveCursor=true)
QVariant GetData() const
MythUIType * GetFocusWidget(void) const
QString m_inetref
Definition: recordingrule.h:89
MythMainWindow * GetMythMainWindow(void)
void Create(bool *err)
QStringList GetSupportedImageExtensionFilter()
MythScreenType * m_screen
QList< ArtworkInfo > ArtworkList
MythUIImage * m_banner
MetadataDownload * m_imageLookup
uint GetYearOfInitialRelease(void) const
Definition: programinfo.h:403
void PromptForRecGroup(void)
MythUISpinBox * m_startoffsetSpin
MythUISpinBox * m_seasonSpin
MythUIButton * m_onlineBannerButton
MythUIButtonList * m_transcodeprofileList
static QString fs11(QT_TRANSLATE_NOOP("SchedFilterEditor", "No episodes"))
Dialog prompting the user to enter a text string.
void TranscodeChanged(bool enable)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:823
void DupMethodChanged(MythUIButtonListItem *item)
MythUICheckBox * m_userjob3Check
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:38
static Type kEventType
bool IsLoaded() const
Definition: recordingrule.h:55
void OnSearchListSelection(RefCountHandler< MetadataLookup > lookup)
void QueryComplete(MetadataLookup *lookup)
QString m_title
Recording rule is enabled?
Definition: recordingrule.h:75
void SetHost(const QString &host)
void RuleChanged(void)
virtual bool keyPressEvent(QKeyEvent *)
Key event handler.
void ShowStoreOpt(void)
MythUIButton * m_onlineCoverartButton
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
void SetReturnEvent(QObject *retobject, const QString &resultid)
void showMenu(void)
MythUICheckBox * m_userjob2Check
void Lookup(ProgramInfo *pginfo, bool automatic=true, bool getimages=true, bool allowgeneric=false)
void OnImageSearchListSelection(ArtworkInfo info, VideoArtworkType type)
void SetSubtype(LookupType subtype)
void SetValue(int val)
Definition: mythuispinbox.h:25
MythUIButtonList * m_maxbehaviourList
QString m_recProfile
uint GetRecordingRuleID(void) const
Definition: programinfo.h:430
void SetRule(RecordingRule *rule)
MetadataLookupList lookupList
MythUIButton * m_previewButton
QStringList m_descriptions
MythScreenStack * m_popupStack
bool CanSetArtwork(void)
static QStringList GetNames(void)
Definition: playgroup.cpp:206
SchedFilterEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
void SetCheckState(MythUIStateType::StateType state)
MythUIButtonList * m_dupscopeList
bool Load(bool asTemplate=false)
void SetType(MetadataType type)
unsigned m_filter
QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
Definition: videoutils.h:65
FilterOptMixin(MythScreenType &screen, RecordingRule *rule, FilterOptMixin *other=NULL)
QString m_category
Definition: recordingrule.h:80
MythUICheckBox * m_userjob1Check
void LoadTemplate(QString name)
void SetItemCurrent(MythUIButtonListItem *item)
bool LoadTemplate(QString category, QString categoryType="Default")
MythUIButton * m_queryButton
DownloadMap GetDownloads() const
static QMap< int, QString > GetTranscodingProfiles()
virtual void PopScreen(MythScreenType *screen=NULL, bool allowFade=true, bool deleteScreen=true)
MetadataImageDownload * m_imageDownload
MythUIButton * m_localCoverartButton
static QStringList GetTemplateNames(void)
void PromptForRecGroup(void)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:623
MythUIButtonList * m_dupmethodList
void SetEpisode(uint episode)
Screen in which all other widgets are contained and rendered.
MythUISpinBox * m_maxepSpin
void customEvent(QEvent *event)
bool Create(void)
Definition: proglist.cpp:153
ScheduleEditor * m_editor
MythUIButtonList * m_activeFiltersList
void addLookup(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_lookupList takes ownership of the gi...
ArtworkMap GetArtwork(QString inetref, uint season, bool strict)
MythUISpinBox * m_episodeSpin
QMultiMap< VideoArtworkType, ArtworkInfo > ArtworkMap
virtual void Save(void)=0
LookupType
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form...
Definition: mythdialogbox.h:37
void ShowNextView(void)
MythUIButton * m_storeOptButton
StoreOptMixin * m_other
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
Definition: mythuitype.cpp:367
void ShowPreviousView(void)
PostProcMixin(MythScreenType &screen, RecordingRule *rule, PostProcMixin *other=NULL)
MythUIButtonList * m_recprofileList
CategoryType GetCategoryType(void) const
Definition: programinfo.h:418
int GetIntValue(void) const
Definition: mythuispinbox.h:29
static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor", "New episode"))
MetadataOptions(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
PostProcMixin * m_other
SchedOptMixin(MythScreenType &screen, RecordingRule *rule, SchedOptMixin *other=NULL)
void setChecked(CheckState state)
int CreateRecordingGroup(const QString &groupName)
SchedOptMixin * m_other
MythUIButtonList * m_recgroupList
void ShowPreview(void)
RecSearchType m_searchType
Mixin for post processing.
QString GetText(void) const
MythNotificationCenter * GetNotificationCenter(void)
MythUIButtonListItem * GetItemCurrent() const
MythUIButtonList * m_rulesList
uint GetEpisode(void) const
Definition: programinfo.h:347
SchedOptEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
void SetTextFromMaps(void)
void RuleChanged(void)
StoreOptMixin(MythScreenType &screen, RecordingRule *rule, StoreOptMixin *other=NULL)
static QString GetDisplayName(uint inputid)
Definition: cardutil.cpp:1141
void HandleDownloadedImages(MetadataLookup *lookup)