MythTV  0.28pre
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 
64 void *ScheduleEditor::RunScheduleEditor(ProgramInfo *proginfo, void *player)
65 {
66  RecordingRule *rule = new RecordingRule();
67  rule->LoadByProgram(proginfo);
68 
70  ScheduleEditor *se = new ScheduleEditor(mainStack, rule,
71  static_cast<TV*>(player));
72 
73  if (se->Create())
74  mainStack->AddScreen(se, (player == NULL));
75  else
76  delete se;
77 
78  return NULL;
79 }
80 
87  RecordingInfo *recInfo, TV *player)
88  : ScheduleCommon(parent, "ScheduleEditor"),
89  SchedOptMixin(*this, NULL), FilterOptMixin(*this, NULL),
90  StoreOptMixin(*this, NULL), PostProcMixin(*this, NULL),
91  m_recInfo(new RecordingInfo(*recInfo)), m_recordingRule(NULL),
92  m_sendSig(false),
93  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
94  m_schedOptButton(NULL), m_storeOptButton(NULL),
95  m_postProcButton(NULL), m_schedInfoButton(NULL),
96  m_previewButton(NULL), m_metadataButton(NULL),
97  m_filtersButton(NULL),
98  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
99 {
106 }
107 
109  RecordingRule *recRule, TV *player)
110  : ScheduleCommon(parent, "ScheduleEditor"),
111  SchedOptMixin(*this, recRule),
112  FilterOptMixin(*this, recRule),
113  StoreOptMixin(*this, recRule),
114  PostProcMixin(*this, recRule),
115  m_recInfo(NULL), m_recordingRule(recRule),
116  m_sendSig(false),
117  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
118  m_schedOptButton(NULL), m_storeOptButton(NULL),
119  m_postProcButton(NULL), m_schedInfoButton(NULL),
120  m_previewButton(NULL), m_metadataButton(NULL),
121  m_filtersButton(NULL),
122  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
123 {
124 }
125 
127 {
128  delete m_recordingRule;
129 
130  // if we have a player, we need to tell we are done
131  if (m_player)
132  {
133  QString message = QString("VIEWSCHEDULED_EXITING");
134  qApp->postEvent(m_player, new MythEvent(message));
135  }
136 }
137 
139 {
140  if (!LoadWindowFromXML("schedule-ui.xml", "scheduleeditor", this))
141  return false;
142 
143  bool err = false;
144 
145  UIUtilE::Assign(this, m_rulesList, "rules", &err);
146 
147  UIUtilW::Assign(this, m_schedOptButton, "schedoptions");
148  UIUtilW::Assign(this, m_storeOptButton, "storeoptions");
149  UIUtilW::Assign(this, m_postProcButton, "postprocessing");
150  UIUtilW::Assign(this, m_metadataButton, "metadata");
151  UIUtilW::Assign(this, m_schedInfoButton, "schedinfo");
152  UIUtilW::Assign(this, m_previewButton, "preview");
153  UIUtilW::Assign(this, m_filtersButton, "filters");
154 
155  SchedOptMixin::Create(&err);
157  StoreOptMixin::Create(&err);
158  PostProcMixin::Create(&err);
159 
160  UIUtilW::Assign(this, m_cancelButton, "cancel");
161  UIUtilE::Assign(this, m_saveButton, "save", &err);
162 
163  if (err)
164  {
165  LOG(VB_GENERAL, LOG_ERR, "ScheduleEditor, theme is missing "
166  "required elements");
167  return false;
168  }
169 
170  connect(m_rulesList, SIGNAL(itemSelected(MythUIButtonListItem *)),
172 
173  if (m_schedOptButton)
174  connect(m_schedOptButton, SIGNAL(Clicked()), SLOT(ShowSchedOpt()));
175  if (m_filtersButton)
176  connect(m_filtersButton, SIGNAL(Clicked()), SLOT(ShowFilters()));
177  if (m_storeOptButton)
178  connect(m_storeOptButton, SIGNAL(Clicked()), SLOT(ShowStoreOpt()));
179  if (m_postProcButton)
180  connect(m_postProcButton, SIGNAL(Clicked()), SLOT(ShowPostProc()));
181  if (m_schedInfoButton)
182  connect(m_schedInfoButton, SIGNAL(Clicked()), SLOT(ShowSchedInfo()));
183  if (m_previewButton)
184  connect(m_previewButton, SIGNAL(Clicked()), SLOT(ShowPreview()));
185  if (m_metadataButton)
186  connect(m_metadataButton, SIGNAL(Clicked()), SLOT(ShowMetadataOptions()));
187 
188  if (m_cancelButton)
189  connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
190  connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
191 
192  if (m_schedInfoButton)
194  if (m_previewButton)
196 
197  if (m_dupmethodList)
198  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
200  if (m_filtersList)
201  connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
203  if (m_maxepSpin)
204  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
206  if (m_recgroupList)
207  connect(m_recgroupList, SIGNAL(LosingFocus()),
208  SLOT(PromptForRecGroup()));
209  if (m_transcodeCheck)
210  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
211  SLOT(TranscodeChanged(bool)));
212 
213  BuildFocusList();
214 
215  if (!m_recordingRule->IsLoaded())
216  {
217  if (m_recInfo)
219  else if (m_recordingRule->m_recordID)
221 
222  if (!m_recordingRule->IsLoaded())
223  {
224  LOG(VB_GENERAL, LOG_ERR,
225  "ScheduleEditor::Create() - Failed to load recording rule");
226  return false;
227  }
228  }
229 
230  if (m_player)
231  m_player->StartEmbedding(QRect());
232 
233  return true;
234 }
235 
237 {
238  if (m_child)
239  m_child->Close();
240 
241  // don't fade the screen if we are returning to the player
242  if (m_player)
243  GetScreenStack()->PopScreen(this, false);
244  else
245  GetScreenStack()->PopScreen(this, true);
246 }
247 
249 {
254 
255  if (!m_loaded)
256  {
257  // Copy this now, it will change briefly after the first item
258  // is inserted into the list by design of
259  // MythUIButtonList::itemSelected()
261 
262  // Rules List
264  {
266  .compare("Default", Qt::CaseInsensitive) != 0)
267  {
269  tr("Delete this recording rule template"),
270  ENUM_TO_QVARIANT(kNotRecording));
271  }
274  ENUM_TO_QVARIANT(kTemplateRecord));
275  }
276  else if (m_recordingRule->m_isOverride)
277  {
279  tr("Record this showing with normal options"),
280  ENUM_TO_QVARIANT(kNotRecording));
283  ENUM_TO_QVARIANT(kOverrideRecord));
286  ENUM_TO_QVARIANT(kDontRecord));
287  }
288  else
289  {
290  bool hasChannel = !m_recordingRule->m_station.isEmpty();
291  bool isManual = (m_recordingRule->m_searchType == kManualSearch);
292 
295  ENUM_TO_QVARIANT(kNotRecording));
296  if (hasChannel)
299  ENUM_TO_QVARIANT(kSingleRecord));
300  if (!isManual)
303  ENUM_TO_QVARIANT(kOneRecord));
304  if (!hasChannel || isManual)
307  ENUM_TO_QVARIANT(kWeeklyRecord));
308  if (!hasChannel || isManual)
311  ENUM_TO_QVARIANT(kDailyRecord));
312  if (!isManual)
315  ENUM_TO_QVARIANT(kAllRecord));
316  }
317 
319  }
320  m_rulesList->SetValueByData(ENUM_TO_QVARIANT(m_recordingRule->m_type));
321 
322  InfoMap progMap;
323 
324  m_recordingRule->ToMap(progMap);
325 
326  if (m_recInfo)
327  m_recInfo->ToMap(progMap);
328 
329  SetTextFromMap(progMap);
330 
331  m_loaded = true;
332 }
333 
335 {
337  Load();
338  emit templateLoaded();
339 }
340 
342 {
343  if (!item)
344  return;
345 
346  m_recordingRule->m_type = static_cast<RecordingType>
347  (item->GetData().toInt());
348 
349  bool isScheduled = (m_recordingRule->m_type != kNotRecording &&
351 
352  if (m_schedOptButton)
353  m_schedOptButton->SetEnabled(isScheduled);
354  if (m_filtersButton)
355  m_filtersButton->SetEnabled(isScheduled);
356  if (m_storeOptButton)
357  m_storeOptButton->SetEnabled(isScheduled);
358  if (m_postProcButton)
359  m_postProcButton->SetEnabled(isScheduled);
360  if (m_metadataButton)
361  m_metadataButton->SetEnabled(isScheduled &&
363 
368 }
369 
371 {
373 }
374 
376 {
378 }
379 
381 {
383 }
384 
386 {
388 }
389 
391 {
393 }
394 
396 {
397  if (m_child)
398  m_child->Close();
399 
401  {
402  int recid = m_recordingRule->m_recordID;
403  DeleteRule();
404  if (recid)
405  emit ruleDeleted(recid);
406  Close();
407  return;
408  }
409 
414  m_recordingRule->Save(true);
416 
417  Close();
418 }
419 
421 {
423 }
424 
426 {
429  return;
430 
431  if (m_child)
432  m_child->Close();
433 
435 
437  SchedOptEditor *schedoptedit = new SchedOptEditor(mainStack, *this,
439  if (!schedoptedit->Create())
440  {
441  delete schedoptedit;
442  return;
443  }
444 
446  m_child = schedoptedit;
447  mainStack->AddScreen(schedoptedit);
448 }
449 
451 {
454  return;
455 
456  if (m_child)
457  m_child->Close();
458 
460 
462  StoreOptEditor *storeoptedit = new StoreOptEditor(mainStack, *this,
464  if (!storeoptedit->Create())
465  {
466  delete storeoptedit;
467  return;
468  }
469 
471  m_child = storeoptedit;
472  mainStack->AddScreen(storeoptedit);
473 }
474 
476 {
479  return;
480 
481  if (m_child)
482  m_child->Close();
483 
485 
487  PostProcEditor *ppedit = new PostProcEditor(mainStack, *this,
489  if (!ppedit->Create())
490  {
491  delete ppedit;
492  return;
493  }
494 
496  m_child = ppedit;
497  mainStack->AddScreen(ppedit);
498 }
499 
501 {
503  return;
504 
505  QString label = tr("Schedule Information");
506 
507  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
508  MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
509 
510  if (menuPopup->Create())
511  {
512  menuPopup->SetReturnEvent(this, "schedinfo");
513 
514  if (m_recInfo)
515  menuPopup->AddButton(tr("Program Details"));
516  menuPopup->AddButton(tr("Upcoming Episodes"));
517  menuPopup->AddButton(tr("Upcoming Recordings"));
519  menuPopup->AddButton(tr("Previously Recorded"));
520 
521  popupStack->AddScreen(menuPopup);
522  }
523  else
524  delete menuPopup;
525 }
526 
527 bool ScheduleEditor::keyPressEvent(QKeyEvent *event)
528 {
529  if (GetFocusWidget()->keyPressEvent(event))
530  return true;
531 
532  bool handled = false;
533  QStringList actions;
534  handled = GetMythMainWindow()->
535  TranslateKeyPress("TV Frontend", event, actions);
536 
537  for (int i = 0; i < actions.size() && !handled; i++)
538  {
539  QString action = actions[i];
540  handled = true;
541 
542  if (action == "MENU")
543  showMenu();
544  else if (action == "INFO")
545  ShowDetails();
546  else if (action == "GUIDE")
547  ShowGuide();
548  else if (action == "UPCOMING")
550  else if (action == "PREVVIEW")
552  else if (action == "NEXTVIEW")
553  ShowNextView();
554  else
555  handled = false;
556  }
557 
558  if (!handled && MythScreenType::keyPressEvent(event))
559  handled = true;
560 
561  return handled;
562 }
563 
564 void ScheduleEditor::customEvent(QEvent *event)
565 {
566  if (event->type() == DialogCompletionEvent::kEventType)
567  {
569 
570  QString resultid = dce->GetId();
571  QString resulttext = dce->GetResultText();
572 
573  if (resultid == "menu")
574  {
575  if (resulttext == tr("Main Options"))
576  m_child->Close();
577  if (resulttext == tr("Schedule Options"))
578  ShowSchedOpt();
579  else if (resulttext == tr("Filter Options"))
580  ShowFilters();
581  else if (resulttext == tr("Storage Options"))
582  ShowStoreOpt();
583  else if (resulttext == tr("Post Processing"))
584  ShowPostProc();
585  else if (resulttext == tr("Metadata Options"))
587  else if (resulttext == tr("Use Template"))
589  else if (resulttext == tr("Schedule Info"))
590  ShowSchedInfo();
591  else if (resulttext == tr("Preview Changes"))
592  ShowPreview();
593  }
594  else if (resultid == "templatemenu")
595  {
596  LoadTemplate(resulttext);
597  }
598  else if (resultid == "schedinfo")
599  {
600  if (resulttext == tr("Program Details"))
601  ShowDetails();
602  else if (resulttext == tr("Upcoming Episodes"))
604  else if (resulttext == tr("Upcoming Recordings"))
606  else if (resulttext == tr("Previously Recorded"))
607  ShowPrevious();
608  }
609  else if (resultid == "newrecgroup")
610  {
611  int groupID = CreateRecordingGroup(resulttext);
612  StoreOptMixin::SetRecGroup(groupID, resulttext);
613  }
614  }
615 }
616 
618 {
620  return;
621 
622  // No rule? Search by title
623  if (m_recordingRule->m_recordID <= 0)
624  {
626  return;
627  }
628 
630  ProgLister *pl = new ProgLister(mainStack, plRecordid,
631  QString::number(m_recordingRule->m_recordID),
632  "");
633 
634  if (pl->Create())
635  mainStack->AddScreen(pl);
636  else
637  delete pl;
638 }
639 
641 {
643  return;
644 
645  // Existing rule and search? Search by rule
646  if (m_recordingRule->m_recordID > 0 &&
649 
650  QString title = m_recordingRule->m_title;
651 
653  title.remove(QRegExp(" \\(.*\\)$"));
654 
656 }
657 
659 {
661  return;
662 
663  if (m_child)
664  {
665  m_child->Save();
666  if (m_view == kSchedOptView)
668  else if (m_view == kStoreOptView)
670  else if (m_view == kPostProcView)
672  }
673 
678 
679  QString ttable = "record_tmp";
680  m_recordingRule->UseTempTable(true, ttable);
681 
683  ViewScheduleDiff *vsd = new ViewScheduleDiff(mainStack, ttable,
686  if (vsd->Create())
687  mainStack->AddScreen(vsd);
688  else
689  delete vsd;
690 
692 }
693 
695 {
699  return;
700 
701  if (m_child)
702  m_child->Close();
703 
705  MetadataOptions *rad = new MetadataOptions(mainStack, *this,
707  if (!rad->Create())
708  {
709  delete rad;
710  return;
711  }
712 
714  m_child = rad;
715  mainStack->AddScreen(rad);
716 }
717 
719 {
722  return;
723 
724  if (m_child)
725  m_child->Close();
726 
728 
730  SchedFilterEditor *schedfilteredit = new SchedFilterEditor(mainStack,
731  *this, *m_recordingRule, m_recInfo);
732  if (!schedfilteredit->Create())
733  {
734  delete schedfilteredit;
735  return;
736  }
737 
739  m_child = schedfilteredit;
740  mainStack->AddScreen(schedfilteredit);
741 }
742 
744 {
747  return;
748 
751  else if (m_view == kMainView)
752  ShowPostProc();
753  else if (m_view == kSchedOptView)
754  m_child->Close();
755  else if (m_view == kFilterView)
756  ShowSchedOpt();
757  else if (m_view == kStoreOptView)
758  ShowFilters();
759  else if (m_view == kPostProcView)
760  ShowStoreOpt();
761  else if (m_view == kMetadataView)
762  ShowPostProc();
763 }
764 
766 {
769  return;
770 
771  if (m_view == kMainView)
772  ShowSchedOpt();
773  else if (m_view == kSchedOptView)
774  ShowFilters();
775  else if (m_view == kFilterView)
776  ShowStoreOpt();
777  else if (m_view == kStoreOptView)
778  ShowPostProc();
781  else if (m_view == kPostProcView)
782  m_child->Close();
783  else if (m_view == kMetadataView)
784  m_child->Close();
785 }
786 
788 {
789  if (m_view == kSchedOptView)
791  else if (m_view == kFilterView)
793  else if (m_view == kStoreOptView)
795  else if (m_view == kPostProcView)
797 
798  m_child = NULL;
799  m_view = kMainView;
800 }
801 
803 {
804  QString label = tr("Options");
805  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
806  MythDialogBox *menuPopup =
807  new MythDialogBox(label, popupStack, "menuPopup");
808 
810  RecordingType type = static_cast<RecordingType>(item->GetData().toInt());
811  bool isScheduled = (type != kNotRecording && type != kDontRecord);
812 
813  if (menuPopup->Create())
814  {
815  menuPopup->SetReturnEvent(this, "menu");
816  if (m_view != kMainView)
817  menuPopup->AddButton(tr("Main Options"));
818  if (isScheduled && m_view != kSchedOptView)
819  menuPopup->AddButton(tr("Schedule Options"));
820  if (isScheduled && m_view != kFilterView)
821  menuPopup->AddButton(tr("Filter Options"));
822  if (isScheduled && m_view != kStoreOptView)
823  menuPopup->AddButton(tr("Storage Options"));
824  if (isScheduled && m_view != kPostProcView)
825  menuPopup->AddButton(tr("Post Processing"));
826  if (isScheduled && !m_recordingRule->m_isTemplate &&
828  menuPopup->AddButton(tr("Metadata Options"));
830  menuPopup->AddButton(tr("Schedule Info"));
832  menuPopup->AddButton(tr("Preview Changes"));
833  menuPopup->AddButton(tr("Use Template"));
834  popupStack->AddScreen(menuPopup);
835  }
836  else
837  {
838  delete menuPopup;
839  }
840 }
841 
843 {
844  QStringList templates = RecordingRule::GetTemplateNames();
845  if (templates.empty())
846  {
847  ShowOkPopup(tr("No templates available"));
848  return;
849  }
850 
851  QString label = tr("Template Options");
852  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
853  MythDialogBox *menuPopup =
854  new MythDialogBox(label, popupStack, "menuPopup");
855 
856  if (menuPopup->Create())
857  {
858  menuPopup->SetReturnEvent(this, "templatemenu");
859  while (!templates.empty())
860  {
861  QString name = templates.front();
862  if (name == "Default")
863  menuPopup->AddButton(tr("Default"));
864  else
865  menuPopup->AddButton(name);
866  templates.pop_front();
867  }
868  popupStack->AddScreen(menuPopup);
869  }
870  else
871  {
872  delete menuPopup;
873  }
874 }
875 
877 
883  ScheduleEditor &editor, RecordingRule &rule,
884  RecordingInfo *recInfo)
885  : MythScreenType(parent, name),
886  m_editor(&editor), m_recordingRule(&rule), m_recInfo(recInfo),
887  m_backButton(NULL), m_saveButton(NULL), m_previewButton(NULL)
888 {
889 }
890 
892 {
893 }
894 
895 bool SchedEditChild::keyPressEvent(QKeyEvent *event)
896 {
897  if (GetFocusWidget()->keyPressEvent(event))
898  return true;
899 
900  bool handled = false;
901  QStringList actions;
902  handled = GetMythMainWindow()->
903  TranslateKeyPress("TV Frontend", event, actions);
904 
905  for (int i = 0; i < actions.size() && !handled; i++)
906  {
907  QString action = actions[i];
908  handled = true;
909 
910  if (action == "MENU")
911  m_editor->showMenu();
912  else if (action == "INFO")
914  else if (action == "UPCOMING")
916  if (action == "ESCAPE")
917  Close();
918  else if (action == "PREVVIEW")
920  else if (action == "NEXTVIEW")
922  else
923  handled = false;
924  }
925 
926  if (!handled && MythScreenType::keyPressEvent(event))
927  handled = true;
928 
929  return handled;
930 }
931 
933  const QString xmlfile, const QString winname, bool isTemplate)
934 {
935  if (!LoadWindowFromXML(xmlfile, winname, this))
936  return false;
937 
938  UIUtilW::Assign(this, m_backButton, "back");
939  UIUtilW::Assign(this, m_saveButton, "save");
940  UIUtilW::Assign(this, m_previewButton, "preview");
941 
942  connect(this, SIGNAL(Closing()), m_editor, SLOT(ChildClosing()));
943  connect(m_editor, SIGNAL(templateLoaded()), SLOT(Load()));
944 
945  if (m_backButton)
946  connect(m_backButton, SIGNAL(Clicked()), SLOT(Close()));
947  if (m_saveButton)
948  connect(m_saveButton, SIGNAL(Clicked()), m_editor, SLOT(Save()));
949  if (m_previewButton)
950  connect(m_previewButton, SIGNAL(Clicked()),
951  m_editor, SLOT(ShowPreview()));
952 
953  if (m_previewButton)
954  m_previewButton->SetEnabled(!isTemplate);
955 
956  return true;
957 }
958 
960 {
961  InfoMap progMap;
962 
963  m_recordingRule->ToMap(progMap);
964 
965  if (m_recInfo)
966  m_recInfo->ToMap(progMap);
967 
968  SetTextFromMap(progMap);
969 }
970 
972 {
973  Save();
974  emit Closing();
976 }
977 
979 
986  ScheduleEditor &editor,
987  RecordingRule &rule,
988  RecordingInfo *recInfo)
989  : SchedEditChild(parent, "ScheduleOptionsEditor", editor, rule, recInfo),
990  SchedOptMixin(*this, &rule, &editor), m_filtersButton(NULL)
991 {
992 }
993 
995 {
996 }
997 
999 {
1001  "schedule-ui.xml", "scheduleoptionseditor",
1003  {
1004  return false;
1005  }
1006 
1007  bool err = false;
1008 
1009  SchedOptMixin::Create(&err);
1010 
1011  UIUtilW::Assign(this, m_filtersButton, "filters");
1012 
1013  if (err)
1014  {
1015  LOG(VB_GENERAL, LOG_ERR, "SchedOptEditor, theme is missing "
1016  "required elements");
1017  return false;
1018  }
1019 
1020  if (m_dupmethodList)
1021  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
1023 
1024  if (m_filtersButton)
1025  connect(m_filtersButton, SIGNAL(Clicked()),
1026  m_editor, SLOT(ShowFilters()));
1027 
1028  BuildFocusList();
1029 
1030  return true;
1031 }
1032 
1034 {
1036  SetTextFromMaps();
1037 }
1038 
1040 {
1042 }
1043 
1045 {
1047 }
1048 
1050 
1057  ScheduleEditor &editor,
1058  RecordingRule &rule,
1059  RecordingInfo *recInfo)
1060  : SchedEditChild(parent, "ScheduleFilterEditor", editor, rule, recInfo),
1061  FilterOptMixin(*this, &rule, &editor)
1062 {
1063 }
1064 
1066 {
1067 }
1068 
1070 {
1072  "schedule-ui.xml", "schedulefiltereditor",
1074  {
1075  return false;
1076  }
1077 
1078  bool err = false;
1079 
1080  FilterOptMixin::Create(&err);
1081 
1082  if (err)
1083  {
1084  LOG(VB_GENERAL, LOG_ERR, "SchedFilterEditor, theme is missing "
1085  "required elements");
1086  return false;
1087  }
1088 
1089  connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
1091 
1092  BuildFocusList();
1093 
1094  return true;
1095 }
1096 
1098 {
1100  SetTextFromMaps();
1101 }
1102 
1104 {
1106 }
1107 
1109 {
1111 }
1112 
1114 
1121  ScheduleEditor &editor,
1122  RecordingRule &rule,
1123  RecordingInfo *recInfo)
1124  : SchedEditChild(parent, "StorageOptionsEditor", editor, rule, recInfo),
1125  StoreOptMixin(*this, &rule, &editor)
1126 {
1127 }
1128 
1130 {
1131 }
1132 
1134 {
1136  "schedule-ui.xml", "storageoptionseditor",
1138  {
1139  return false;
1140  }
1141 
1142  bool err = false;
1143 
1144  StoreOptMixin::Create(&err);
1145 
1146  if (err)
1147  {
1148  LOG(VB_GENERAL, LOG_ERR, "StoreOptEditor, theme is missing "
1149  "required elements");
1150  return false;
1151  }
1152 
1153  if (m_maxepSpin)
1154  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
1156  if (m_recgroupList)
1157  connect(m_recgroupList, SIGNAL(LosingFocus()),
1158  SLOT(PromptForRecGroup()));
1159 
1160  BuildFocusList();
1161 
1162  return true;
1163 }
1164 
1166 {
1168  SetTextFromMaps();
1169 }
1170 
1172 {
1174 }
1175 
1177 {
1179 }
1180 
1181 void StoreOptEditor::customEvent(QEvent *event)
1182 {
1183  if (event->type() == DialogCompletionEvent::kEventType)
1184  {
1186 
1187  QString resultid = dce->GetId();
1188  QString resulttext = dce->GetResultText();
1189 
1190  if (resultid == "newrecgroup")
1191  {
1192  int groupID = CreateRecordingGroup(resulttext);
1193  StoreOptMixin::SetRecGroup(groupID, resulttext);
1194  }
1195  }
1196 }
1197 
1199 {
1201 }
1202 
1204 
1211  ScheduleEditor &editor,
1212  RecordingRule &rule,
1213  RecordingInfo *recInfo)
1214  : SchedEditChild(parent, "PostProcOptionsEditor", editor, rule, recInfo),
1215  PostProcMixin(*this, &rule, &editor)
1216 {
1217 }
1218 
1220 {
1221 }
1222 
1224 {
1226  "schedule-ui.xml", "postproceditor",
1228  {
1229  return false;
1230  }
1231 
1232  bool err = false;
1233 
1234  PostProcMixin::Create(&err);
1235 
1236  if (err)
1237  {
1238  LOG(VB_GENERAL, LOG_ERR, "PostProcEditor, theme is missing "
1239  "required elements");
1240  return false;
1241  }
1242 
1243  if (m_transcodeCheck)
1244  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
1245  SLOT(TranscodeChanged(bool)));
1246 
1247  BuildFocusList();
1248 
1249  return true;
1250 }
1251 
1253 {
1255  SetTextFromMaps();
1256 }
1257 
1259 {
1261 }
1262 
1264 {
1266 }
1267 
1269 
1276  ScheduleEditor &editor,
1277  RecordingRule &rule,
1278  RecordingInfo *recInfo)
1279  : SchedEditChild(parent, "MetadataOptions", editor, rule, recInfo),
1280  m_busyPopup(NULL), m_fanart(NULL), m_coverart(NULL),
1281  m_banner(NULL), m_inetrefEdit(NULL), m_seasonSpin(NULL),
1282  m_episodeSpin(NULL), m_queryButton(NULL), m_localFanartButton(NULL),
1283  m_localCoverartButton(NULL), m_localBannerButton(NULL),
1284  m_onlineFanartButton(NULL), m_onlineCoverartButton(NULL),
1285  m_onlineBannerButton(NULL)
1286 {
1287  m_popupStack = GetMythMainWindow()->GetStack("popup stack");
1288 
1289  m_metadataFactory = new MetadataFactory(this);
1290  m_imageLookup = new MetadataDownload(this);
1292 
1295 }
1296 
1298 {
1299  if (m_imageLookup)
1300  {
1301  m_imageLookup->cancel();
1302  delete m_imageLookup;
1303  m_imageLookup = NULL;
1304  }
1305 
1306  if (m_imageDownload)
1307  {
1309  delete m_imageDownload;
1310  m_imageDownload = NULL;
1311  }
1312 }
1313 
1315 {
1317  "schedule-ui.xml", "metadataoptions",
1319  {
1320  return false;
1321  }
1322 
1323  bool err = false;
1324 
1325  UIUtilE::Assign(this, m_inetrefEdit, "inetref_edit", &err);
1326  UIUtilE::Assign(this, m_seasonSpin, "season_spinbox", &err);
1327  UIUtilE::Assign(this, m_episodeSpin, "episode_spinbox", &err);
1328  UIUtilE::Assign(this, m_queryButton, "query_button", &err);
1329  UIUtilE::Assign(this, m_localFanartButton, "local_fanart_button", &err);
1330  UIUtilE::Assign(this, m_localCoverartButton, "local_coverart_button", &err);
1331  UIUtilE::Assign(this, m_localBannerButton, "local_banner_button", &err);
1332  UIUtilE::Assign(this, m_onlineFanartButton, "online_fanart_button", &err);
1333  UIUtilE::Assign(this, m_onlineCoverartButton, "online_coverart_button", &err);
1334  UIUtilE::Assign(this, m_onlineBannerButton, "online_banner_button", &err);
1335  UIUtilW::Assign(this, m_fanart, "fanart");
1336  UIUtilW::Assign(this, m_coverart, "coverart");
1337  UIUtilW::Assign(this, m_banner, "banner");
1338 
1339  if (err)
1340  {
1341  LOG(VB_GENERAL, LOG_ERR, "MetadataOptions, theme is missing "
1342  "required elements");
1343  return false;
1344  }
1345 
1346  connect(m_queryButton, SIGNAL(Clicked()),
1347  SLOT(PerformQuery()));
1348  connect(m_localFanartButton, SIGNAL(Clicked()),
1349  SLOT(SelectLocalFanart()));
1350  connect(m_localCoverartButton, SIGNAL(Clicked()),
1351  SLOT(SelectLocalCoverart()));
1352  connect(m_localBannerButton, SIGNAL(Clicked()),
1353  SLOT(SelectLocalBanner()));
1354  connect(m_onlineFanartButton, SIGNAL(Clicked()),
1355  SLOT(SelectOnlineFanart()));
1356  connect(m_onlineCoverartButton, SIGNAL(Clicked()),
1357  SLOT(SelectOnlineCoverart()));
1358  connect(m_onlineBannerButton, SIGNAL(Clicked()),
1359  SLOT(SelectOnlineBanner()));
1360 
1361  connect(m_seasonSpin, SIGNAL(itemSelected(MythUIButtonListItem*)),
1362  SLOT(ValuesChanged()));
1363 
1364  // InetRef
1366 
1367  // Season
1368  m_seasonSpin->SetRange(0,9999,1,5);
1370 
1371  // Episode
1372  m_episodeSpin->SetRange(0,9999,1,10);
1374 
1375  if (m_coverart)
1376  {
1378  m_coverart->Load();
1379  }
1380 
1381  if (m_fanart)
1382  {
1384  m_fanart->Load();
1385  }
1386 
1387  if (m_banner)
1388  {
1390  m_banner->Load();
1391  }
1392 
1393  BuildFocusList();
1394 
1395  return true;
1396 }
1397 
1399 {
1400  SetTextFromMaps();
1401 }
1402 
1404 {
1405  if (m_busyPopup)
1406  return;
1407 
1408  QString message = title;
1409 
1410  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
1411  "metaoptsdialog");
1412 
1413  if (m_busyPopup->Create())
1415 }
1416 
1418 {
1419  CreateBusyDialog(tr("Trying to manually find this "
1420  "recording online..."));
1421 
1423 
1424  lookup->SetAutomatic(false);
1425  m_metadataFactory->Lookup(lookup);
1426 }
1427 
1429 {
1430  QueryComplete(lookup);
1431 }
1432 
1435 {
1436  QString msg = tr("Downloading selected artwork...");
1437  CreateBusyDialog(msg);
1438 
1439  MetadataLookup *lookup = new MetadataLookup();
1440 
1441  lookup->SetType(kMetadataVideo);
1443  lookup->SetAutomatic(true);
1444  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1445 
1446  ArtworkMap downloads;
1447  downloads.insert(type, info);
1448  lookup->SetDownloads(downloads);
1449  lookup->SetAllowOverwrites(true);
1450  lookup->SetTitle(m_recordingRule->m_title);
1452  lookup->SetInetref(m_inetrefEdit->GetText());
1453  lookup->SetSeason(m_seasonSpin->GetIntValue());
1454  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1455 
1456  m_imageDownload->addDownloads(lookup);
1457 }
1458 
1460 {
1461  if (!CanSetArtwork())
1462  return;
1463 
1464  QString url = generate_file_url("Fanart",
1466  "");
1467  FindImagePopup(url,"",*this, "fanart");
1468 }
1469 
1471 {
1472  if (!CanSetArtwork())
1473  return;
1474 
1475  QString url = generate_file_url("Coverart",
1477  "");
1478  FindImagePopup(url,"",*this, "coverart");
1479 }
1480 
1482 {
1483  if (!CanSetArtwork())
1484  return;
1485 
1486  QString url = generate_file_url("Banners",
1488  "");
1489  FindImagePopup(url,"",*this, "banner");
1490 }
1491 
1493 {
1495 }
1496 
1498 {
1500 }
1501 
1503 {
1505 }
1506 
1508 {
1509  // Season
1510  if (m_seasonSpin)
1512 
1513  // Episode
1514  if (m_episodeSpin)
1516 
1517  // InetRef
1518  if (m_inetrefEdit)
1520 }
1521 
1523 {
1524  if (!lookup)
1525  return;
1526 
1527  // InetRef
1528  m_inetrefEdit->SetText(lookup->GetInetref());
1529 
1530  // Season
1531  m_seasonSpin->SetValue(lookup->GetSeason());
1532 
1533  // Episode
1534  m_episodeSpin->SetValue(lookup->GetEpisode());
1535 
1536  InfoMap metadataMap;
1537  lookup->toMap(metadataMap);
1538  SetTextFromMap(metadataMap);
1539 }
1540 
1542  const QString &prefixAlt,
1543  QObject &inst,
1544  const QString &returnEvent)
1545 {
1546  QString fp;
1547 
1548  if (prefix.startsWith("myth://"))
1549  fp = prefix;
1550  else
1551  fp = prefix.isEmpty() ? prefixAlt : prefix;
1552 
1553  MythScreenStack *popupStack =
1554  GetMythMainWindow()->GetStack("popup stack");
1555 
1556  MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, fp);
1558  if (fb->Create())
1559  {
1560  fb->SetReturnEvent(&inst, returnEvent);
1561  popupStack->AddScreen(fb);
1562  }
1563  else
1564  delete fb;
1565 }
1566 
1568 {
1569  QStringList ret;
1570 
1571  QList<QByteArray> exts = QImageReader::supportedImageFormats();
1572  for (QList<QByteArray>::iterator p = exts.begin(); p != exts.end(); ++p)
1573  {
1574  ret.append(QString("*.").append(*p));
1575  }
1576 
1577  return ret;
1578 }
1579 
1581 {
1582  if (m_inetrefEdit->GetText().isEmpty())
1583  {
1584  ShowOkPopup(tr("You must set a reference number "
1585  "on this rule to set artwork. For items "
1586  "without a metadata source, you can set "
1587  "any unique value."));
1588  return false;
1589  }
1590 
1591  return true;
1592 }
1593 
1595 {
1596  MetadataLookup *lookup = new MetadataLookup();
1597  lookup->SetStep(kLookupSearch);
1598  lookup->SetType(mtype);
1600 
1601  if (type == kUnknownVideo)
1602  {
1604  (m_seasonSpin->GetIntValue() == 0 &&
1605  m_episodeSpin->GetIntValue() == 0))
1606  {
1607  lookup->SetSubtype(kProbableMovie);
1608  }
1609  else
1610  {
1612  }
1613  }
1614  else
1615  {
1616  // we could determine the type from the inetref
1617  lookup->SetSubtype(type);
1618  }
1619  lookup->SetAllowGeneric(true);
1620  lookup->SetHandleImages(false);
1622  lookup->SetTitle(m_recordingRule->m_title);
1624  lookup->SetInetref(m_inetrefEdit->GetText());
1626  lookup->SetSeason(m_seasonSpin->GetIntValue());
1627  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1628 
1629  return lookup;
1630 }
1631 
1633 {
1634  if (!CanSetArtwork())
1635  return;
1636 
1637  QString msg = tr("Searching for available artwork...");
1638  CreateBusyDialog(msg);
1639 
1641 
1642  lookup->SetAutomatic(true);
1643  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1644  m_imageLookup->addLookup(lookup);
1645 }
1646 
1648 {
1649  if (!lookup)
1650  return;
1651 
1652  if (m_busyPopup)
1653  {
1654  m_busyPopup->Close();
1655  m_busyPopup = NULL;
1656  }
1657 
1658  VideoArtworkType type = lookup->GetData().value<VideoArtworkType>();
1659  ArtworkList list = lookup->GetArtwork(type);
1660 
1661  if (list.isEmpty())
1662  {
1663  MythWarningNotification n(tr("No image found"), tr("Schedule Editor"));
1665  return;
1666  }
1667 
1668  ImageSearchResultsDialog *resultsdialog =
1669  new ImageSearchResultsDialog(m_popupStack, list, type);
1670 
1671  connect(resultsdialog, SIGNAL(haveResult(ArtworkInfo, VideoArtworkType)),
1673 
1674  if (resultsdialog->Create())
1675  m_popupStack->AddScreen(resultsdialog);
1676 }
1677 
1679 {
1680  if (!lookup)
1681  return;
1682 
1683  DownloadMap map = lookup->GetDownloads();
1684 
1685  if (map.isEmpty())
1686  return;
1687 
1688  for (DownloadMap::const_iterator i = map.begin(); i != map.end(); ++i)
1689  {
1690  VideoArtworkType type = i.key();
1691  ArtworkInfo info = i.value();
1692 
1693  if (type == kArtworkCoverart)
1694  m_artworkMap.replace(kArtworkCoverart, info);
1695  else if (type == kArtworkFanart)
1696  m_artworkMap.replace(kArtworkFanart, info);
1697  else if (type == kArtworkBanner)
1698  m_artworkMap.replace(kArtworkBanner, info);
1699  }
1700 
1703 
1704  ValuesChanged();
1705 }
1706 
1708 {
1711 
1712  if (m_coverart)
1713  {
1715  m_coverart->Load();
1716  }
1717 
1718  if (m_fanart)
1719  {
1721  m_fanart->Load();
1722  }
1723 
1724  if (m_banner)
1725  {
1727  m_banner->Load();
1728  }
1729 }
1730 
1731 void MetadataOptions::customEvent(QEvent *levent)
1732 {
1733  if (levent->type() == MetadataFactoryMultiResult::kEventType)
1734  {
1735  if (m_busyPopup)
1736  {
1737  m_busyPopup->Close();
1738  m_busyPopup = NULL;
1739  }
1740 
1741  MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
1742 
1743  if (!mfmr)
1744  return;
1745 
1746  MetadataLookupList list = mfmr->results;
1747 
1748  if (list.count() > 1)
1749  {
1750  int yearindex = -1;
1751 
1752  for (int p = 0; p != list.size(); ++p)
1753  {
1754  if (!m_recordingRule->m_seriesid.isEmpty() &&
1755  m_recordingRule->m_seriesid == (list[p])->GetTMSref())
1756  {
1757  MetadataLookup *lookup = list[p];
1758  QueryComplete(lookup);
1759  return;
1760  }
1761  else if (m_recInfo &&
1763  (list[p])->GetYear() != 0 &&
1764  m_recInfo->GetYearOfInitialRelease() == (list[p])->GetYear())
1765  {
1766  if (yearindex > -1)
1767  {
1768  LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite "
1769  "match could be found based on year alone.");
1770  yearindex = -2;
1771  }
1772  else if (yearindex == -1)
1773  {
1774  LOG(VB_GENERAL, LOG_INFO, "Matched based on year. ");
1775  yearindex = p;
1776  }
1777  }
1778  }
1779 
1780  if (yearindex > -1)
1781  {
1782  MetadataLookup *lookup = list[yearindex];
1783  QueryComplete(lookup);
1784  return;
1785  }
1786 
1787  LOG(VB_GENERAL, LOG_INFO, "Falling through to selection dialog.");
1788  MetadataResultsDialog *resultsdialog =
1790 
1791  connect(resultsdialog, SIGNAL(haveResult(RefCountHandler<MetadataLookup>)),
1793  Qt::QueuedConnection);
1794 
1795  if (resultsdialog->Create())
1796  m_popupStack->AddScreen(resultsdialog);
1797  }
1798  }
1799  else if (levent->type() == MetadataFactorySingleResult::kEventType)
1800  {
1801  if (m_busyPopup)
1802  {
1803  m_busyPopup->Close();
1804  m_busyPopup = NULL;
1805  }
1806 
1807  MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
1808 
1809  if (!mfsr)
1810  return;
1811 
1812  MetadataLookup *lookup = mfsr->result;
1813 
1814  if (!lookup)
1815  return;
1816 
1817  QueryComplete(lookup);
1818  }
1819  else if (levent->type() == MetadataFactoryNoResult::kEventType)
1820  {
1821  if (m_busyPopup)
1822  {
1823  m_busyPopup->Close();
1824  m_busyPopup = NULL;
1825  }
1826 
1827  MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
1828 
1829  if (!mfnr)
1830  return;
1831 
1832  QString title = tr("No match found for this recording. You can "
1833  "try entering a TVDB/TMDB number, season, and "
1834  "episode manually.");
1835 
1836  MythConfirmationDialog *okPopup =
1837  new MythConfirmationDialog(m_popupStack, title, false);
1838 
1839  if (okPopup->Create())
1840  m_popupStack->AddScreen(okPopup);
1841  }
1842  else if (levent->type() == MetadataLookupEvent::kEventType)
1843  {
1844  if (m_busyPopup)
1845  {
1846  m_busyPopup->Close();
1847  m_busyPopup = NULL;
1848  }
1849 
1850  MetadataLookupEvent *lue = (MetadataLookupEvent *)levent;
1851 
1852  MetadataLookupList lul = lue->lookupList;
1853 
1854  if (lul.isEmpty())
1855  return;
1856 
1857  if (lul.count() >= 1)
1858  {
1859  OnArtworkSearchDone(lul[0]);
1860  }
1861  }
1862  else if (levent->type() == MetadataLookupFailure::kEventType)
1863  {
1864  if (m_busyPopup)
1865  {
1866  m_busyPopup->Close();
1867  m_busyPopup = NULL;
1868  }
1869 
1871 
1872  MetadataLookupList lul = luf->lookupList;
1873 
1874  if (lul.size())
1875  {
1876  QString title = tr("This number, season, and episode combination "
1877  "does not appear to be valid (or the site may "
1878  "be down). Check your information and try "
1879  "again.");
1880 
1881  MythConfirmationDialog *okPopup =
1882  new MythConfirmationDialog(m_popupStack, title, false);
1883 
1884  if (okPopup->Create())
1885  m_popupStack->AddScreen(okPopup);
1886  }
1887  }
1888  else if (levent->type() == ImageDLEvent::kEventType)
1889  {
1890  if (m_busyPopup)
1891  {
1892  m_busyPopup->Close();
1893  m_busyPopup = NULL;
1894  }
1895 
1896  ImageDLEvent *ide = (ImageDLEvent *)levent;
1897 
1898  MetadataLookup *lookup = ide->item;
1899 
1900  if (!lookup)
1901  return;
1902 
1903  HandleDownloadedImages(lookup);
1904  }
1905  else if (levent->type() == ImageDLFailureEvent::kEventType)
1906  {
1907  if (m_busyPopup)
1908  {
1909  m_busyPopup->Close();
1910  m_busyPopup = NULL;
1911  }
1912  MythErrorNotification n(tr("Failed to retrieve image(s)"),
1913  tr("Schedule Editor"),
1914  tr("Check logs"));
1916  }
1917  else if (levent->type() == DialogCompletionEvent::kEventType)
1918  {
1919  DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent);
1920 
1921  const QString resultid = dce->GetId();
1922  ArtworkInfo info;
1923  info.url = dce->GetResultText();
1924 
1925  if (resultid == "coverart")
1926  {
1927  m_artworkMap.replace(kArtworkCoverart, info);
1928  }
1929  else if (resultid == "fanart")
1930  {
1931  m_artworkMap.replace(kArtworkFanart, info);
1932  }
1933  else if (resultid == "banner")
1934  {
1935  m_artworkMap.replace(kArtworkBanner, info);
1936  }
1937 
1940 
1941  ValuesChanged();
1942  }
1943 
1944 }
1945 
1947 
1954  SchedOptMixin *other)
1955  : m_prioritySpin(NULL), m_startoffsetSpin(NULL), m_endoffsetSpin(NULL),
1956  m_dupmethodList(NULL), m_dupscopeList(NULL), m_inputList(NULL),
1957  m_ruleactiveCheck(NULL), m_newrepeatList(NULL),
1958  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false),
1959  m_haveRepeats(gCoreContext->GetNumSetting("HaveRepeats", 0))
1960 {
1961 }
1962 
1963 void SchedOptMixin::Create(bool *err)
1964 {
1965  if (!m_rule)
1966  return;
1967 
1968  if (m_other && !m_other->m_prioritySpin)
1969  UIUtilE::Assign(m_screen, m_prioritySpin, "priority", err);
1970  else
1971  UIUtilW::Assign(m_screen, m_prioritySpin, "priority");
1972 
1974  UIUtilE::Assign(m_screen, m_startoffsetSpin, "startoffset", err);
1975  else
1976  UIUtilW::Assign(m_screen, m_startoffsetSpin, "startoffset");
1977 
1978  if (m_other && !m_other->m_endoffsetSpin)
1979  UIUtilE::Assign(m_screen, m_endoffsetSpin, "endoffset", err);
1980  else
1981  UIUtilW::Assign(m_screen, m_endoffsetSpin, "endoffset");
1982 
1983  if (m_other && !m_other->m_dupmethodList)
1984  UIUtilE::Assign(m_screen, m_dupmethodList, "dupmethod", err);
1985  else
1986  UIUtilW::Assign(m_screen, m_dupmethodList, "dupmethod");
1987 
1988  if (m_other && !m_other->m_dupscopeList)
1989  UIUtilE::Assign(m_screen, m_dupscopeList, "dupscope", err);
1990  else
1991  UIUtilW::Assign(m_screen, m_dupscopeList, "dupscope");
1992 
1993  if (m_other && !m_other->m_inputList)
1994  UIUtilE::Assign(m_screen, m_inputList, "input", err);
1995  else
1997 
1999  UIUtilE::Assign(m_screen, m_ruleactiveCheck, "ruleactive", err);
2000  else
2001  UIUtilW::Assign(m_screen, m_ruleactiveCheck, "ruleactive");
2002 
2003  UIUtilW::Assign(m_screen, m_newrepeatList, "newrepeat");
2004 }
2005 
2007 {
2008  if (!m_rule)
2009  return;
2010 
2011  // Priority
2012  if (m_prioritySpin)
2013  {
2014  if (!m_loaded)
2015  m_prioritySpin->SetRange(-99,99,1,5);
2017  }
2018 
2019  // Start Offset
2020  if (m_startoffsetSpin)
2021  {
2022  if (!m_loaded)
2023  m_startoffsetSpin->SetRange(480,-480,1,10);
2025  }
2026 
2027  // End Offset
2028  if (m_endoffsetSpin)
2029  {
2030  if (!m_loaded)
2031  m_endoffsetSpin->SetRange(-480,480,1,10);
2033  }
2034 
2035  // Duplicate Match Type
2036  if (m_dupmethodList)
2037  {
2038  if (!m_loaded)
2039  {
2041 
2044  ENUM_TO_QVARIANT(kDupCheckSubDesc));
2047  ENUM_TO_QVARIANT(kDupCheckSubThenDesc));
2050  ENUM_TO_QVARIANT(kDupCheckSub));
2053  ENUM_TO_QVARIANT(kDupCheckDesc));
2056  ENUM_TO_QVARIANT(kDupCheckNone));
2057 
2058  m_rule->m_dupMethod = dupMethod;
2059  }
2060  m_dupmethodList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupMethod));
2061  }
2062 
2063  // Duplicate Matching Scope
2064  if (m_dupscopeList)
2065  {
2066  if (!m_loaded)
2067  {
2070  ENUM_TO_QVARIANT(kDupsInAll));
2073  ENUM_TO_QVARIANT(kDupsInRecorded));
2076  ENUM_TO_QVARIANT(kDupsInOldRecorded));
2077  if (m_haveRepeats && !m_newrepeatList &&
2079  {
2082  ENUM_TO_QVARIANT(kDupsNewEpi|kDupsInAll));
2083  }
2084  }
2085  m_dupscopeList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupIn));
2086  }
2087 
2088  // Preferred Input
2089  if (m_inputList)
2090  {
2091  if (!m_loaded)
2092  {
2094  QObject::tr("Use any available input"),
2095  qVariantFromValue(0));
2096 
2097  vector<uint> inputids = CardUtil::GetInputList();
2098  for (uint i = 0; i < inputids.size(); ++i)
2099  {
2101  QObject::tr("Prefer input %1")
2102  .arg(CardUtil::GetDisplayName(inputids[i])), inputids[i]);
2103  }
2104  }
2106  }
2107 
2108  // Active/Disabled
2109  if (m_ruleactiveCheck)
2110  {
2112  }
2113 
2114  // Record new and repeat
2115  if (m_newrepeatList)
2116  {
2117  if (!m_loaded)
2118  {
2120  QObject::tr("Record new and repeat "
2121  "episodes"), ENUM_TO_QVARIANT(0));
2123  QObject::tr("Record new episodes only"),
2124  ENUM_TO_QVARIANT(kDupsNewEpi));
2125  }
2126  m_newrepeatList->SetValueByData(ENUM_TO_QVARIANT
2127  (m_rule->m_dupIn & kDupsNewEpi));
2128  }
2129 
2130  m_loaded = true;
2131 
2132  RuleChanged();
2133 }
2134 
2136 {
2137  if (!m_rule)
2138  return;
2139 
2140  if (m_prioritySpin)
2142  if (m_startoffsetSpin)
2144  if (m_endoffsetSpin)
2146  if (m_dupmethodList)
2147  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2148  (m_dupmethodList->GetDataValue().toInt());
2149  if (m_dupscopeList)
2150  {
2151  int mask = ((m_other && m_other->m_newrepeatList) ||
2152  m_newrepeatList) ? kDupsInAll : ~0;
2153  int val = ((m_rule->m_dupIn & ~mask) |
2154  m_dupscopeList->GetDataValue().toInt());
2155  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2156  }
2157  if (m_inputList)
2159  if (m_ruleactiveCheck)
2161  if (m_newrepeatList)
2162  {
2163  int val = ((m_rule->m_dupIn & ~kDupsNewEpi) |
2164  m_newrepeatList->GetDataValue().toInt());
2165  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2166  }
2167 }
2168 
2170 {
2171  if (!m_rule)
2172  return;
2173 
2174  bool isScheduled = (m_rule->m_type != kNotRecording &&
2175  m_rule->m_type != kDontRecord);
2176  bool isSingle = (m_rule->m_type == kSingleRecord ||
2178 
2179  if (m_prioritySpin)
2180  m_prioritySpin->SetEnabled(isScheduled);
2181  if (m_startoffsetSpin)
2182  m_startoffsetSpin->SetEnabled(isScheduled);
2183  if (m_endoffsetSpin)
2184  m_endoffsetSpin->SetEnabled(isScheduled);
2185  if (m_dupmethodList)
2186  m_dupmethodList->SetEnabled(isScheduled && !isSingle);
2187  if (m_dupscopeList)
2188  m_dupscopeList->SetEnabled(isScheduled && !isSingle &&
2190  if (m_inputList)
2191  m_inputList->SetEnabled(isScheduled);
2192  if (m_ruleactiveCheck)
2193  m_ruleactiveCheck->SetEnabled(isScheduled);
2194  if (m_newrepeatList)
2195  m_newrepeatList->SetEnabled(isScheduled && !isSingle && m_haveRepeats);
2196 }
2197 
2199 {
2200  if (!item || !m_rule)
2201  return;
2202 
2203  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2204  (item->GetData().toInt());
2205 
2206  if (m_dupscopeList)
2208 }
2209 
2211 
2218  FilterOptMixin *other)
2219  : m_filtersList(NULL), m_activeFiltersList(NULL),
2220  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2221 {
2222 }
2223 
2224 void FilterOptMixin::Create(bool *err)
2225 {
2226  if (!m_rule)
2227  return;
2228 
2229  if (m_other && !m_other->m_filtersList)
2230  UIUtilE::Assign(m_screen, m_filtersList, "filters", err);
2231  else
2232  UIUtilW::Assign(m_screen, m_filtersList, "filters");
2233 
2234  UIUtilW::Assign(m_screen, m_activeFiltersList, "activefilters");
2235  if (m_activeFiltersList)
2237 }
2238 
2240 {
2241  if (!m_rule)
2242  return;
2243 
2244  if (!m_loaded)
2245  {
2246  MSqlQuery query(MSqlQuery::InitCon());
2247 
2248  query.prepare("SELECT filterid, description, newruledefault "
2249  "FROM recordfilter ORDER BY filterid");
2250 
2251  if (query.exec())
2252  {
2253  while (query.next())
2254  {
2255  m_descriptions << QObject::tr(query.value(1).toString()
2256  .toUtf8().constData());
2257  }
2258  }
2259  m_loaded = true;
2260  }
2261 
2262  if (m_activeFiltersList)
2264 
2265  MythUIButtonListItem *button;
2266  QStringList::iterator Idesc;
2267  int idx;
2268  bool active;
2269  bool not_empty = m_filtersList && !m_filtersList->IsEmpty();
2270  for (Idesc = m_descriptions.begin(), idx = 0;
2271  Idesc != m_descriptions.end(); ++Idesc, ++idx)
2272  {
2273  active = m_rule->m_filter & (1 << idx);
2274  if (m_filtersList)
2275  {
2276  if (not_empty)
2277  button = m_filtersList->GetItemAt(idx);
2278  else
2279  button = new MythUIButtonListItem(m_filtersList, *Idesc, idx);
2280  button->setCheckable(true);
2283  }
2284  if (active && m_activeFiltersList)
2285  {
2286  /* Create a simple list of active filters the theme can
2287  use for informational purposes. */
2289  *Idesc, idx);
2290  button->setCheckable(false);
2291  }
2292  }
2293 
2295  {
2297  QObject::tr("None"), idx);
2298  button->setCheckable(false);
2299  }
2300 
2301  RuleChanged();
2302 }
2303 
2305 {
2306  if (!m_rule || !m_filtersList)
2307  return;
2308 
2309  // Iterate through button list, and build the mask
2310  MythUIButtonListItem *button;
2311  uint32_t filter_mask = 0;
2312  int idx, end;
2313 
2314  end = m_filtersList->GetCount();
2315  for (idx = 0; idx < end; ++idx)
2316  {
2317  if ((button = m_filtersList->GetItemAt(idx)) &&
2319  filter_mask |= (1 << button->GetData().value<uint32_t>());
2320  }
2321  m_rule->m_filter = filter_mask;
2322 }
2323 
2325 {
2326  if (!m_rule)
2327  return;
2328 
2329  bool enabled = m_rule->m_type != kNotRecording &&
2331  if (m_filtersList)
2332  m_filtersList->SetEnabled(enabled);
2333  if (m_activeFiltersList)
2334  m_activeFiltersList->SetEnabled(enabled);
2335 }
2336 
2338 {
2342 }
2343 
2344 
2346 
2353  StoreOptMixin *other)
2354  : m_recprofileList(NULL), m_recgroupList(NULL), m_storagegroupList(NULL),
2355  m_playgroupList(NULL), m_maxepSpin(NULL), m_maxbehaviourList(NULL),
2356  m_autoexpireCheck(NULL),
2357  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2358 {
2359 }
2360 
2361 void StoreOptMixin::Create(bool *err)
2362 {
2363  if (!m_rule)
2364  return;
2365 
2366  if (m_other && !m_other->m_recprofileList)
2367  UIUtilE::Assign(m_screen, m_recprofileList, "recprofile", err);
2368  else
2369  UIUtilW::Assign(m_screen, m_recprofileList, "recprofile");
2370 
2371  if (m_other && !m_other->m_recgroupList)
2372  UIUtilE::Assign(m_screen, m_recgroupList, "recgroup", err);
2373  else
2374  UIUtilW::Assign(m_screen, m_recgroupList, "recgroup");
2375 
2377  UIUtilE::Assign(m_screen, m_storagegroupList, "storagegroup", err);
2378  else
2379  UIUtilW::Assign(m_screen, m_storagegroupList, "storagegroup");
2380 
2381  if (m_other && !m_other->m_playgroupList)
2382  UIUtilE::Assign(m_screen, m_playgroupList, "playgroup", err);
2383  else
2384  UIUtilW::Assign(m_screen, m_playgroupList, "playgroup");
2385 
2386  if (m_other && !m_other->m_maxepSpin)
2387  UIUtilE::Assign(m_screen, m_maxepSpin, "maxepisodes", err);
2388  else
2389  UIUtilW::Assign(m_screen, m_maxepSpin, "maxepisodes");
2390 
2392  UIUtilE::Assign(m_screen, m_maxbehaviourList, "maxnewest", err);
2393  else
2395 
2397  UIUtilE::Assign(m_screen, m_autoexpireCheck, "autoexpire", err);
2398  else
2399  UIUtilW::Assign(m_screen, m_autoexpireCheck, "autoexpire");
2400 }
2401 
2403 {
2404  if (!m_rule)
2405  return;
2406 
2407  QString label;
2408  QStringList groups;
2409  QStringList::Iterator it;
2410  MSqlQuery query(MSqlQuery::InitCon());
2411 
2412  // Recording Profile
2413  if (m_recprofileList)
2414  {
2415  if (!m_loaded)
2416  {
2417  label = QObject::tr("Record using the %1 profile");
2418 
2420  label.arg(QObject::tr("Default")),
2421  qVariantFromValue(QString("Default")));
2422  // LiveTV profile - it's for LiveTV not scheduled recordings??
2424  label.arg(QObject::tr("LiveTV")),
2425  qVariantFromValue(QString("LiveTV")));
2427  label.arg(QObject::tr("High Quality")),
2428  qVariantFromValue(QString("High Quality")));
2430  label.arg(QObject::tr("Low Quality")),
2431  qVariantFromValue(QString("Low Quality")));
2432  }
2434  }
2435 
2436  // Recording Group
2437  if (m_recgroupList)
2438  {
2439  if (!m_loaded)
2440  {
2441  label = QObject::tr("Include in the \"%1\" recording group");
2443  QObject::tr("Create a new recording group"),
2444  qVariantFromValue(QString("__NEW_GROUP__")));
2445 
2446  query.prepare("SELECT recgroupid, recgroup FROM recgroups "
2447  "WHERE recgroup <> 'Deleted' AND "
2448  " recgroup <> 'LiveTV' "
2449  "ORDER BY special DESC, recgroup ASC"); // Special groups first
2450  if (query.exec())
2451  {
2452  while (query.next())
2453  {
2454  int id = query.value(0).toInt();
2455  QString name = query.value(1).toString();
2456 
2457  if (name == "Default")
2458  name = QObject::tr("Default");
2459  new MythUIButtonListItem(m_recgroupList, label.arg(name),
2460  qVariantFromValue(id));
2461  }
2462  }
2463 
2464  }
2466  }
2467 
2468  // Storage Group
2469  if (m_storagegroupList)
2470  {
2471  if (!m_loaded)
2472  {
2473  label = QObject::tr("Store in the \"%1\" storage group");
2475  label.arg(QObject::tr("Default")),
2476  qVariantFromValue(QString("Default")));
2477 
2479  for (it = groups.begin(); it != groups.end(); ++it)
2480  {
2481  if ((*it).compare("Default", Qt::CaseInsensitive) != 0)
2483  label.arg(*it), qVariantFromValue(*it));
2484  }
2485  }
2487  }
2488 
2489  // Playback Group
2490  if (m_playgroupList)
2491  {
2492  if (!m_loaded)
2493  {
2494  label = QObject::tr("Use \"%1\" playback group settings");
2496  label.arg(QObject::tr("Default")),
2497  qVariantFromValue(QString("Default")));
2498 
2499  groups = PlayGroup::GetNames();
2500  for (it = groups.begin(); it != groups.end(); ++it)
2501  {
2502  new MythUIButtonListItem(m_playgroupList, label.arg(*it),
2503  qVariantFromValue(*it));
2504  }
2505  }
2507  }
2508 
2509  // Max Episodes
2510  if (m_maxepSpin)
2511  {
2512  if (!m_loaded)
2513  {
2514  int maxEpisodes = m_rule->m_maxEpisodes;
2515  m_maxepSpin->SetRange(0,100,1,5);
2516  m_rule->m_maxEpisodes = maxEpisodes;
2517  }
2519  }
2520 
2521  // Max Episode Behaviour
2522  if (m_maxbehaviourList)
2523  {
2524  if (!m_loaded)
2525  {
2527  QObject::tr("Don't record if this would exceed the max "
2528  "episodes"), qVariantFromValue(false));
2530  QObject::tr("Delete oldest if this would exceed the max "
2531  "episodes"), qVariantFromValue(true));
2532  }
2534  }
2535 
2536  // Auto-Expire
2537  if (m_autoexpireCheck)
2538  {
2540  }
2541 
2542  m_loaded = true;
2543 
2544  RuleChanged();
2545 }
2546 
2548 {
2549  if (!m_rule)
2550  return;
2551 
2552  if (m_recprofileList)
2554 
2555  if (m_recgroupList)
2556  {
2557  // If the user selected 'Create a new regroup' but failed to enter a
2558  // name when prompted, restore the original value
2559  if (m_recgroupList->GetDataValue().toString() == "__NEW_GROUP__")
2562  }
2563 
2564  if (m_storagegroupList)
2566 
2567  if (m_playgroupList)
2569 
2570  if (m_maxepSpin)
2572 
2573  if (m_maxbehaviourList)
2575 
2576  if (m_autoexpireCheck)
2578 }
2579 
2581 {
2582  if (!m_rule)
2583  return;
2584 
2585  bool isScheduled = (m_rule->m_type != kNotRecording &&
2586  m_rule->m_type != kDontRecord);
2587  bool isSingle = (m_rule->m_type == kSingleRecord ||
2589 
2590  if (m_recprofileList)
2591  m_recprofileList->SetEnabled(isScheduled);
2592  if (m_recgroupList)
2593  m_recgroupList->SetEnabled(isScheduled);
2594  if (m_storagegroupList)
2595  m_storagegroupList->SetEnabled(isScheduled);
2596  if (m_playgroupList)
2597  m_playgroupList->SetEnabled(isScheduled);
2598  if (m_maxepSpin)
2599  m_maxepSpin->SetEnabled(isScheduled && !isSingle);
2600  if (m_maxbehaviourList)
2601  m_maxbehaviourList->SetEnabled(isScheduled && !isSingle &&
2602  m_rule->m_maxEpisodes != 0);
2603  if (m_autoexpireCheck)
2604  m_autoexpireCheck->SetEnabled(isScheduled);
2605 }
2606 
2608 {
2609  if (!item || !m_rule)
2610  return;
2611 
2612  m_rule->m_maxEpisodes = item->GetData().toInt();
2613 
2614  if (m_maxbehaviourList)
2616 }
2617 
2619 {
2620  if (!m_rule)
2621  return;
2622 
2623  if (m_recgroupList->GetDataValue().toString() != "__NEW_GROUP__")
2624  return;
2625 
2626  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2627 
2628  QString label =
2629  QObject::tr("New Recording group name: ");
2630 
2631  MythTextInputDialog *textDialog =
2632  new MythTextInputDialog(popupStack, label,
2633  static_cast<InputFilter>(FilterSymbols | FilterPunct));
2634 
2635  textDialog->SetReturnEvent(m_screen, "newrecgroup");
2636 
2637  if (textDialog->Create())
2638  popupStack->AddScreen(textDialog, false);
2639 }
2640 
2641 void StoreOptMixin::SetRecGroup(int recgroupID, QString recgroup)
2642 {
2643  if (!m_rule || recgroupID <= 0)
2644  return;
2645 
2646  if (m_recgroupList)
2647  {
2648  recgroup = recgroup.trimmed();
2649  if (recgroup.isEmpty())
2650  return;
2651 
2652  QString label = QObject::tr("Include in the \"%1\" recording group");
2653  MythUIButtonListItem *item =
2654  new MythUIButtonListItem(m_recgroupList, label.arg(recgroup),
2655  qVariantFromValue(recgroup));
2657 
2658  if (m_other && m_other->m_recgroupList)
2659  {
2661  label.arg(recgroup), qVariantFromValue(recgroupID));
2663  }
2664  }
2665 }
2666 
2667 int StoreOptMixin::CreateRecordingGroup(const QString& groupName)
2668 {
2669  int groupID = -1;
2670  MSqlQuery query(MSqlQuery::InitCon());
2671 
2672  query.prepare("INSERT INTO recgroups SET recgroup = :NAME, "
2673  "displayname = :DISPLAYNAME");
2674  query.bindValue(":NAME", groupName);
2675  query.bindValue(":DISPLAYNAME", groupName);
2676 
2677  if (query.exec())
2678  groupID = query.lastInsertId().toInt();
2679 
2680  if (groupID <= 0)
2681  LOG(VB_GENERAL, LOG_ERR, QString("Could not create recording group (%1). "
2682  "Does it already exist?").arg(groupName));
2683 
2684  return groupID;
2685 }
2686 
2688 
2695  PostProcMixin *other)
2696  : m_commflagCheck(NULL), m_transcodeCheck(NULL),
2697  m_transcodeprofileList(NULL), m_userjob1Check(NULL),
2698  m_userjob2Check(NULL), m_userjob3Check(NULL), m_userjob4Check(NULL),
2699  m_metadataLookupCheck(NULL),
2700  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2701 {
2702 }
2703 
2704 void PostProcMixin::Create(bool *err)
2705 {
2706  if (!m_rule)
2707  return;
2708 
2709  if (m_other && !m_other->m_commflagCheck)
2710  UIUtilE::Assign(m_screen, m_commflagCheck, "autocommflag", err);
2711  else
2712  UIUtilW::Assign(m_screen, m_commflagCheck, "autocommflag");
2713 
2714  if (m_other && !m_other->m_transcodeCheck)
2715  UIUtilE::Assign(m_screen, m_transcodeCheck, "autotranscode", err);
2716  else
2717  UIUtilW::Assign(m_screen, m_transcodeCheck, "autotranscode");
2718 
2720  UIUtilE::Assign(m_screen, m_transcodeprofileList, "transcodeprofile", err);
2721  else
2722  UIUtilW::Assign(m_screen, m_transcodeprofileList, "transcodeprofile");
2723 
2724  if (m_other && !m_other->m_userjob1Check)
2725  UIUtilE::Assign(m_screen, m_userjob1Check, "userjob1", err);
2726  else
2728 
2729  if (m_other && !m_other->m_userjob2Check)
2730  UIUtilE::Assign(m_screen, m_userjob2Check, "userjob2", err);
2731  else
2733 
2734  if (m_other && !m_other->m_userjob3Check)
2735  UIUtilE::Assign(m_screen, m_userjob3Check, "userjob3", err);
2736  else
2738 
2739  if (m_other && !m_other->m_userjob4Check)
2740  UIUtilE::Assign(m_screen, m_userjob4Check, "userjob4", err);
2741  else
2743 
2744  UIUtilW::Assign(m_screen, m_metadataLookupCheck, "metadatalookup");
2745 }
2746 
2748 {
2749  if (!m_rule)
2750  return;
2751 
2752  // Auto-commflag
2753  if (m_commflagCheck)
2754  {
2756  }
2757 
2758  // Auto-transcode
2759  if (m_transcodeCheck)
2760  {
2762  }
2763 
2764  // Transcode Method
2766  {
2767  if (!m_loaded)
2768  {
2769  QMap<int, QString> profiles = RecordingProfile::GetTranscodingProfiles();
2770  QMap<int, QString>::iterator it;
2771  for (it = profiles.begin(); it != profiles.end(); ++it)
2772  {
2774  qVariantFromValue(it.key()));
2775  }
2776  }
2778  }
2779 
2780  // User Job #1
2781  if (m_userjob1Check)
2782  {
2783  if (!m_loaded)
2784  {
2785  MythUIText *userjob1Text = NULL;
2786  UIUtilW::Assign(m_screen, userjob1Text, "userjob1text");
2787  if (userjob1Text)
2788  userjob1Text->SetText(QObject::tr("Run '%1'")
2789  .arg(gCoreContext->GetSetting("UserJobDesc1"), "User Job 1"));
2790  }
2792  }
2793 
2794  // User Job #2
2795  if (m_userjob2Check)
2796  {
2797  if (!m_loaded)
2798  {
2799  MythUIText *userjob2Text = NULL;
2800  UIUtilW::Assign(m_screen, userjob2Text, "userjob2text");
2801  if (userjob2Text)
2802  userjob2Text->SetText(QObject::tr("Run '%1'")
2803  .arg(gCoreContext->GetSetting("UserJobDesc2"), "User Job 2"));
2804  }
2806  }
2807 
2808  // User Job #3
2809  if (m_userjob3Check)
2810  {
2811  if (!m_loaded)
2812  {
2813  MythUIText *userjob3Text = NULL;
2814  UIUtilW::Assign(m_screen, userjob3Text, "userjob3text");
2815  if (userjob3Text)
2816  userjob3Text->SetText(QObject::tr("Run '%1'")
2817  .arg(gCoreContext->GetSetting("UserJobDesc3"), "User Job 3"));
2818  }
2820  }
2821 
2822  // User Job #4
2823  if (m_userjob4Check)
2824  {
2825  if (!m_loaded)
2826  {
2827  MythUIText *userjob4Text = NULL;
2828  UIUtilW::Assign(m_screen, userjob4Text, "userjob4text");
2829  if (userjob4Text)
2830  userjob4Text->SetText(QObject::tr("Run '%1'")
2831  .arg(gCoreContext->GetSetting("UserJobDesc4"), "User Job 4"));
2832  }
2834  }
2835 
2836  // Auto Metadata Lookup
2838  {
2840  }
2841 
2842  m_loaded = true;
2843 
2844  RuleChanged();
2845 }
2846 
2848 {
2849  if (!m_rule)
2850  return;
2851 
2852  if (m_commflagCheck)
2854  if (m_transcodeCheck)
2858  if (m_userjob1Check)
2860  if (m_userjob2Check)
2862  if (m_userjob3Check)
2864  if (m_userjob4Check)
2869 }
2870 
2872 {
2873  if (!m_rule)
2874  return;
2875 
2876  bool isScheduled = (m_rule->m_type != kNotRecording &&
2877  m_rule->m_type != kDontRecord);
2878 
2879  if (m_commflagCheck)
2880  m_commflagCheck->SetEnabled(isScheduled);
2881  if (m_transcodeCheck)
2882  m_transcodeCheck->SetEnabled(isScheduled);
2884  m_transcodeprofileList->SetEnabled(isScheduled &&
2886  if (m_userjob1Check)
2887  m_userjob1Check->SetEnabled(isScheduled);
2888  if (m_userjob2Check)
2889  m_userjob2Check->SetEnabled(isScheduled);
2890  if (m_userjob3Check)
2891  m_userjob3Check->SetEnabled(isScheduled);
2892  if (m_userjob4Check)
2893  m_userjob4Check->SetEnabled(isScheduled);
2895  m_metadataLookupCheck->SetEnabled(isScheduled);
2896 }
2897 
2899 {
2900  if (!m_rule)
2901  return;
2902 
2903  m_rule->m_autoTranscode = enable;
2904 
2907 }
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:785
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=NULL)
Definition: mythuiutils.h:26
MythUICheckBox * m_commflagCheck
void SetTitle(const QString &title)
void SetHandleImages(bool handle)
void MaxEpisodesChanged(MythUIButtonListItem *)
virtual void ShowUpcoming(void) const
Show the upcoming recordings for this title.
Select post-processing options.
void ruleDeleted(int ruleId)
static QString fs8(QT_TRANSLATE_NOOP("SchedFilterEditor","This time"))
void showUpcomingByTitle(void)
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:884
MythUICheckBox * m_ruleactiveCheck
void RuleChanged(void)
uint GetYearOfInitialRelease(void) const
Definition: programinfo.h:401
virtual void ShowGuide(void) const
Show the program guide.
void DupMethodChanged(MythUIButtonListItem *)
void SetSubtitle(const QString &subtitle)
MetadataLookupList results
void SetAutomatic(bool autom)
void UseTempTable(bool usetemp, QString table="record_tmp")
MythUISpinBox * m_endoffsetSpin
bool StartEmbedding(const QRect &)
Definition: tv_play.cpp:8490
ScheduleEditor(MythScreenStack *parent, RecordingInfo *recinfo, TV *player=NULL)
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:83
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.
bool IsLoaded() const
Definition: recordingrule.h:55
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
MetadataType
ArtworkMap m_artworkMap
MythUISpinBox * m_prioritySpin
PostProcEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
QVariant value(int i) const
Definition: mythdbcon.h:182
enum RecordingDupInTypes RecordingDupInType
int GetIntValue(void) const
Definition: mythuispinbox.h:29
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
static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor","New episode"))
void SetAllowOverwrites(bool allow)
MythUIButtonList * m_playgroupList
void ToMap(InfoMap &infoMap) const
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
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:33
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...
AllMusic * parent
virtual bool Create(void)
MythScreenStack * GetStack(const QString &stackname)
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.
GLint GLenum GLsizei GLint GLenum GLenum type
ArtworkList GetArtwork(VideoArtworkType type) const
static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor","This episode"))
RecordingType m_type
Definition: recordingrule.h:99
MythScreenStack * GetMainStack()
MythUIButton * m_schedOptButton
void showTemplateMenu(void)
SchedEditChild * m_child
RecordingDupMethodType m_dupMethod
void ShowSchedInfo(void)
uint GetRecordingRuleID(void) const
Definition: programinfo.h:430
Select schedule options.
void SetRule(RecordingRule *rule)
MythUIButtonListItem * GetItemCurrent() const
SchedEditChild(MythScreenStack *parent, const QString &name, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor","First showing"))
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.
void BuildFocusList(void)
static Type kEventType
Definition: mythdialogbox.h:45
MetadataLookup * item
RecordingRule * m_recordingRule
QVariant GetDataValue() const
MetadataLookup * CreateLookup(MetadataType mtype)
MythUICheckBox * m_metadataLookupCheck
MythUIImage * m_fanart
uint GetEpisode() const
void SetStep(LookupStep step)
RecordingDupMethodType
void SetNameFilter(QStringList filter)
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)
Holds information on recordings and videos.
Definition: programinfo.h:65
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)
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's original state, should not reset changes made by the theme.
RecordingRule * m_rule
virtual void Load(void)=0
MythUIButtonList * m_storagegroupList
void FilterChanged(MythUIButtonListItem *)
void ruleSaved(int ruleId)
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:911
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)
uint GetSeason() const
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
void ShowPostProc(void)
StoreOptEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
uint GetSeason(void) const
Definition: programinfo.h:344
MythUIButton * m_schedInfoButton
virtual void SetTextFromMap(const InfoMap &infoMap)
Control TV playback TVPlaybackAborted(void)
Definition: tv_play.h:291
QString GetMasterHostName(void)
RecordingRule * m_rule
MythUIButton * m_saveButton
static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor","Prime time"))
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Mixin for storage options.
void SetRule(RecordingRule *rule)
void Closing(void)
virtual void ShowDetails(void) const
Show the Program Details screen.
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:542
void FindNetArt(VideoArtworkType type)
MythUIBusyDialog * m_busyPopup
static QString fs9(QT_TRANSLATE_NOOP("SchedFilterEditor","This day and time"))
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:31
void SetDownloads(ArtworkMap map)
void SetRecGroup(int recgroupID, QString recgroup)
const char * name
Definition: ParseText.cpp:338
void ShowSchedOpt(void)
void ShowFilters(void)
FilterOptMixin * m_other
MythScreenStack * GetScreenStack() const
void ShowMetadataOptions(void)
QString m_seriesid
Definition: recordingrule.h:87
MythUIType * GetFocusWidget(void) const
MythUIButton * m_localBannerButton
MythUIButton * m_previewButton
static void * RunScheduleEditor(ProgramInfo *proginfo, void *player=NULL)
Callback.
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)
static vector< uint > GetInputList(void)
Definition: cardutil.cpp:1940
QString m_inetref
Definition: recordingrule.h:89
QString GetText(void) const
MythMainWindow * GetMythMainWindow(void)
void Create(bool *err)
QStringList GetSupportedImageExtensionFilter()
QVariant GetData() const
MythScreenType * m_screen
virtual void ShowPrevious(void) const
Show the previous recordings for this recording rule.
QList< ArtworkInfo > ArtworkList
MythUIImage * m_banner
MetadataDownload * m_imageLookup
void PromptForRecGroup(void)
MythUISpinBox * m_startoffsetSpin
static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor","This series"))
MythUISpinBox * m_seasonSpin
MythUIButton * m_onlineBannerButton
MythUIButtonList * m_transcodeprofileList
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:810
void DupMethodChanged(MythUIButtonListItem *item)
MythUICheckBox * m_userjob3Check
virtual bool CreateEditChild(QString xmlfile, QString winname, bool isTemplate)
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
static Type kEventType
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)
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...
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.
bool GetBooleanCheckState(void) const
void SetReturnEvent(QObject *retobject, const QString &resultid)
void showMenu(void)
uint GetEpisode(void) const
Definition: programinfo.h:345
MythUICheckBox * m_userjob2Check
void Lookup(ProgramInfo *pginfo, bool automatic=true, bool getimages=true, bool allowgeneric=false)
CheckState state() const
void OnImageSearchListSelection(ArtworkInfo info, VideoArtworkType type)
void SetSubtype(LookupType subtype)
void SetValue(int val)
Definition: mythuispinbox.h:25
MythUIButtonList * m_maxbehaviourList
QString m_recProfile
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:173
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
static QString fs10(QT_TRANSLATE_NOOP("SchedFilterEditor","This channel"))
static QMap< int, QString > GetTranscodingProfiles()
virtual void PopScreen(MythScreenType *screen=NULL, bool allowFade=true, bool deleteScreen=true)
MetadataImageDownload * m_imageDownload
QString GetInetref() const
MythUIButton * m_localCoverartButton
static QStringList GetTemplateNames(void)
void PromptForRecGroup(void)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:610
MythUIButtonList * m_dupmethodList
CategoryType GetCategoryType(void) const
Definition: programinfo.h:416
MythUIButton * m_saveButton
void SetEpisode(uint episode)
static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor","Identifiable 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:32
void ShowNextView(void)
MythUIButton * m_storeOptButton
StoreOptMixin * m_other
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
Definition: mythuitype.cpp:362
void ShowPreviousView(void)
PostProcMixin(MythScreenType &screen, RecordingRule *rule, PostProcMixin *other=NULL)
MythUIButtonList * m_recprofileList
MetadataOptions(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
PostProcMixin * m_other
static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor","Commercial free"))
MythUIButton * m_cancelButton
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.
MythNotificationCenter * GetNotificationCenter(void)
MythUIButtonList * m_rulesList
DownloadMap GetDownloads() const
SchedOptEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
MythUIButtonListItem * GetItemAt(int pos) const
void SetTextFromMaps(void)
static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor","High definition"))
void RuleChanged(void)
StoreOptMixin(MythScreenType &screen, RecordingRule *rule, StoreOptMixin *other=NULL)
static QString GetDisplayName(uint inputid)
Definition: cardutil.cpp:1006
void HandleDownloadedImages(MetadataLookup *lookup)