00001
00002 #include "schedulecommon.h"
00003
00004
00005 #include <QCoreApplication>
00006
00007
00008 #include "mythcorecontext.h"
00009 #include "programinfo.h"
00010 #include "remoteutil.h"
00011
00012
00013 #include "recordinginfo.h"
00014 #include "tvremoteutil.h"
00015
00016
00017 #include "mythscreentype.h"
00018 #include "mythdialogbox.h"
00019 #include "mythmainwindow.h"
00020
00021
00022 #include "scheduleeditor.h"
00023 #include "progdetails.h"
00024 #include "proglist.h"
00025 #include "customedit.h"
00026
00030 void ScheduleCommon::ShowDetails(ProgramInfo *pginfo) const
00031 {
00032 if (!pginfo)
00033 return;
00034
00035 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00036 ProgDetails *details_dialog = new ProgDetails(mainStack, pginfo);
00037
00038 if (!details_dialog->Create())
00039 {
00040 delete details_dialog;
00041 return;
00042 }
00043
00044 mainStack->AddScreen(details_dialog);
00045 }
00046
00050 void ScheduleCommon::ShowUpcoming(const QString &title,
00051 const QString &seriesid) const
00052 {
00053 if (title.isEmpty())
00054 return;
00055
00056 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00057 ProgLister *pl = new ProgLister(mainStack, plTitle, title, seriesid);
00058 if (pl->Create())
00059 {
00060 mainStack->AddScreen(pl);
00061 }
00062 else
00063 delete pl;
00064 }
00065
00069 void ScheduleCommon::ShowUpcoming(ProgramInfo *pginfo) const
00070 {
00071 if (!pginfo)
00072 return;
00073
00074 ShowUpcoming(pginfo->GetTitle(), pginfo->GetSeriesID());
00075 }
00076
00080 void ScheduleCommon::ShowUpcomingScheduled(ProgramInfo *pginfo) const
00081 {
00082 if (!pginfo)
00083 return;
00084
00085 RecordingInfo ri(*pginfo);
00086 uint id;
00087
00088 if ((id = ri.GetRecordingRuleID()) <= 0)
00089 return ShowUpcoming(pginfo->GetTitle(), pginfo->GetSeriesID());
00090
00091 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00092 ProgLister *pl = new ProgLister(mainStack, plRecordid,
00093 QString::number(id), "");
00094
00095 if (pl->Create())
00096 mainStack->AddScreen(pl);
00097 else
00098 delete pl;
00099 }
00100
00105 void ScheduleCommon::EditRecording(ProgramInfo *pginfo)
00106 {
00107 if (!pginfo)
00108 return;
00109
00110 RecordingInfo ri(*pginfo);
00111
00112 if (!ri.GetRecordingRuleID())
00113 EditScheduled(&ri);
00114 else if (ri.GetRecordingStatus() <= rsWillRecord ||
00115 ri.GetRecordingStatus() == rsOtherShowing)
00116 ShowRecordingDialog(ri);
00117 else
00118 ShowNotRecordingDialog(ri);
00119 }
00120
00124 void ScheduleCommon::EditScheduled(ProgramInfo *pginfo)
00125 {
00126 if (!pginfo)
00127 return;
00128
00129 RecordingInfo ri(*pginfo);
00130 EditScheduled(&ri);
00131 }
00132
00136 void ScheduleCommon::EditScheduled(RecordingInfo *recinfo)
00137 {
00138 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00139 ScheduleEditor *schededit = new ScheduleEditor(mainStack, recinfo);
00140 if (schededit->Create())
00141 mainStack->AddScreen(schededit);
00142 else
00143 delete schededit;
00144 }
00145
00149 void ScheduleCommon::EditCustom(ProgramInfo *pginfo)
00150 {
00151 if (!pginfo)
00152 return;
00153
00154 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00155 CustomEdit *ce = new CustomEdit(mainStack, pginfo);
00156 if (ce->Create())
00157 mainStack->AddScreen(ce);
00158 else
00159 delete ce;
00160 }
00161
00165 void ScheduleCommon::MakeOverride(RecordingInfo *recinfo, bool startActive)
00166 {
00167 if (!recinfo || !recinfo->GetRecordingRuleID())
00168 return;
00169
00170 RecordingRule *recrule = new RecordingRule();
00171
00172 if (!recrule->LoadByProgram(static_cast<ProgramInfo*>(recinfo)))
00173 LOG(VB_GENERAL, LOG_ERR, "Failed to load by program info");
00174
00175 if (!recrule->MakeOverride())
00176 {
00177 LOG(VB_GENERAL, LOG_ERR, "Failed to make Override");
00178 delete recrule;
00179 return;
00180 }
00181 if (startActive)
00182 recrule->m_type = kOverrideRecord;
00183
00184 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00185 ScheduleEditor *schededit = new ScheduleEditor(mainStack, recrule);
00186 if (schededit->Create())
00187 mainStack->AddScreen(schededit);
00188 else
00189 delete schededit;
00190 }
00191
00196 void ScheduleCommon::ShowRecordingDialog(const RecordingInfo& recinfo)
00197 {
00198 QString message = recinfo.toString(ProgramInfo::kTitleSubtitle, " - ");
00199
00200 message += "\n\n";
00201 message += toDescription(recinfo.GetRecordingStatus(),
00202 recinfo.GetRecordingRuleType(),
00203 recinfo.GetRecordingStartTime());
00204
00205 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00206 MythDialogBox *menuPopup = new MythDialogBox(message, popupStack,
00207 "recOptionPopup", true);
00208
00209 if (menuPopup->Create())
00210 {
00211 menuPopup->SetReturnEvent(this, "schedulerecording");
00212
00213 QDateTime now = QDateTime::currentDateTime();
00214
00215 if (recinfo.GetRecordingStartTime() < now &&
00216 recinfo.GetRecordingEndTime() > now)
00217 {
00218 if (recinfo.GetRecordingStatus() != rsRecording &&
00219 recinfo.GetRecordingStatus() != rsTuning &&
00220 recinfo.GetRecordingStatus() != rsOtherRecording &&
00221 recinfo.GetRecordingStatus() != rsOtherTuning)
00222 menuPopup->AddButton(tr("Reactivate"),
00223 qVariantFromValue(recinfo));
00224 else
00225 menuPopup->AddButton(tr("Stop recording"),
00226 qVariantFromValue(recinfo));
00227 }
00228
00229 if (recinfo.GetRecordingEndTime() > now)
00230 {
00231 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00232 recinfo.GetRecordingRuleType() != kOverrideRecord)
00233 {
00234 if (recinfo.GetRecordingStartTime() > now)
00235 {
00236 menuPopup->AddButton(tr("Don't record"),
00237 qVariantFromValue(recinfo));
00238 }
00239
00240 const RecordingDupMethodType dupmethod =
00241 recinfo.GetDuplicateCheckMethod();
00242
00243 if (recinfo.GetRecordingStatus() != rsRecording &&
00244 recinfo.GetRecordingStatus() != rsTuning &&
00245 recinfo.GetRecordingStatus() != rsOtherRecording &&
00246 recinfo.GetRecordingStatus() != rsOtherTuning &&
00247 recinfo.GetRecordingRuleType() != kFindOneRecord &&
00248 !((recinfo.GetFindID() == 0 ||
00249 !IsFindApplicable(recinfo)) &&
00250 recinfo.GetCategoryType() == "series" &&
00251 recinfo.GetProgramID().contains(QRegExp("0000$"))) &&
00252 ((!(dupmethod & kDupCheckNone) &&
00253 !recinfo.GetProgramID().isEmpty() &&
00254 (recinfo.GetFindID() != 0 ||
00255 !IsFindApplicable(recinfo))) ||
00256 ((dupmethod & kDupCheckSub) &&
00257 !recinfo.GetSubtitle().isEmpty()) ||
00258 ((dupmethod & kDupCheckDesc) &&
00259 !recinfo.GetDescription().isEmpty()) ||
00260 ((dupmethod & kDupCheckSubThenDesc) &&
00261 (!recinfo.GetSubtitle().isEmpty() ||
00262 !recinfo.GetDescription().isEmpty())) ))
00263 {
00264 menuPopup->AddButton(tr("Never record"),
00265 qVariantFromValue(recinfo));
00266 }
00267 }
00268
00269 if (recinfo.GetRecordingRuleType() != kOverrideRecord &&
00270 recinfo.GetRecordingRuleType() != kDontRecord)
00271 {
00272 if (recinfo.GetRecordingStatus() == rsRecording ||
00273 recinfo.GetRecordingStatus() == rsTuning ||
00274 recinfo.GetRecordingStatus() == rsOtherRecording ||
00275 recinfo.GetRecordingStatus() == rsOtherTuning)
00276 {
00277 menuPopup->AddButton(tr("Modify Recording Options"),
00278 qVariantFromValue(recinfo));
00279 }
00280 else
00281 {
00282 menuPopup->AddButton(tr("Edit Options"),
00283 qVariantFromValue(recinfo));
00284
00285 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00286 recinfo.GetRecordingRuleType() != kFindOneRecord)
00287 {
00288 menuPopup->AddButton(tr("Add Override"),
00289 qVariantFromValue(recinfo));
00290 }
00291 }
00292 }
00293
00294 if (recinfo.GetRecordingRuleType() == kOverrideRecord ||
00295 recinfo.GetRecordingRuleType() == kDontRecord)
00296 {
00297 if (recinfo.GetRecordingStatus() == rsRecording ||
00298 recinfo.GetRecordingStatus() == rsTuning ||
00299 recinfo.GetRecordingStatus() == rsOtherRecording ||
00300 recinfo.GetRecordingStatus() == rsOtherTuning)
00301 {
00302 menuPopup->AddButton(tr("Modify Recording Options"),
00303 qVariantFromValue(recinfo));
00304 }
00305 else
00306 {
00307 menuPopup->AddButton(tr("Edit Override"),
00308 qVariantFromValue(recinfo));
00309 menuPopup->AddButton(tr("Clear Override"),
00310 qVariantFromValue(recinfo));
00311 }
00312 }
00313 }
00314
00315 popupStack->AddScreen(menuPopup);
00316 }
00317 else
00318 delete menuPopup;
00319 }
00320
00325 void ScheduleCommon::ShowNotRecordingDialog(const RecordingInfo& recinfo)
00326 {
00327 QString timeFormat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
00328
00329 QString message = recinfo.toString(ProgramInfo::kTitleSubtitle, " - ");
00330
00331 message += "\n\n";
00332 message += toDescription(recinfo.GetRecordingStatus(),
00333 recinfo.GetRecordingRuleType(),
00334 recinfo.GetRecordingStartTime());
00335
00336 if (recinfo.GetRecordingStatus() == rsConflict ||
00337 recinfo.GetRecordingStatus() == rsLaterShowing)
00338 {
00339 vector<ProgramInfo *> *confList = RemoteGetConflictList(&recinfo);
00340
00341 if (!confList->empty())
00342 {
00343 message += " ";
00344 message += tr("The following programs will be recorded instead:");
00345 message += "\n";
00346 }
00347
00348 uint maxi = 0;
00349 for (; confList->begin() != confList->end() && maxi < 4; maxi++)
00350 {
00351 ProgramInfo *p = *confList->begin();
00352 message += QString("%1 - %2 %3\n")
00353 .arg(p->GetRecordingStartTime().toString(timeFormat))
00354 .arg(p->GetRecordingEndTime().toString(timeFormat))
00355 .arg(p->toString(ProgramInfo::kTitleSubtitle, " - "));
00356 delete p;
00357 confList->erase(confList->begin());
00358 }
00359 message += "\n";
00360 while (!confList->empty())
00361 {
00362 delete confList->back();
00363 confList->pop_back();
00364 }
00365 delete confList;
00366 }
00367
00368 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00369 MythDialogBox *menuPopup = new MythDialogBox(message, popupStack,
00370 "notRecOptionPopup", true);
00371
00372 if (menuPopup->Create())
00373 {
00374 menuPopup->SetReturnEvent(this, "schedulenotrecording");
00375
00376 QDateTime now = QDateTime::currentDateTime();
00377
00378 if ((recinfo.GetRecordingStartTime() < now) &&
00379 (recinfo.GetRecordingEndTime() > now) &&
00380 (recinfo.GetRecordingStatus() != rsDontRecord) &&
00381 (recinfo.GetRecordingStatus() != rsNotListed))
00382 {
00383 menuPopup->AddButton(tr("Reactivate"),
00384 qVariantFromValue(recinfo));
00385 }
00386
00387 if (recinfo.GetRecordingEndTime() > now)
00388 {
00389 if ((recinfo.GetRecordingRuleType() != kSingleRecord &&
00390 recinfo.GetRecordingRuleType() != kOverrideRecord) &&
00391 (recinfo.GetRecordingStatus() == rsDontRecord ||
00392 recinfo.GetRecordingStatus() == rsPreviousRecording ||
00393 recinfo.GetRecordingStatus() == rsCurrentRecording ||
00394 recinfo.GetRecordingStatus() == rsEarlierShowing ||
00395 recinfo.GetRecordingStatus() == rsNeverRecord ||
00396 recinfo.GetRecordingStatus() == rsRepeat ||
00397 recinfo.GetRecordingStatus() == rsInactive ||
00398 recinfo.GetRecordingStatus() == rsLaterShowing))
00399 {
00400 menuPopup->AddButton(tr("Record anyway"),
00401 qVariantFromValue(recinfo));
00402 if (recinfo.GetRecordingStatus() == rsPreviousRecording ||
00403 recinfo.GetRecordingStatus() == rsNeverRecord)
00404 {
00405 menuPopup->AddButton(tr("Forget Previous"),
00406 qVariantFromValue(recinfo));
00407 }
00408 }
00409
00410 if (recinfo.GetRecordingRuleType() != kOverrideRecord &&
00411 recinfo.GetRecordingRuleType() != kDontRecord)
00412 {
00413 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00414 recinfo.GetRecordingStatus() != rsPreviousRecording &&
00415 recinfo.GetRecordingStatus() != rsCurrentRecording &&
00416 recinfo.GetRecordingStatus() != rsNeverRecord &&
00417 recinfo.GetRecordingStatus() != rsNotListed)
00418 {
00419 if (recinfo.GetRecordingStartTime() > now)
00420 {
00421 menuPopup->AddButton(tr("Don't record"),
00422 qVariantFromValue(recinfo));
00423 }
00424
00425 const RecordingDupMethodType dupmethod =
00426 recinfo.GetDuplicateCheckMethod();
00427
00428 if (recinfo.GetRecordingRuleType() != kFindOneRecord &&
00429 !((recinfo.GetFindID() == 0 ||
00430 !IsFindApplicable(recinfo)) &&
00431 recinfo.GetCategoryType() == "series" &&
00432 recinfo.GetProgramID().contains(QRegExp("0000$"))) &&
00433 ((!(dupmethod & kDupCheckNone) &&
00434 !recinfo.GetProgramID().isEmpty() &&
00435 (recinfo.GetFindID() != 0 ||
00436 !IsFindApplicable(recinfo))) ||
00437 ((dupmethod & kDupCheckSub) &&
00438 !recinfo.GetSubtitle().isEmpty()) ||
00439 ((dupmethod & kDupCheckDesc) &&
00440 !recinfo.GetDescription().isEmpty()) ||
00441 ((dupmethod & kDupCheckSubThenDesc) &&
00442 (!recinfo.GetSubtitle().isEmpty() ||
00443 !recinfo.GetDescription().isEmpty())) ))
00444 {
00445 menuPopup->AddButton(tr("Never record"),
00446 qVariantFromValue(recinfo));
00447 }
00448 }
00449
00450 menuPopup->AddButton(tr("Edit Options"),
00451 qVariantFromValue(recinfo));
00452
00453 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00454 recinfo.GetRecordingRuleType() != kFindOneRecord &&
00455 recinfo.GetRecordingStatus() != rsNotListed)
00456 {
00457 menuPopup->AddButton(tr("Add Override"),
00458 qVariantFromValue(recinfo));
00459 }
00460 }
00461
00462 if (recinfo.GetRecordingRuleType() == kOverrideRecord ||
00463 recinfo.GetRecordingRuleType() == kDontRecord)
00464 {
00465 menuPopup->AddButton(tr("Edit Override"),
00466 qVariantFromValue(recinfo));
00467 menuPopup->AddButton(tr("Clear Override"),
00468 qVariantFromValue(recinfo));
00469 }
00470 }
00471
00472 popupStack->AddScreen(menuPopup);
00473 }
00474 else
00475 delete menuPopup;
00476 }
00477
00478 void ScheduleCommon::customEvent(QEvent *event)
00479 {
00480 if (event->type() == DialogCompletionEvent::kEventType)
00481 {
00482 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00483
00484 QString resultid = dce->GetId();
00485 QString resulttext = dce->GetResultText();
00486
00487 if (resultid == "schedulenotrecording")
00488 {
00489 if (!qVariantCanConvert<RecordingInfo>(dce->GetData()))
00490 return;
00491
00492 RecordingInfo recInfo = qVariantValue<RecordingInfo>
00493 (dce->GetData());
00494
00495 if (resulttext == tr("Reactivate"))
00496 recInfo.ReactivateRecording();
00497 else if (resulttext == tr("Record anyway"))
00498 {
00499 recInfo.ApplyRecordStateChange(kOverrideRecord);
00500 if (recInfo.GetRecordingStartTime() < QDateTime::currentDateTime())
00501 recInfo.ReactivateRecording();
00502 }
00503 else if (resulttext == tr("Forget Previous"))
00504 recInfo.ForgetHistory();
00505 else if (resulttext == tr("Don't record"))
00506 recInfo.ApplyRecordStateChange(kDontRecord);
00507 else if (resulttext == tr("Never record"))
00508 {
00509 recInfo.SetRecordingStatus(rsNeverRecord);
00510 recInfo.SetScheduledStartTime(QDateTime::currentDateTime());
00511 recInfo.SetScheduledEndTime(recInfo.GetRecordingStartTime());
00512 recInfo.AddHistory(true, true);
00513 }
00514 else if (resulttext == tr("Clear Override"))
00515 recInfo.ApplyRecordStateChange(kNotRecording);
00516 else if (resulttext == tr("Edit Override") ||
00517 resulttext == tr("Edit Options"))
00518 {
00519 EditScheduled(&recInfo);
00520 }
00521 else if (resulttext == tr("Add Override"))
00522 {
00523 MakeOverride(&recInfo);
00524 }
00525 }
00526 else if (resultid == "schedulerecording")
00527 {
00528 if (!qVariantCanConvert<RecordingInfo>(dce->GetData()))
00529 return;
00530
00531 RecordingInfo recInfo = qVariantValue<RecordingInfo>
00532 (dce->GetData());
00533
00534 if (resulttext == tr("Reactivate"))
00535 recInfo.ReactivateRecording();
00536 else if (resulttext == tr("Stop recording"))
00537 {
00538 ProgramInfo pginfo(
00539 recInfo.GetChanID(), recInfo.GetRecordingStartTime());
00540 if (pginfo.GetChanID())
00541 RemoteStopRecording(&pginfo);
00542 }
00543 else if (resulttext == tr("Don't record"))
00544 recInfo.ApplyRecordStateChange(kDontRecord);
00545 else if (resulttext == tr("Never record"))
00546 {
00547 recInfo.SetRecordingStatus(rsNeverRecord);
00548 recInfo.SetScheduledStartTime(QDateTime::currentDateTime());
00549 recInfo.SetScheduledEndTime(recInfo.GetRecordingStartTime());
00550 recInfo.AddHistory(true, true);
00551 }
00552 else if (resulttext == tr("Clear Override"))
00553 recInfo.ApplyRecordStateChange(kNotRecording);
00554 else if (resulttext == tr("Modify Recording Options"))
00555 {
00556 if (recInfo.GetRecordingRuleType() == kSingleRecord ||
00557 recInfo.GetRecordingRuleType() == kOverrideRecord ||
00558 recInfo.GetRecordingRuleType() == kFindOneRecord)
00559 EditScheduled(&recInfo);
00560 else
00561 MakeOverride(&recInfo, true);
00562 }
00563 else if (resulttext == tr("Edit Override") ||
00564 resulttext == tr("Edit Options"))
00565 {
00566 EditScheduled(&recInfo);
00567 }
00568 else if (resulttext == tr("Add Override"))
00569 {
00570 MakeOverride(&recInfo);
00571 }
00572 }
00573 }
00574 }
00575
00580 bool ScheduleCommon::IsFindApplicable(const RecordingInfo& recInfo) const
00581 {
00582 return recInfo.GetRecordingRuleType() == kFindDailyRecord ||
00583 recInfo.GetRecordingRuleType() == kFindWeeklyRecord;
00584 }