MythTV  0.28pre
 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 #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 "mythuistatetype.h"
28 #include "mythuispinbox.h"
29 #include "mythuicheckbox.h"
30 #include "mythdialogbox.h"
31 #include "mythprogressdialog.h"
32 #include "mythuifilebrowser.h"
33 #include "mythuimetadataresults.h"
34 #include "mythuiimageresults.h"
35 #include "videoutils.h"
36 #include "mythuiutils.h"
37 #include "mythtypes.h"
38 
39 #include "metadataimagehelper.h"
40 
41 // Mythfrontend
42 #include "proglist.h"
43 #include "viewschedulediff.h"
44 
45 #define ENUM_TO_QVARIANT(a) qVariantFromValue(static_cast<int>(a))
46 
47 //static const QString _Location = QObject::tr("Schedule Editor");
48 
49 // Define the strings inserted into the recordfilter table in the
50 // database. This should make them available to the translators.
51 static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor", "New episode"));
52 static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor", "Identifiable episode"));
53 static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor", "First showing"));
54 static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor", "Prime time"));
55 static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor", "Commercial free"));
56 static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor", "High definition"));
57 static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor", "This episode"));
58 static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor", "This series"));
59 static QString fs8(QT_TRANSLATE_NOOP("SchedFilterEditor", "This time"));
60 static QString fs9(QT_TRANSLATE_NOOP("SchedFilterEditor", "This day and time"));
61 static QString fs10(QT_TRANSLATE_NOOP("SchedFilterEditor", "This channel"));
62 
63 void *ScheduleEditor::RunScheduleEditor(ProgramInfo *proginfo, void *player)
64 {
65  RecordingRule *rule = new RecordingRule();
66  rule->LoadByProgram(proginfo);
67 
69  ScheduleEditor *se = new ScheduleEditor(mainStack, rule,
70  static_cast<TV*>(player));
71 
72  if (se->Create())
73  mainStack->AddScreen(se, (player == NULL));
74  else
75  delete se;
76 
77  return NULL;
78 }
79 
86  RecordingInfo *recInfo, TV *player)
87  : ScheduleCommon(parent, "ScheduleEditor"),
88  SchedOptMixin(*this, NULL), StoreOptMixin(*this, NULL),
89  PostProcMixin(*this, NULL),
90  m_recInfo(new RecordingInfo(*recInfo)), m_recordingRule(NULL),
91  m_sendSig(false),
92  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
93  m_schedOptButton(NULL), m_storeOptButton(NULL),
94  m_postProcButton(NULL), m_schedInfoButton(NULL),
95  m_previewButton(NULL), m_metadataButton(NULL),
96  m_filtersButton(NULL),
97  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
98 {
104 }
105 
107  RecordingRule *recRule, TV *player)
108  : ScheduleCommon(parent, "ScheduleEditor"),
109  SchedOptMixin(*this, recRule),
110  StoreOptMixin(*this, recRule),
111  PostProcMixin(*this, recRule),
112  m_recInfo(NULL), m_recordingRule(recRule),
113  m_sendSig(false),
114  m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
115  m_schedOptButton(NULL), m_storeOptButton(NULL),
116  m_postProcButton(NULL), m_schedInfoButton(NULL),
117  m_previewButton(NULL), m_metadataButton(NULL),
118  m_filtersButton(NULL),
119  m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
120 {
121 }
122 
124 {
125  delete m_recordingRule;
126 
127  // if we have a player, we need to tell we are done
128  if (m_player)
129  {
130  QString message = QString("VIEWSCHEDULED_EXITING");
131  qApp->postEvent(m_player, new MythEvent(message));
132  }
133 }
134 
136 {
137  if (!LoadWindowFromXML("schedule-ui.xml", "scheduleeditor", this))
138  return false;
139 
140  bool err = false;
141 
142  UIUtilE::Assign(this, m_rulesList, "rules", &err);
143 
144  UIUtilW::Assign(this, m_schedOptButton, "schedoptions");
145  UIUtilW::Assign(this, m_storeOptButton, "storeoptions");
146  UIUtilW::Assign(this, m_postProcButton, "postprocessing");
147  UIUtilW::Assign(this, m_metadataButton, "metadata");
148  UIUtilW::Assign(this, m_schedInfoButton, "schedinfo");
149  UIUtilW::Assign(this, m_previewButton, "preview");
150  UIUtilW::Assign(this, m_filtersButton, "filters");
151 
152  SchedOptMixin::Create(&err);
153  StoreOptMixin::Create(&err);
154  PostProcMixin::Create(&err);
155 
156  UIUtilW::Assign(this, m_cancelButton, "cancel");
157  UIUtilE::Assign(this, m_saveButton, "save", &err);
158 
159  if (err)
160  {
161  LOG(VB_GENERAL, LOG_ERR, "ScheduleEditor, theme is missing "
162  "required elements");
163  return false;
164  }
165 
166  connect(m_rulesList, SIGNAL(itemSelected(MythUIButtonListItem *)),
168 
169  if (m_schedOptButton)
170  connect(m_schedOptButton, SIGNAL(Clicked()), SLOT(ShowSchedOpt()));
171  if (m_filtersButton)
172  connect(m_filtersButton, SIGNAL(Clicked()), SLOT(ShowFilters()));
173  if (m_storeOptButton)
174  connect(m_storeOptButton, SIGNAL(Clicked()), SLOT(ShowStoreOpt()));
175  if (m_postProcButton)
176  connect(m_postProcButton, SIGNAL(Clicked()), SLOT(ShowPostProc()));
177  if (m_schedInfoButton)
178  connect(m_schedInfoButton, SIGNAL(Clicked()), SLOT(ShowSchedInfo()));
179  if (m_previewButton)
180  connect(m_previewButton, SIGNAL(Clicked()), SLOT(ShowPreview()));
181  if (m_metadataButton)
182  connect(m_metadataButton, SIGNAL(Clicked()), SLOT(ShowMetadataOptions()));
183 
184  if (m_cancelButton)
185  connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
186  connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
187 
188  if (m_schedInfoButton)
190  if (m_previewButton)
192 
193  if (m_dupmethodList)
194  connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
196  if (m_maxepSpin)
197  connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
199  if (m_recgroupList)
200  connect(m_recgroupList, SIGNAL(LosingFocus()),
201  SLOT(PromptForRecGroup()));
202  if (m_transcodeCheck)
203  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
204  SLOT(TranscodeChanged(bool)));
205 
206  BuildFocusList();
207 
208  if (!m_recordingRule->IsLoaded())
209  {
210  if (m_recInfo)
212  else if (m_recordingRule->m_recordID)
214 
215  if (!m_recordingRule->IsLoaded())
216  {
217  LOG(VB_GENERAL, LOG_ERR,
218  "ScheduleEditor::Create() - Failed to load recording rule");
219  return false;
220  }
221  }
222 
223  if (m_player)
224  m_player->StartEmbedding(QRect());
225 
226  return true;
227 }
228 
230 {
231  if (m_child)
232  m_child->Close();
233 
234  // don't fade the screen if we are returning to the player
235  if (m_player)
236  GetScreenStack()->PopScreen(this, false);
237  else
238  GetScreenStack()->PopScreen(this, true);
239 }
240 
242 {
246 
247  if (!m_loaded)
248  {
249  // Copy this now, it will change briefly after the first item
250  // is inserted into the list by design of
251  // MythUIButtonList::itemSelected()
253 
254  // Rules List
256  {
258  .compare("Default", Qt::CaseInsensitive) != 0)
259  {
261  tr("Delete this recording rule template"),
262  ENUM_TO_QVARIANT(kNotRecording));
263  }
266  ENUM_TO_QVARIANT(kTemplateRecord));
267  }
268  else if (m_recordingRule->m_isOverride)
269  {
271  tr("Record this showing with normal options"),
272  ENUM_TO_QVARIANT(kNotRecording));
275  ENUM_TO_QVARIANT(kOverrideRecord));
278  ENUM_TO_QVARIANT(kDontRecord));
279  }
280  else
281  {
282  bool hasChannel = !m_recordingRule->m_station.isEmpty();
283  bool isManual = (m_recordingRule->m_searchType == kManualSearch);
284 
287  ENUM_TO_QVARIANT(kNotRecording));
288  if (hasChannel)
291  ENUM_TO_QVARIANT(kSingleRecord));
292  if (!isManual)
295  ENUM_TO_QVARIANT(kOneRecord));
296  if (!hasChannel || isManual)
299  ENUM_TO_QVARIANT(kWeeklyRecord));
300  if (!hasChannel || isManual)
303  ENUM_TO_QVARIANT(kDailyRecord));
304  if (!isManual)
307  ENUM_TO_QVARIANT(kAllRecord));
308  }
309 
311  }
312  m_rulesList->SetValueByData(ENUM_TO_QVARIANT(m_recordingRule->m_type));
313 
314  InfoMap progMap;
315 
316  m_recordingRule->ToMap(progMap);
317 
318  if (m_recInfo)
319  m_recInfo->ToMap(progMap);
320 
321  SetTextFromMap(progMap);
322 
323  m_loaded = true;
324 }
325 
327 {
329  Load();
330  emit templateLoaded();
331 }
332 
334 {
335  if (!item)
336  return;
337 
338  m_recordingRule->m_type = static_cast<RecordingType>
339  (item->GetData().toInt());
340 
341  bool isScheduled = (m_recordingRule->m_type != kNotRecording &&
343 
344  if (m_schedOptButton)
345  m_schedOptButton->SetEnabled(isScheduled);
346  if (m_filtersButton)
347  m_filtersButton->SetEnabled(isScheduled);
348  if (m_storeOptButton)
349  m_storeOptButton->SetEnabled(isScheduled);
350  if (m_postProcButton)
351  m_postProcButton->SetEnabled(isScheduled);
352  if (m_metadataButton)
353  m_metadataButton->SetEnabled(isScheduled &&
355 
359 }
360 
362 {
364 }
365 
367 {
369 }
370 
372 {
374 }
375 
377 {
379 }
380 
382 {
383  if (m_child)
384  m_child->Close();
385 
387  {
388  int recid = m_recordingRule->m_recordID;
389  DeleteRule();
390  if (recid)
391  emit ruleDeleted(recid);
392  Close();
393  return;
394  }
395 
399  m_recordingRule->Save(true);
401 
402  Close();
403 }
404 
406 {
408 }
409 
411 {
414  return;
415 
416  if (m_child)
417  m_child->Close();
418 
420 
422  SchedOptEditor *schedoptedit = new SchedOptEditor(mainStack, *this,
424  if (!schedoptedit->Create())
425  {
426  delete schedoptedit;
427  return;
428  }
429 
431  m_child = schedoptedit;
432  mainStack->AddScreen(schedoptedit);
433 }
434 
436 {
439  return;
440 
441  if (m_child)
442  m_child->Close();
443 
445 
447  StoreOptEditor *storeoptedit = new StoreOptEditor(mainStack, *this,
449  if (!storeoptedit->Create())
450  {
451  delete storeoptedit;
452  return;
453  }
454 
456  m_child = storeoptedit;
457  mainStack->AddScreen(storeoptedit);
458 }
459 
461 {
464  return;
465 
466  if (m_child)
467  m_child->Close();
468 
470 
472  PostProcEditor *ppedit = new PostProcEditor(mainStack, *this,
474  if (!ppedit->Create())
475  {
476  delete ppedit;
477  return;
478  }
479 
481  m_child = ppedit;
482  mainStack->AddScreen(ppedit);
483 }
484 
486 {
488  return;
489 
490  QString label = tr("Schedule Information");
491 
492  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
493  MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
494 
495  if (menuPopup->Create())
496  {
497  menuPopup->SetReturnEvent(this, "schedinfo");
498 
499  if (m_recInfo)
500  menuPopup->AddButton(tr("Program Details"));
501  menuPopup->AddButton(tr("Upcoming Episodes"));
502  menuPopup->AddButton(tr("Upcoming Recordings"));
503  menuPopup->AddButton(tr("Previously Recorded"));
504 
505  popupStack->AddScreen(menuPopup);
506  }
507  else
508  delete menuPopup;
509 }
510 
511 bool ScheduleEditor::keyPressEvent(QKeyEvent *event)
512 {
513  if (GetFocusWidget()->keyPressEvent(event))
514  return true;
515 
516  bool handled = false;
517  QStringList actions;
518  handled = GetMythMainWindow()->
519  TranslateKeyPress("TV Frontend", event, actions);
520 
521  for (int i = 0; i < actions.size() && !handled; i++)
522  {
523  QString action = actions[i];
524  handled = true;
525 
526  if (action == "MENU")
527  showMenu();
528  else if (action == "INFO")
530  else if (action == "UPCOMING")
532  else if (action == "PREVVIEW")
534  else if (action == "NEXTVIEW")
535  ShowNextView();
536  else
537  handled = false;
538  }
539 
540  if (!handled && MythScreenType::keyPressEvent(event))
541  handled = true;
542 
543  return handled;
544 }
545 
546 void ScheduleEditor::customEvent(QEvent *event)
547 {
548  if (event->type() == DialogCompletionEvent::kEventType)
549  {
551 
552  QString resultid = dce->GetId();
553  QString resulttext = dce->GetResultText();
554 
555  if (resultid == "menu")
556  {
557  if (resulttext == tr("Main Options"))
558  m_child->Close();
559  if (resulttext == tr("Schedule Options"))
560  ShowSchedOpt();
561  else if (resulttext == tr("Filter Options"))
562  ShowFilters();
563  else if (resulttext == tr("Storage Options"))
564  ShowStoreOpt();
565  else if (resulttext == tr("Post Processing"))
566  ShowPostProc();
567  else if (resulttext == tr("Metadata Options"))
569  else if (resulttext == tr("Use Template"))
571  else if (resulttext == tr("Schedule Info"))
572  ShowSchedInfo();
573  else if (resulttext == tr("Preview Changes"))
574  ShowPreview();
575  }
576  else if (resultid == "templatemenu")
577  {
578  LoadTemplate(resulttext);
579  }
580  else if (resultid == "schedinfo")
581  {
582  if (resulttext == tr("Program Details"))
584  else if (resulttext == tr("Upcoming Episodes"))
586  else if (resulttext == tr("Upcoming Recordings"))
588  else if (resulttext == tr("Previously Recorded"))
589  showPrevious();
590  }
591  else if (resultid == "newrecgroup")
592  {
593  int groupID = CreateRecordingGroup(resulttext);
594  StoreOptMixin::SetRecGroup(groupID, resulttext);
595  }
596  }
597 }
598 
600 {
602  return;
603 
604  QString title;
605  if (m_recInfo)
606  title = m_recInfo->GetTitle();
607 
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 = button->GetData().value<int>();
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 << button->GetData().value<uint32_t>());
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  int groupID = CreateRecordingGroup(resulttext);
1232  StoreOptMixin::SetRecGroup(groupID, resulttext);
1233  }
1234  }
1235 }
1236 
1238 {
1240 }
1241 
1243 
1250  ScheduleEditor &editor,
1251  RecordingRule &rule,
1252  RecordingInfo *recInfo)
1253  : SchedEditChild(parent, "PostProcOptionsEditor", editor, rule, recInfo),
1254  PostProcMixin(*this, &rule, &editor)
1255 {
1256 }
1257 
1259 {
1260 }
1261 
1263 {
1265  "schedule-ui.xml", "postproceditor",
1267  {
1268  return false;
1269  }
1270 
1271  bool err = false;
1272 
1273  PostProcMixin::Create(&err);
1274 
1275  if (err)
1276  {
1277  LOG(VB_GENERAL, LOG_ERR, "PostProcEditor, theme is missing "
1278  "required elements");
1279  return false;
1280  }
1281 
1282  if (m_transcodeCheck)
1283  connect(m_transcodeCheck, SIGNAL(toggled(bool)),
1284  SLOT(TranscodeChanged(bool)));
1285 
1286  BuildFocusList();
1287 
1288  return true;
1289 }
1290 
1292 {
1294  SetTextFromMaps();
1295 }
1296 
1298 {
1300 }
1301 
1303 {
1305 }
1306 
1308 
1315  ScheduleEditor &editor,
1316  RecordingRule &rule,
1317  RecordingInfo *recInfo)
1318  : SchedEditChild(parent, "MetadataOptions", editor, rule, recInfo),
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  MetadataLookup *lookup = new MetadataLookup();
1459 
1460  CreateBusyDialog(tr("Trying to manually find this "
1461  "recording online..."));
1462 
1463  lookup->SetStep(kLookupSearch);
1464  lookup->SetType(kMetadataRecording);
1466  (m_seasonSpin->GetIntValue() == 0 &&
1467  m_episodeSpin->GetIntValue() == 0))
1468  lookup->SetSubtype(kProbableMovie);
1469  else
1471  lookup->SetAllowGeneric(true);
1472  lookup->SetAutomatic(false);
1473  lookup->SetHandleImages(false);
1475  lookup->SetTitle(m_recordingRule->m_title);
1477  lookup->SetInetref(m_inetrefEdit->GetText());
1479  lookup->SetSeason(m_seasonSpin->GetIntValue());
1480  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1481 
1482  m_metadataFactory->Lookup(lookup);
1483 }
1484 
1486 {
1487  QueryComplete(lookup);
1488 }
1489 
1492 {
1493  QString msg = tr("Downloading selected artwork...");
1494  CreateBusyDialog(msg);
1495 
1496  MetadataLookup *lookup = new MetadataLookup();
1497 
1498  lookup->SetType(kMetadataVideo);
1500  lookup->SetAutomatic(true);
1501  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1502 
1503  ArtworkMap downloads;
1504  downloads.insert(type, info);
1505  lookup->SetDownloads(downloads);
1506  lookup->SetAllowOverwrites(true);
1507  lookup->SetTitle(m_recordingRule->m_title);
1509  lookup->SetInetref(m_inetrefEdit->GetText());
1510  lookup->SetSeason(m_seasonSpin->GetIntValue());
1511  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1512 
1513  m_imageDownload->addDownloads(lookup);
1514 }
1515 
1517 {
1518  if (!CanSetArtwork())
1519  return;
1520 
1521  QString url = generate_file_url("Fanart",
1523  "");
1524  FindImagePopup(url,"",*this, "fanart");
1525 }
1526 
1528 {
1529  if (!CanSetArtwork())
1530  return;
1531 
1532  QString url = generate_file_url("Coverart",
1534  "");
1535  FindImagePopup(url,"",*this, "coverart");
1536 }
1537 
1539 {
1540  if (!CanSetArtwork())
1541  return;
1542 
1543  QString url = generate_file_url("Banners",
1545  "");
1546  FindImagePopup(url,"",*this, "banner");
1547 }
1548 
1550 {
1552 }
1553 
1555 {
1557 }
1558 
1560 {
1562 }
1563 
1565 {
1566  // Season
1567  if (m_seasonSpin)
1569 
1570  // Episode
1571  if (m_episodeSpin)
1573 
1574  // InetRef
1575  if (m_inetrefEdit)
1577 }
1578 
1580 {
1581  if (!lookup)
1582  return;
1583 
1584  // InetRef
1585  m_inetrefEdit->SetText(lookup->GetInetref());
1586 
1587  // Season
1588  m_seasonSpin->SetValue(lookup->GetSeason());
1589 
1590  // Episode
1591  m_episodeSpin->SetValue(lookup->GetEpisode());
1592 
1593  InfoMap 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  MetadataLookup *lookup = new MetadataLookup();
1657 
1658  QString msg = tr("Searching for available artwork...");
1659  CreateBusyDialog(msg);
1660 
1661  lookup->SetStep(kLookupSearch);
1662  lookup->SetType(kMetadataVideo);
1663  lookup->SetAutomatic(true);
1664  lookup->SetHandleImages(false);
1666  (m_seasonSpin->GetIntValue() == 0 &&
1667  m_episodeSpin->GetIntValue() == 0))
1668  lookup->SetSubtype(kProbableMovie);
1669  else
1671  lookup->SetAllowGeneric(true);
1672  lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
1674  lookup->SetTitle(m_recordingRule->m_title);
1676  lookup->SetInetref(m_inetrefEdit->GetText());
1678  lookup->SetSeason(m_seasonSpin->GetIntValue());
1679  lookup->SetEpisode(m_episodeSpin->GetIntValue());
1680 
1681  m_imageLookup->addLookup(lookup);
1682 }
1683 
1685 {
1686  if (!lookup)
1687  return;
1688 
1689  if (m_busyPopup)
1690  {
1691  m_busyPopup->Close();
1692  m_busyPopup = NULL;
1693  }
1694 
1695  VideoArtworkType type = lookup->GetData().value<VideoArtworkType>();
1696  ArtworkList list = lookup->GetArtwork(type);
1697 
1698  if (list.isEmpty())
1699  {
1700  MythWarningNotification n(tr("No image found"), tr("Schedule Editor"));
1702  return;
1703  }
1704 
1705  ImageSearchResultsDialog *resultsdialog =
1706  new ImageSearchResultsDialog(m_popupStack, list, type);
1707 
1708  connect(resultsdialog, SIGNAL(haveResult(ArtworkInfo, VideoArtworkType)),
1710 
1711  if (resultsdialog->Create())
1712  m_popupStack->AddScreen(resultsdialog);
1713 }
1714 
1716 {
1717  if (!lookup)
1718  return;
1719 
1720  DownloadMap map = lookup->GetDownloads();
1721 
1722  if (map.isEmpty())
1723  return;
1724 
1725  for (DownloadMap::const_iterator i = map.begin(); i != map.end(); ++i)
1726  {
1727  VideoArtworkType type = i.key();
1728  ArtworkInfo info = i.value();
1729 
1730  if (type == kArtworkCoverart)
1731  m_artworkMap.replace(kArtworkCoverart, info);
1732  else if (type == kArtworkFanart)
1733  m_artworkMap.replace(kArtworkFanart, info);
1734  else if (type == kArtworkBanner)
1735  m_artworkMap.replace(kArtworkBanner, info);
1736  }
1737 
1740 
1741  ValuesChanged();
1742 }
1743 
1745 {
1748 
1749  if (m_coverart)
1750  {
1752  m_coverart->Load();
1753  }
1754 
1755  if (m_fanart)
1756  {
1758  m_fanart->Load();
1759  }
1760 
1761  if (m_banner)
1762  {
1764  m_banner->Load();
1765  }
1766 }
1767 
1768 void MetadataOptions::customEvent(QEvent *levent)
1769 {
1770  if (levent->type() == MetadataFactoryMultiResult::kEventType)
1771  {
1772  if (m_busyPopup)
1773  {
1774  m_busyPopup->Close();
1775  m_busyPopup = NULL;
1776  }
1777 
1778  MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
1779 
1780  if (!mfmr)
1781  return;
1782 
1783  MetadataLookupList list = mfmr->results;
1784 
1785  if (list.count() > 1)
1786  {
1787  int yearindex = -1;
1788 
1789  for (int p = 0; p != list.size(); ++p)
1790  {
1791  if (!m_recordingRule->m_seriesid.isEmpty() &&
1792  m_recordingRule->m_seriesid == (list[p])->GetTMSref())
1793  {
1794  MetadataLookup *lookup = list[p];
1795  QueryComplete(lookup);
1796  return;
1797  }
1798  else if (m_recInfo &&
1800  (list[p])->GetYear() != 0 &&
1801  m_recInfo->GetYearOfInitialRelease() == (list[p])->GetYear())
1802  {
1803  if (yearindex > -1)
1804  {
1805  LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite "
1806  "match could be found based on year alone.");
1807  yearindex = -2;
1808  }
1809  else if (yearindex == -1)
1810  {
1811  LOG(VB_GENERAL, LOG_INFO, "Matched based on year. ");
1812  yearindex = p;
1813  }
1814  }
1815  }
1816 
1817  if (yearindex > -1)
1818  {
1819  MetadataLookup *lookup = list[yearindex];
1820  QueryComplete(lookup);
1821  return;
1822  }
1823 
1824  LOG(VB_GENERAL, LOG_INFO, "Falling through to selection dialog.");
1825  MetadataResultsDialog *resultsdialog =
1827 
1828  connect(resultsdialog, SIGNAL(haveResult(RefCountHandler<MetadataLookup>)),
1830  Qt::QueuedConnection);
1831 
1832  if (resultsdialog->Create())
1833  m_popupStack->AddScreen(resultsdialog);
1834  }
1835  }
1836  else if (levent->type() == MetadataFactorySingleResult::kEventType)
1837  {
1838  if (m_busyPopup)
1839  {
1840  m_busyPopup->Close();
1841  m_busyPopup = NULL;
1842  }
1843 
1844  MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
1845 
1846  if (!mfsr)
1847  return;
1848 
1849  MetadataLookup *lookup = mfsr->result;
1850 
1851  if (!lookup)
1852  return;
1853 
1854  QueryComplete(lookup);
1855  }
1856  else if (levent->type() == MetadataFactoryNoResult::kEventType)
1857  {
1858  if (m_busyPopup)
1859  {
1860  m_busyPopup->Close();
1861  m_busyPopup = NULL;
1862  }
1863 
1864  MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
1865 
1866  if (!mfnr)
1867  return;
1868 
1869  QString title = tr("No match found for this recording. You can "
1870  "try entering a TVDB/TMDB number, season, and "
1871  "episode manually.");
1872 
1873  MythConfirmationDialog *okPopup =
1874  new MythConfirmationDialog(m_popupStack, title, false);
1875 
1876  if (okPopup->Create())
1877  m_popupStack->AddScreen(okPopup);
1878  }
1879  else if (levent->type() == MetadataLookupEvent::kEventType)
1880  {
1881  if (m_busyPopup)
1882  {
1883  m_busyPopup->Close();
1884  m_busyPopup = NULL;
1885  }
1886 
1887  MetadataLookupEvent *lue = (MetadataLookupEvent *)levent;
1888 
1889  MetadataLookupList lul = lue->lookupList;
1890 
1891  if (lul.isEmpty())
1892  return;
1893 
1894  if (lul.count() >= 1)
1895  {
1896  OnArtworkSearchDone(lul[0]);
1897  }
1898  }
1899  else if (levent->type() == MetadataLookupFailure::kEventType)
1900  {
1901  if (m_busyPopup)
1902  {
1903  m_busyPopup->Close();
1904  m_busyPopup = NULL;
1905  }
1906 
1908 
1909  MetadataLookupList lul = luf->lookupList;
1910 
1911  if (lul.size())
1912  {
1913  QString title = tr("This number, season, and episode combination "
1914  "does not appear to be valid (or the site may "
1915  "be down). Check your information and try "
1916  "again.");
1917 
1918  MythConfirmationDialog *okPopup =
1919  new MythConfirmationDialog(m_popupStack, title, false);
1920 
1921  if (okPopup->Create())
1922  m_popupStack->AddScreen(okPopup);
1923  }
1924  }
1925  else if (levent->type() == ImageDLEvent::kEventType)
1926  {
1927  if (m_busyPopup)
1928  {
1929  m_busyPopup->Close();
1930  m_busyPopup = NULL;
1931  }
1932 
1933  ImageDLEvent *ide = (ImageDLEvent *)levent;
1934 
1935  MetadataLookup *lookup = ide->item;
1936 
1937  if (!lookup)
1938  return;
1939 
1940  HandleDownloadedImages(lookup);
1941  }
1942  else if (levent->type() == ImageDLFailureEvent::kEventType)
1943  {
1944  if (m_busyPopup)
1945  {
1946  m_busyPopup->Close();
1947  m_busyPopup = NULL;
1948  }
1949  MythErrorNotification n(tr("Failed to retrieve image(s)"),
1950  tr("Schedule Editor"),
1951  tr("Check logs"));
1953  }
1954  else if (levent->type() == DialogCompletionEvent::kEventType)
1955  {
1956  DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent);
1957 
1958  const QString resultid = dce->GetId();
1959  ArtworkInfo info;
1960  info.url = dce->GetResultText();
1961 
1962  if (resultid == "coverart")
1963  {
1964  m_artworkMap.replace(kArtworkCoverart, info);
1965  }
1966  else if (resultid == "fanart")
1967  {
1968  m_artworkMap.replace(kArtworkFanart, info);
1969  }
1970  else if (resultid == "banner")
1971  {
1972  m_artworkMap.replace(kArtworkBanner, info);
1973  }
1974 
1977 
1978  ValuesChanged();
1979  }
1980 
1981 }
1982 
1984 
1991  SchedOptMixin *other)
1992  : m_prioritySpin(NULL), m_startoffsetSpin(NULL), m_endoffsetSpin(NULL),
1993  m_dupmethodList(NULL), m_dupscopeList(NULL), m_inputList(NULL),
1994  m_ruleactiveCheck(NULL), m_newrepeatList(NULL),
1995  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false),
1996  m_haveRepeats(gCoreContext->GetNumSetting("HaveRepeats", 0))
1997 {
1998 }
1999 
2000 void SchedOptMixin::Create(bool *err)
2001 {
2002  if (!m_rule)
2003  return;
2004 
2005  if (m_other && !m_other->m_prioritySpin)
2006  UIUtilE::Assign(m_screen, m_prioritySpin, "priority", err);
2007  else
2008  UIUtilW::Assign(m_screen, m_prioritySpin, "priority");
2009 
2011  UIUtilE::Assign(m_screen, m_startoffsetSpin, "startoffset", err);
2012  else
2013  UIUtilW::Assign(m_screen, m_startoffsetSpin, "startoffset");
2014 
2015  if (m_other && !m_other->m_endoffsetSpin)
2016  UIUtilE::Assign(m_screen, m_endoffsetSpin, "endoffset", err);
2017  else
2018  UIUtilW::Assign(m_screen, m_endoffsetSpin, "endoffset");
2019 
2020  if (m_other && !m_other->m_dupmethodList)
2021  UIUtilE::Assign(m_screen, m_dupmethodList, "dupmethod", err);
2022  else
2023  UIUtilW::Assign(m_screen, m_dupmethodList, "dupmethod");
2024 
2025  if (m_other && !m_other->m_dupscopeList)
2026  UIUtilE::Assign(m_screen, m_dupscopeList, "dupscope", err);
2027  else
2028  UIUtilW::Assign(m_screen, m_dupscopeList, "dupscope");
2029 
2030  if (m_other && !m_other->m_inputList)
2031  UIUtilE::Assign(m_screen, m_inputList, "input", err);
2032  else
2034 
2036  UIUtilE::Assign(m_screen, m_ruleactiveCheck, "ruleactive", err);
2037  else
2038  UIUtilW::Assign(m_screen, m_ruleactiveCheck, "ruleactive");
2039 
2040  UIUtilW::Assign(m_screen, m_newrepeatList, "newrepeat");
2041 }
2042 
2044 {
2045  if (!m_rule)
2046  return;
2047 
2048  // Priority
2049  if (m_prioritySpin)
2050  {
2051  if (!m_loaded)
2052  m_prioritySpin->SetRange(-99,99,1,5);
2054  }
2055 
2056  // Start Offset
2057  if (m_startoffsetSpin)
2058  {
2059  if (!m_loaded)
2060  m_startoffsetSpin->SetRange(480,-480,1,10);
2062  }
2063 
2064  // End Offset
2065  if (m_endoffsetSpin)
2066  {
2067  if (!m_loaded)
2068  m_endoffsetSpin->SetRange(-480,480,1,10);
2070  }
2071 
2072  // Duplicate Match Type
2073  if (m_dupmethodList)
2074  {
2075  if (!m_loaded)
2076  {
2078 
2081  ENUM_TO_QVARIANT(kDupCheckSubDesc));
2084  ENUM_TO_QVARIANT(kDupCheckSubThenDesc));
2087  ENUM_TO_QVARIANT(kDupCheckSub));
2090  ENUM_TO_QVARIANT(kDupCheckDesc));
2093  ENUM_TO_QVARIANT(kDupCheckNone));
2094 
2095  m_rule->m_dupMethod = dupMethod;
2096  }
2097  m_dupmethodList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupMethod));
2098  }
2099 
2100  // Duplicate Matching Scope
2101  if (m_dupscopeList)
2102  {
2103  if (!m_loaded)
2104  {
2107  ENUM_TO_QVARIANT(kDupsInAll));
2110  ENUM_TO_QVARIANT(kDupsInRecorded));
2113  ENUM_TO_QVARIANT(kDupsInOldRecorded));
2114  if (m_haveRepeats && !m_newrepeatList &&
2116  {
2119  ENUM_TO_QVARIANT(kDupsNewEpi|kDupsInAll));
2120  }
2121  }
2122  m_dupscopeList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupIn));
2123  }
2124 
2125  // Preferred Input
2126  if (m_inputList)
2127  {
2128  if (!m_loaded)
2129  {
2131  QObject::tr("Use any available input"),
2132  qVariantFromValue(0));
2133 
2134  vector<uint> inputids = CardUtil::GetAllInputIDs();
2135  for (uint i = 0; i < inputids.size(); ++i)
2136  {
2138  QObject::tr("Prefer input %1")
2139  .arg(CardUtil::GetDisplayName(inputids[i])), inputids[i]);
2140  }
2141  }
2143  }
2144 
2145  // Active/Disabled
2146  if (m_ruleactiveCheck)
2147  {
2149  }
2150 
2151  // Record new and repeat
2152  if (m_newrepeatList)
2153  {
2154  if (!m_loaded)
2155  {
2157  QObject::tr("Record new and repeat "
2158  "episodes"), ENUM_TO_QVARIANT(0));
2160  QObject::tr("Record new episodes only"),
2161  ENUM_TO_QVARIANT(kDupsNewEpi));
2162  }
2163  m_newrepeatList->SetValueByData(ENUM_TO_QVARIANT
2164  (m_rule->m_dupIn & kDupsNewEpi));
2165  }
2166 
2167  m_loaded = true;
2168 
2169  RuleChanged();
2170 }
2171 
2173 {
2174  if (!m_rule)
2175  return;
2176 
2177  if (m_prioritySpin)
2179  if (m_startoffsetSpin)
2181  if (m_endoffsetSpin)
2183  if (m_dupmethodList)
2184  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2185  (m_dupmethodList->GetDataValue().toInt());
2186  if (m_dupscopeList)
2187  {
2188  int mask = ((m_other && m_other->m_newrepeatList) ||
2189  m_newrepeatList) ? kDupsInAll : ~0;
2190  int val = ((m_rule->m_dupIn & ~mask) |
2191  m_dupscopeList->GetDataValue().toInt());
2192  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2193  }
2194  if (m_inputList)
2196  if (m_ruleactiveCheck)
2198  if (m_newrepeatList)
2199  {
2200  int val = ((m_rule->m_dupIn & ~kDupsNewEpi) |
2201  m_newrepeatList->GetDataValue().toInt());
2202  m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
2203  }
2204 }
2205 
2207 {
2208  if (!m_rule)
2209  return;
2210 
2211  bool isScheduled = (m_rule->m_type != kNotRecording &&
2212  m_rule->m_type != kDontRecord);
2213  bool isSingle = (m_rule->m_type == kSingleRecord ||
2215 
2216  if (m_prioritySpin)
2217  m_prioritySpin->SetEnabled(isScheduled);
2218  if (m_startoffsetSpin)
2219  m_startoffsetSpin->SetEnabled(isScheduled);
2220  if (m_endoffsetSpin)
2221  m_endoffsetSpin->SetEnabled(isScheduled);
2222  if (m_dupmethodList)
2223  m_dupmethodList->SetEnabled(isScheduled && !isSingle);
2224  if (m_dupscopeList)
2225  m_dupscopeList->SetEnabled(isScheduled && !isSingle &&
2227  if (m_inputList)
2228  m_inputList->SetEnabled(isScheduled);
2229  if (m_ruleactiveCheck)
2230  m_ruleactiveCheck->SetEnabled(isScheduled);
2231  if (m_newrepeatList)
2232  m_newrepeatList->SetEnabled(isScheduled && !isSingle && m_haveRepeats);
2233 }
2234 
2236 {
2237  if (!item || !m_rule)
2238  return;
2239 
2240  m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
2241  (item->GetData().toInt());
2242 
2243  if (m_dupscopeList)
2245 }
2246 
2248 
2255  StoreOptMixin *other)
2256  : m_recprofileList(NULL), m_recgroupList(NULL), m_storagegroupList(NULL),
2257  m_playgroupList(NULL), m_maxepSpin(NULL), m_maxbehaviourList(NULL),
2258  m_autoexpireCheck(NULL),
2259  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2260 {
2261 }
2262 
2263 void StoreOptMixin::Create(bool *err)
2264 {
2265  if (!m_rule)
2266  return;
2267 
2268  if (m_other && !m_other->m_recprofileList)
2269  UIUtilE::Assign(m_screen, m_recprofileList, "recprofile", err);
2270  else
2271  UIUtilW::Assign(m_screen, m_recprofileList, "recprofile");
2272 
2273  if (m_other && !m_other->m_recgroupList)
2274  UIUtilE::Assign(m_screen, m_recgroupList, "recgroup", err);
2275  else
2276  UIUtilW::Assign(m_screen, m_recgroupList, "recgroup");
2277 
2279  UIUtilE::Assign(m_screen, m_storagegroupList, "storagegroup", err);
2280  else
2281  UIUtilW::Assign(m_screen, m_storagegroupList, "storagegroup");
2282 
2283  if (m_other && !m_other->m_playgroupList)
2284  UIUtilE::Assign(m_screen, m_playgroupList, "playgroup", err);
2285  else
2286  UIUtilW::Assign(m_screen, m_playgroupList, "playgroup");
2287 
2288  if (m_other && !m_other->m_maxepSpin)
2289  UIUtilE::Assign(m_screen, m_maxepSpin, "maxepisodes", err);
2290  else
2291  UIUtilW::Assign(m_screen, m_maxepSpin, "maxepisodes");
2292 
2294  UIUtilE::Assign(m_screen, m_maxbehaviourList, "maxnewest", err);
2295  else
2297 
2299  UIUtilE::Assign(m_screen, m_autoexpireCheck, "autoexpire", err);
2300  else
2301  UIUtilW::Assign(m_screen, m_autoexpireCheck, "autoexpire");
2302 }
2303 
2305 {
2306  if (!m_rule)
2307  return;
2308 
2309  QString label;
2310  QStringList groups;
2311  QStringList::Iterator it;
2312  MSqlQuery query(MSqlQuery::InitCon());
2313 
2314  // Recording Profile
2315  if (m_recprofileList)
2316  {
2317  if (!m_loaded)
2318  {
2319  label = QObject::tr("Record using the %1 profile");
2320 
2322  label.arg(QObject::tr("Default")),
2323  qVariantFromValue(QString("Default")));
2324  // LiveTV profile - it's for LiveTV not scheduled recordings??
2326  label.arg(QObject::tr("LiveTV")),
2327  qVariantFromValue(QString("LiveTV")));
2329  label.arg(QObject::tr("High Quality")),
2330  qVariantFromValue(QString("High Quality")));
2332  label.arg(QObject::tr("Low Quality")),
2333  qVariantFromValue(QString("Low Quality")));
2334  }
2336  }
2337 
2338  // Recording Group
2339  if (m_recgroupList)
2340  {
2341  if (!m_loaded)
2342  {
2343  label = QObject::tr("Include in the \"%1\" recording group");
2345  QObject::tr("Create a new recording group"),
2346  qVariantFromValue(QString("__NEW_GROUP__")));
2347 
2348  query.prepare("SELECT recgroupid, recgroup FROM recgroups "
2349  "WHERE recgroup <> 'Deleted' AND "
2350  " recgroup <> 'LiveTV' "
2351  "ORDER BY special DESC, recgroup ASC"); // Special groups first
2352  if (query.exec())
2353  {
2354  while (query.next())
2355  {
2356  int id = query.value(0).toInt();
2357  QString name = query.value(1).toString();
2358 
2359  if (name == "Default")
2360  name = QObject::tr("Default");
2361  new MythUIButtonListItem(m_recgroupList, label.arg(name),
2362  qVariantFromValue(id));
2363  }
2364  }
2365 
2366  }
2368  }
2369 
2370  // Storage Group
2371  if (m_storagegroupList)
2372  {
2373  if (!m_loaded)
2374  {
2375  label = QObject::tr("Store in the \"%1\" storage group");
2377  label.arg(QObject::tr("Default")),
2378  qVariantFromValue(QString("Default")));
2379 
2381  for (it = groups.begin(); it != groups.end(); ++it)
2382  {
2383  if ((*it).compare("Default", Qt::CaseInsensitive) != 0)
2385  label.arg(*it), qVariantFromValue(*it));
2386  }
2387  }
2389  }
2390 
2391  // Playback Group
2392  if (m_playgroupList)
2393  {
2394  if (!m_loaded)
2395  {
2396  label = QObject::tr("Use \"%1\" playback group settings");
2398  label.arg(QObject::tr("Default")),
2399  qVariantFromValue(QString("Default")));
2400 
2401  groups = PlayGroup::GetNames();
2402  for (it = groups.begin(); it != groups.end(); ++it)
2403  {
2404  new MythUIButtonListItem(m_playgroupList, label.arg(*it),
2405  qVariantFromValue(*it));
2406  }
2407  }
2409  }
2410 
2411  // Max Episodes
2412  if (m_maxepSpin)
2413  {
2414  if (!m_loaded)
2415  {
2416  int maxEpisodes = m_rule->m_maxEpisodes;
2417  m_maxepSpin->SetRange(0,100,1,5);
2418  m_rule->m_maxEpisodes = maxEpisodes;
2419  }
2421  }
2422 
2423  // Max Episode Behaviour
2424  if (m_maxbehaviourList)
2425  {
2426  if (!m_loaded)
2427  {
2429  QObject::tr("Don't record if this would exceed the max "
2430  "episodes"), qVariantFromValue(false));
2432  QObject::tr("Delete oldest if this would exceed the max "
2433  "episodes"), qVariantFromValue(true));
2434  }
2436  }
2437 
2438  // Auto-Expire
2439  if (m_autoexpireCheck)
2440  {
2442  }
2443 
2444  m_loaded = true;
2445 
2446  RuleChanged();
2447 }
2448 
2450 {
2451  if (!m_rule)
2452  return;
2453 
2454  if (m_recprofileList)
2456 
2457  if (m_recgroupList)
2458  {
2459  // If the user selected 'Create a new regroup' but failed to enter a
2460  // name when prompted, restore the original value
2461  if (m_recgroupList->GetDataValue().toString() == "__NEW_GROUP__")
2464  }
2465 
2466  if (m_storagegroupList)
2468 
2469  if (m_playgroupList)
2471 
2472  if (m_maxepSpin)
2474 
2475  if (m_maxbehaviourList)
2477 
2478  if (m_autoexpireCheck)
2480 }
2481 
2483 {
2484  if (!m_rule)
2485  return;
2486 
2487  bool isScheduled = (m_rule->m_type != kNotRecording &&
2488  m_rule->m_type != kDontRecord);
2489  bool isSingle = (m_rule->m_type == kSingleRecord ||
2491 
2492  if (m_recprofileList)
2493  m_recprofileList->SetEnabled(isScheduled);
2494  if (m_recgroupList)
2495  m_recgroupList->SetEnabled(isScheduled);
2496  if (m_storagegroupList)
2497  m_storagegroupList->SetEnabled(isScheduled);
2498  if (m_playgroupList)
2499  m_playgroupList->SetEnabled(isScheduled);
2500  if (m_maxepSpin)
2501  m_maxepSpin->SetEnabled(isScheduled && !isSingle);
2502  if (m_maxbehaviourList)
2503  m_maxbehaviourList->SetEnabled(isScheduled && !isSingle &&
2504  m_rule->m_maxEpisodes != 0);
2505  if (m_autoexpireCheck)
2506  m_autoexpireCheck->SetEnabled(isScheduled);
2507 }
2508 
2510 {
2511  if (!item || !m_rule)
2512  return;
2513 
2514  m_rule->m_maxEpisodes = item->GetData().toInt();
2515 
2516  if (m_maxbehaviourList)
2518 }
2519 
2521 {
2522  if (!m_rule)
2523  return;
2524 
2525  if (m_recgroupList->GetDataValue().toString() != "__NEW_GROUP__")
2526  return;
2527 
2528  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2529 
2530  QString label =
2531  QObject::tr("New Recording group name: ");
2532 
2533  MythTextInputDialog *textDialog =
2534  new MythTextInputDialog(popupStack, label,
2535  static_cast<InputFilter>(FilterSymbols | FilterPunct));
2536 
2537  textDialog->SetReturnEvent(m_screen, "newrecgroup");
2538 
2539  if (textDialog->Create())
2540  popupStack->AddScreen(textDialog, false);
2541 }
2542 
2543 void StoreOptMixin::SetRecGroup(int recgroupID, QString recgroup)
2544 {
2545  if (!m_rule || recgroupID <= 0)
2546  return;
2547 
2548  if (m_recgroupList)
2549  {
2550  recgroup = recgroup.trimmed();
2551  if (recgroup.isEmpty())
2552  return;
2553 
2554  QString label = QObject::tr("Include in the \"%1\" recording group");
2555  MythUIButtonListItem *item =
2556  new MythUIButtonListItem(m_recgroupList, label.arg(recgroup),
2557  qVariantFromValue(recgroup));
2559 
2560  if (m_other && m_other->m_recgroupList)
2561  {
2563  label.arg(recgroup), qVariantFromValue(recgroupID));
2565  }
2566  }
2567 }
2568 
2569 int StoreOptMixin::CreateRecordingGroup(const QString& groupName)
2570 {
2571  int groupID = -1;
2572  MSqlQuery query(MSqlQuery::InitCon());
2573 
2574  query.prepare("INSERT INTO recgroups SET recgroup = :NAME, "
2575  "displayname = :DISPLAYNAME");
2576  query.bindValue(":NAME", groupName);
2577  query.bindValue(":DISPLAYNAME", groupName);
2578 
2579  if (query.exec())
2580  groupID = query.lastInsertId().toInt();
2581 
2582  if (groupID <= 0)
2583  LOG(VB_GENERAL, LOG_ERR, QString("Could not create recording group (%1). "
2584  "Does it already exist?").arg(groupName));
2585 
2586  return groupID;
2587 }
2588 
2590 
2597  PostProcMixin *other)
2598  : m_commflagCheck(NULL), m_transcodeCheck(NULL),
2599  m_transcodeprofileList(NULL), m_userjob1Check(NULL),
2600  m_userjob2Check(NULL), m_userjob3Check(NULL), m_userjob4Check(NULL),
2601  m_metadataLookupCheck(NULL),
2602  m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
2603 {
2604 }
2605 
2606 void PostProcMixin::Create(bool *err)
2607 {
2608  if (!m_rule)
2609  return;
2610 
2611  if (m_other && !m_other->m_commflagCheck)
2612  UIUtilE::Assign(m_screen, m_commflagCheck, "autocommflag", err);
2613  else
2614  UIUtilW::Assign(m_screen, m_commflagCheck, "autocommflag");
2615 
2616  if (m_other && !m_other->m_transcodeCheck)
2617  UIUtilE::Assign(m_screen, m_transcodeCheck, "autotranscode", err);
2618  else
2619  UIUtilW::Assign(m_screen, m_transcodeCheck, "autotranscode");
2620 
2622  UIUtilE::Assign(m_screen, m_transcodeprofileList, "transcodeprofile", err);
2623  else
2624  UIUtilW::Assign(m_screen, m_transcodeprofileList, "transcodeprofile");
2625 
2626  if (m_other && !m_other->m_userjob1Check)
2627  UIUtilE::Assign(m_screen, m_userjob1Check, "userjob1", err);
2628  else
2630 
2631  if (m_other && !m_other->m_userjob2Check)
2632  UIUtilE::Assign(m_screen, m_userjob2Check, "userjob2", err);
2633  else
2635 
2636  if (m_other && !m_other->m_userjob3Check)
2637  UIUtilE::Assign(m_screen, m_userjob3Check, "userjob3", err);
2638  else
2640 
2641  if (m_other && !m_other->m_userjob4Check)
2642  UIUtilE::Assign(m_screen, m_userjob4Check, "userjob4", err);
2643  else
2645 
2646  UIUtilW::Assign(m_screen, m_metadataLookupCheck, "metadatalookup");
2647 }
2648 
2650 {
2651  if (!m_rule)
2652  return;
2653 
2654  // Auto-commflag
2655  if (m_commflagCheck)
2656  {
2658  }
2659 
2660  // Auto-transcode
2661  if (m_transcodeCheck)
2662  {
2664  }
2665 
2666  // Transcode Method
2668  {
2669  if (!m_loaded)
2670  {
2671  QMap<int, QString> profiles = RecordingProfile::GetTranscodingProfiles();
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 }
QString m_subtitle
Definition: recordingrule.h:76
MetadataFactory * m_metadataFactory
void ShowUpcoming(const QString &title, const QString &seriesid) const
Show the upcoming recordings for this title.
MythScreenType * m_screen
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:765
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 *)
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:857
MythUICheckBox * m_ruleactiveCheck
uint GetYearOfInitialRelease(void) const
Definition: programinfo.h:402
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:8527
ScheduleEditor(MythScreenStack *parent, RecordingInfo *recinfo, TV *player=NULL)
bool LoadByProgram(const ProgramInfo *proginfo)
MythUIButton * m_localFanartButton
Dialog asking for user confirmation.
Select schedule filters.
void ToggleSelected(MythUIButtonListItem *item)
void ShowPrevious(ProgramInfo *pginfo) const
Show the previous recordings for this recording rule.
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
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:27
ArtworkMap m_artworkMap
MythUISpinBox * m_prioritySpin
PostProcEditor(MythScreenStack *parent, ScheduleEditor &editor, RecordingRule &rule, RecordingInfo *recinfo)
QString toDescription(RecStatusType recstatus, RecordingType rectype, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
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)
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:32
void Load(void)
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
AllMusic * parent
MythScreenStack * GetStack(const QString &stackname)
void ShowDetails(ProgramInfo *pginfo) const
RecordingInfo * m_recInfo
void CreateBusyDialog(QString title)
unsigned int uint
Definition: compat.h:135
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
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:83
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
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
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:72
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
RecordingRule * m_rule
virtual void Load(void)=0
MythUIButtonList * m_storagegroupList
void ruleSaved(int ruleId)
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:884
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:345
MythUIButton * m_schedInfoButton
virtual void SetTextFromMap(const InfoMap &infoMap)
Control TV playback TVPlaybackAborted(void)
Definition: tv_play.h:291
QString GetMasterHostName(void)
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)
void FindNetArt(VideoArtworkType type)
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:529
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)
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)
lzo_uintptr_t p
Definition: minilzo.cpp:2207
RecordingDupInType m_dupIn
bool keyPressEvent(QKeyEvent *event)
Key event handler.
void ChildClosing(void)
void SetText(const QString &text, bool moveCursor=true)
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
QList< ArtworkInfo > ArtworkList
MythUIImage * m_banner
MetadataDownload * m_imageLookup
void PromptForRecGroup(void)
MythUISpinBox * m_startoffsetSpin
void showPrevious(void)
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:790
void DupMethodChanged(MythUIButtonListItem *item)
MythUICheckBox * m_userjob3Check
virtual bool CreateEditChild(QString xmlfile, QString winname, bool isTemplate)
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
MythUIButtonList * m_filtersList
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:346
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
MetadataLookupList lookupList
MythUIButton * m_previewButton
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
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:597
MythUIButtonList * m_dupmethodList
CategoryType GetCategoryType(void) const
Definition: programinfo.h:417
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:145
ScheduleEditor * m_editor
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
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
static vector< uint > GetAllInputIDs(void)
Definition: cardutil.cpp:1347
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)
QString GetTitle(void) const
Definition: programinfo.h:342
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:1270
void HandleDownloadedImages(MetadataLookup *lookup)