00001
00002 #include "scheduleeditor.h"
00003
00004
00005 #include <QString>
00006 #include <QHash>
00007 #include <QCoreApplication>
00008
00009
00010 #include "mythcorecontext.h"
00011 #include "storagegroup.h"
00012 #include "programtypes.h"
00013
00014
00015 #include "playgroup.h"
00016 #include "tv_play.h"
00017 #include "recordingprofile.h"
00018 #include "cardutil.h"
00019
00020
00021 #include "mythmainwindow.h"
00022 #include "mythuihelper.h"
00023 #include "mythuibuttonlist.h"
00024 #include "mythuibutton.h"
00025 #include "mythuitext.h"
00026 #include "mythuistatetype.h"
00027 #include "mythuispinbox.h"
00028 #include "mythuicheckbox.h"
00029 #include "mythdialogbox.h"
00030 #include "mythprogressdialog.h"
00031 #include "mythuifilebrowser.h"
00032 #include "mythuimetadataresults.h"
00033 #include "mythuiimageresults.h"
00034 #include "videoutils.h"
00035 #include "mythuiutils.h"
00036
00037 #include "metadataimagehelper.h"
00038
00039
00040 #include "proglist.h"
00041 #include "viewschedulediff.h"
00042
00043 #define ENUM_TO_QVARIANT(a) qVariantFromValue(static_cast<int>(a))
00044
00045
00046
00047 static QString fs0(QT_TRANSLATE_NOOP("SchedFilterEditor", "New episode"));
00048 static QString fs1(QT_TRANSLATE_NOOP("SchedFilterEditor", "Identifiable episode"));
00049 static QString fs2(QT_TRANSLATE_NOOP("SchedFilterEditor", "First showing"));
00050 static QString fs3(QT_TRANSLATE_NOOP("SchedFilterEditor", "Prime time"));
00051 static QString fs4(QT_TRANSLATE_NOOP("SchedFilterEditor", "Commercial free"));
00052 static QString fs5(QT_TRANSLATE_NOOP("SchedFilterEditor", "High definition"));
00053 static QString fs6(QT_TRANSLATE_NOOP("SchedFilterEditor", "This episode"));
00054 static QString fs7(QT_TRANSLATE_NOOP("SchedFilterEditor", "This series"));
00055
00056 void *ScheduleEditor::RunScheduleEditor(ProgramInfo *proginfo, void *player)
00057 {
00058 RecordingRule *rule = new RecordingRule();
00059 rule->LoadByProgram(proginfo);
00060
00061 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00062 ScheduleEditor *se = new ScheduleEditor(mainStack, rule,
00063 static_cast<TV*>(player));
00064
00065 if (se->Create())
00066 mainStack->AddScreen(se, (player == NULL));
00067 else
00068 delete se;
00069
00070 return NULL;
00071 }
00072
00078 ScheduleEditor::ScheduleEditor(MythScreenStack *parent,
00079 RecordingInfo *recInfo, TV *player)
00080 : ScheduleCommon(parent, "ScheduleEditor"),
00081 SchedOptMixin(*this, NULL), StoreOptMixin(*this, NULL),
00082 PostProcMixin(*this, NULL),
00083 m_recInfo(new RecordingInfo(*recInfo)), m_recordingRule(NULL),
00084 m_sendSig(false),
00085 m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
00086 m_schedOptButton(NULL), m_storeOptButton(NULL),
00087 m_postProcButton(NULL), m_schedInfoButton(NULL),
00088 m_previewButton(NULL), m_metadataButton(NULL),
00089 m_filtersButton(NULL),
00090 m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
00091 {
00092 m_recordingRule = new RecordingRule();
00093 m_recordingRule->m_recordID = m_recInfo->GetRecordingRuleID();
00094 SchedOptMixin::SetRule(m_recordingRule);
00095 StoreOptMixin::SetRule(m_recordingRule);
00096 PostProcMixin::SetRule(m_recordingRule);
00097 }
00098
00099 ScheduleEditor::ScheduleEditor(MythScreenStack *parent,
00100 RecordingRule *recRule, TV *player)
00101 : ScheduleCommon(parent, "ScheduleEditor"),
00102 SchedOptMixin(*this, recRule),
00103 StoreOptMixin(*this, recRule),
00104 PostProcMixin(*this, recRule),
00105 m_recInfo(NULL), m_recordingRule(recRule),
00106 m_sendSig(false),
00107 m_saveButton(NULL), m_cancelButton(NULL), m_rulesList(NULL),
00108 m_schedOptButton(NULL), m_storeOptButton(NULL),
00109 m_postProcButton(NULL), m_schedInfoButton(NULL),
00110 m_previewButton(NULL), m_metadataButton(NULL),
00111 m_filtersButton(NULL),
00112 m_player(player), m_loaded(false), m_view(kMainView), m_child(NULL)
00113 {
00114 }
00115
00116 ScheduleEditor::~ScheduleEditor(void)
00117 {
00118 delete m_recordingRule;
00119
00120
00121 if (m_player)
00122 {
00123 QString message = QString("VIEWSCHEDULED_EXITING");
00124 qApp->postEvent(m_player, new MythEvent(message));
00125 }
00126 }
00127
00128 bool ScheduleEditor::Create()
00129 {
00130 if (!LoadWindowFromXML("schedule-ui.xml", "scheduleeditor", this))
00131 return false;
00132
00133 bool err = false;
00134
00135 UIUtilE::Assign(this, m_rulesList, "rules", &err);
00136
00137 UIUtilW::Assign(this, m_schedOptButton, "schedoptions");
00138 UIUtilW::Assign(this, m_storeOptButton, "storeoptions");
00139 UIUtilW::Assign(this, m_postProcButton, "postprocessing");
00140 UIUtilW::Assign(this, m_metadataButton, "metadata");
00141 UIUtilW::Assign(this, m_schedInfoButton, "schedinfo");
00142 UIUtilW::Assign(this, m_previewButton, "preview");
00143 UIUtilW::Assign(this, m_filtersButton, "filters");
00144
00145 SchedOptMixin::Create(&err);
00146 StoreOptMixin::Create(&err);
00147 PostProcMixin::Create(&err);
00148
00149 UIUtilW::Assign(this, m_cancelButton, "cancel");
00150 UIUtilE::Assign(this, m_saveButton, "save", &err);
00151
00152 if (err)
00153 {
00154 LOG(VB_GENERAL, LOG_ERR, "ScheduleEditor, theme is missing "
00155 "required elements");
00156 return false;
00157 }
00158
00159 connect(m_rulesList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00160 SLOT(RuleChanged(MythUIButtonListItem *)));
00161
00162 if (m_schedOptButton)
00163 connect(m_schedOptButton, SIGNAL(Clicked()), SLOT(ShowSchedOpt()));
00164 if (m_filtersButton)
00165 connect(m_filtersButton, SIGNAL(Clicked()), SLOT(ShowFilters()));
00166 if (m_storeOptButton)
00167 connect(m_storeOptButton, SIGNAL(Clicked()), SLOT(ShowStoreOpt()));
00168 if (m_postProcButton)
00169 connect(m_postProcButton, SIGNAL(Clicked()), SLOT(ShowPostProc()));
00170 if (m_schedInfoButton)
00171 connect(m_schedInfoButton, SIGNAL(Clicked()), SLOT(ShowSchedInfo()));
00172 if (m_previewButton)
00173 connect(m_previewButton, SIGNAL(Clicked()), SLOT(ShowPreview()));
00174 if (m_metadataButton)
00175 connect(m_metadataButton, SIGNAL(Clicked()), SLOT(ShowMetadataOptions()));
00176
00177 if (m_cancelButton)
00178 connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
00179 connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
00180
00181 if (m_metadataButton)
00182 m_metadataButton->SetEnabled(!m_recordingRule->m_isTemplate);
00183 if (m_schedInfoButton)
00184 m_schedInfoButton->SetEnabled(!m_recordingRule->m_isTemplate);
00185 if (m_previewButton)
00186 m_previewButton->SetEnabled(!m_recordingRule->m_isTemplate);
00187
00188 if (m_dupmethodList)
00189 connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00190 SLOT(DupMethodChanged(MythUIButtonListItem *)));
00191 if (m_maxepSpin)
00192 connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
00193 SLOT(MaxEpisodesChanged(MythUIButtonListItem *)));
00194 if (m_recgroupList)
00195 connect(m_recgroupList, SIGNAL(LosingFocus()),
00196 SLOT(PromptForRecGroup()));
00197 if (m_transcodeCheck)
00198 connect(m_transcodeCheck, SIGNAL(toggled(bool)),
00199 SLOT(TranscodeChanged(bool)));
00200
00201 BuildFocusList();
00202
00203 if (!m_recordingRule->IsLoaded())
00204 {
00205 if (m_recInfo)
00206 m_recordingRule->LoadByProgram(m_recInfo);
00207 else if (m_recordingRule->m_recordID)
00208 m_recordingRule->Load();
00209
00210 if (!m_recordingRule->IsLoaded())
00211 {
00212 LOG(VB_GENERAL, LOG_ERR,
00213 "ScheduleEditor::Create() - Failed to load recording rule");
00214 return false;
00215 }
00216 }
00217
00218 if (m_player)
00219 m_player->StartEmbedding(QRect());
00220
00221 return true;
00222 }
00223
00224 void ScheduleEditor::Close()
00225 {
00226 if (m_child)
00227 m_child->Close();
00228
00229
00230 if (m_player)
00231 GetScreenStack()->PopScreen(this, false);
00232 else
00233 GetScreenStack()->PopScreen(this, true);
00234 }
00235
00236 void ScheduleEditor::Load()
00237 {
00238 SchedOptMixin::Load();
00239 StoreOptMixin::Load();
00240 PostProcMixin::Load();
00241
00242 if (!m_loaded)
00243 {
00244
00245
00246
00247 RecordingType type = m_recordingRule->m_type;
00248
00249
00250 if (m_recordingRule->m_isTemplate)
00251 {
00252 if (m_recordingRule->m_category
00253 .compare("Default", Qt::CaseInsensitive) != 0)
00254 {
00255 new MythUIButtonListItem(m_rulesList,
00256 tr("Delete this recording rule template"),
00257 ENUM_TO_QVARIANT(kNotRecording));
00258 }
00259 new MythUIButtonListItem(m_rulesList,
00260 tr("Modify this recording rule template"),
00261 ENUM_TO_QVARIANT(kTemplateRecord));
00262 }
00263 else if (m_recordingRule->m_isOverride)
00264 {
00265 new MythUIButtonListItem(m_rulesList,
00266 tr("Record this showing with normal options"),
00267 ENUM_TO_QVARIANT(kNotRecording));
00268 new MythUIButtonListItem(m_rulesList,
00269 tr("Record this showing with override options"),
00270 ENUM_TO_QVARIANT(kOverrideRecord));
00271 new MythUIButtonListItem(m_rulesList,
00272 tr("Do not allow this showing to be recorded"),
00273 ENUM_TO_QVARIANT(kDontRecord));
00274 }
00275 else
00276 {
00277 bool hasChannel = !m_recordingRule->m_station.isEmpty();
00278 bool isManual = (m_recordingRule->m_searchType == kManualSearch);
00279
00280 new MythUIButtonListItem(m_rulesList,
00281 tr("Do not record this program"),
00282 ENUM_TO_QVARIANT(kNotRecording));
00283
00284 if (hasChannel)
00285 new MythUIButtonListItem(m_rulesList,
00286 tr("Record only this showing"),
00287 ENUM_TO_QVARIANT(kSingleRecord));
00288 if (!isManual)
00289 new MythUIButtonListItem(m_rulesList,
00290 tr("Record one showing of this title"),
00291 ENUM_TO_QVARIANT(kFindOneRecord));
00292 if (hasChannel)
00293 new MythUIButtonListItem(m_rulesList,
00294 tr("Record in this timeslot every week"),
00295 ENUM_TO_QVARIANT(kWeekslotRecord));
00296 if (!isManual)
00297 new MythUIButtonListItem(m_rulesList,
00298 tr("Record one showing of this title every week"),
00299 ENUM_TO_QVARIANT(kFindWeeklyRecord));
00300 if (hasChannel)
00301 new MythUIButtonListItem(m_rulesList,
00302 tr("Record in this timeslot every day"),
00303 ENUM_TO_QVARIANT(kTimeslotRecord));
00304 if (!isManual)
00305 new MythUIButtonListItem(m_rulesList,
00306 tr("Record one showing of this title every day"),
00307 ENUM_TO_QVARIANT(kFindDailyRecord));
00308 if (hasChannel && !isManual)
00309 new MythUIButtonListItem(m_rulesList,
00310 tr("Record at any time on this channel"),
00311 ENUM_TO_QVARIANT(kChannelRecord));
00312 if (!isManual)
00313 new MythUIButtonListItem(m_rulesList,
00314 ("Record at any time on any channel"),
00315 ENUM_TO_QVARIANT(kAllRecord));
00316 }
00317
00318 m_recordingRule->m_type = type;
00319 }
00320 m_rulesList->SetValueByData(ENUM_TO_QVARIANT(m_recordingRule->m_type));
00321
00322 InfoMap progMap;
00323
00324 m_recordingRule->ToMap(progMap);
00325
00326 if (m_recInfo)
00327 m_recInfo->ToMap(progMap);
00328
00329 SetTextFromMap(progMap);
00330
00331 m_loaded = true;
00332 }
00333
00334 void ScheduleEditor::LoadTemplate(QString name)
00335 {
00336 m_recordingRule->LoadTemplate(name);
00337 Load();
00338 emit templateLoaded();
00339 }
00340
00341 void ScheduleEditor::RuleChanged(MythUIButtonListItem *item)
00342 {
00343 if (!item)
00344 return;
00345
00346 m_recordingRule->m_type = static_cast<RecordingType>
00347 (item->GetData().toInt());
00348
00349 bool isScheduled = (m_recordingRule->m_type != kNotRecording &&
00350 m_recordingRule->m_type != kDontRecord);
00351
00352 if (m_schedOptButton)
00353 m_schedOptButton->SetEnabled(isScheduled);
00354 if (m_filtersButton)
00355 m_filtersButton->SetEnabled(isScheduled);
00356 if (m_storeOptButton)
00357 m_storeOptButton->SetEnabled(isScheduled);
00358 if (m_postProcButton)
00359 m_postProcButton->SetEnabled(isScheduled);
00360
00361 SchedOptMixin::RuleChanged();
00362 StoreOptMixin::RuleChanged();
00363 PostProcMixin::RuleChanged();
00364 }
00365
00366 void ScheduleEditor::DupMethodChanged(MythUIButtonListItem *item)
00367 {
00368 SchedOptMixin::DupMethodChanged(item);
00369 }
00370
00371 void ScheduleEditor::MaxEpisodesChanged(MythUIButtonListItem *item)
00372 {
00373 StoreOptMixin::MaxEpisodesChanged(item);
00374 }
00375
00376 void ScheduleEditor::PromptForRecGroup(void)
00377 {
00378 StoreOptMixin::PromptForRecGroup();
00379 }
00380
00381 void ScheduleEditor::TranscodeChanged(bool enable)
00382 {
00383 PostProcMixin::TranscodeChanged(enable);
00384 }
00385
00386 void ScheduleEditor::Save()
00387 {
00388 if (m_child)
00389 m_child->Close();
00390
00391 if (m_recordingRule->m_type == kNotRecording)
00392 {
00393 int recid = m_recordingRule->m_recordID;
00394 DeleteRule();
00395 if (recid)
00396 emit ruleDeleted(recid);
00397 Close();
00398 return;
00399 }
00400
00401 SchedOptMixin::Save();
00402 StoreOptMixin::Save();
00403 PostProcMixin::Save();
00404 m_recordingRule->Save(true);
00405 emit ruleSaved(m_recordingRule->m_recordID);
00406
00407 Close();
00408 }
00409
00410 void ScheduleEditor::DeleteRule()
00411 {
00412 m_recordingRule->Delete();
00413 }
00414
00415 void ScheduleEditor::ShowSchedOpt()
00416 {
00417 if (m_recordingRule->m_type == kNotRecording ||
00418 m_recordingRule->m_type == kDontRecord)
00419 return;
00420
00421 if (m_child)
00422 m_child->Close();
00423
00424 SchedOptMixin::Save();
00425
00426 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00427 SchedOptEditor *schedoptedit = new SchedOptEditor(mainStack, *this,
00428 *m_recordingRule, m_recInfo);
00429 if (!schedoptedit->Create())
00430 {
00431 delete schedoptedit;
00432 return;
00433 }
00434
00435 m_view = kSchedOptView;
00436 m_child = schedoptedit;
00437 mainStack->AddScreen(schedoptedit);
00438 }
00439
00440 void ScheduleEditor::ShowStoreOpt()
00441 {
00442 if (m_recordingRule->m_type == kNotRecording ||
00443 m_recordingRule->m_type == kDontRecord)
00444 return;
00445
00446 if (m_child)
00447 m_child->Close();
00448
00449 StoreOptMixin::Save();
00450
00451 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00452 StoreOptEditor *storeoptedit = new StoreOptEditor(mainStack, *this,
00453 *m_recordingRule, m_recInfo);
00454 if (!storeoptedit->Create())
00455 {
00456 delete storeoptedit;
00457 return;
00458 }
00459
00460 m_view = kStoreOptView;
00461 m_child = storeoptedit;
00462 mainStack->AddScreen(storeoptedit);
00463 }
00464
00465 void ScheduleEditor::ShowPostProc()
00466 {
00467 if (m_recordingRule->m_type == kNotRecording ||
00468 m_recordingRule->m_type == kDontRecord)
00469 return;
00470
00471 if (m_child)
00472 m_child->Close();
00473
00474 PostProcMixin::Save();
00475
00476 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00477 PostProcEditor *ppedit = new PostProcEditor(mainStack, *this,
00478 *m_recordingRule, m_recInfo);
00479 if (!ppedit->Create())
00480 {
00481 delete ppedit;
00482 return;
00483 }
00484
00485 m_view = kPostProcView;
00486 m_child = ppedit;
00487 mainStack->AddScreen(ppedit);
00488 }
00489
00490 void ScheduleEditor::ShowSchedInfo()
00491 {
00492 if (m_recordingRule->m_type == kTemplateRecord)
00493 return;
00494
00495 QString label = tr("Schedule Information");
00496
00497 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00498 MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
00499
00500 if (menuPopup->Create())
00501 {
00502 menuPopup->SetReturnEvent(this, "schedinfo");
00503
00504 if (m_recInfo)
00505 menuPopup->AddButton(tr("Program Details"));
00506 menuPopup->AddButton(tr("Upcoming Episodes"));
00507 menuPopup->AddButton(tr("Upcoming Recordings"));
00508 menuPopup->AddButton(tr("Previously Scheduled"));
00509
00510 popupStack->AddScreen(menuPopup);
00511 }
00512 else
00513 delete menuPopup;
00514 }
00515
00516 bool ScheduleEditor::keyPressEvent(QKeyEvent *event)
00517 {
00518 if (GetFocusWidget()->keyPressEvent(event))
00519 return true;
00520
00521 bool handled = false;
00522 QStringList actions;
00523 handled = GetMythMainWindow()->
00524 TranslateKeyPress("TV Frontend", event, actions);
00525
00526 for (int i = 0; i < actions.size() && !handled; i++)
00527 {
00528 QString action = actions[i];
00529 handled = true;
00530
00531 if (action == "MENU")
00532 showMenu();
00533 else if (action == "INFO")
00534 ShowDetails(m_recInfo);
00535 else if (action == "UPCOMING")
00536 showUpcomingByTitle();
00537 else if (action == "PREVVIEW")
00538 ShowPreviousView();
00539 else if (action == "NEXTVIEW")
00540 ShowNextView();
00541 else
00542 handled = false;
00543 }
00544
00545 if (!handled && MythScreenType::keyPressEvent(event))
00546 handled = true;
00547
00548 return handled;
00549 }
00550
00551 void ScheduleEditor::customEvent(QEvent *event)
00552 {
00553 if (event->type() == DialogCompletionEvent::kEventType)
00554 {
00555 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00556
00557 QString resultid = dce->GetId();
00558 QString resulttext = dce->GetResultText();
00559
00560 if (resultid == "menu")
00561 {
00562 if (resulttext == tr("Main Options"))
00563 m_child->Close();
00564 if (resulttext == tr("Schedule Options"))
00565 ShowSchedOpt();
00566 else if (resulttext == tr("Filter Options"))
00567 ShowFilters();
00568 else if (resulttext == tr("Storage Options"))
00569 ShowStoreOpt();
00570 else if (resulttext == tr("Post Processing"))
00571 ShowPostProc();
00572 else if (resulttext == tr("Metadata Options"))
00573 ShowMetadataOptions();
00574 else if (resulttext == tr("Use Template"))
00575 showTemplateMenu();
00576 else if (resulttext == tr("Schedule Info"))
00577 ShowSchedInfo();
00578 else if (resulttext == tr("Preview Changes"))
00579 ShowPreview();
00580 }
00581 else if (resultid == "templatemenu")
00582 {
00583 LoadTemplate(resulttext);
00584 }
00585 else if (resultid == "schedinfo")
00586 {
00587 if (resulttext == tr("Program Details"))
00588 ShowDetails(m_recInfo);
00589 else if (resulttext == tr("Upcoming Episodes"))
00590 showUpcomingByTitle();
00591 else if (resulttext == tr("Upcoming Recordings"))
00592 showUpcomingByRule();
00593 else if (resulttext == tr("Previously Scheduled"))
00594 showPrevious();
00595 }
00596 else if (resultid == "newrecgroup")
00597 {
00598 StoreOptMixin::SetRecGroup(resulttext);
00599 }
00600 }
00601 }
00602
00603 void ScheduleEditor::showPrevious(void)
00604 {
00605 if (m_recordingRule->m_type == kTemplateRecord)
00606 return;
00607
00608 QString title;
00609 if (m_recInfo)
00610 title = m_recInfo->GetTitle();
00611 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00612 ProgLister *pl = new ProgLister(mainStack, m_recordingRule->m_recordID,
00613 title);
00614 if (pl->Create())
00615 mainStack->AddScreen(pl);
00616 else
00617 delete pl;
00618 }
00619
00620 void ScheduleEditor::showUpcomingByRule(void)
00621 {
00622 if (m_recordingRule->m_type == kTemplateRecord)
00623 return;
00624
00625
00626 if (m_recordingRule->m_recordID <= 0)
00627 {
00628 showUpcomingByTitle();
00629 return;
00630 }
00631
00632 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00633 ProgLister *pl = new ProgLister(mainStack, plRecordid,
00634 QString::number(m_recordingRule->m_recordID),
00635 "");
00636
00637 if (pl->Create())
00638 mainStack->AddScreen(pl);
00639 else
00640 delete pl;
00641 }
00642
00643 void ScheduleEditor::showUpcomingByTitle(void)
00644 {
00645 if (m_recordingRule->m_type == kTemplateRecord)
00646 return;
00647
00648
00649 if (m_recordingRule->m_recordID > 0 &&
00650 m_recordingRule->m_searchType != kNoSearch)
00651 showUpcomingByRule();
00652
00653 QString title = m_recordingRule->m_title;
00654
00655 if (m_recordingRule->m_searchType != kNoSearch)
00656 title.remove(QRegExp(" \\(.*\\)$"));
00657
00658 ShowUpcoming(title, m_recordingRule->m_seriesid);
00659 }
00660
00661 void ScheduleEditor::ShowPreview(void)
00662 {
00663 if (m_recordingRule->m_type == kTemplateRecord)
00664 return;
00665
00666 if (m_child)
00667 {
00668 m_child->Save();
00669 if (m_view == kSchedOptView)
00670 SchedOptMixin::Load();
00671 else if (m_view == kStoreOptView)
00672 StoreOptMixin::Load();
00673 else if (m_view == kPostProcView)
00674 PostProcMixin::Load();
00675 }
00676
00677 SchedOptMixin::Save();
00678 StoreOptMixin::Save();
00679 PostProcMixin::Save();
00680
00681 QString ttable = "record_tmp";
00682 m_recordingRule->UseTempTable(true, ttable);
00683
00684 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00685 ViewScheduleDiff *vsd = new ViewScheduleDiff(mainStack, ttable,
00686 m_recordingRule->m_tempID,
00687 m_recordingRule->m_title);
00688 if (vsd->Create())
00689 mainStack->AddScreen(vsd);
00690 else
00691 delete vsd;
00692
00693 m_recordingRule->UseTempTable(false);
00694 }
00695
00696 void ScheduleEditor::ShowMetadataOptions(void)
00697 {
00698 if (m_recordingRule->m_type == kNotRecording ||
00699 m_recordingRule->m_type == kDontRecord ||
00700 m_recordingRule->m_type == kTemplateRecord)
00701 return;
00702
00703 if (m_child)
00704 m_child->Close();
00705
00706 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00707 MetadataOptions *rad = new MetadataOptions(mainStack, *this,
00708 *m_recordingRule, m_recInfo);
00709 if (!rad->Create())
00710 {
00711 delete rad;
00712 return;
00713 }
00714
00715 m_view = kMetadataView;
00716 m_child = rad;
00717 mainStack->AddScreen(rad);
00718 }
00719
00720 void ScheduleEditor::ShowFilters(void)
00721 {
00722 if (m_recordingRule->m_type == kNotRecording ||
00723 m_recordingRule->m_type == kDontRecord)
00724 return;
00725
00726 if (m_child)
00727 m_child->Close();
00728
00729 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00730 SchedFilterEditor *schedfilteredit = new SchedFilterEditor(mainStack,
00731 *this, *m_recordingRule, m_recInfo);
00732 if (!schedfilteredit->Create())
00733 {
00734 delete schedfilteredit;
00735 return;
00736 }
00737
00738 m_view = kFilterView;
00739 m_child = schedfilteredit;
00740 mainStack->AddScreen(schedfilteredit);
00741 }
00742
00743 void ScheduleEditor::ShowPreviousView(void)
00744 {
00745 if (m_recordingRule->m_type == kNotRecording ||
00746 m_recordingRule->m_type == kDontRecord)
00747 return;
00748
00749 if (m_view == kMainView && !m_recordingRule->m_isTemplate)
00750 ShowMetadataOptions();
00751 else if (m_view == kMainView)
00752 ShowPostProc();
00753 else if (m_view == kSchedOptView)
00754 m_child->Close();
00755 else if (m_view == kFilterView)
00756 ShowSchedOpt();
00757 else if (m_view == kStoreOptView)
00758 ShowFilters();
00759 else if (m_view == kPostProcView)
00760 ShowStoreOpt();
00761 else if (m_view == kMetadataView)
00762 ShowPostProc();
00763 }
00764
00765 void ScheduleEditor::ShowNextView(void)
00766 {
00767 if (m_recordingRule->m_type == kNotRecording ||
00768 m_recordingRule->m_type == kDontRecord)
00769 return;
00770
00771 if (m_view == kMainView)
00772 ShowSchedOpt();
00773 else if (m_view == kSchedOptView)
00774 ShowFilters();
00775 else if (m_view == kFilterView)
00776 ShowStoreOpt();
00777 else if (m_view == kStoreOptView)
00778 ShowPostProc();
00779 else if (m_view == kPostProcView && !m_recordingRule->m_isTemplate)
00780 ShowMetadataOptions();
00781 else if (m_view == kPostProcView)
00782 m_child->Close();
00783 else if (m_view == kMetadataView)
00784 m_child->Close();
00785 }
00786
00787 void ScheduleEditor::ChildClosing(void)
00788 {
00789 if (m_view == kSchedOptView)
00790 SchedOptMixin::Load();
00791 else if (m_view == kStoreOptView)
00792 StoreOptMixin::Load();
00793 else if (m_view == kPostProcView)
00794 PostProcMixin::Load();
00795
00796 m_child = NULL;
00797 m_view = kMainView;
00798 }
00799
00800 void ScheduleEditor::showMenu(void)
00801 {
00802 QString label = tr("Options");
00803 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00804 MythDialogBox *menuPopup =
00805 new MythDialogBox(label, popupStack, "menuPopup");
00806
00807 MythUIButtonListItem *item = m_rulesList->GetItemCurrent();
00808 RecordingType type = static_cast<RecordingType>(item->GetData().toInt());
00809 bool isScheduled = (type != kNotRecording && type != kDontRecord);
00810
00811 if (menuPopup->Create())
00812 {
00813 menuPopup->SetReturnEvent(this, "menu");
00814 if (m_view != kMainView)
00815 menuPopup->AddButton(tr("Main Options"));
00816 if (isScheduled && m_view != kSchedOptView)
00817 menuPopup->AddButton(tr("Schedule Options"));
00818 if (isScheduled && m_view != kFilterView)
00819 menuPopup->AddButton(tr("Filter Options"));
00820 if (isScheduled && m_view != kStoreOptView)
00821 menuPopup->AddButton(tr("Storage Options"));
00822 if (isScheduled && m_view != kPostProcView)
00823 menuPopup->AddButton(tr("Post Processing"));
00824 if (isScheduled && !m_recordingRule->m_isTemplate &&
00825 m_view != kMetadataView)
00826 menuPopup->AddButton(tr("Metadata Options"));
00827 if (!m_recordingRule->m_isTemplate)
00828 menuPopup->AddButton(tr("Schedule Info"));
00829 if (!m_recordingRule->m_isTemplate)
00830 menuPopup->AddButton(tr("Preview Changes"));
00831 menuPopup->AddButton(tr("Use Template"));
00832 popupStack->AddScreen(menuPopup);
00833 }
00834 else
00835 {
00836 delete menuPopup;
00837 }
00838 }
00839
00840 void ScheduleEditor::showTemplateMenu(void)
00841 {
00842 QStringList templates = RecordingRule::GetTemplateNames();
00843 if (templates.empty())
00844 {
00845 ShowOkPopup(tr("No templates available"));
00846 return;
00847 }
00848
00849 QString label = tr("Template Options");
00850 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00851 MythDialogBox *menuPopup =
00852 new MythDialogBox(label, popupStack, "menuPopup");
00853
00854 if (menuPopup->Create())
00855 {
00856 menuPopup->SetReturnEvent(this, "templatemenu");
00857 while (!templates.empty())
00858 {
00859 QString name = templates.front();
00860 if (name == "Default")
00861 menuPopup->AddButton(tr("Default"));
00862 else
00863 menuPopup->AddButton(name);
00864 templates.pop_front();
00865 }
00866 popupStack->AddScreen(menuPopup);
00867 }
00868 else
00869 {
00870 delete menuPopup;
00871 }
00872 }
00873
00875
00880 SchedEditChild::SchedEditChild(MythScreenStack *parent, const QString name,
00881 ScheduleEditor &editor, RecordingRule &rule,
00882 RecordingInfo *recInfo)
00883 : MythScreenType(parent, name),
00884 m_editor(&editor), m_recordingRule(&rule), m_recInfo(recInfo),
00885 m_backButton(NULL), m_saveButton(NULL), m_previewButton(NULL)
00886 {
00887 }
00888
00889 SchedEditChild::~SchedEditChild(void)
00890 {
00891 }
00892
00893 bool SchedEditChild::keyPressEvent(QKeyEvent *event)
00894 {
00895 if (GetFocusWidget()->keyPressEvent(event))
00896 return true;
00897
00898 bool handled = false;
00899 QStringList actions;
00900 handled = GetMythMainWindow()->
00901 TranslateKeyPress("TV Frontend", event, actions);
00902
00903 for (int i = 0; i < actions.size() && !handled; i++)
00904 {
00905 QString action = actions[i];
00906 handled = true;
00907
00908 if (action == "MENU")
00909 m_editor->showMenu();
00910 else if (action == "INFO")
00911 m_editor->ShowDetails(m_recInfo);
00912 else if (action == "UPCOMING")
00913 m_editor->showUpcomingByTitle();
00914 if (action == "ESCAPE")
00915 Close();
00916 else if (action == "PREVVIEW")
00917 m_editor->ShowPreviousView();
00918 else if (action == "NEXTVIEW")
00919 m_editor->ShowNextView();
00920 else
00921 handled = false;
00922 }
00923
00924 if (!handled && MythScreenType::keyPressEvent(event))
00925 handled = true;
00926
00927 return handled;
00928 }
00929
00930 bool SchedEditChild::Create(const QString xmlfile, const QString winname,
00931 bool isTemplate)
00932 {
00933 if (!LoadWindowFromXML(xmlfile, winname, this))
00934 return false;
00935
00936 UIUtilW::Assign(this, m_backButton, "back");
00937 UIUtilW::Assign(this, m_saveButton, "save");
00938 UIUtilW::Assign(this, m_previewButton, "preview");
00939
00940 connect(this, SIGNAL(Closing()), m_editor, SLOT(ChildClosing()));
00941 connect(m_editor, SIGNAL(templateLoaded()), SLOT(Load()));
00942
00943 if (m_backButton)
00944 connect(m_backButton, SIGNAL(Clicked()), SLOT(Close()));
00945 if (m_saveButton)
00946 connect(m_saveButton, SIGNAL(Clicked()), m_editor, SLOT(Save()));
00947 if (m_previewButton)
00948 connect(m_previewButton, SIGNAL(Clicked()),
00949 m_editor, SLOT(ShowPreview()));
00950
00951 if (m_previewButton)
00952 m_previewButton->SetEnabled(!isTemplate);
00953
00954 return true;
00955 }
00956
00957 void SchedEditChild::SetTextFromMaps(void)
00958 {
00959 InfoMap progMap;
00960
00961 m_recordingRule->ToMap(progMap);
00962
00963 if (m_recInfo)
00964 m_recInfo->ToMap(progMap);
00965
00966 SetTextFromMap(progMap);
00967 }
00968
00969 void SchedEditChild::Close(void)
00970 {
00971 Save();
00972 emit Closing();
00973 MythScreenType::Close();
00974 }
00975
00977
00983 SchedOptEditor::SchedOptEditor(MythScreenStack *parent,
00984 ScheduleEditor &editor,
00985 RecordingRule &rule,
00986 RecordingInfo *recInfo)
00987 : SchedEditChild(parent, "ScheduleOptionsEditor", editor, rule, recInfo),
00988 SchedOptMixin(*this, &rule, &editor), m_filtersButton(NULL)
00989 {
00990 }
00991
00992 SchedOptEditor::~SchedOptEditor(void)
00993 {
00994 }
00995
00996 bool SchedOptEditor::Create()
00997 {
00998 if (!SchedEditChild::Create("schedule-ui.xml", "scheduleoptionseditor",
00999 m_recordingRule->m_isTemplate))
01000 return false;
01001
01002 bool err = false;
01003
01004 SchedOptMixin::Create(&err);
01005
01006 UIUtilW::Assign(this, m_filtersButton, "filters");
01007
01008 if (err)
01009 {
01010 LOG(VB_GENERAL, LOG_ERR, "SchedOptEditor, theme is missing "
01011 "required elements");
01012 return false;
01013 }
01014
01015 if (m_dupmethodList)
01016 connect(m_dupmethodList, SIGNAL(itemSelected(MythUIButtonListItem *)),
01017 SLOT(DupMethodChanged(MythUIButtonListItem *)));
01018
01019 if (m_filtersButton)
01020 connect(m_filtersButton, SIGNAL(Clicked()),
01021 m_editor, SLOT(ShowFilters()));
01022
01023 BuildFocusList();
01024
01025 return true;
01026 }
01027
01028 void SchedOptEditor::Load()
01029 {
01030 SchedOptMixin::Load();
01031 SetTextFromMaps();
01032 }
01033
01034 void SchedOptEditor::Save()
01035 {
01036 SchedOptMixin::Save();
01037 }
01038
01039 void SchedOptEditor::DupMethodChanged(MythUIButtonListItem *item)
01040 {
01041 SchedOptMixin::DupMethodChanged(item);
01042 }
01043
01045
01051 SchedFilterEditor::SchedFilterEditor(MythScreenStack *parent,
01052 ScheduleEditor &editor,
01053 RecordingRule &rule,
01054 RecordingInfo *recInfo)
01055 : SchedEditChild(parent, "ScheduleFilterEditor", editor, rule, recInfo),
01056 m_filtersList(NULL), m_loaded(false)
01057 {
01058 }
01059
01060 SchedFilterEditor::~SchedFilterEditor(void)
01061 {
01062 }
01063
01064 bool SchedFilterEditor::Create()
01065 {
01066 if (!SchedEditChild::Create("schedule-ui.xml", "schedulefiltereditor",
01067 m_recordingRule->m_isTemplate))
01068 return false;
01069
01070 bool err = false;
01071
01072 UIUtilE::Assign(this, m_filtersList, "filters", &err);
01073
01074 if (err)
01075 {
01076 LOG(VB_GENERAL, LOG_ERR, "SchedFilterEditor, theme is missing "
01077 "required elements");
01078 return false;
01079 }
01080
01081 connect(m_filtersList, SIGNAL(itemClicked(MythUIButtonListItem *)),
01082 SLOT(ToggleSelected(MythUIButtonListItem *)));
01083
01084 BuildFocusList();
01085
01086 return true;
01087 }
01088
01089 void SchedFilterEditor::Load()
01090 {
01091 int filterid;
01092 MythUIButtonListItem *button;
01093
01094 if (!m_loaded)
01095 {
01096 MSqlQuery query(MSqlQuery::InitCon());
01097
01098 query.prepare("SELECT filterid, description, newruledefault "
01099 "FROM recordfilter ORDER BY filterid");
01100
01101 if (query.exec())
01102 {
01103 while (query.next())
01104 {
01105 filterid = query.value(0).toInt();
01106 QString description = tr(query.value(1).toString()
01107 .toUtf8().constData());
01108
01109 button = new MythUIButtonListItem(m_filtersList, description,
01110 filterid);
01111 button->setCheckable(true);
01112 }
01113 }
01114 }
01115
01116 int idx, end = m_filtersList->GetCount();
01117 for (idx = 0; idx < end; ++idx)
01118 {
01119 button = m_filtersList->GetItemAt(idx);
01120 int filterid = qVariantValue<int>(button->GetData());
01121 button->setChecked(m_recordingRule->m_filter & (1 << filterid) ?
01122 MythUIButtonListItem::FullChecked :
01123 MythUIButtonListItem::NotChecked);
01124 }
01125
01126 SetTextFromMaps();
01127
01128 m_loaded = true;
01129 }
01130
01131 void SchedFilterEditor::ToggleSelected(MythUIButtonListItem *item)
01132 {
01133 item->setChecked(item->state() == MythUIButtonListItem::FullChecked ?
01134 MythUIButtonListItem::NotChecked :
01135 MythUIButtonListItem::FullChecked);
01136 }
01137
01138 void SchedFilterEditor::Save()
01139 {
01140
01141 MythUIButtonListItem *button;
01142 uint32_t filter_mask = 0;
01143 int idx, end;
01144
01145 end = m_filtersList->GetCount();
01146 for (idx = 0; idx < end; ++idx)
01147 {
01148 if ((button = m_filtersList->GetItemAt(idx)) &&
01149 button->state() == MythUIButtonListItem::FullChecked)
01150 filter_mask |= (1 << qVariantValue<uint32_t>(button->GetData()));
01151 }
01152 m_recordingRule->m_filter = filter_mask;
01153 }
01154
01156
01162 StoreOptEditor::StoreOptEditor(MythScreenStack *parent,
01163 ScheduleEditor &editor,
01164 RecordingRule &rule,
01165 RecordingInfo *recInfo)
01166 : SchedEditChild(parent, "StorageOptionsEditor", editor, rule, recInfo),
01167 StoreOptMixin(*this, &rule, &editor)
01168 {
01169 }
01170
01171 StoreOptEditor::~StoreOptEditor(void)
01172 {
01173 }
01174
01175 bool StoreOptEditor::Create()
01176 {
01177 if (!SchedEditChild::Create("schedule-ui.xml", "storageoptionseditor",
01178 m_recordingRule->m_isTemplate))
01179 return false;
01180
01181 bool err = false;
01182
01183 StoreOptMixin::Create(&err);
01184
01185 if (err)
01186 {
01187 LOG(VB_GENERAL, LOG_ERR, "StoreOptEditor, theme is missing "
01188 "required elements");
01189 return false;
01190 }
01191
01192 if (m_maxepSpin)
01193 connect(m_maxepSpin, SIGNAL(itemSelected(MythUIButtonListItem *)),
01194 SLOT(MaxEpisodesChanged(MythUIButtonListItem *)));
01195 if (m_recgroupList)
01196 connect(m_recgroupList, SIGNAL(LosingFocus()),
01197 SLOT(PromptForRecGroup()));
01198
01199 BuildFocusList();
01200
01201 return true;
01202 }
01203
01204 void StoreOptEditor::Load()
01205 {
01206 StoreOptMixin::Load();
01207 SetTextFromMaps();
01208 }
01209
01210 void StoreOptEditor::MaxEpisodesChanged(MythUIButtonListItem *item)
01211 {
01212 StoreOptMixin::MaxEpisodesChanged(item);
01213 }
01214
01215 void StoreOptEditor::PromptForRecGroup(void)
01216 {
01217 StoreOptMixin::PromptForRecGroup();
01218 }
01219
01220 void StoreOptEditor::customEvent(QEvent *event)
01221 {
01222 if (event->type() == DialogCompletionEvent::kEventType)
01223 {
01224 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
01225
01226 QString resultid = dce->GetId();
01227 QString resulttext = dce->GetResultText();
01228
01229 if (resultid == "newrecgroup")
01230 {
01231 StoreOptMixin::SetRecGroup(resulttext);
01232 }
01233 }
01234 }
01235
01236 void StoreOptEditor::Save()
01237 {
01238 StoreOptMixin::Save();
01239 }
01240
01242
01248 PostProcEditor::PostProcEditor(MythScreenStack *parent,
01249 ScheduleEditor &editor,
01250 RecordingRule &rule,
01251 RecordingInfo *recInfo)
01252 : SchedEditChild(parent, "PostProcOptionsEditor", editor, rule, recInfo),
01253 PostProcMixin(*this, &rule, &editor)
01254 {
01255 }
01256
01257 PostProcEditor::~PostProcEditor(void)
01258 {
01259 }
01260
01261 bool PostProcEditor::Create()
01262 {
01263 if (!SchedEditChild::Create("schedule-ui.xml", "postproceditor",
01264 m_recordingRule->m_isTemplate))
01265 return false;
01266
01267 bool err = false;
01268
01269 PostProcMixin::Create(&err);
01270
01271 if (err)
01272 {
01273 LOG(VB_GENERAL, LOG_ERR, "PostProcEditor, theme is missing "
01274 "required elements");
01275 return false;
01276 }
01277
01278 if (m_transcodeCheck)
01279 connect(m_transcodeCheck, SIGNAL(toggled(bool)),
01280 SLOT(TranscodeChanged(bool)));
01281
01282 BuildFocusList();
01283
01284 return true;
01285 }
01286
01287 void PostProcEditor::Load()
01288 {
01289 PostProcMixin::Load();
01290 SetTextFromMaps();
01291 }
01292
01293 void PostProcEditor::TranscodeChanged(bool enable)
01294 {
01295 PostProcMixin::TranscodeChanged(enable);
01296 }
01297
01298 void PostProcEditor::Save()
01299 {
01300 PostProcMixin::Save();
01301 }
01302
01304
01310 MetadataOptions::MetadataOptions(MythScreenStack *parent,
01311 ScheduleEditor &editor,
01312 RecordingRule &rule,
01313 RecordingInfo *recInfo)
01314 : SchedEditChild(parent, "MetadataOptions", editor, rule, recInfo),
01315 m_lookup(NULL),
01316 m_busyPopup(NULL), m_fanart(NULL), m_coverart(NULL),
01317 m_banner(NULL), m_inetrefEdit(NULL), m_seasonSpin(NULL),
01318 m_episodeSpin(NULL), m_queryButton(NULL), m_localFanartButton(NULL),
01319 m_localCoverartButton(NULL), m_localBannerButton(NULL),
01320 m_onlineFanartButton(NULL), m_onlineCoverartButton(NULL),
01321 m_onlineBannerButton(NULL)
01322 {
01323 m_popupStack = GetMythMainWindow()->GetStack("popup stack");
01324
01325 m_metadataFactory = new MetadataFactory(this);
01326 m_imageLookup = new MetadataDownload(this);
01327 m_imageDownload = new MetadataImageDownload(this);
01328
01329 m_artworkMap = GetArtwork(m_recordingRule->m_inetref,
01330 m_recordingRule->m_season);
01331 }
01332
01333 MetadataOptions::~MetadataOptions(void)
01334 {
01335 if (m_imageLookup)
01336 {
01337 m_imageLookup->cancel();
01338 delete m_imageLookup;
01339 m_imageLookup = NULL;
01340 }
01341
01342 if (m_imageDownload)
01343 {
01344 m_imageDownload->cancel();
01345 delete m_imageDownload;
01346 m_imageDownload = NULL;
01347 }
01348 }
01349
01350 bool MetadataOptions::Create()
01351 {
01352 if (!SchedEditChild::Create("schedule-ui.xml", "metadataoptions",
01353 m_recordingRule->m_isTemplate))
01354 return false;
01355
01356 bool err = false;
01357
01358 UIUtilE::Assign(this, m_inetrefEdit, "inetref_edit", &err);
01359 UIUtilE::Assign(this, m_seasonSpin, "season_spinbox", &err);
01360 UIUtilE::Assign(this, m_episodeSpin, "episode_spinbox", &err);
01361 UIUtilE::Assign(this, m_queryButton, "query_button", &err);
01362 UIUtilE::Assign(this, m_localFanartButton, "local_fanart_button", &err);
01363 UIUtilE::Assign(this, m_localCoverartButton, "local_coverart_button", &err);
01364 UIUtilE::Assign(this, m_localBannerButton, "local_banner_button", &err);
01365 UIUtilE::Assign(this, m_onlineFanartButton, "online_fanart_button", &err);
01366 UIUtilE::Assign(this, m_onlineCoverartButton, "online_coverart_button", &err);
01367 UIUtilE::Assign(this, m_onlineBannerButton, "online_banner_button", &err);
01368 UIUtilW::Assign(this, m_fanart, "fanart");
01369 UIUtilW::Assign(this, m_coverart, "coverart");
01370 UIUtilW::Assign(this, m_banner, "banner");
01371
01372 if (err)
01373 {
01374 LOG(VB_GENERAL, LOG_ERR, "MetadataOptions, theme is missing "
01375 "required elements");
01376 return false;
01377 }
01378
01379 connect(m_queryButton, SIGNAL(Clicked()),
01380 SLOT(PerformQuery()));
01381 connect(m_localFanartButton, SIGNAL(Clicked()),
01382 SLOT(SelectLocalFanart()));
01383 connect(m_localCoverartButton, SIGNAL(Clicked()),
01384 SLOT(SelectLocalCoverart()));
01385 connect(m_localBannerButton, SIGNAL(Clicked()),
01386 SLOT(SelectLocalBanner()));
01387 connect(m_onlineFanartButton, SIGNAL(Clicked()),
01388 SLOT(SelectOnlineFanart()));
01389 connect(m_onlineCoverartButton, SIGNAL(Clicked()),
01390 SLOT(SelectOnlineCoverart()));
01391 connect(m_onlineBannerButton, SIGNAL(Clicked()),
01392 SLOT(SelectOnlineBanner()));
01393
01394 connect(m_seasonSpin, SIGNAL(itemSelected(MythUIButtonListItem*)),
01395 SLOT(ValuesChanged()));
01396
01397
01398 m_inetrefEdit->SetText(m_recordingRule->m_inetref);
01399
01400
01401 m_seasonSpin->SetRange(0,9999,1,5);
01402 m_seasonSpin->SetValue(m_recordingRule->m_season);
01403
01404
01405 m_episodeSpin->SetRange(0,9999,1,10);
01406 m_episodeSpin->SetValue(m_recordingRule->m_episode);
01407
01408 if (m_coverart)
01409 {
01410 m_coverart->SetFilename(m_artworkMap.value(kArtworkCoverart).url);
01411 m_coverart->Load();
01412 }
01413
01414 if (m_fanart)
01415 {
01416 m_fanart->SetFilename(m_artworkMap.value(kArtworkFanart).url);
01417 m_fanart->Load();
01418 }
01419
01420 if (m_banner)
01421 {
01422 m_banner->SetFilename(m_artworkMap.value(kArtworkBanner).url);
01423 m_banner->Load();
01424 }
01425
01426 BuildFocusList();
01427
01428 return true;
01429 }
01430
01431 void MetadataOptions::Load()
01432 {
01433 SetTextFromMaps();
01434 }
01435
01436 void MetadataOptions::CreateBusyDialog(QString title)
01437 {
01438 if (m_busyPopup)
01439 return;
01440
01441 QString message = title;
01442
01443 m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
01444 "metaoptsdialog");
01445
01446 if (m_busyPopup->Create())
01447 m_popupStack->AddScreen(m_busyPopup);
01448 }
01449
01450 void MetadataOptions::PerformQuery()
01451 {
01452 m_lookup = new MetadataLookup();
01453
01454 CreateBusyDialog(tr("Trying to manually find this "
01455 "recording online..."));
01456
01457 m_lookup->SetStep(kLookupSearch);
01458 m_lookup->SetType(kMetadataRecording);
01459 if (m_seasonSpin->GetIntValue() > 0 ||
01460 m_episodeSpin->GetIntValue() > 0)
01461 m_lookup->SetSubtype(kProbableTelevision);
01462 else
01463 m_lookup->SetSubtype(kProbableMovie);
01464 m_lookup->SetAllowGeneric(true);
01465 m_lookup->SetAutomatic(false);
01466 m_lookup->SetHandleImages(false);
01467 m_lookup->SetHost(gCoreContext->GetMasterHostName());
01468 m_lookup->SetTitle(m_recordingRule->m_title);
01469 m_lookup->SetSubtitle(m_recordingRule->m_subtitle);
01470 m_lookup->SetInetref(m_inetrefEdit->GetText());
01471 m_lookup->SetCollectionref(m_inetrefEdit->GetText());
01472 m_lookup->SetSeason(m_seasonSpin->GetIntValue());
01473 m_lookup->SetEpisode(m_episodeSpin->GetIntValue());
01474
01475 m_metadataFactory->Lookup(m_lookup);
01476 }
01477
01478 void MetadataOptions::OnSearchListSelection(MetadataLookup *lookup)
01479 {
01480 QueryComplete(lookup);
01481 }
01482
01483 void MetadataOptions::OnImageSearchListSelection(ArtworkInfo info,
01484 VideoArtworkType type)
01485 {
01486 QString msg = tr("Downloading selected artwork...");
01487 CreateBusyDialog(msg);
01488
01489 m_lookup = new MetadataLookup();
01490 m_lookup->SetType(kMetadataVideo);
01491 m_lookup->SetHost(gCoreContext->GetMasterHostName());
01492 m_lookup->SetAutomatic(true);
01493 m_lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
01494
01495 ArtworkMap downloads;
01496 downloads.insert(type, info);
01497 m_lookup->SetDownloads(downloads);
01498 m_lookup->SetAllowOverwrites(true);
01499 m_lookup->SetTitle(m_recordingRule->m_title);
01500 m_lookup->SetSubtitle(m_recordingRule->m_subtitle);
01501 m_lookup->SetInetref(m_inetrefEdit->GetText());
01502 m_lookup->SetSeason(m_seasonSpin->GetIntValue());
01503 m_lookup->SetEpisode(m_episodeSpin->GetIntValue());
01504
01505 m_imageDownload->addDownloads(m_lookup);
01506 }
01507
01508 void MetadataOptions::SelectLocalFanart()
01509 {
01510 if (!CanSetArtwork())
01511 return;
01512
01513 QString url = generate_file_url("Fanart",
01514 gCoreContext->GetMasterHostName(),
01515 "");
01516 FindImagePopup(url,"",*this, "fanart");
01517 }
01518
01519 void MetadataOptions::SelectLocalCoverart()
01520 {
01521 if (!CanSetArtwork())
01522 return;
01523
01524 QString url = generate_file_url("Coverart",
01525 gCoreContext->GetMasterHostName(),
01526 "");
01527 FindImagePopup(url,"",*this, "coverart");
01528 }
01529
01530 void MetadataOptions::SelectLocalBanner()
01531 {
01532 if (!CanSetArtwork())
01533 return;
01534
01535 QString url = generate_file_url("Banners",
01536 gCoreContext->GetMasterHostName(),
01537 "");
01538 FindImagePopup(url,"",*this, "banner");
01539 }
01540
01541 void MetadataOptions::SelectOnlineFanart()
01542 {
01543 FindNetArt(kArtworkFanart);
01544 }
01545
01546 void MetadataOptions::SelectOnlineCoverart()
01547 {
01548 FindNetArt(kArtworkCoverart);
01549 }
01550
01551 void MetadataOptions::SelectOnlineBanner()
01552 {
01553 FindNetArt(kArtworkBanner);
01554 }
01555
01556 void MetadataOptions::Save()
01557 {
01558
01559 if (m_seasonSpin)
01560 m_recordingRule->m_season = m_seasonSpin->GetIntValue();
01561
01562
01563 if (m_episodeSpin)
01564 m_recordingRule->m_episode = m_episodeSpin->GetIntValue();
01565
01566
01567 if (m_inetrefEdit)
01568 m_recordingRule->m_inetref = m_inetrefEdit->GetText();
01569 }
01570
01571 void MetadataOptions::QueryComplete(MetadataLookup *lookup)
01572 {
01573 if (!lookup)
01574 return;
01575
01576 m_lookup = lookup;
01577
01578
01579 m_inetrefEdit->SetText(m_lookup->GetInetref());
01580
01581
01582 m_seasonSpin->SetValue(m_lookup->GetSeason());
01583
01584
01585 m_episodeSpin->SetValue(m_lookup->GetEpisode());
01586
01587 MetadataMap metadataMap;
01588 lookup->toMap(metadataMap);
01589 SetTextFromMap(metadataMap);
01590 }
01591
01592 void MetadataOptions::FindImagePopup(const QString &prefix,
01593 const QString &prefixAlt,
01594 QObject &inst,
01595 const QString &returnEvent)
01596 {
01597 QString fp;
01598
01599 if (prefix.startsWith("myth://"))
01600 fp = prefix;
01601 else
01602 fp = prefix.isEmpty() ? prefixAlt : prefix;
01603
01604 MythScreenStack *popupStack =
01605 GetMythMainWindow()->GetStack("popup stack");
01606
01607 MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, fp);
01608 fb->SetNameFilter(GetSupportedImageExtensionFilter());
01609 if (fb->Create())
01610 {
01611 fb->SetReturnEvent(&inst, returnEvent);
01612 popupStack->AddScreen(fb);
01613 }
01614 else
01615 delete fb;
01616 }
01617
01618 QStringList MetadataOptions::GetSupportedImageExtensionFilter()
01619 {
01620 QStringList ret;
01621
01622 QList<QByteArray> exts = QImageReader::supportedImageFormats();
01623 for (QList<QByteArray>::iterator p = exts.begin(); p != exts.end(); ++p)
01624 {
01625 ret.append(QString("*.").append(*p));
01626 }
01627
01628 return ret;
01629 }
01630
01631 bool MetadataOptions::CanSetArtwork()
01632 {
01633 if (m_inetrefEdit->GetText().isEmpty())
01634 {
01635 ShowOkPopup(tr("You must set a reference number "
01636 "on this rule to set artwork. For items "
01637 "without a metadata source, you can set "
01638 "any unique value."));
01639 return false;
01640 }
01641
01642 return true;
01643 }
01644
01645 void MetadataOptions::FindNetArt(VideoArtworkType type)
01646 {
01647 if (!CanSetArtwork())
01648 return;
01649
01650 m_lookup = new MetadataLookup();
01651
01652 QString msg = tr("Searching for available artwork...");
01653 CreateBusyDialog(msg);
01654
01655 m_lookup->SetStep(kLookupSearch);
01656 m_lookup->SetType(kMetadataVideo);
01657 m_lookup->SetAutomatic(true);
01658 m_lookup->SetHandleImages(false);
01659 if (m_seasonSpin->GetIntValue() > 0 ||
01660 m_episodeSpin->GetIntValue() > 0)
01661 m_lookup->SetSubtype(kProbableTelevision);
01662 else
01663 m_lookup->SetSubtype(kProbableMovie);
01664 m_lookup->SetAllowGeneric(true);
01665 m_lookup->SetData(qVariantFromValue<VideoArtworkType>(type));
01666 m_lookup->SetHost(gCoreContext->GetMasterHostName());
01667 m_lookup->SetTitle(m_recordingRule->m_title);
01668 m_lookup->SetSubtitle(m_recordingRule->m_subtitle);
01669 m_lookup->SetInetref(m_inetrefEdit->GetText());
01670 m_lookup->SetCollectionref(m_inetrefEdit->GetText());
01671 m_lookup->SetSeason(m_seasonSpin->GetIntValue());
01672 m_lookup->SetEpisode(m_episodeSpin->GetIntValue());
01673
01674 m_imageLookup->addLookup(m_lookup);
01675 }
01676
01677 void MetadataOptions::OnArtworkSearchDone(MetadataLookup *lookup)
01678 {
01679 if (!lookup)
01680 return;
01681
01682 if (m_busyPopup)
01683 {
01684 m_busyPopup->Close();
01685 m_busyPopup = NULL;
01686 }
01687
01688 VideoArtworkType type = qVariantValue<VideoArtworkType>(lookup->GetData());
01689 ArtworkList list = lookup->GetArtwork(type);
01690
01691 if (list.count() == 0)
01692 return;
01693
01694 ImageSearchResultsDialog *resultsdialog =
01695 new ImageSearchResultsDialog(m_popupStack, list, type);
01696
01697 connect(resultsdialog, SIGNAL(haveResult(ArtworkInfo, VideoArtworkType)),
01698 SLOT(OnImageSearchListSelection(ArtworkInfo, VideoArtworkType)));
01699
01700 if (resultsdialog->Create())
01701 m_popupStack->AddScreen(resultsdialog);
01702 }
01703
01704 void MetadataOptions::HandleDownloadedImages(MetadataLookup *lookup)
01705 {
01706 if (!lookup)
01707 return;
01708
01709 DownloadMap map = lookup->GetDownloads();
01710
01711 if (!map.size())
01712 return;
01713
01714 for (DownloadMap::const_iterator i = map.begin(); i != map.end(); ++i)
01715 {
01716 VideoArtworkType type = i.key();
01717 ArtworkInfo info = i.value();
01718
01719 if (type == kArtworkCoverart)
01720 m_artworkMap.replace(kArtworkCoverart, info);
01721 else if (type == kArtworkFanart)
01722 m_artworkMap.replace(kArtworkFanart, info);
01723 else if (type == kArtworkBanner)
01724 m_artworkMap.replace(kArtworkBanner, info);
01725 }
01726
01727 SetArtwork(m_inetrefEdit->GetText(), m_seasonSpin->GetIntValue(),
01728 gCoreContext->GetMasterHostName(), m_artworkMap);
01729
01730 ValuesChanged();
01731 }
01732
01733 void MetadataOptions::ValuesChanged()
01734 {
01735 m_artworkMap = GetArtwork(m_inetrefEdit->GetText(),
01736 m_seasonSpin->GetIntValue());
01737
01738 if (m_coverart)
01739 {
01740 m_coverart->SetFilename(m_artworkMap.value(kArtworkCoverart).url);
01741 m_coverart->Load();
01742 }
01743
01744 if (m_fanart)
01745 {
01746 m_fanart->SetFilename(m_artworkMap.value(kArtworkFanart).url);
01747 m_fanart->Load();
01748 }
01749
01750 if (m_banner)
01751 {
01752 m_banner->SetFilename(m_artworkMap.value(kArtworkBanner).url);
01753 m_banner->Load();
01754 }
01755 }
01756
01757 void MetadataOptions::customEvent(QEvent *levent)
01758 {
01759 if (levent->type() == MetadataFactoryMultiResult::kEventType)
01760 {
01761 if (m_busyPopup)
01762 {
01763 m_busyPopup->Close();
01764 m_busyPopup = NULL;
01765 }
01766
01767 MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent);
01768
01769 if (!mfmr)
01770 return;
01771
01772 MetadataLookupList list = mfmr->results;
01773
01774 if (list.count() > 1)
01775 {
01776 int yearindex = -1;
01777
01778 for (int p = 0; p != list.size(); ++p)
01779 {
01780 if (!m_recordingRule->m_seriesid.isEmpty() &&
01781 m_recordingRule->m_seriesid == (list[p])->GetTMSref())
01782 {
01783 MetadataLookup *lookup = list.takeAt(p);
01784 QueryComplete(lookup);
01785 qDeleteAll(list);
01786 return;
01787 }
01788 else if (m_recInfo &&
01789 m_recInfo->GetYearOfInitialRelease() != 0 &&
01790 (list[p])->GetYear() != 0 &&
01791 m_recInfo->GetYearOfInitialRelease() == (list[p])->GetYear())
01792 {
01793 if (yearindex > -1)
01794 {
01795 LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite "
01796 "match could be found based on year alone.");
01797 yearindex = -2;
01798 }
01799 else if (yearindex == -1)
01800 {
01801 LOG(VB_GENERAL, LOG_INFO, "Matched based on year. ");
01802 yearindex = p;
01803 }
01804 }
01805 }
01806
01807 if (yearindex > -1)
01808 {
01809 MetadataLookup *lookup = list.takeAt(yearindex);
01810 QueryComplete(lookup);
01811 qDeleteAll(list);
01812 return;
01813 }
01814
01815 LOG(VB_GENERAL, LOG_INFO, "Falling through to selection dialog.");
01816 MetadataResultsDialog *resultsdialog =
01817 new MetadataResultsDialog(m_popupStack, list);
01818
01819 connect(resultsdialog, SIGNAL(haveResult(MetadataLookup*)),
01820 SLOT(OnSearchListSelection(MetadataLookup*)),
01821 Qt::QueuedConnection);
01822
01823 if (resultsdialog->Create())
01824 m_popupStack->AddScreen(resultsdialog);
01825 }
01826 }
01827 else if (levent->type() == MetadataFactorySingleResult::kEventType)
01828 {
01829 if (m_busyPopup)
01830 {
01831 m_busyPopup->Close();
01832 m_busyPopup = NULL;
01833 }
01834
01835 MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent);
01836
01837 if (!mfsr)
01838 return;
01839
01840 MetadataLookup *lookup = mfsr->result;
01841
01842 if (!lookup)
01843 return;
01844
01845 QueryComplete(lookup);
01846 }
01847 else if (levent->type() == MetadataFactoryNoResult::kEventType)
01848 {
01849 if (m_busyPopup)
01850 {
01851 m_busyPopup->Close();
01852 m_busyPopup = NULL;
01853 }
01854
01855 MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent);
01856
01857 if (!mfnr)
01858 return;
01859
01860 MetadataLookup *lookup = mfnr->result;
01861
01862 delete lookup;
01863 lookup = NULL;
01864
01865 QString title = tr("No match found for this recording. You can "
01866 "try entering a TVDB/TMDB number, season, and "
01867 "episode manually.");
01868
01869 MythConfirmationDialog *okPopup =
01870 new MythConfirmationDialog(m_popupStack, title, false);
01871
01872 if (okPopup->Create())
01873 m_popupStack->AddScreen(okPopup);
01874 }
01875 else if (levent->type() == MetadataLookupEvent::kEventType)
01876 {
01877 if (m_busyPopup)
01878 {
01879 m_busyPopup->Close();
01880 m_busyPopup = NULL;
01881 }
01882
01883 MetadataLookupEvent *lue = (MetadataLookupEvent *)levent;
01884
01885 MetadataLookupList lul = lue->lookupList;
01886
01887 if (lul.isEmpty())
01888 return;
01889
01890 if (lul.count() >= 1)
01891 {
01892 OnArtworkSearchDone(lul.takeFirst());
01893 }
01894 }
01895 else if (levent->type() == MetadataLookupFailure::kEventType)
01896 {
01897 if (m_busyPopup)
01898 {
01899 m_busyPopup->Close();
01900 m_busyPopup = NULL;
01901 }
01902
01903 MetadataLookupFailure *luf = (MetadataLookupFailure *)levent;
01904
01905 MetadataLookupList lul = luf->lookupList;
01906
01907 if (lul.size())
01908 {
01909 MetadataLookup *lookup = lul.takeFirst();
01910
01911 QString title = tr("This number, season, and episode combination "
01912 "does not appear to be valid (or the site may "
01913 "be down). Check your information and try "
01914 "again.");
01915
01916 MythConfirmationDialog *okPopup =
01917 new MythConfirmationDialog(m_popupStack, title, false);
01918
01919 if (okPopup->Create())
01920 m_popupStack->AddScreen(okPopup);
01921
01922 delete lookup;
01923 lookup = NULL;
01924 }
01925 }
01926 else if (levent->type() == ImageDLEvent::kEventType)
01927 {
01928 if (m_busyPopup)
01929 {
01930 m_busyPopup->Close();
01931 m_busyPopup = NULL;
01932 }
01933
01934 ImageDLEvent *ide = (ImageDLEvent *)levent;
01935
01936 MetadataLookup *lookup = ide->item;
01937
01938 if (!lookup)
01939 return;
01940
01941 HandleDownloadedImages(lookup);
01942 }
01943 else if (levent->type() == ImageDLFailureEvent::kEventType)
01944 {
01945 if (m_busyPopup)
01946 {
01947 m_busyPopup->Close();
01948 m_busyPopup = NULL;
01949 }
01950
01951 ImageDLFailureEvent *ide = (ImageDLFailureEvent *)levent;
01952
01953 MetadataLookup *lookup = ide->item;
01954
01955 if (!lookup)
01956 return;
01957
01958 delete lookup;
01959 lookup = NULL;
01960 }
01961 else if (levent->type() == DialogCompletionEvent::kEventType)
01962 {
01963 DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent);
01964
01965 const QString resultid = dce->GetId();
01966 ArtworkInfo info;
01967 info.url = dce->GetResultText();
01968
01969 if (resultid == "coverart")
01970 {
01971 m_artworkMap.replace(kArtworkCoverart, info);
01972 }
01973 else if (resultid == "fanart")
01974 {
01975 m_artworkMap.replace(kArtworkFanart, info);
01976 }
01977 else if (resultid == "banner")
01978 {
01979 m_artworkMap.replace(kArtworkBanner, info);
01980 }
01981
01982 SetArtwork(m_inetrefEdit->GetText(), m_seasonSpin->GetIntValue(),
01983 gCoreContext->GetMasterHostName(), m_artworkMap);
01984
01985 ValuesChanged();
01986 }
01987
01988 }
01989
01991
01997 SchedOptMixin::SchedOptMixin(MythScreenType &screen, RecordingRule *rule,
01998 SchedOptMixin *other)
01999 : m_prioritySpin(NULL), m_startoffsetSpin(NULL), m_endoffsetSpin(NULL),
02000 m_dupmethodList(NULL), m_dupscopeList(NULL), m_inputList(NULL),
02001 m_ruleactiveCheck(NULL), m_newrepeatList(NULL),
02002 m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false),
02003 m_haveRepeats(gCoreContext->GetNumSetting("HaveRepeats", 0))
02004 {
02005 }
02006
02007 void SchedOptMixin::Create(bool *err)
02008 {
02009 if (!m_rule)
02010 return;
02011
02012 if (m_other && !m_other->m_prioritySpin)
02013 UIUtilE::Assign(m_screen, m_prioritySpin, "priority", err);
02014 else
02015 UIUtilW::Assign(m_screen, m_prioritySpin, "priority");
02016
02017 if (m_other && !m_other->m_startoffsetSpin)
02018 UIUtilE::Assign(m_screen, m_startoffsetSpin, "startoffset", err);
02019 else
02020 UIUtilW::Assign(m_screen, m_startoffsetSpin, "startoffset");
02021
02022 if (m_other && !m_other->m_endoffsetSpin)
02023 UIUtilE::Assign(m_screen, m_endoffsetSpin, "endoffset", err);
02024 else
02025 UIUtilW::Assign(m_screen, m_endoffsetSpin, "endoffset");
02026
02027 if (m_other && !m_other->m_dupmethodList)
02028 UIUtilE::Assign(m_screen, m_dupmethodList, "dupmethod", err);
02029 else
02030 UIUtilW::Assign(m_screen, m_dupmethodList, "dupmethod");
02031
02032 if (m_other && !m_other->m_dupscopeList)
02033 UIUtilE::Assign(m_screen, m_dupscopeList, "dupscope", err);
02034 else
02035 UIUtilW::Assign(m_screen, m_dupscopeList, "dupscope");
02036
02037 if (m_other && !m_other->m_inputList)
02038 UIUtilE::Assign(m_screen, m_inputList, "input", err);
02039 else
02040 UIUtilW::Assign(m_screen, m_inputList, "input");
02041
02042 if (m_other && !m_other->m_ruleactiveCheck)
02043 UIUtilE::Assign(m_screen, m_ruleactiveCheck, "ruleactive", err);
02044 else
02045 UIUtilW::Assign(m_screen, m_ruleactiveCheck, "ruleactive");
02046
02047 UIUtilW::Assign(m_screen, m_newrepeatList, "newrepeat");
02048 }
02049
02050 void SchedOptMixin::Load(void)
02051 {
02052 if (!m_rule)
02053 return;
02054
02055
02056 if (m_prioritySpin)
02057 {
02058 if (!m_loaded)
02059 m_prioritySpin->SetRange(-99,99,1,5);
02060 m_prioritySpin->SetValue(m_rule->m_recPriority);
02061 }
02062
02063
02064 if (m_startoffsetSpin)
02065 {
02066 if (!m_loaded)
02067 m_startoffsetSpin->SetRange(480,-480,1,10);
02068 m_startoffsetSpin->SetValue(m_rule->m_startOffset);
02069 }
02070
02071
02072 if (m_endoffsetSpin)
02073 {
02074 if (!m_loaded)
02075 m_endoffsetSpin->SetRange(-480,480,1,10);
02076 m_endoffsetSpin->SetValue(m_rule->m_endOffset);
02077 }
02078
02079
02080 if (m_dupmethodList)
02081 {
02082 if (!m_loaded)
02083 {
02084 RecordingDupMethodType dupMethod = m_rule->m_dupMethod;
02085
02086 new MythUIButtonListItem(m_dupmethodList,
02087 QObject::tr("Match duplicates using subtitle & description"),
02088 ENUM_TO_QVARIANT(kDupCheckSubDesc));
02089 new MythUIButtonListItem(m_dupmethodList,
02090 QObject::tr("Match duplicates using subtitle then description"),
02091 ENUM_TO_QVARIANT(kDupCheckSubThenDesc));
02092 new MythUIButtonListItem(m_dupmethodList,
02093 QObject::tr("Match duplicates using subtitle"),
02094 ENUM_TO_QVARIANT(kDupCheckSub));
02095 new MythUIButtonListItem(m_dupmethodList,
02096 QObject::tr("Match duplicates using description"),
02097 ENUM_TO_QVARIANT(kDupCheckDesc));
02098 new MythUIButtonListItem(m_dupmethodList,
02099 QObject::tr("Don't match duplicates"),
02100 ENUM_TO_QVARIANT(kDupCheckNone));
02101
02102 m_rule->m_dupMethod = dupMethod;
02103 }
02104 m_dupmethodList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupMethod));
02105 }
02106
02107
02108 if (m_dupscopeList)
02109 {
02110 if (!m_loaded)
02111 {
02112 new MythUIButtonListItem(m_dupscopeList,
02113 QObject::tr("Look for duplicates in current and previous "
02114 "recordings"), ENUM_TO_QVARIANT(kDupsInAll));
02115 new MythUIButtonListItem(m_dupscopeList,
02116 QObject::tr("Look for duplicates in current recordings only"),
02117 ENUM_TO_QVARIANT(kDupsInRecorded));
02118 new MythUIButtonListItem(m_dupscopeList,
02119 QObject::tr("Look for duplicates in previous recordings only"),
02120 ENUM_TO_QVARIANT(kDupsInOldRecorded));
02121 if (m_haveRepeats && !m_newrepeatList &&
02122 (!m_other || !m_other->m_newrepeatList))
02123 {
02124 new MythUIButtonListItem(m_dupscopeList,
02125 QObject::tr("Record new episodes only"),
02126 ENUM_TO_QVARIANT(kDupsNewEpi|kDupsInAll));
02127 }
02128 }
02129 m_dupscopeList->SetValueByData(ENUM_TO_QVARIANT(m_rule->m_dupIn));
02130 }
02131
02132
02133 if (m_inputList)
02134 {
02135 if (!m_loaded)
02136 {
02137 new MythUIButtonListItem(m_inputList,
02138 QObject::tr("Use any available input"),
02139 qVariantFromValue(0));
02140
02141 vector<uint> inputids = CardUtil::GetAllInputIDs();
02142 for (uint i = 0; i < inputids.size(); ++i)
02143 {
02144 new MythUIButtonListItem(m_inputList,
02145 QObject::tr("Prefer input %1")
02146 .arg(CardUtil::GetDisplayName(inputids[i])), inputids[i]);
02147 }
02148 }
02149 m_inputList->SetValueByData(m_rule->m_prefInput);
02150 }
02151
02152
02153 if (m_ruleactiveCheck)
02154 {
02155 m_ruleactiveCheck->SetCheckState(!m_rule->m_isInactive);
02156 }
02157
02158
02159 if (m_newrepeatList)
02160 {
02161 if (!m_loaded)
02162 {
02163 new MythUIButtonListItem(m_newrepeatList,
02164 QObject::tr("Record new and repeat "
02165 "episodes"), ENUM_TO_QVARIANT(0));
02166 new MythUIButtonListItem(m_newrepeatList,
02167 QObject::tr("Record new episodes only"),
02168 ENUM_TO_QVARIANT(kDupsNewEpi));
02169 }
02170 m_newrepeatList->SetValueByData(ENUM_TO_QVARIANT
02171 (m_rule->m_dupIn & kDupsNewEpi));
02172 }
02173
02174 m_loaded = true;
02175
02176 RuleChanged();
02177 }
02178
02179 void SchedOptMixin::Save(void)
02180 {
02181 if (!m_rule)
02182 return;
02183
02184 if (m_prioritySpin)
02185 m_rule->m_recPriority = m_prioritySpin->GetIntValue();
02186 if (m_startoffsetSpin)
02187 m_rule->m_startOffset = m_startoffsetSpin->GetIntValue();
02188 if (m_endoffsetSpin)
02189 m_rule->m_endOffset = m_endoffsetSpin->GetIntValue();
02190 if (m_dupmethodList)
02191 m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
02192 (m_dupmethodList->GetDataValue().toInt());
02193 if (m_dupscopeList)
02194 {
02195 int mask = ((m_other && m_other->m_newrepeatList) ||
02196 m_newrepeatList) ? kDupsInAll : ~0;
02197 int val = ((m_rule->m_dupIn & ~mask) |
02198 m_dupscopeList->GetDataValue().toInt());
02199 m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
02200 }
02201 if (m_inputList)
02202 m_rule->m_prefInput = m_inputList->GetDataValue().toInt();
02203 if (m_ruleactiveCheck)
02204 m_rule->m_isInactive = !m_ruleactiveCheck->GetBooleanCheckState();
02205 if (m_newrepeatList)
02206 {
02207 int val = ((m_rule->m_dupIn & ~kDupsNewEpi) |
02208 m_newrepeatList->GetDataValue().toInt());
02209 m_rule->m_dupIn = static_cast<RecordingDupInType>(val);
02210 }
02211 }
02212
02213 void SchedOptMixin::RuleChanged(void)
02214 {
02215 if (!m_rule)
02216 return;
02217
02218 bool isScheduled = (m_rule->m_type != kNotRecording &&
02219 m_rule->m_type != kDontRecord);
02220 bool isSingle = (m_rule->m_type == kSingleRecord ||
02221 m_rule->m_type == kOverrideRecord);
02222
02223 if (m_prioritySpin)
02224 m_prioritySpin->SetEnabled(isScheduled);
02225 if (m_startoffsetSpin)
02226 m_startoffsetSpin->SetEnabled(isScheduled);
02227 if (m_endoffsetSpin)
02228 m_endoffsetSpin->SetEnabled(isScheduled);
02229 if (m_dupmethodList)
02230 m_dupmethodList->SetEnabled(isScheduled && !isSingle);
02231 if (m_dupscopeList)
02232 m_dupscopeList->SetEnabled(isScheduled && !isSingle &&
02233 m_rule->m_dupMethod != kDupCheckNone);
02234 if (m_inputList)
02235 m_inputList->SetEnabled(isScheduled);
02236 if (m_ruleactiveCheck)
02237 m_ruleactiveCheck->SetEnabled(isScheduled);
02238 if (m_newrepeatList)
02239 m_newrepeatList->SetEnabled(isScheduled && !isSingle && m_haveRepeats);
02240 }
02241
02242 void SchedOptMixin::DupMethodChanged(MythUIButtonListItem *item)
02243 {
02244 if (!item || !m_rule)
02245 return;
02246
02247 m_rule->m_dupMethod = static_cast<RecordingDupMethodType>
02248 (item->GetData().toInt());
02249
02250 if (m_dupscopeList)
02251 m_dupscopeList->SetEnabled(m_rule->m_dupMethod != kDupCheckNone);
02252 }
02253
02255
02261 StoreOptMixin::StoreOptMixin(MythScreenType &screen, RecordingRule *rule,
02262 StoreOptMixin *other)
02263 : m_recprofileList(NULL), m_recgroupList(NULL), m_storagegroupList(NULL),
02264 m_playgroupList(NULL), m_maxepSpin(NULL), m_maxbehaviourList(NULL),
02265 m_autoexpireCheck(NULL),
02266 m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
02267 {
02268 }
02269
02270 void StoreOptMixin::Create(bool *err)
02271 {
02272 if (!m_rule)
02273 return;
02274
02275 if (m_other && !m_other->m_recprofileList)
02276 UIUtilE::Assign(m_screen, m_recprofileList, "recprofile", err);
02277 else
02278 UIUtilW::Assign(m_screen, m_recprofileList, "recprofile");
02279
02280 if (m_other && !m_other->m_recgroupList)
02281 UIUtilE::Assign(m_screen, m_recgroupList, "recgroup", err);
02282 else
02283 UIUtilW::Assign(m_screen, m_recgroupList, "recgroup");
02284
02285 if (m_other && !m_other->m_storagegroupList)
02286 UIUtilE::Assign(m_screen, m_storagegroupList, "storagegroup", err);
02287 else
02288 UIUtilW::Assign(m_screen, m_storagegroupList, "storagegroup");
02289
02290 if (m_other && !m_other->m_playgroupList)
02291 UIUtilE::Assign(m_screen, m_playgroupList, "playgroup", err);
02292 else
02293 UIUtilW::Assign(m_screen, m_playgroupList, "playgroup");
02294
02295 if (m_other && !m_other->m_maxepSpin)
02296 UIUtilE::Assign(m_screen, m_maxepSpin, "maxepisodes", err);
02297 else
02298 UIUtilW::Assign(m_screen, m_maxepSpin, "maxepisodes");
02299
02300 if (m_other && !m_other->m_maxbehaviourList)
02301 UIUtilE::Assign(m_screen, m_maxbehaviourList, "maxnewest", err);
02302 else
02303 UIUtilW::Assign(m_screen, m_maxbehaviourList, "maxnewest");
02304
02305 if (m_other && !m_other->m_autoexpireCheck)
02306 UIUtilE::Assign(m_screen, m_autoexpireCheck, "autoexpire", err);
02307 else
02308 UIUtilW::Assign(m_screen, m_autoexpireCheck, "autoexpire");
02309 }
02310
02311 void StoreOptMixin::Load(void)
02312 {
02313 if (!m_rule)
02314 return;
02315
02316 QString label;
02317 QStringList groups;
02318 QStringList::Iterator it;
02319 MSqlQuery query(MSqlQuery::InitCon());
02320
02321
02322 if (m_recprofileList)
02323 {
02324 if (!m_loaded)
02325 {
02326 label = QObject::tr("Record using the %1 profile");
02327 QMap<int, QString> profiles = RecordingProfile::listProfiles(0);
02328 QMap<int, QString>::iterator pit;
02329 for (pit = profiles.begin(); pit != profiles.end(); ++pit)
02330 {
02331 new MythUIButtonListItem(m_recprofileList,
02332 label.arg(pit.value()),
02333 qVariantFromValue(pit.value()));
02334 }
02335 }
02336 m_recprofileList->SetValueByData(m_rule->m_recProfile);
02337 }
02338
02339
02340 if (m_recgroupList)
02341 {
02342 if (!m_loaded)
02343 {
02344 label = QObject::tr("Include in the \"%1\" recording group");
02345 new MythUIButtonListItem(m_recgroupList,
02346 QObject::tr("Create a new recording group"),
02347 qVariantFromValue(QString("__NEW_GROUP__")));
02348 new MythUIButtonListItem(m_recgroupList,
02349 label.arg(QObject::tr("Default")),
02350 qVariantFromValue(QString("Default")));
02351
02352 groups.clear();
02353 if (m_rule->m_recGroup != "Default" &&
02354 m_rule->m_recGroup != "__NEW_GROUP__")
02355 groups << m_rule->m_recGroup;
02356 query.prepare("SELECT DISTINCT recgroup FROM recorded "
02357 "WHERE recgroup <> 'Default' AND "
02358 " recgroup <> 'Deleted'");
02359 if (query.exec())
02360 {
02361 while (query.next())
02362 groups += query.value(0).toString();
02363 }
02364 query.prepare("SELECT DISTINCT recgroup FROM record "
02365 "WHERE recgroup <> 'Default'");
02366 if (query.exec())
02367 {
02368 while (query.next())
02369 groups += query.value(0).toString();
02370 }
02371
02372 groups.sort();
02373 groups.removeDuplicates();
02374 for (it = groups.begin(); it != groups.end(); ++it)
02375 {
02376 new MythUIButtonListItem(m_recgroupList, label.arg(*it),
02377 qVariantFromValue(*it));
02378 }
02379 }
02380 m_recgroupList->SetValueByData(m_rule->m_recGroup);
02381 }
02382
02383
02384 if (m_storagegroupList)
02385 {
02386 if (!m_loaded)
02387 {
02388 label = QObject::tr("Store in the \"%1\" storage group");
02389 new MythUIButtonListItem(m_storagegroupList,
02390 label.arg(QObject::tr("Default")),
02391 qVariantFromValue(QString("Default")));
02392
02393 groups = StorageGroup::getRecordingsGroups();
02394 for (it = groups.begin(); it != groups.end(); ++it)
02395 {
02396 if ((*it).compare("Default", Qt::CaseInsensitive) != 0)
02397 new MythUIButtonListItem(m_storagegroupList,
02398 label.arg(*it), qVariantFromValue(*it));
02399 }
02400 }
02401 m_storagegroupList->SetValueByData(m_rule->m_storageGroup);
02402 }
02403
02404
02405 if (m_playgroupList)
02406 {
02407 if (!m_loaded)
02408 {
02409 label = QObject::tr("Use \"%1\" playback group settings");
02410 new MythUIButtonListItem(m_playgroupList,
02411 label.arg(QObject::tr("Default")),
02412 qVariantFromValue(QString("Default")));
02413
02414 groups = PlayGroup::GetNames();
02415 for (it = groups.begin(); it != groups.end(); ++it)
02416 {
02417 new MythUIButtonListItem(m_playgroupList, label.arg(*it),
02418 qVariantFromValue(*it));
02419 }
02420 }
02421 m_playgroupList->SetValueByData(m_rule->m_playGroup);
02422 }
02423
02424
02425 if (m_maxepSpin)
02426 {
02427 if (!m_loaded)
02428 {
02429 int maxEpisodes = m_rule->m_maxEpisodes;
02430 m_maxepSpin->SetRange(0,100,1,5);
02431 m_rule->m_maxEpisodes = maxEpisodes;
02432 }
02433 m_maxepSpin->SetValue(m_rule->m_maxEpisodes);
02434 }
02435
02436
02437 if (m_maxbehaviourList)
02438 {
02439 if (!m_loaded)
02440 {
02441 new MythUIButtonListItem(m_maxbehaviourList,
02442 QObject::tr("Don't record if this would exceed the max "
02443 "episodes"), qVariantFromValue(false));
02444 new MythUIButtonListItem(m_maxbehaviourList,
02445 QObject::tr("Delete oldest if this would exceed the max "
02446 "episodes"), qVariantFromValue(true));
02447 }
02448 m_maxbehaviourList->SetValueByData(m_rule->m_maxNewest);
02449 }
02450
02451
02452 if (m_autoexpireCheck)
02453 {
02454 m_autoexpireCheck->SetCheckState(m_rule->m_autoExpire);
02455 }
02456
02457 m_loaded = true;
02458
02459 RuleChanged();
02460 }
02461
02462 void StoreOptMixin::Save(void)
02463 {
02464 if (!m_rule)
02465 return;
02466
02467 if (m_recprofileList)
02468 m_rule->m_recProfile = m_recprofileList->GetDataValue().toString();
02469
02470 if (m_recgroupList)
02471 {
02472
02473
02474 if (m_recgroupList->GetDataValue().toString() == "__NEW_GROUP__")
02475 m_recgroupList->SetValueByData(m_rule->m_recGroup);
02476 m_rule->m_recGroup = m_recgroupList->GetDataValue().toString();
02477 }
02478
02479 if (m_storagegroupList)
02480 m_rule->m_storageGroup = m_storagegroupList->GetDataValue().toString();
02481
02482 if (m_playgroupList)
02483 m_rule->m_playGroup = m_playgroupList->GetDataValue().toString();
02484
02485 if (m_maxepSpin)
02486 m_rule->m_maxEpisodes = m_maxepSpin->GetIntValue();
02487
02488 if (m_maxbehaviourList)
02489 m_rule->m_maxNewest = m_maxbehaviourList->GetDataValue().toBool();
02490
02491 if (m_autoexpireCheck)
02492 m_rule->m_autoExpire = m_autoexpireCheck->GetBooleanCheckState();
02493 }
02494
02495 void StoreOptMixin::RuleChanged(void)
02496 {
02497 if (!m_rule)
02498 return;
02499
02500 bool isScheduled = (m_rule->m_type != kNotRecording &&
02501 m_rule->m_type != kDontRecord);
02502 bool isSingle = (m_rule->m_type == kSingleRecord ||
02503 m_rule->m_type == kOverrideRecord);
02504
02505 if (m_recprofileList)
02506 m_recprofileList->SetEnabled(isScheduled);
02507 if (m_recgroupList)
02508 m_recgroupList->SetEnabled(isScheduled);
02509 if (m_storagegroupList)
02510 m_storagegroupList->SetEnabled(isScheduled);
02511 if (m_playgroupList)
02512 m_playgroupList->SetEnabled(isScheduled);
02513 if (m_maxepSpin)
02514 m_maxepSpin->SetEnabled(isScheduled && !isSingle);
02515 if (m_maxbehaviourList)
02516 m_maxbehaviourList->SetEnabled(isScheduled && !isSingle &&
02517 m_rule->m_maxEpisodes != 0);
02518 if (m_autoexpireCheck)
02519 m_autoexpireCheck->SetEnabled(isScheduled);
02520 }
02521
02522 void StoreOptMixin::MaxEpisodesChanged(MythUIButtonListItem *item)
02523 {
02524 if (!item || !m_rule)
02525 return;
02526
02527 m_rule->m_maxEpisodes = item->GetData().toInt();
02528
02529 if (m_maxbehaviourList)
02530 m_maxbehaviourList->SetEnabled(m_rule->m_maxEpisodes != 0);
02531 }
02532
02533 void StoreOptMixin::PromptForRecGroup(void)
02534 {
02535 if (!m_rule)
02536 return;
02537
02538 if (m_recgroupList->GetDataValue().toString() != "__NEW_GROUP__")
02539 return;
02540
02541 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
02542
02543 QString label =
02544 QObject::tr("Create New Recording Group. Enter group name: ");
02545
02546 MythTextInputDialog *textDialog =
02547 new MythTextInputDialog(popupStack, label,
02548 static_cast<InputFilter>(FilterSymbols | FilterPunct));
02549
02550 textDialog->SetReturnEvent(m_screen, "newrecgroup");
02551
02552 if (textDialog->Create())
02553 popupStack->AddScreen(textDialog, false);
02554 }
02555
02556 void StoreOptMixin::SetRecGroup(QString recgroup)
02557 {
02558 if (!m_rule)
02559 return;
02560
02561 if (m_recgroupList)
02562 {
02563 recgroup = recgroup.trimmed();
02564 if (recgroup.isEmpty())
02565 return;
02566
02567 QString label = QObject::tr("Include in the \"%1\" recording group");
02568 MythUIButtonListItem *item =
02569 new MythUIButtonListItem(m_recgroupList, label.arg(recgroup),
02570 qVariantFromValue(recgroup));
02571 m_recgroupList->SetItemCurrent(item);
02572
02573 if (m_other && m_other->m_recgroupList)
02574 {
02575 item = new MythUIButtonListItem(m_other->m_recgroupList,
02576 label.arg(recgroup), qVariantFromValue(recgroup));
02577 m_other->m_recgroupList->SetItemCurrent(item);
02578 }
02579 }
02580 }
02581
02583
02589 PostProcMixin::PostProcMixin(MythScreenType &screen, RecordingRule *rule,
02590 PostProcMixin *other)
02591 : m_commflagCheck(NULL), m_transcodeCheck(NULL),
02592 m_transcodeprofileList(NULL), m_userjob1Check(NULL),
02593 m_userjob2Check(NULL), m_userjob3Check(NULL), m_userjob4Check(NULL),
02594 m_metadataLookupCheck(NULL),
02595 m_screen(&screen), m_rule(rule), m_other(other), m_loaded(false)
02596 {
02597 }
02598
02599 void PostProcMixin::Create(bool *err)
02600 {
02601 if (!m_rule)
02602 return;
02603
02604 if (m_other && !m_other->m_commflagCheck)
02605 UIUtilE::Assign(m_screen, m_commflagCheck, "autocommflag", err);
02606 else
02607 UIUtilW::Assign(m_screen, m_commflagCheck, "autocommflag");
02608
02609 if (m_other && !m_other->m_transcodeCheck)
02610 UIUtilE::Assign(m_screen, m_transcodeCheck, "autotranscode", err);
02611 else
02612 UIUtilW::Assign(m_screen, m_transcodeCheck, "autotranscode");
02613
02614 if (m_other && !m_other->m_transcodeprofileList)
02615 UIUtilE::Assign(m_screen, m_transcodeprofileList, "transcodeprofile", err);
02616 else
02617 UIUtilW::Assign(m_screen, m_transcodeprofileList, "transcodeprofile");
02618
02619 if (m_other && !m_other->m_userjob1Check)
02620 UIUtilE::Assign(m_screen, m_userjob1Check, "userjob1", err);
02621 else
02622 UIUtilW::Assign(m_screen, m_userjob1Check, "userjob1");
02623
02624 if (m_other && !m_other->m_userjob2Check)
02625 UIUtilE::Assign(m_screen, m_userjob2Check, "userjob2", err);
02626 else
02627 UIUtilW::Assign(m_screen, m_userjob2Check, "userjob2");
02628
02629 if (m_other && !m_other->m_userjob3Check)
02630 UIUtilE::Assign(m_screen, m_userjob3Check, "userjob3", err);
02631 else
02632 UIUtilW::Assign(m_screen, m_userjob3Check, "userjob3");
02633
02634 if (m_other && !m_other->m_userjob4Check)
02635 UIUtilE::Assign(m_screen, m_userjob4Check, "userjob4", err);
02636 else
02637 UIUtilW::Assign(m_screen, m_userjob4Check, "userjob4");
02638
02639 UIUtilW::Assign(m_screen, m_metadataLookupCheck, "metadatalookup");
02640 }
02641
02642 void PostProcMixin::Load(void)
02643 {
02644 if (!m_rule)
02645 return;
02646
02647
02648 if (m_commflagCheck)
02649 {
02650 m_commflagCheck->SetCheckState(m_rule->m_autoCommFlag);
02651 }
02652
02653
02654 if (m_transcodeCheck)
02655 {
02656 m_transcodeCheck->SetCheckState(m_rule->m_autoTranscode);
02657 }
02658
02659
02660 if (m_transcodeprofileList)
02661 {
02662 if (!m_loaded)
02663 {
02664 QMap<int, QString> profiles =
02665 RecordingProfile::listProfiles(RecordingProfile::TranscoderGroup);
02666 QMap<int, QString>::iterator it;
02667 for (it = profiles.begin(); it != profiles.end(); ++it)
02668 {
02669 new MythUIButtonListItem(m_transcodeprofileList, it.value(),
02670 qVariantFromValue(it.key()));
02671 }
02672 }
02673 m_transcodeprofileList->SetValueByData(m_rule->m_transcoder);
02674 }
02675
02676
02677 if (m_userjob1Check)
02678 {
02679 if (!m_loaded)
02680 {
02681 MythUIText *userjob1Text = NULL;
02682 UIUtilW::Assign(m_screen, userjob1Text, "userjob1text");
02683 if (userjob1Text)
02684 userjob1Text->SetText(QObject::tr("Run '%1'")
02685 .arg(gCoreContext->GetSetting("UserJobDesc1"), "User Job 1"));
02686 }
02687 m_userjob1Check->SetCheckState(m_rule->m_autoUserJob1);
02688 }
02689
02690
02691 if (m_userjob2Check)
02692 {
02693 if (!m_loaded)
02694 {
02695 MythUIText *userjob2Text = NULL;
02696 UIUtilW::Assign(m_screen, userjob2Text, "userjob2text");
02697 if (userjob2Text)
02698 userjob2Text->SetText(QObject::tr("Run '%1'")
02699 .arg(gCoreContext->GetSetting("UserJobDesc2"), "User Job 2"));
02700 }
02701 m_userjob2Check->SetCheckState(m_rule->m_autoUserJob2);
02702 }
02703
02704
02705 if (m_userjob3Check)
02706 {
02707 if (!m_loaded)
02708 {
02709 MythUIText *userjob3Text = NULL;
02710 UIUtilW::Assign(m_screen, userjob3Text, "userjob3text");
02711 if (userjob3Text)
02712 userjob3Text->SetText(QObject::tr("Run '%1'")
02713 .arg(gCoreContext->GetSetting("UserJobDesc3"), "User Job 3"));
02714 }
02715 m_userjob3Check->SetCheckState(m_rule->m_autoUserJob3);
02716 }
02717
02718
02719 if (m_userjob4Check)
02720 {
02721 if (!m_loaded)
02722 {
02723 MythUIText *userjob4Text = NULL;
02724 UIUtilW::Assign(m_screen, userjob4Text, "userjob4text");
02725 if (userjob4Text)
02726 userjob4Text->SetText(QObject::tr("Run '%1'")
02727 .arg(gCoreContext->GetSetting("UserJobDesc4"), "User Job 4"));
02728 }
02729 m_userjob4Check->SetCheckState(m_rule->m_autoUserJob4);
02730 }
02731
02732
02733 if (m_metadataLookupCheck)
02734 {
02735 m_metadataLookupCheck->SetCheckState(m_rule->m_autoMetadataLookup);
02736 }
02737
02738 m_loaded = true;
02739
02740 RuleChanged();
02741 }
02742
02743 void PostProcMixin::Save(void)
02744 {
02745 if (!m_rule)
02746 return;
02747
02748 if (m_commflagCheck)
02749 m_rule->m_autoCommFlag = m_commflagCheck->GetBooleanCheckState();
02750 if (m_transcodeCheck)
02751 m_rule->m_autoTranscode = m_transcodeCheck->GetBooleanCheckState();
02752 if (m_transcodeprofileList)
02753 m_rule->m_transcoder = m_transcodeprofileList->GetDataValue().toInt();
02754 if (m_userjob1Check)
02755 m_rule->m_autoUserJob1 = m_userjob1Check->GetBooleanCheckState();
02756 if (m_userjob2Check)
02757 m_rule->m_autoUserJob2 = m_userjob2Check->GetBooleanCheckState();
02758 if (m_userjob3Check)
02759 m_rule->m_autoUserJob3 = m_userjob3Check->GetBooleanCheckState();
02760 if (m_userjob4Check)
02761 m_rule->m_autoUserJob4 = m_userjob4Check->GetBooleanCheckState();
02762 if (m_metadataLookupCheck)
02763 m_rule->m_autoMetadataLookup =
02764 m_metadataLookupCheck->GetBooleanCheckState();
02765 }
02766
02767 void PostProcMixin::RuleChanged(void)
02768 {
02769 if (!m_rule)
02770 return;
02771
02772 bool isScheduled = (m_rule->m_type != kNotRecording &&
02773 m_rule->m_type != kDontRecord);
02774
02775 if (m_commflagCheck)
02776 m_commflagCheck->SetEnabled(isScheduled);
02777 if (m_transcodeCheck)
02778 m_transcodeCheck->SetEnabled(isScheduled);
02779 if (m_transcodeprofileList)
02780 m_transcodeprofileList->SetEnabled(isScheduled &&
02781 m_rule->m_autoTranscode);
02782 if (m_userjob1Check)
02783 m_userjob1Check->SetEnabled(isScheduled);
02784 if (m_userjob2Check)
02785 m_userjob2Check->SetEnabled(isScheduled);
02786 if (m_userjob3Check)
02787 m_userjob3Check->SetEnabled(isScheduled);
02788 if (m_userjob4Check)
02789 m_userjob4Check->SetEnabled(isScheduled);
02790 if (m_metadataLookupCheck)
02791 m_metadataLookupCheck->SetEnabled(isScheduled);
02792 }
02793
02794 void PostProcMixin::TranscodeChanged(bool enable)
02795 {
02796 if (!m_rule)
02797 return;
02798
02799 m_rule->m_autoTranscode = enable;
02800
02801 if (m_transcodeprofileList)
02802 m_transcodeprofileList->SetEnabled(m_rule->m_autoTranscode);
02803 }
02804