MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
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 
14 // Libmythtv
15 #include "playgroup.h"
16 #include "tv_play.h"
17 #include "recordingprofile.h"
18 #include "cardutil.h"
19 
20 // Libmythui
21 #include "mythmainwindow.h"
22 #include "mythuihelper.h"
23 #include "mythuibuttonlist.h"
24 #include "mythuibutton.h"
25 #include "mythuitext.h"
26 #include "mythuistatetype.h"
27 #include "mythuispinbox.h"
28 #include "mythuicheckbox.h"
29 #include "mythdialogbox.h"
30 #include "mythprogressdialog.h"
31 #include "mythuifilebrowser.h"
32 #include "mythuimetadataresults.h"
33 #include "mythuiimageresults.h"
34 #include "videoutils.h"
35 #include "mythuiutils.h"
36 
37 #include "metadataimagehelper.h"
38 
39 // Mythfrontend
40 #include "proglist.h"
41 #include "viewschedulediff.h"
42 
43 #define ENUM_TO_QVARIANT(a) qVariantFromValue(static_cast<int>(a))
44 
45 // Define the strings inserted into the recordfilter table in the
46 // database. This should make them available to the translators.
47 static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor", "New episode"));
48 static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor", "Identifiable episode"));
49 static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor", "First showing"));
50 static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor", "Prime time"));
51 static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor", "Commercial free"));
52 static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor", "High definition"));
53 static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor", "This episode"));
54 static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor", "This series"));
55 static QString fs8(QT_TRANSLATE_NOOP("SchedFilterEditor", "This time"));
56 static QString fs9(QT_TRANSLATE_NOOP("SchedFilterEditor", "This day and time"));
57 static QString fs10(QT_TRANSLATE_NOOP("SchedFilterEditor", "This channel"));
58 
59 void *ScheduleEditor::RunScheduleEditor(ProgramInfo *proginfo, void *player)
60 {
61  RecordingRule *rule = new RecordingRule();
62  rule->LoadByProgram(proginfo);
63 
65  ScheduleEditor *se = new ScheduleEditor(mainStack, rule,
66  static_cast<TV*>(player));
67 
68  if (se->Create())
69  mainStack->AddScreen(se, (player == NULL));
70  else
71  delete se;
72 
73  return NULL;
74 }
75 
82  RecordingInfo *recInfo, TV *player)
83  : ScheduleCommon(parent, "ScheduleEditor"),
84  SchedOptMixin(*this, NULL), StoreOptMixin(*this, NULL),
85  PostProcMixin(*this, NULL),
86  m_recInfo(new RecordingInfo(*recInfo)), m_recordingRule(NULL),
87  m_sendSig(false),
88  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
89  m_schedOptButton(NULL), m_storeOptButton(NULL),
90  m_postProcButton(NULL), m_schedInfoButton(NULL),
91  m_previewButton(NULL), m_metadataButton(NULL),
92  m_filtersButton(NULL),
93  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
94 {
100 }
101 
103  RecordingRule *recRule, TV *player)
104  : ScheduleCommon(parent, "ScheduleEditor"),
105  SchedOptMixin(*this, recRule),
106  StoreOptMixin(*this, recRule),
107  PostProcMixin(*this, recRule),
108  m_recInfo(NULL), m_recordingRule(recRule),
109  m_sendSig(false),
110  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
111  m_schedOptButton(NULL), m_storeOptButton(NULL),
112  m_postProcButton(NULL), m_schedInfoButton(NULL),
113  m_previewButton(NULL), m_metadataButton(NULL),
114  m_filtersButton(NULL),
115  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
116 {
117 }
118 
120 {
121  delete m_recordingRule;
122 
123  // if we have a player, we need to tell we are done
124  if (m_player)
125  {
126  QString message = QString("VIEWSCHEDULED_EXITING");
127  qApp->postEvent(m_player, new MythEvent(message));
128  }
129 }
130 
132 {
133  if (!LoadWindowFromXML("schedule-ui.xml", "scheduleeditor", this))
134  return false;
135 
136  bool err = false;
137 
138  UIUtilE::Assign(this, m_rulesList, "rules", &err);
139 
140  UIUtilW::Assign(this, m_schedOptButton, "schedoptions");
141  UIUtilW::Assign(this, m_storeOptButton, "storeoptions");
142  UIUtilW::Assign(this, m_postProcButton, "postprocessing");
143  UIUtilW::Assign(this, m_metadataButton, "metadata");
144  UIUtilW::Assign(this, m_schedInfoButton, "schedinfo");
145  UIUtilW::Assign(this, m_previewButton, "preview");
146  UIUtilW::Assign(this, m_filtersButton, "filters");
147 
148  SchedOptMixin::Create(&err);
149  StoreOptMixin::Create(&err);
150  PostProcMixin::Create(&err);
151 
152  UIUtilW::Assign(this, m_cancelButton, "cancel");
153  UIUtilE::Assign(this, m_saveButton, "save", &err);
154 
155  if (err)
156  {
157  LOG(VB_GENERAL, LOG_ERR, "ScheduleEditor, theme is missing "
158  "required elements");
159  return false;
160  }
161 
162  connect(m_rulesList, SIGNAL(itemSelected(MythUIButtonListItem *)),
164 
165  if (m_schedOptButton)
166  connect(m_schedOptButton, SIGNAL(Clicked()), SLOT(ShowSchedOpt()));
167  if (m_filtersButton)
168  connect(m_filtersButton, SIGNAL(Clicked()), SLOT(ShowFilters()));
169  if (m_storeOptButton)
170  connect(m_storeOptButton, SIGNAL(Clicked()), SLOT(ShowStoreOpt()));
171  if (m_postProcButton)
172  connect(m_postProcButton, SIGNAL(Clicked()), SLOT(ShowPostProc()));
173  if (m_schedInfoButton)
174  connect(m_schedInfoButton, SIGNAL(Clicked()), SLOT(ShowSchedInfo()));
175  if (m_previewButton)
176  connect(m_previewButton, SIGNAL(Clicked()), SLOT(ShowPreview()));
177  if (m_metadataButton)
178  connect(m_metadataButton, SIGNAL(Clicked()), SLOT(ShowMetadataOptions()));
179 
180  if (m_cancelButton)
181  connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
182  connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
183 
184  if (m_schedInfoButton)
186  if (m_previewButton)
188 
189  if (m_dupmethodList)
190  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
192  if (m_maxepSpin)
193  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
195  if (m_recgroupList)
196  connect(m_recgroupList, SIGNAL(LosingFocus()),
197  SLOT(PromptForRecGroup()));
198  if (m_transcodeCheck)
199  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
200  SLOT(TranscodeChanged(bool)));
201 
202  BuildFocusList();
203 
204  if (!m_recordingRule->IsLoaded())
205  {
206  if (m_recInfo)
208  else if (m_recordingRule->m_recordID)
210 
211  if (!m_recordingRule->IsLoaded())
212  {
213  LOG(VB_GENERAL, LOG_ERR,
214  "ScheduleEditor::Create() - Failed to load recording rule");
215  return false;
216  }
217  }
218 
219  if (m_player)
220  m_player->StartEmbedding(QRect());
221 
222  return true;
223 }
224 
226 {
227  if (m_child)
228  m_child->Close();
229 
230  // don't fade the screen if we are returning to the player
231  if (m_player)
232  GetScreenStack()->PopScreen(this, false);
233  else
234  GetScreenStack()->PopScreen(this, true);
235 }
236 
238 {
242 
243  if (!m_loaded)
244  {
245  // Copy this now, it will change briefly after the first item
246  // is inserted into the list by design of
247  // MythUIButtonList::itemSelected()
249 
250  // Rules List
252  {
254  .compare("Default", Qt::CaseInsensitive) != 0)
255  {
257  tr("Delete this recording rule template"),
258  ENUM_TO_QVARIANT(kNotRecording));
259  }
261  tr("Modify this recording rule template"),
262  ENUM_TO_QVARIANT(kTemplateRecord));
263  }
264  else if (m_recordingRule->m_isOverride)
265  {
267  tr("Record this showing with normal options"),
268  ENUM_TO_QVARIANT(kNotRecording));
270  tr("Record this showing with override options"),
271  ENUM_TO_QVARIANT(kOverrideRecord));
273  tr("Do not record this showing"),
274  ENUM_TO_QVARIANT(kDontRecord));
275  }
276  else
277  {
278  bool hasChannel = !m_recordingRule->m_station.isEmpty();
279  bool isManual = (m_recordingRule->m_searchType == kManualSearch);
280 
282  tr("Do not record this program"),
283  ENUM_TO_QVARIANT(kNotRecording));
284  if (hasChannel)
286  tr("Record only this showing"),
287  ENUM_TO_QVARIANT(kSingleRecord));
288  if (!isManual)
290  tr("Record only one showing"),
291  ENUM_TO_QVARIANT(kOneRecord));
292  if (!hasChannel || isManual)
294  tr("Record one showing every week"),
295  ENUM_TO_QVARIANT(kWeeklyRecord));
296  if (!hasChannel || isManual)
298  tr("Record one showing every day"),
299  ENUM_TO_QVARIANT(kDailyRecord));
300  if (!isManual)
302  tr("Record all showings"),
303  ENUM_TO_QVARIANT(kAllRecord));
304  }
305 
307  }
308  m_rulesList->SetValueByData(ENUM_TO_QVARIANT(m_recordingRule->m_type));
309 
310  InfoMap progMap;
311 
312  m_recordingRule->ToMap(progMap);
313 
314  if (m_recInfo)
315  m_recInfo->ToMap(progMap);
316 
317  SetTextFromMap(progMap);
318 
319  m_loaded = true;
320 }
321 
323 {
325  Load();
326  emit templateLoaded();
327 }
328 
330 {
331  if (!item)
332  return;
333 
334  m_recordingRule->m_type = static_cast<RecordingType>
335  (item->GetData().toInt());
336 
337  bool isScheduled = (m_recordingRule->m_type != kNotRecording &&
339 
340  if (m_schedOptButton)
341  m_schedOptButton->SetEnabled(isScheduled);
342  if (m_filtersButton)
343  m_filtersButton->SetEnabled(isScheduled);
344  if (m_storeOptButton)
345  m_storeOptButton->SetEnabled(isScheduled);
346  if (m_postProcButton)
347  m_postProcButton->SetEnabled(isScheduled);
348  if (m_metadataButton)
349  m_metadataButton->SetEnabled(isScheduled &&
351 
355 }
356 
358 {
360 }
361 
363 {
365 }
366 
368 {
370 }
371 
373 {
375 }
376 
378 {
379  if (m_child)
380  m_child->Close();
381 
383  {
384  int recid = m_recordingRule->m_recordID;
385  DeleteRule();
386  if (recid)
387  emit ruleDeleted(recid);
388  Close();
389  return;
390  }
391 
395  m_recordingRule->Save(true);
397 
398  Close();
399 }
400 
402 {
404 }
405 
407 {
410  return;
411 
412  if (m_child)
413  m_child->Close();
414 
416 
418  SchedOptEditor *schedoptedit = new SchedOptEditor(mainStack, *this,
420  if (!schedoptedit->Create())
421  {
422  delete schedoptedit;
423  return;
424  }
425 
427  m_child = schedoptedit;
428  mainStack->AddScreen(schedoptedit);
429 }
430 
432 {
435  return;
436 
437  if (m_child)
438  m_child->Close();
439 
441 
443  StoreOptEditor *storeoptedit = new StoreOptEditor(mainStack, *this,
445  if (!storeoptedit->Create())
446  {
447  delete storeoptedit;
448  return;
449  }
450 
452  m_child = storeoptedit;
453  mainStack->AddScreen(storeoptedit);
454 }
455 
457 {
460  return;
461 
462  if (m_child)
463  m_child->Close();
464 
466 
468  PostProcEditor *ppedit = new PostProcEditor(mainStack, *this,
470  if (!ppedit->Create())
471  {
472  delete ppedit;
473  return;
474  }
475 
477  m_child = ppedit;
478  mainStack->AddScreen(ppedit);
479 }
480 
482 {
484  return;
485 
486  QString label = tr("Schedule Information");
487 
488  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
489  MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
490 
491  if (menuPopup->Create())
492  {
493  menuPopup->SetReturnEvent(this, "schedinfo");
494 
495  if (m_recInfo)
496  menuPopup->AddButton(tr("Program Details"));
497  menuPopup->AddButton(tr("Upcoming Episodes"));
498  menuPopup->AddButton(tr("Upcoming Recordings"));
499  menuPopup->AddButton(tr("Previously Scheduled"));
500 
501  popupStack->AddScreen(menuPopup);
502  }
503  else
504  delete menuPopup;
505 }
506 
507 bool ScheduleEditor::keyPressEvent(QKeyEvent *event)
508 {
509  if (GetFocusWidget()->keyPressEvent(event))
510  return true;
511 
512  bool handled = false;
513  QStringList actions;
514  handled = GetMythMainWindow()->
515  TranslateKeyPress("TV Frontend", event, actions);
516 
517  for (int i = 0; i < actions.size() && !handled; i++)
518  {
519  QString action = actions[i];
520  handled = true;
521 
522  if (action == "MENU")
523  showMenu();
524  else if (action == "INFO")
526  else if (action == "UPCOMING")
528  else if (action == "PREVVIEW")
530  else if (action == "NEXTVIEW")
531  ShowNextView();
532  else
533  handled = false;
534  }
535 
536  if (!handled && MythScreenType::keyPressEvent(event))
537  handled = true;
538 
539  return handled;
540 }
541 
542 void ScheduleEditor::customEvent(QEvent *event)
543 {
544  if (event->type() == DialogCompletionEvent::kEventType)
545  {
547 
548  QString resultid = dce->GetId();
549  QString resulttext = dce->GetResultText();
550 
551  if (resultid == "menu")
552  {
553  if (resulttext == tr("Main Options"))
554  m_child->Close();
555  if (resulttext == tr("Schedule Options"))
556  ShowSchedOpt();
557  else if (resulttext == tr("Filter Options"))
558  ShowFilters();
559  else if (resulttext == tr("Storage Options"))
560  ShowStoreOpt();
561  else if (resulttext == tr("Post Processing"))
562  ShowPostProc();
563  else if (resulttext == tr("Metadata Options"))
565  else if (resulttext == tr("Use Template"))
567  else if (resulttext == tr("Schedule Info"))
568  ShowSchedInfo();
569  else if (resulttext == tr("Preview Changes"))
570  ShowPreview();
571  }
572  else if (resultid == "templatemenu")
573  {
574  LoadTemplate(resulttext);
575  }
576  else if (resultid == "schedinfo")
577  {
578  if (resulttext == tr("Program Details"))
580  else if (resulttext == tr("Upcoming Episodes"))
582  else if (resulttext == tr("Upcoming Recordings"))
584  else if (resulttext == tr("Previously Scheduled"))
585  showPrevious();
586  }
587  else if (resultid == "newrecgroup")
588  {
589  StoreOptMixin::SetRecGroup(resulttext);
590  }
591  }
592 }
593 
595 {
597  return;
598 
599  QString title;
600  if (m_recInfo)
601  title = m_recInfo->GetTitle();
603  ProgLister *pl = new ProgLister(mainStack, m_recordingRule->m_recordID,
604  title);
605  if (pl->Create())
606  mainStack->AddScreen(pl);
607  else
608  delete pl;
609 }
610 
612 {
614  return;
615 
616  // No rule? Search by title
617  if (m_recordingRule->m_recordID <= 0)
618  {
620  return;
621  }
622 
624  ProgLister *pl = new ProgLister(mainStack, plRecordid,
625  QString::number(m_recordingRule->m_recordID),
626  "");
627 
628  if (pl->Create())
629  mainStack->AddScreen(pl);
630  else
631  delete pl;
632 }
633 
635 {
637  return;
638 
639  // Existing rule and search? Search by rule
640  if (m_recordingRule->m_recordID > 0 &&
643 
644  QString title = m_recordingRule->m_title;
645 
647  title.remove(QRegExp(" \\(.*\\)$"));
648 
650 }
651 
653 {
655  return;
656 
657  if (m_child)
658  {
659  m_child->Save();
660  if (m_view == kSchedOptView)
662  else if (m_view == kStoreOptView)
664  else if (m_view == kPostProcView)
666  }
667 
671 
672  QString ttable = "record_tmp";
673  m_recordingRule->UseTempTable(true, ttable);
674 
676  ViewScheduleDiff *vsd = new ViewScheduleDiff(mainStack, ttable,
679  if (vsd->Create())
680  mainStack->AddScreen(vsd);
681  else
682  delete vsd;
683 
685 }
686 
688 {
692  return;
693 
694  if (m_child)
695  m_child->Close();
696 
698  MetadataOptions *rad = new MetadataOptions(mainStack, *this,
700  if (!rad->Create())
701  {
702  delete rad;
703  return;
704  }
705 
707  m_child = rad;
708  mainStack->AddScreen(rad);
709 }
710 
712 {
715  return;
716 
717  if (m_child)
718  m_child->Close();
719 
721  SchedFilterEditor *schedfilteredit = new SchedFilterEditor(mainStack,
722  *this, *m_recordingRule, m_recInfo);
723  if (!schedfilteredit->Create())
724  {
725  delete schedfilteredit;
726  return;
727  }
728 
730  m_child = schedfilteredit;
731  mainStack->AddScreen(schedfilteredit);
732 }
733 
735 {
738  return;
739 
742  else if (m_view == kMainView)
743  ShowPostProc();
744  else if (m_view == kSchedOptView)
745  m_child->Close();
746  else if (m_view == kFilterView)
747  ShowSchedOpt();
748  else if (m_view == kStoreOptView)
749  ShowFilters();
750  else if (m_view == kPostProcView)
751  ShowStoreOpt();
752  else if (m_view == kMetadataView)
753  ShowPostProc();
754 }
755 
757 {
760  return;
761 
762  if (m_view == kMainView)
763  ShowSchedOpt();
764  else if (m_view == kSchedOptView)
765  ShowFilters();
766  else if (m_view == kFilterView)
767  ShowStoreOpt();
768  else if (m_view == kStoreOptView)
769  ShowPostProc();
772  else if (m_view == kPostProcView)
773  m_child->Close();
774  else if (m_view == kMetadataView)
775  m_child->Close();
776 }
777 
779 {
780  if (m_view == kSchedOptView)
782  else if (m_view == kStoreOptView)
784  else if (m_view == kPostProcView)
786 
787  m_child = NULL;
788  m_view = kMainView;
789 }
790 
792 {
793  QString label = tr("Options");
794  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
795  MythDialogBox *menuPopup =
796  new MythDialogBox(label, popupStack, "menuPopup");
797 
799  RecordingType type = static_cast<RecordingType>(item->GetData().toInt());
800  bool isScheduled = (type != kNotRecording && type != kDontRecord);
801 
802  if (menuPopup->Create())
803  {
804  menuPopup->SetReturnEvent(this, "menu");
805  if (m_view != kMainView)
806  menuPopup->AddButton(tr("Main Options"));
807  if (isScheduled && m_view != kSchedOptView)
808  menuPopup->AddButton(tr("Schedule Options"));
809  if (isScheduled && m_view != kFilterView)
810  menuPopup->AddButton(tr("Filter Options"));
811  if (isScheduled && m_view != kStoreOptView)
812  menuPopup->AddButton(tr("Storage Options"));
813  if (isScheduled && m_view != kPostProcView)
814  menuPopup->AddButton(tr("Post Processing"));
815  if (isScheduled && !m_recordingRule->m_isTemplate &&
817  menuPopup->AddButton(tr("Metadata Options"));
819  menuPopup->AddButton(tr("Schedule Info"));
821  menuPopup->AddButton(tr("Preview Changes"));
822  menuPopup->AddButton(tr("Use Template"));
823  popupStack->AddScreen(menuPopup);
824  }
825  else
826  {
827  delete menuPopup;
828  }
829 }
830 
832 {
833  QStringList templates = RecordingRule::GetTemplateNames();
834  if (templates.empty())
835  {
836  ShowOkPopup(tr("No templates available"));
837  return;
838  }
839 
840  QString label = tr("Template Options");
841  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
842  MythDialogBox *menuPopup =
843  new MythDialogBox(label, popupStack, "menuPopup");
844 
845  if (menuPopup->Create())
846  {
847  menuPopup->SetReturnEvent(this, "templatemenu");
848  while (!templates.empty())
849  {
850  QString name = templates.front();
851  if (name == "Default")
852  menuPopup->AddButton(tr("Default"));
853  else
854  menuPopup->AddButton(name);
855  templates.pop_front();
856  }
857  popupStack->AddScreen(menuPopup);
858  }
859  else
860  {
861  delete menuPopup;
862  }
863 }
864 
866 
872  ScheduleEditor &editor, RecordingRule &rule,
873  RecordingInfo *recInfo)
874  : MythScreenType(parent, name),
875  m_editor(&editor), m_recordingRule(&rule), m_recInfo(recInfo),
876  m_backButton(NULL), m_saveButton(NULL), m_previewButton(NULL)
877 {
878 }
879 
881 {
882 }
883 
884 bool SchedEditChild::keyPressEvent(QKeyEvent *event)
885 {
886  if (GetFocusWidget()->keyPressEvent(event))
887  return true;
888 
889  bool handled = false;
890  QStringList actions;
891  handled = GetMythMainWindow()->
892  TranslateKeyPress("TV Frontend", event, actions);
893 
894  for (int i = 0; i < actions.size() && !handled; i++)
895  {
896  QString action = actions[i];
897  handled = true;
898 
899  if (action == "MENU")
900  m_editor->showMenu();
901  else if (action == "INFO")
903  else if (action == "UPCOMING")
905  if (action == "ESCAPE")
906  Close();
907  else if (action == "PREVVIEW")
909  else if (action == "NEXTVIEW")
911  else
912  handled = false;
913  }
914 
915  if (!handled && MythScreenType::keyPressEvent(event))
916  handled = true;
917 
918  return handled;
919 }
920 
922  const QString xmlfile, const QString winname, bool isTemplate)
923 {
924  if (!LoadWindowFromXML(xmlfile, winname, this))
925  return false;
926 
927  UIUtilW::Assign(this, m_backButton, "back");
928  UIUtilW::Assign(this, m_saveButton, "save");
929  UIUtilW::Assign(this, m_previewButton, "preview");
930 
931  connect(this, SIGNAL(Closing()), m_editor, SLOT(ChildClosing()));
932  connect(m_editor, SIGNAL(templateLoaded()), SLOT(Load()));
933 
934  if (m_backButton)
935  connect(m_backButton, SIGNAL(Clicked()), SLOT(Close()));
936  if (m_saveButton)
937  connect(m_saveButton, SIGNAL(Clicked()), m_editor, SLOT(Save()));
938  if (m_previewButton)
939  connect(m_previewButton, SIGNAL(Clicked()),
940  m_editor, SLOT(ShowPreview()));
941 
942  if (m_previewButton)
943  m_previewButton->SetEnabled(!isTemplate);
944 
945  return true;
946 }
947 
949 {
950  InfoMap progMap;
951 
952  m_recordingRule->ToMap(progMap);
953 
954  if (m_recInfo)
955  m_recInfo->ToMap(progMap);
956 
957  SetTextFromMap(progMap);
958 }
959 
961 {
962  Save();
963  emit Closing();
965 }
966 
968 
975  ScheduleEditor &editor,
976  RecordingRule &rule,
977  RecordingInfo *recInfo)
978  : SchedEditChild(parent, "ScheduleOptionsEditor", editor, rule, recInfo),
979  SchedOptMixin(*this, &rule, &editor), m_filtersButton(NULL)
980 {
981 }
982 
984 {
985 }
986 
988 {
990  "schedule-ui.xml", "scheduleoptionseditor",
992  {
993  return false;
994  }
995 
996  bool err = false;
997 
998  SchedOptMixin::Create(&err);
999 
1000  UIUtilW::Assign(this, m_filtersButton, "filters");
1001 
1002  if (err)
1003  {
1004  LOG(VB_GENERAL, LOG_ERR, "SchedOptEditor, theme is missing "
1005  "required elements");
1006  return false;
1007  }
1008 
1009  if (m_dupmethodList)
1010  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
1012 
1013  if (m_filtersButton)
1014  connect(m_filtersButton, SIGNAL(Clicked()),
1015  m_editor, SLOT(ShowFilters()));
1016 
1017  BuildFocusList();
1018 
1019  return true;
1020 }
1021 
1023 {
1025  SetTextFromMaps();
1026 }
1027 
1029 {
1031 }
1032 
1034 {
1036 }
1037 
1039 
1046  ScheduleEditor &editor,
1047  RecordingRule &rule,
1048  RecordingInfo *recInfo)
1049  : SchedEditChild(parent, "ScheduleFilterEditor", editor, rule, recInfo),
1050  m_filtersList(NULL), m_loaded(false)
1051 {
1052 }
1053 
1055 {
1056 }
1057 
1059 {
1061  "schedule-ui.xml", "schedulefiltereditor",
1063  {
1064  return false;
1065  }
1066 
1067  bool err = false;
1068 
1069  UIUtilE::Assign(this, m_filtersList, "filters", &err);
1070 
1071  if (err)
1072  {
1073  LOG(VB_GENERAL, LOG_ERR, "SchedFilterEditor, theme is missing "
1074  "required elements");
1075  return false;
1076  }
1077 
1078  connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
1080 
1081  BuildFocusList();
1082 
1083  return true;
1084 }
1085 
1087 {
1088  int filterid;
1089  MythUIButtonListItem *button;
1090 
1091  if (!m_loaded)
1092  {
1093  MSqlQuery query(MSqlQuery::InitCon());
1094 
1095  query.prepare("SELECT filterid, description, newruledefault "
1096  "FROM recordfilter ORDER BY filterid");
1097 
1098  if (query.exec())
1099  {
1100  while (query.next())
1101  {
1102  filterid = query.value(0).toInt();
1103  QString description = tr(query.value(1).toString()
1104  .toUtf8().constData());
1105  // Fill in list of possible filters
1106  button = new MythUIButtonListItem(m_filtersList, description,
1107  filterid);
1108  button->setCheckable(true);
1109  }
1110  }
1111  }
1112 
1113  int idx, end = m_filtersList->GetCount();
1114  for (idx = 0; idx < end; ++idx)
1115  {
1116  button = m_filtersList->GetItemAt(idx);
1117  int filterid = qVariantValue<int>(button->GetData());
1118  button->setChecked(m_recordingRule->m_filter & (1 << filterid) ?
1121  }
1122 
1123  SetTextFromMaps();
1124 
1125  m_loaded = true;
1126 }
1127 
1129 {
1133 }
1134 
1136 {
1137  // Iterate through button list, and build the mask
1138  MythUIButtonListItem *button;
1139  uint32_t filter_mask = 0;
1140  int idx, end;
1141 
1142  end = m_filtersList->GetCount();
1143  for (idx = 0; idx < end; ++idx)
1144  {
1145  if ((button = m_filtersList->GetItemAt(idx)) &&
1147  filter_mask |= (1 << qVariantValue<uint32_t>(button->GetData()));
1148  }
1149  m_recordingRule->m_filter = filter_mask;
1150 }
1151 
1153 
1160  ScheduleEditor &editor,
1161  RecordingRule &rule,
1162  RecordingInfo *recInfo)
1163  : SchedEditChild(parent, "StorageOptionsEditor", editor, rule, recInfo),
1164  StoreOptMixin(*this, &rule, &editor)
1165 {
1166 }
1167 
1169 {
1170 }
1171 
1173 {
1175  "schedule-ui.xml", "storageoptionseditor",
1177  {
1178  return false;
1179  }
1180 
1181  bool err = false;
1182 
1183  StoreOptMixin::Create(&err);
1184 
1185  if (err)
1186  {
1187  LOG(VB_GENERAL, LOG_ERR, "StoreOptEditor, theme is missing "
1188  "required elements");
1189  return false;
1190  }
1191 
1192  if (m_maxepSpin)
1193  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
1195  if (m_recgroupList)
1196  connect(m_recgroupList, SIGNAL(LosingFocus()),
1197  SLOT(PromptForRecGroup()));
1198 
1199  BuildFocusList();
1200 
1201  return true;
1202 }
1203 
1205 {
1207  SetTextFromMaps();
1208 }
1209 
1211 {
1213 }
1214 
1216 {
1218 }
1219 
1220 void StoreOptEditor::customEvent(QEvent *event)
1221 {
1222  if (event->type() == DialogCompletionEvent::kEventType)
1223  {
1225 
1226  QString resultid = dce->GetId();
1227  QString resulttext = dce->GetResultText();
1228 
1229  if (resultid == "newrecgroup")
1230  {
1231  StoreOptMixin::SetRecGroup(resulttext);
1232  }
1233  }
1234 }
1235 
1237 {
1239 }
1240 
1242 
1249  ScheduleEditor &editor,
1250  RecordingRule &rule,
1251  RecordingInfo *recInfo)
1252  : SchedEditChild(parent, "PostProcOptionsEditor", editor, rule, recInfo),
1253  PostProcMixin(*this, &rule, &editor)
1254 {
1255 }
1256 
1258 {
1259 }
1260 
1262 {
1264  "schedule-ui.xml", "postproceditor",
1266  {
1267  return false;
1268  }
1269 
1270  bool err = false;
1271 
1272  PostProcMixin::Create(&err);
1273 
1274  if (err)
1275  {
1276  LOG(VB_GENERAL, LOG_ERR, "PostProcEditor, theme is missing "
1277  "required elements");
1278  return false;
1279  }
1280 
1281  if (m_transcodeCheck)
1282  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
1283  SLOT(TranscodeChanged(bool)));
1284 
1285  BuildFocusList();
1286 
1287  return true;
1288 }
1289 
1291 {
1293  SetTextFromMaps();
1294 }
1295 
1297 {
1299 }
1300 
1302 {
1304 }
1305 
1307 
1314  ScheduleEditor &editor,
1315  RecordingRule &rule,
1316  RecordingInfo *recInfo)
1317  : SchedEditChild(parent, "MetadataOptions", editor, rule, recInfo),
1318  m_lookup(NULL),
1319  m_busyPopup(NULL), m_fanart(NULL), m_coverart(NULL),
1320  m_banner(NULL), m_inetrefEdit(NULL), m_seasonSpin(NULL),
1321  m_episodeSpin(NULL), m_queryButton(NULL), m_localFanartButton(NULL),
1322  m_localCoverartButton(NULL), m_localBannerButton(NULL),
1323  m_onlineFanartButton(NULL), m_onlineCoverartButton(NULL),
1324  m_onlineBannerButton(NULL)
1325 {
1326  m_popupStack = GetMythMainWindow()->GetStack("popup stack");
1327 
1328  m_metadataFactory = new MetadataFactory(this);
1329  m_imageLookup = new MetadataDownload(this);
1331 
1334 }
1335 
1337 {
1338  if (m_imageLookup)
1339  {
1340  m_imageLookup->cancel();
1341  delete m_imageLookup;
1342  m_imageLookup = NULL;
1343  }
1344 
1345  if (m_imageDownload)
1346  {
1348  delete m_imageDownload;
1349  m_imageDownload = NULL;
1350  }
1351 }
1352 
1354 {
1356  "schedule-ui.xml", "metadataoptions",
1358  {
1359  return false;
1360  }
1361 
1362  bool err = false;
1363 
1364  UIUtilE::Assign(this, m_inetrefEdit, "inetref_edit", &err);
1365  UIUtilE::Assign(this, m_seasonSpin, "season_spinbox", &err);
1366  UIUtilE::Assign(this, m_episodeSpin, "episode_spinbox", &err);
1367  UIUtilE::Assign(this, m_queryButton, "query_button", &err);
1368  UIUtilE::Assign(this, m_localFanartButton, "local_fanart_button", &err);
1369  UIUtilE::Assign(this, m_localCoverartButton, "local_coverart_button", &err);
1370  UIUtilE::Assign(this, m_localBannerButton, "local_banner_button", &err);
1371  UIUtilE::Assign(this, m_onlineFanartButton, "online_fanart_button", &err);
1372  UIUtilE::Assign(this, m_onlineCoverartButton, "online_coverart_button", &err);
1373  UIUtilE::Assign(this, m_onlineBannerButton, "online_banner_button", &err);
1374  UIUtilW::Assign(this, m_fanart, "fanart");
1375  UIUtilW::Assign(this, m_coverart, "coverart");
1376  UIUtilW::Assign(this, m_banner, "banner");
1377 
1378  if (err)
1379  {
1380  LOG(VB_GENERAL, LOG_ERR, "MetadataOptions, theme is missing "
1381  "required elements");
1382  return false;
1383  }
1384 
1385  connect(m_queryButton, SIGNAL(Clicked()),
1386  SLOT(PerformQuery()));
1387  connect(m_localFanartButton, SIGNAL(Clicked()),
1388  SLOT(SelectLocalFanart()));
1389  connect(m_localCoverartButton, SIGNAL(Clicked()),
1390  SLOT(SelectLocalCoverart()));
1391  connect(m_localBannerButton, SIGNAL(Clicked()),
1392  SLOT(SelectLocalBanner()));
1393  connect(m_onlineFanartButton, SIGNAL(Clicked()),
1394  SLOT(SelectOnlineFanart()));
1395  connect(m_onlineCoverartButton, SIGNAL(Clicked()),
1396  SLOT(SelectOnlineCoverart()));
1397  connect(m_onlineBannerButton, SIGNAL(Clicked()),
1398  SLOT(SelectOnlineBanner()));
1399 
1400  connect(m_seasonSpin, SIGNAL(itemSelected(MythUIButtonListItem*)),
1401  SLOT(ValuesChanged()));
1402 
1403  // InetRef
1405 
1406  // Season
1407  m_seasonSpin->SetRange(0,9999,1,5);
1409 
1410  // Episode
1411  m_episodeSpin->SetRange(0,9999,1,10);
1413 
1414  if (m_coverart)
1415  {
1417  m_coverart->Load();
1418  }
1419 
1420  if (m_fanart)
1421  {
1423  m_fanart->Load();
1424  }
1425 
1426  if (m_banner)
1427  {
1429  m_banner->Load();
1430  }
1431 
1432  BuildFocusList();
1433 
1434  return true;
1435 }
1436 
1438 {
1439  SetTextFromMaps();
1440 }
1441 
1443 {
1444  if (m_busyPopup)
1445  return;
1446 
1447  QString message = title;
1448 
1449  m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
1450  "metaoptsdialog");
1451 
1452  if (m_busyPopup->Create())
1454 }
1455 
1457 {
1458  m_lookup = new MetadataLookup();
1459 
1460  CreateBusyDialog(tr("Trying to manually find this "
1461  "recording online..."));
1462 
1465  if (m_seasonSpin->GetIntValue() > 0 ||
1466  m_episodeSpin->GetIntValue() > 0)
1468  else
1470  m_lookup->SetAllowGeneric(true);
1471  m_lookup->SetAutomatic(false);
1472  m_lookup->SetHandleImages(false);
1480 
1482 }
1483 
1485 {
1486  QueryComplete(lookup);
1487 }
1488 
1491 {
1492  QString msg = tr("Downloading selected artwork...");
1493  CreateBusyDialog(msg);
1494 
1495  m_lookup = new MetadataLookup();
1498  m_lookup->SetAutomatic(true);
1499  m_lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1500 
1501  ArtworkMap downloads;
1502  downloads.insert(type, info);
1503  m_lookup->SetDownloads(downloads);
1510 
1512 }
1513 
1515 {
1516  if (!CanSetArtwork())
1517  return;
1518 
1519  QString url = generate_file_url("Fanart",
1521  "");
1522  FindImagePopup(url,"",*this, "fanart");
1523 }
1524 
1526 {
1527  if (!CanSetArtwork())
1528  return;
1529 
1530  QString url = generate_file_url("Coverart",
1532  "");
1533  FindImagePopup(url,"",*this, "coverart");
1534 }
1535 
1537 {
1538  if (!CanSetArtwork())
1539  return;
1540 
1541  QString url = generate_file_url("Banners",
1543  "");
1544  FindImagePopup(url,"",*this, "banner");
1545 }
1546 
1548 {
1550 }
1551 
1553 {
1555 }
1556 
1558 {
1560 }
1561 
1563 {
1564  // Season
1565  if (m_seasonSpin)
1567 
1568  // Episode
1569  if (m_episodeSpin)
1571 
1572  // InetRef
1573  if (m_inetrefEdit)
1575 }
1576 
1578 {
1579  if (!lookup)
1580  return;
1581 
1582  m_lookup = lookup;
1583 
1584  // InetRef
1586 
1587  // Season
1589 
1590  // Episode
1592 
1593  MetadataMap metadataMap;
1594  lookup->toMap(metadataMap);
1595  SetTextFromMap(metadataMap);
1596 }
1597 
1599  const QString &prefixAlt,
1600  QObject &inst,
1601  const QString &returnEvent)
1602 {
1603  QString fp;
1604 
1605  if (prefix.startsWith("myth://"))
1606  fp = prefix;
1607  else
1608  fp = prefix.isEmpty() ? prefixAlt : prefix;
1609 
1610  MythScreenStack *popupStack =
1611  GetMythMainWindow()->GetStack("popup stack");
1612 
1613  MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, fp);
1615  if (fb->Create())
1616  {
1617  fb->SetReturnEvent(&inst, returnEvent);
1618  popupStack->AddScreen(fb);
1619  }
1620  else
1621  delete fb;
1622 }
1623 
1625 {
1626  QStringList ret;
1627 
1628  QList<QByteArray> exts = QImageReader::supportedImageFormats();
1629  for (QList<QByteArray>::iterator p = exts.begin(); p != exts.end(); ++p)
1630  {
1631  ret.append(QString("*.").append(*p));
1632  }
1633 
1634  return ret;
1635 }
1636 
1638 {
1639  if (m_inetrefEdit->GetText().isEmpty())
1640  {
1641  ShowOkPopup(tr("You must set a reference number "
1642  "on this rule to set artwork. For items "
1643  "without a metadata source, you can set "
1644  "any unique value."));
1645  return false;
1646  }
1647 
1648  return true;
1649 }
1650 
1652 {
1653  if (!CanSetArtwork())
1654  return;
1655 
1656  m_lookup = new MetadataLookup();
1657 
1658  QString msg = tr("Searching for available artwork...");
1659  CreateBusyDialog(msg);
1660 
1663  m_lookup->SetAutomatic(true);
1664  m_lookup->SetHandleImages(false);
1665  if (m_seasonSpin->GetIntValue() > 0 ||
1666  m_episodeSpin->GetIntValue() > 0)
1668  else
1670  m_lookup->SetAllowGeneric(true);
1671  m_lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1679 
1681 }
1682 
1684 {
1685  if (!lookup)
1686  return;
1687 
1688  if (m_busyPopup)
1689  {
1690  m_busyPopup->Close();
1691  m_busyPopup = NULL;
1692  }
1693 
1694  VideoArtworkType type = qVariantValue<VideoArtworkType>(lookup->GetData());
1695  ArtworkList list = lookup->GetArtwork(type);
1696 
1697  if (list.count() == 0)
1698  return;
1699 
1700  ImageSearchResultsDialog *resultsdialog =
1701  new ImageSearchResultsDialog(m_popupStack, list, type);
1702 
1703  connect(resultsdialog, SIGNAL(haveResult(ArtworkInfo, VideoArtworkType)),
1705 
1706  if (resultsdialog->Create())
1707  m_popupStack->AddScreen(resultsdialog);
1708 }
1709 
1711 {
1712  if (!lookup)
1713  return;
1714 
1715  DownloadMap map = lookup->GetDownloads();
1716 
1717  if (map.isEmpty())
1718  return;
1719 
1720  for (DownloadMap::const_iterator i = map.begin(); i != map.end(); ++i)
1721  {
1722  VideoArtworkType type = i.key();
1723  ArtworkInfo info = i.value();
1724 
1725  if (type == kArtworkCoverart)
1726  m_artworkMap.replace(kArtworkCoverart, info);
1727  else if (type == kArtworkFanart)
1728  m_artworkMap.replace(kArtworkFanart, info);
1729  else if (type == kArtworkBanner)
1730  m_artworkMap.replace(kArtworkBanner, info);
1731  }
1732 
1735 
1736  ValuesChanged();
1737 }
1738 
1740 {
1743 
1744  if (m_coverart)
1745  {
1747  m_coverart->Load();
1748  }
1749 
1750  if (m_fanart)
1751  {
1753  m_fanart->Load();
1754  }
1755 
1756  if (m_banner)
1757  {
1759  m_banner->Load();
1760  }
1761 }
1762 
1763 void MetadataOptions::customEvent(QEvent *levent)
1764 {
1765  if (levent->type() == MetadataFactoryMultiResult::kEventType)
1766  {
1767  if (m_busyPopup)
1768  {
1769  m_busyPopup->Close();
1770  m_busyPopup = NULL;
1771  }
1772 
1773  MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
1774 
1775  if (!mfmr)
1776  return;
1777 
1778  MetadataLookupList list = mfmr->results;
1779 
1780  if (list.count() > 1)
1781  {
1782  int yearindex = -1;
1783 
1784  for (int p = 0; p != list.size(); ++p)
1785  {
1786  if (!m_recordingRule->m_seriesid.isEmpty() &&
1787  m_recordingRule->m_seriesid == (list[p])->GetTMSref())
1788  {
1789  MetadataLookup *lookup = list.takeAt(p);
1790  QueryComplete(lookup);
1791  qDeleteAll(list);
1792  return;
1793  }
1794  else if (m_recInfo &&
1796  (list[p])->GetYear() != 0 &&
1797  m_recInfo->GetYearOfInitialRelease() == (list[p])->GetYear())
1798  {
1799  if (yearindex > -1)
1800  {
1801  LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite "
1802  "match could be found based on year alone.");
1803  yearindex = -2;
1804  }
1805  else if (yearindex == -1)
1806  {
1807  LOG(VB_GENERAL, LOG_INFO, "Matched based on year. ");
1808  yearindex = p;
1809  }
1810  }
1811  }
1812 
1813  if (yearindex > -1)
1814  {
1815  MetadataLookup *lookup = list.takeAt(yearindex);
1816  QueryComplete(lookup);
1817  qDeleteAll(list);
1818  return;
1819  }
1820 
1821  LOG(VB_GENERAL, LOG_INFO, "Falling through to selection dialog.");
1822  MetadataResultsDialog *resultsdialog =
1824 
1825  connect(resultsdialog, SIGNAL(haveResult(MetadataLookup*)),
1827  Qt::QueuedConnection);
1828 
1829  if (resultsdialog->Create())
1830  m_popupStack->AddScreen(resultsdialog);
1831  }
1832  }
1833  else if (levent->type() == MetadataFactorySingleResult::kEventType)
1834  {
1835  if (m_busyPopup)
1836  {
1837  m_busyPopup->Close();
1838  m_busyPopup = NULL;
1839  }
1840 
1841  MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
1842 
1843  if (!mfsr)
1844  return;
1845 
1846  MetadataLookup *lookup = mfsr->result;
1847 
1848  if (!lookup)
1849  return;
1850 
1851  QueryComplete(lookup);
1852  }
1853  else if (levent->type() == MetadataFactoryNoResult::kEventType)
1854  {
1855  if (m_busyPopup)
1856  {
1857  m_busyPopup->Close();
1858  m_busyPopup = NULL;
1859  }
1860 
1861  MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
1862 
1863  if (!mfnr)
1864  return;
1865 
1866  MetadataLookup *lookup = mfnr->result;
1867 
1868  delete lookup;
1869  lookup = NULL;
1870 
1871  QString title = tr("No match found for this recording. You can "
1872  "try entering a TVDB/TMDB number, season, and "
1873  "episode manually.");
1874 
1875  MythConfirmationDialog *okPopup =
1876  new MythConfirmationDialog(m_popupStack, title, false);
1877 
1878  if (okPopup->Create())
1879  m_popupStack->AddScreen(okPopup);
1880  }
1881  else if (levent->type() == MetadataLookupEvent::kEventType)
1882  {
1883  if (m_busyPopup)
1884  {
1885  m_busyPopup->Close();
1886  m_busyPopup = NULL;
1887  }
1888 
1889  MetadataLookupEvent *lue = (MetadataLookupEvent *)levent;
1890 
1891  MetadataLookupList lul = lue->lookupList;
1892 
1893  if (lul.isEmpty())
1894  return;
1895 
1896  if (lul.count() >= 1)
1897  {
1898  OnArtworkSearchDone(lul.takeFirst());
1899  }
1900  }
1901  else if (levent->type() == MetadataLookupFailure::kEventType)
1902  {
1903  if (m_busyPopup)
1904  {
1905  m_busyPopup->Close();
1906  m_busyPopup = NULL;
1907  }
1908 
1910 
1911  MetadataLookupList lul = luf->lookupList;
1912 
1913  if (lul.size())
1914  {
1915  MetadataLookup *lookup = lul.takeFirst();
1916 
1917  QString title = tr("This number, season, and episode combination "
1918  "does not appear to be valid (or the site may "
1919  "be down). Check your information and try "
1920  "again.");
1921 
1922  MythConfirmationDialog *okPopup =
1923  new MythConfirmationDialog(m_popupStack, title, false);
1924 
1925  if (okPopup->Create())
1926  m_popupStack->AddScreen(okPopup);
1927 
1928  delete lookup;
1929  lookup = NULL;
1930  }
1931  }
1932  else if (levent->type() == ImageDLEvent::kEventType)
1933  {
1934  if (m_busyPopup)
1935  {
1936  m_busyPopup->Close();
1937  m_busyPopup = NULL;
1938  }
1939 
1940  ImageDLEvent *ide = (ImageDLEvent *)levent;
1941 
1942  MetadataLookup *lookup = ide->item;
1943 
1944  if (!lookup)
1945  return;
1946 
1947  HandleDownloadedImages(lookup);
1948  }
1949  else if (levent->type() == ImageDLFailureEvent::kEventType)
1950  {
1951  if (m_busyPopup)
1952  {
1953  m_busyPopup->Close();
1954  m_busyPopup = NULL;
1955  }
1956 
1957  ImageDLFailureEvent *ide = (ImageDLFailureEvent *)levent;
1958 
1959  MetadataLookup *lookup = ide->item;
1960 
1961  if (!lookup)
1962  return;
1963 
1964  delete lookup;
1965  lookup = NULL;
1966  }
1967  else if (levent->type() == DialogCompletionEvent::kEventType)
1968  {
1969  DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent);
1970 
1971  const QString resultid = dce->GetId();
1972  ArtworkInfo info;
1973  info.url = dce->GetResultText();
1974 
1975  if (resultid == "coverart")
1976  {
1977  m_artworkMap.replace(kArtworkCoverart, info);
1978  }
1979  else if (resultid == "fanart")
1980  {
1981  m_artworkMap.replace(kArtworkFanart, info);
1982  }
1983  else if (resultid == "banner")
1984  {
1985  m_artworkMap.replace(kArtworkBanner, info);
1986  }
1987 
1990 
1991  ValuesChanged();
1992  }
1993 
1994 }
1995 
1997 
2004  SchedOptMixin *other)
2005  : m_prioritySpin(NULL), m_startoffsetSpin(NULL), m_endoffsetSpin(NULL),
2006  m_dupmethodList(NULL), m_dupscopeList(NULL), m_inputList(NULL),
2007  m_ruleactiveCheck(NULL), m_newrepeatList(NULL),
2008  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false),
2009  m_haveRepeats(gCoreContext->GetNumSetting("HaveRepeats", 0))
2010 {
2011 }
2012 
2013 void SchedOptMixin::Create(bool *err)
2014 {
2015  if (!m_rule)
2016  return;
2017 
2018  if (m_other && !m_other->m_prioritySpin)
2019  UIUtilE::Assign(m_screen, m_prioritySpin, "priority", err);
2020  else
2021  UIUtilW::Assign(m_screen, m_prioritySpin, "priority");
2022 
2024  UIUtilE::Assign(m_screen, m_startoffsetSpin, "startoffset", err);
2025  else
2026  UIUtilW::Assign(m_screen, m_startoffsetSpin, "startoffset");
2027 
2028  if (m_other && !m_other->m_endoffsetSpin)
2029  UIUtilE::Assign(m_screen, m_endoffsetSpin, "endoffset", err);
2030  else
2031  UIUtilW::Assign(m_screen, m_endoffsetSpin, "endoffset");
2032 
2033  if (m_other && !m_other->m_dupmethodList)
2034  UIUtilE::Assign(m_screen, m_dupmethodList, "dupmethod", err);
2035  else
2036  UIUtilW::Assign(m_screen, m_dupmethodList, "dupmethod");
2037 
2038  if (m_other && !m_other->m_dupscopeList)
2039  UIUtilE::Assign(m_screen, m_dupscopeList, "dupscope", err);
2040  else
2041  UIUtilW::Assign(m_screen, m_dupscopeList, "dupscope");
2042 
2043  if (m_other && !m_other->m_inputList)
2044  UIUtilE::Assign(m_screen, m_inputList, "input", err);
2045  else
2047 
2049  UIUtilE::Assign(m_screen, m_ruleactiveCheck, "ruleactive", err);
2050  else
2051  UIUtilW::Assign(m_screen, m_ruleactiveCheck, "ruleactive");
2052 
2053  UIUtilW::Assign(m_screen, m_newrepeatList, "newrepeat");
2054 }
2055 
2057 {
2058  if (!m_rule)
2059  return;
2060 
2061  // Priority
2062  if (m_prioritySpin)
2063  {
2064  if (!m_loaded)
2065  m_prioritySpin->SetRange(-99,99,1,5);
2067  }
2068 
2069  // Start Offset
2070  if (m_startoffsetSpin)
2071  {
2072  if (!m_loaded)
2073  m_startoffsetSpin->SetRange(480,-480,1,10);
2075  }
2076 
2077  // End Offset
2078  if (m_endoffsetSpin)
2079  {
2080  if (!m_loaded)
2081  m_endoffsetSpin->SetRange(-480,480,1,10);
2083  }
2084 
2085  // Duplicate Match Type
2086  if (m_dupmethodList)
2087  {
2088  if (!m_loaded)
2089  {
2091 
2093  QObject::tr("Match duplicates using subtitle & description"),
2094  ENUM_TO_QVARIANT(kDupCheckSubDesc));
2096  QObject::tr("Match duplicates using subtitle then description"),
2097  ENUM_TO_QVARIANT(kDupCheckSubThenDesc));
2099  QObject::tr("Match duplicates using subtitle"),
2100  ENUM_TO_QVARIANT(kDupCheckSub));
2102  QObject::tr("Match duplicates using description"),
2103  ENUM_TO_QVARIANT(kDupCheckDesc));
2105  QObject::tr("Don't match duplicates"),
2106  ENUM_TO_QVARIANT(kDupCheckNone));
2107 
2108  m_rule->m_dupMethod = dupMethod;
2109  }
2110  m_dupmethodList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupMethod));
2111  }
2112 
2113  // Duplicate Matching Scope
2114  if (m_dupscopeList)
2115  {
2116  if (!m_loaded)
2117  {
2119  QObject::tr("Look for duplicates in current and previous "
2120  "recordings"), ENUM_TO_QVARIANT(kDupsInAll));
2122  QObject::tr("Look for duplicates in current recordings only"),
2123  ENUM_TO_QVARIANT(kDupsInRecorded));
2125  QObject::tr("Look for duplicates in previous recordings only"),
2126  ENUM_TO_QVARIANT(kDupsInOldRecorded));
2127  if (m_haveRepeats && !m_newrepeatList &&
2129  {
2131  QObject::tr("Record new episodes only"),
2132  ENUM_TO_QVARIANT(kDupsNewEpi|kDupsInAll));
2133  }
2134  }
2135  m_dupscopeList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupIn));
2136  }
2137 
2138  // Preferred Input
2139  if (m_inputList)
2140  {
2141  if (!m_loaded)
2142  {
2144  QObject::tr("Use any available input"),
2145  qVariantFromValue(0));
2146 
2147  vector<uint> inputids = CardUtil::GetAllInputIDs();
2148  for (uint i = 0; i < inputids.size(); ++i)
2149  {
2151  QObject::tr("Prefer input %1")
2152  .arg(CardUtil::GetDisplayName(inputids[i])), inputids[i]);
2153  }
2154  }
2156  }
2157 
2158  // Active/Disabled
2159  if (m_ruleactiveCheck)
2160  {
2162  }
2163 
2164  // Record new and repeat
2165  if (m_newrepeatList)
2166  {
2167  if (!m_loaded)
2168  {
2170  QObject::tr("Record new and repeat "
2171  "episodes"), ENUM_TO_QVARIANT(0));
2173  QObject::tr("Record new episodes only"),
2174  ENUM_TO_QVARIANT(kDupsNewEpi));
2175  }
2176  m_newrepeatList->SetValueByData(ENUM_TO_QVARIANT
2177  (m_rule->m_dupIn & kDupsNewEpi));
2178  }
2179 
2180  m_loaded = true;
2181 
2182  RuleChanged();
2183 }
2184 
2186 {
2187  if (!m_rule)
2188  return;
2189 
2190  if (m_prioritySpin)
2192  if (m_startoffsetSpin)
2194  if (m_endoffsetSpin)
2196  if (m_dupmethodList)
2197  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2198  (m_dupmethodList->GetDataValue().toInt());
2199  if (m_dupscopeList)
2200  {
2201  int mask = ((m_other && m_other->m_newrepeatList) ||
2202  m_newrepeatList) ? kDupsInAll : ~0;
2203  int val = ((m_rule->m_dupIn & ~mask) |
2204  m_dupscopeList->GetDataValue().toInt());
2205  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2206  }
2207  if (m_inputList)
2209  if (m_ruleactiveCheck)
2211  if (m_newrepeatList)
2212  {
2213  int val = ((m_rule->m_dupIn & ~kDupsNewEpi) |
2214  m_newrepeatList->GetDataValue().toInt());
2215  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2216  }
2217 }
2218 
2220 {
2221  if (!m_rule)
2222  return;
2223 
2224  bool isScheduled = (m_rule->m_type != kNotRecording &&
2225  m_rule->m_type != kDontRecord);
2226  bool isSingle = (m_rule->m_type == kSingleRecord ||
2228 
2229  if (m_prioritySpin)
2230  m_prioritySpin->SetEnabled(isScheduled);
2231  if (m_startoffsetSpin)
2232  m_startoffsetSpin->SetEnabled(isScheduled);
2233  if (m_endoffsetSpin)
2234  m_endoffsetSpin->SetEnabled(isScheduled);
2235  if (m_dupmethodList)
2236  m_dupmethodList->SetEnabled(isScheduled && !isSingle);
2237  if (m_dupscopeList)
2238  m_dupscopeList->SetEnabled(isScheduled && !isSingle &&
2240  if (m_inputList)
2241  m_inputList->SetEnabled(isScheduled);
2242  if (m_ruleactiveCheck)
2243  m_ruleactiveCheck->SetEnabled(isScheduled);
2244  if (m_newrepeatList)
2245  m_newrepeatList->SetEnabled(isScheduled && !isSingle && m_haveRepeats);
2246 }
2247 
2249 {
2250  if (!item || !m_rule)
2251  return;
2252 
2253  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2254  (item->GetData().toInt());
2255 
2256  if (m_dupscopeList)
2258 }
2259 
2261 
2268  StoreOptMixin *other)
2269  : m_recprofileList(NULL), m_recgroupList(NULL), m_storagegroupList(NULL),
2270  m_playgroupList(NULL), m_maxepSpin(NULL), m_maxbehaviourList(NULL),
2271  m_autoexpireCheck(NULL),
2272  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2273 {
2274 }
2275 
2276 void StoreOptMixin::Create(bool *err)
2277 {
2278  if (!m_rule)
2279  return;
2280 
2281  if (m_other && !m_other->m_recprofileList)
2282  UIUtilE::Assign(m_screen, m_recprofileList, "recprofile", err);
2283  else
2284  UIUtilW::Assign(m_screen, m_recprofileList, "recprofile");
2285 
2286  if (m_other && !m_other->m_recgroupList)
2287  UIUtilE::Assign(m_screen, m_recgroupList, "recgroup", err);
2288  else
2289  UIUtilW::Assign(m_screen, m_recgroupList, "recgroup");
2290 
2292  UIUtilE::Assign(m_screen, m_storagegroupList, "storagegroup", err);
2293  else
2294  UIUtilW::Assign(m_screen, m_storagegroupList, "storagegroup");
2295 
2296  if (m_other && !m_other->m_playgroupList)
2297  UIUtilE::Assign(m_screen, m_playgroupList, "playgroup", err);
2298  else
2299  UIUtilW::Assign(m_screen, m_playgroupList, "playgroup");
2300 
2301  if (m_other && !m_other->m_maxepSpin)
2302  UIUtilE::Assign(m_screen, m_maxepSpin, "maxepisodes", err);
2303  else
2304  UIUtilW::Assign(m_screen, m_maxepSpin, "maxepisodes");
2305 
2307  UIUtilE::Assign(m_screen, m_maxbehaviourList, "maxnewest", err);
2308  else
2310 
2312  UIUtilE::Assign(m_screen, m_autoexpireCheck, "autoexpire", err);
2313  else
2314  UIUtilW::Assign(m_screen, m_autoexpireCheck, "autoexpire");
2315 }
2316 
2318 {
2319  if (!m_rule)
2320  return;
2321 
2322  QString label;
2323  QStringList groups;
2324  QStringList::Iterator it;
2325  MSqlQuery query(MSqlQuery::InitCon());
2326 
2327  // Recording Profile
2328  if (m_recprofileList)
2329  {
2330  if (!m_loaded)
2331  {
2332  label = QObject::tr("Record using the %1 profile");
2333  QMap<int, QString> profiles = RecordingProfile::listProfiles(0);
2334  QMap<int, QString>::iterator pit;
2335  for (pit = profiles.begin(); pit != profiles.end(); ++pit)
2336  {
2338  label.arg(pit.value()),
2339  qVariantFromValue(pit.value()));
2340  }
2341  }
2343  }
2344 
2345  // Recording Group
2346  if (m_recgroupList)
2347  {
2348  if (!m_loaded)
2349  {
2350  label = QObject::tr("Include in the \"%1\" recording group");
2352  QObject::tr("Create a new recording group"),
2353  qVariantFromValue(QString("__NEW_GROUP__")));
2355  label.arg(QObject::tr("Default")),
2356  qVariantFromValue(QString("Default")));
2357 
2358  groups.clear();
2359  if (m_rule->m_recGroup != "Default" &&
2360  m_rule->m_recGroup != "__NEW_GROUP__")
2361  groups << m_rule->m_recGroup;
2362  query.prepare("SELECT DISTINCT recgroup FROM recorded "
2363  "WHERE recgroup <> 'Default' AND "
2364  " recgroup <> 'Deleted'");
2365  if (query.exec())
2366  {
2367  while (query.next())
2368  groups += query.value(0).toString();
2369  }
2370  query.prepare("SELECT DISTINCT recgroup FROM record "
2371  "WHERE recgroup <> 'Default'");
2372  if (query.exec())
2373  {
2374  while (query.next())
2375  groups += query.value(0).toString();
2376  }
2377 
2378  groups.sort();
2379  groups.removeDuplicates();
2380  for (it = groups.begin(); it != groups.end(); ++it)
2381  {
2382  new MythUIButtonListItem(m_recgroupList, label.arg(*it),
2383  qVariantFromValue(*it));
2384  }
2385  }
2387  }
2388 
2389  // Storage Group
2390  if (m_storagegroupList)
2391  {
2392  if (!m_loaded)
2393  {
2394  label = QObject::tr("Store in the \"%1\" storage group");
2396  label.arg(QObject::tr("Default")),
2397  qVariantFromValue(QString("Default")));
2398 
2400  for (it = groups.begin(); it != groups.end(); ++it)
2401  {
2402  if ((*it).compare("Default", Qt::CaseInsensitive) != 0)
2404  label.arg(*it), qVariantFromValue(*it));
2405  }
2406  }
2408  }
2409 
2410  // Playback Group
2411  if (m_playgroupList)
2412  {
2413  if (!m_loaded)
2414  {
2415  label = QObject::tr("Use \"%1\" playback group settings");
2417  label.arg(QObject::tr("Default")),
2418  qVariantFromValue(QString("Default")));
2419 
2420  groups = PlayGroup::GetNames();
2421  for (it = groups.begin(); it != groups.end(); ++it)
2422  {
2423  new MythUIButtonListItem(m_playgroupList, label.arg(*it),
2424  qVariantFromValue(*it));
2425  }
2426  }
2428  }
2429 
2430  // Max Episodes
2431  if (m_maxepSpin)
2432  {
2433  if (!m_loaded)
2434  {
2435  int maxEpisodes = m_rule->m_maxEpisodes;
2436  m_maxepSpin->SetRange(0,100,1,5);
2437  m_rule->m_maxEpisodes = maxEpisodes;
2438  }
2440  }
2441 
2442  // Max Episode Behaviour
2443  if (m_maxbehaviourList)
2444  {
2445  if (!m_loaded)
2446  {
2448  QObject::tr("Don't record if this would exceed the max "
2449  "episodes"), qVariantFromValue(false));
2451  QObject::tr("Delete oldest if this would exceed the max "
2452  "episodes"), qVariantFromValue(true));
2453  }
2455  }
2456 
2457  // Auto-Expire
2458  if (m_autoexpireCheck)
2459  {
2461  }
2462 
2463  m_loaded = true;
2464 
2465  RuleChanged();
2466 }
2467 
2469 {
2470  if (!m_rule)
2471  return;
2472 
2473  if (m_recprofileList)
2475 
2476  if (m_recgroupList)
2477  {
2478  // If the user selected 'Create a new regroup' but failed to enter a
2479  // name when prompted, restore the original value
2480  if (m_recgroupList->GetDataValue().toString() == "__NEW_GROUP__")
2482  m_rule->m_recGroup = m_recgroupList->GetDataValue().toString();
2483  }
2484 
2485  if (m_storagegroupList)
2487 
2488  if (m_playgroupList)
2490 
2491  if (m_maxepSpin)
2493 
2494  if (m_maxbehaviourList)
2496 
2497  if (m_autoexpireCheck)
2499 }
2500 
2502 {
2503  if (!m_rule)
2504  return;
2505 
2506  bool isScheduled = (m_rule->m_type != kNotRecording &&
2507  m_rule->m_type != kDontRecord);
2508  bool isSingle = (m_rule->m_type == kSingleRecord ||
2510 
2511  if (m_recprofileList)
2512  m_recprofileList->SetEnabled(isScheduled);
2513  if (m_recgroupList)
2514  m_recgroupList->SetEnabled(isScheduled);
2515  if (m_storagegroupList)
2516  m_storagegroupList->SetEnabled(isScheduled);
2517  if (m_playgroupList)
2518  m_playgroupList->SetEnabled(isScheduled);
2519  if (m_maxepSpin)
2520  m_maxepSpin->SetEnabled(isScheduled && !isSingle);
2521  if (m_maxbehaviourList)
2522  m_maxbehaviourList->SetEnabled(isScheduled && !isSingle &&
2523  m_rule->m_maxEpisodes != 0);
2524  if (m_autoexpireCheck)
2525  m_autoexpireCheck->SetEnabled(isScheduled);
2526 }
2527 
2529 {
2530  if (!item || !m_rule)
2531  return;
2532 
2533  m_rule->m_maxEpisodes = item->GetData().toInt();
2534 
2535  if (m_maxbehaviourList)
2537 }
2538 
2540 {
2541  if (!m_rule)
2542  return;
2543 
2544  if (m_recgroupList->GetDataValue().toString() != "__NEW_GROUP__")
2545  return;
2546 
2547  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2548 
2549  QString label =
2550  QObject::tr("Create New Recording Group. Enter group name: ");
2551 
2552  MythTextInputDialog *textDialog =
2553  new MythTextInputDialog(popupStack, label,
2554  static_cast<InputFilter>(FilterSymbols | FilterPunct));
2555 
2556  textDialog->SetReturnEvent(m_screen, "newrecgroup");
2557 
2558  if (textDialog->Create())
2559  popupStack->AddScreen(textDialog, false);
2560 }
2561 
2562 void StoreOptMixin::SetRecGroup(QString recgroup)
2563 {
2564  if (!m_rule)
2565  return;
2566 
2567  if (m_recgroupList)
2568  {
2569  recgroup = recgroup.trimmed();
2570  if (recgroup.isEmpty())
2571  return;
2572 
2573  QString label = QObject::tr("Include in the \"%1\" recording group");
2574  MythUIButtonListItem *item =
2575  new MythUIButtonListItem(m_recgroupList, label.arg(recgroup),
2576  qVariantFromValue(recgroup));
2578 
2579  if (m_other && m_other->m_recgroupList)
2580  {
2582  label.arg(recgroup), qVariantFromValue(recgroup));
2584  }
2585  }
2586 }
2587 
2589 
2596  PostProcMixin *other)
2597  : m_commflagCheck(NULL), m_transcodeCheck(NULL),
2598  m_transcodeprofileList(NULL), m_userjob1Check(NULL),
2599  m_userjob2Check(NULL), m_userjob3Check(NULL), m_userjob4Check(NULL),
2600  m_metadataLookupCheck(NULL),
2601  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2602 {
2603 }
2604 
2605 void PostProcMixin::Create(bool *err)
2606 {
2607  if (!m_rule)
2608  return;
2609 
2610  if (m_other && !m_other->m_commflagCheck)
2611  UIUtilE::Assign(m_screen, m_commflagCheck, "autocommflag", err);
2612  else
2613  UIUtilW::Assign(m_screen, m_commflagCheck, "autocommflag");
2614 
2615  if (m_other && !m_other->m_transcodeCheck)
2616  UIUtilE::Assign(m_screen, m_transcodeCheck, "autotranscode", err);
2617  else
2618  UIUtilW::Assign(m_screen, m_transcodeCheck, "autotranscode");
2619 
2621  UIUtilE::Assign(m_screen, m_transcodeprofileList, "transcodeprofile", err);
2622  else
2623  UIUtilW::Assign(m_screen, m_transcodeprofileList, "transcodeprofile");
2624 
2625  if (m_other && !m_other->m_userjob1Check)
2626  UIUtilE::Assign(m_screen, m_userjob1Check, "userjob1", err);
2627  else
2629 
2630  if (m_other && !m_other->m_userjob2Check)
2631  UIUtilE::Assign(m_screen, m_userjob2Check, "userjob2", err);
2632  else
2634 
2635  if (m_other && !m_other->m_userjob3Check)
2636  UIUtilE::Assign(m_screen, m_userjob3Check, "userjob3", err);
2637  else
2639 
2640  if (m_other && !m_other->m_userjob4Check)
2641  UIUtilE::Assign(m_screen, m_userjob4Check, "userjob4", err);
2642  else
2644 
2645  UIUtilW::Assign(m_screen, m_metadataLookupCheck, "metadatalookup");
2646 }
2647 
2649 {
2650  if (!m_rule)
2651  return;
2652 
2653  // Auto-commflag
2654  if (m_commflagCheck)
2655  {
2657  }
2658 
2659  // Auto-transcode
2660  if (m_transcodeCheck)
2661  {
2663  }
2664 
2665  // Transcode Method
2667  {
2668  if (!m_loaded)
2669  {
2670  QMap<int, QString> profiles =
2672  QMap<int, QString>::iterator it;
2673  for (it = profiles.begin(); it != profiles.end(); ++it)
2674  {
2676  qVariantFromValue(it.key()));
2677  }
2678  }
2680  }
2681 
2682  // User Job #1
2683  if (m_userjob1Check)
2684  {
2685  if (!m_loaded)
2686  {
2687  MythUIText *userjob1Text = NULL;
2688  UIUtilW::Assign(m_screen, userjob1Text, "userjob1text");
2689  if (userjob1Text)
2690  userjob1Text->SetText(QObject::tr("Run '%1'")
2691  .arg(gCoreContext->GetSetting("UserJobDesc1"), "User Job 1"));
2692  }
2694  }
2695 
2696  // User Job #2
2697  if (m_userjob2Check)
2698  {
2699  if (!m_loaded)
2700  {
2701  MythUIText *userjob2Text = NULL;
2702  UIUtilW::Assign(m_screen, userjob2Text, "userjob2text");
2703  if (userjob2Text)
2704  userjob2Text->SetText(QObject::tr("Run '%1'")
2705  .arg(gCoreContext->GetSetting("UserJobDesc2"), "User Job 2"));
2706  }
2708  }
2709 
2710  // User Job #3
2711  if (m_userjob3Check)
2712  {
2713  if (!m_loaded)
2714  {
2715  MythUIText *userjob3Text = NULL;
2716  UIUtilW::Assign(m_screen, userjob3Text, "userjob3text");
2717  if (userjob3Text)
2718  userjob3Text->SetText(QObject::tr("Run '%1'")
2719  .arg(gCoreContext->GetSetting("UserJobDesc3"), "User Job 3"));
2720  }
2722  }
2723 
2724  // User Job #4
2725  if (m_userjob4Check)
2726  {
2727  if (!m_loaded)
2728  {
2729  MythUIText *userjob4Text = NULL;
2730  UIUtilW::Assign(m_screen, userjob4Text, "userjob4text");
2731  if (userjob4Text)
2732  userjob4Text->SetText(QObject::tr("Run '%1'")
2733  .arg(gCoreContext->GetSetting("UserJobDesc4"), "User Job 4"));
2734  }
2736  }
2737 
2738  // Auto Metadata Lookup
2740  {
2742  }
2743 
2744  m_loaded = true;
2745 
2746  RuleChanged();
2747 }
2748 
2750 {
2751  if (!m_rule)
2752  return;
2753 
2754  if (m_commflagCheck)
2756  if (m_transcodeCheck)
2760  if (m_userjob1Check)
2762  if (m_userjob2Check)
2764  if (m_userjob3Check)
2766  if (m_userjob4Check)
2771 }
2772 
2774 {
2775  if (!m_rule)
2776  return;
2777 
2778  bool isScheduled = (m_rule->m_type != kNotRecording &&
2779  m_rule->m_type != kDontRecord);
2780 
2781  if (m_commflagCheck)
2782  m_commflagCheck->SetEnabled(isScheduled);
2783  if (m_transcodeCheck)
2784  m_transcodeCheck->SetEnabled(isScheduled);
2786  m_transcodeprofileList->SetEnabled(isScheduled &&
2788  if (m_userjob1Check)
2789  m_userjob1Check->SetEnabled(isScheduled);
2790  if (m_userjob2Check)
2791  m_userjob2Check->SetEnabled(isScheduled);
2792  if (m_userjob3Check)
2793  m_userjob3Check->SetEnabled(isScheduled);
2794  if (m_userjob4Check)
2795  m_userjob4Check->SetEnabled(isScheduled);
2797  m_metadataLookupCheck->SetEnabled(isScheduled);
2798 }
2799 
2801 {
2802  if (!m_rule)
2803  return;
2804 
2805  m_rule->m_autoTranscode = enable;
2806 
2809 }
2810