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) const
00051 {
00052 if (title.isEmpty())
00053 return;
00054
00055 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00056 ProgLister *pl = new ProgLister(mainStack, plTitle, title, "");
00057 if (pl->Create())
00058 {
00059 mainStack->AddScreen(pl);
00060 }
00061 else
00062 delete pl;
00063 }
00064
00068 void ScheduleCommon::ShowUpcoming(ProgramInfo *pginfo) const
00069 {
00070 if (!pginfo)
00071 return;
00072
00073 ShowUpcoming(pginfo->GetTitle());
00074 }
00075
00080 void ScheduleCommon::EditRecording(ProgramInfo *pginfo)
00081 {
00082 if (!pginfo)
00083 return;
00084
00085 RecordingInfo ri(*pginfo);
00086
00087 if (!ri.GetRecordingRuleID())
00088 EditScheduled(&ri);
00089 else if (ri.GetRecordingStatus() <= rsWillRecord)
00090 ShowRecordingDialog(ri);
00091 else
00092 ShowNotRecordingDialog(ri);
00093 }
00094
00098 void ScheduleCommon::EditScheduled(ProgramInfo *pginfo)
00099 {
00100 if (!pginfo)
00101 return;
00102
00103 RecordingInfo ri(*pginfo);
00104 EditScheduled(&ri);
00105 }
00106
00110 void ScheduleCommon::EditScheduled(RecordingInfo *recinfo)
00111 {
00112 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00113 ScheduleEditor *schededit = new ScheduleEditor(mainStack, recinfo);
00114 if (schededit->Create())
00115 mainStack->AddScreen(schededit);
00116 else
00117 delete schededit;
00118 }
00119
00123 void ScheduleCommon::EditCustom(ProgramInfo *pginfo)
00124 {
00125 if (!pginfo)
00126 return;
00127
00128 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00129 CustomEdit *ce = new CustomEdit(mainStack, pginfo);
00130 if (ce->Create())
00131 mainStack->AddScreen(ce);
00132 else
00133 delete ce;
00134 }
00135
00139 void ScheduleCommon::MakeOverride(RecordingInfo *recinfo, bool startActive)
00140 {
00141 if (!recinfo || !recinfo->GetRecordingRuleID())
00142 return;
00143
00144 RecordingRule *recrule = new RecordingRule();
00145
00146 if (!recrule->LoadByProgram(static_cast<ProgramInfo*>(recinfo)))
00147 VERBOSE(VB_IMPORTANT, QString("Failed to load by program info"));
00148
00149 if (!recrule->MakeOverride())
00150 {
00151 VERBOSE(VB_IMPORTANT, QString("Failed to make Override"));
00152 delete recrule;
00153 return;
00154 }
00155 if (startActive)
00156 recrule->m_type = kOverrideRecord;
00157
00158 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00159 ScheduleEditor *schededit = new ScheduleEditor(mainStack, recrule);
00160 if (schededit->Create())
00161 mainStack->AddScreen(schededit);
00162 else
00163 delete schededit;
00164 }
00165
00170 void ScheduleCommon::ShowRecordingDialog(const RecordingInfo& recinfo)
00171 {
00172 QString message = recinfo.toString(ProgramInfo::kTitleSubtitle, " - ");
00173
00174 message += "\n\n";
00175 message += toDescription(
00176 recinfo.GetRecordingStatus(), recinfo.GetRecordingStartTime());
00177
00178 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00179 MythDialogBox *menuPopup = new MythDialogBox(message, popupStack,
00180 "recOptionPopup", true);
00181
00182 if (menuPopup->Create())
00183 {
00184 menuPopup->SetReturnEvent(this, "schedulerecording");
00185
00186 QDateTime now = QDateTime::currentDateTime();
00187
00188 if (recinfo.GetRecordingStartTime() < now &&
00189 recinfo.GetRecordingEndTime() > now)
00190 {
00191 if (recinfo.GetRecordingStatus() != rsRecording)
00192 menuPopup->AddButton(tr("Reactivate"),
00193 qVariantFromValue(recinfo));
00194 else
00195 menuPopup->AddButton(tr("Stop recording"),
00196 qVariantFromValue(recinfo));
00197 }
00198
00199 if (recinfo.GetRecordingEndTime() > now)
00200 {
00201 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00202 recinfo.GetRecordingRuleType() != kOverrideRecord)
00203 {
00204 if (recinfo.GetRecordingStartTime() > now)
00205 {
00206 menuPopup->AddButton(tr("Don't record"),
00207 qVariantFromValue(recinfo));
00208 }
00209
00210 const RecordingDupMethodType dupmethod =
00211 recinfo.GetDuplicateCheckMethod();
00212
00213 if (recinfo.GetRecordingStatus() != rsRecording &&
00214 recinfo.GetRecordingRuleType() != kFindOneRecord &&
00215 !((recinfo.GetFindID() == 0 ||
00216 !IsFindApplicable(recinfo)) &&
00217 recinfo.GetCategoryType() == "series" &&
00218 recinfo.GetProgramID().contains(QRegExp("0000$"))) &&
00219 ((!(dupmethod & kDupCheckNone) &&
00220 !recinfo.GetProgramID().isEmpty() &&
00221 (recinfo.GetFindID() != 0 ||
00222 !IsFindApplicable(recinfo))) ||
00223 ((dupmethod & kDupCheckSub) &&
00224 !recinfo.GetSubtitle().isEmpty()) ||
00225 ((dupmethod & kDupCheckDesc) &&
00226 !recinfo.GetDescription().isEmpty()) ||
00227 ((dupmethod & kDupCheckSubThenDesc) &&
00228 (!recinfo.GetSubtitle().isEmpty() ||
00229 !recinfo.GetDescription().isEmpty())) ))
00230 {
00231 menuPopup->AddButton(tr("Never record"),
00232 qVariantFromValue(recinfo));
00233 }
00234 }
00235
00236 if (recinfo.GetRecordingRuleType() != kOverrideRecord &&
00237 recinfo.GetRecordingRuleType() != kDontRecord)
00238 {
00239 if (recinfo.GetRecordingStatus() == rsRecording)
00240 {
00241 menuPopup->AddButton(tr("Modify Recording Options"),
00242 qVariantFromValue(recinfo));
00243 }
00244 else
00245 {
00246 menuPopup->AddButton(tr("Edit Options"),
00247 qVariantFromValue(recinfo));
00248
00249 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00250 recinfo.GetRecordingRuleType() != kFindOneRecord)
00251 {
00252 menuPopup->AddButton(tr("Add Override"),
00253 qVariantFromValue(recinfo));
00254 }
00255 }
00256 }
00257
00258 if (recinfo.GetRecordingRuleType() == kOverrideRecord ||
00259 recinfo.GetRecordingRuleType() == kDontRecord)
00260 {
00261 if (recinfo.GetRecordingStatus() == rsRecording)
00262 {
00263 menuPopup->AddButton(tr("Modify Recording Options"),
00264 qVariantFromValue(recinfo));
00265 }
00266 else
00267 {
00268 menuPopup->AddButton(tr("Edit Override"),
00269 qVariantFromValue(recinfo));
00270 menuPopup->AddButton(tr("Clear Override"),
00271 qVariantFromValue(recinfo));
00272 }
00273 }
00274 }
00275
00276 popupStack->AddScreen(menuPopup);
00277 }
00278 else
00279 delete menuPopup;
00280 }
00281
00286 void ScheduleCommon::ShowNotRecordingDialog(const RecordingInfo& recinfo)
00287 {
00288 QString timeFormat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
00289
00290 QString message = recinfo.toString(ProgramInfo::kTitleSubtitle, " - ");
00291
00292 message += "\n\n";
00293 message += toDescription(
00294 recinfo.GetRecordingStatus(), recinfo.GetRecordingStartTime());
00295
00296 if (recinfo.GetRecordingStatus() == rsConflict ||
00297 recinfo.GetRecordingStatus() == rsLaterShowing)
00298 {
00299 vector<ProgramInfo *> *confList = RemoteGetConflictList(&recinfo);
00300
00301 if (confList->size())
00302 message += tr(" The following programs will be recorded "
00303 "instead:\n");
00304
00305 uint maxi = 0;
00306 for (; confList->begin() != confList->end() && maxi < 4; maxi++)
00307 {
00308 ProgramInfo *p = *confList->begin();
00309 message += QString("%1 - %2 %3\n")
00310 .arg(p->GetRecordingStartTime().toString(timeFormat))
00311 .arg(p->GetRecordingEndTime().toString(timeFormat))
00312 .arg(p->toString(ProgramInfo::kTitleSubtitle, " - "));
00313 delete p;
00314 confList->erase(confList->begin());
00315 }
00316 message += "\n";
00317 while (!confList->empty())
00318 {
00319 delete confList->back();
00320 confList->pop_back();
00321 }
00322 delete confList;
00323 }
00324
00325 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00326 MythDialogBox *menuPopup = new MythDialogBox(message, popupStack,
00327 "notRecOptionPopup", true);
00328
00329 if (menuPopup->Create())
00330 {
00331 menuPopup->SetReturnEvent(this, "schedulenotrecording");
00332
00333 QDateTime now = QDateTime::currentDateTime();
00334
00335 if ((recinfo.GetRecordingStartTime() < now) &&
00336 (recinfo.GetRecordingEndTime() > now) &&
00337 (recinfo.GetRecordingStatus() != rsDontRecord) &&
00338 (recinfo.GetRecordingStatus() != rsNotListed))
00339 {
00340 menuPopup->AddButton(tr("Reactivate"),
00341 qVariantFromValue(recinfo));
00342 }
00343
00344 if (recinfo.GetRecordingEndTime() > now)
00345 {
00346 if ((recinfo.GetRecordingRuleType() != kSingleRecord &&
00347 recinfo.GetRecordingRuleType() != kOverrideRecord) &&
00348 (recinfo.GetRecordingStatus() == rsDontRecord ||
00349 recinfo.GetRecordingStatus() == rsPreviousRecording ||
00350 recinfo.GetRecordingStatus() == rsCurrentRecording ||
00351 recinfo.GetRecordingStatus() == rsEarlierShowing ||
00352 recinfo.GetRecordingStatus() == rsOtherShowing ||
00353 recinfo.GetRecordingStatus() == rsNeverRecord ||
00354 recinfo.GetRecordingStatus() == rsRepeat ||
00355 recinfo.GetRecordingStatus() == rsInactive ||
00356 recinfo.GetRecordingStatus() == rsLaterShowing))
00357 {
00358 menuPopup->AddButton(tr("Record anyway"),
00359 qVariantFromValue(recinfo));
00360 if (recinfo.GetRecordingStatus() == rsPreviousRecording ||
00361 recinfo.GetRecordingStatus() == rsNeverRecord)
00362 {
00363 menuPopup->AddButton(tr("Forget Previous"),
00364 qVariantFromValue(recinfo));
00365 }
00366 }
00367
00368 if (recinfo.GetRecordingRuleType() != kOverrideRecord &&
00369 recinfo.GetRecordingRuleType() != kDontRecord)
00370 {
00371 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00372 recinfo.GetRecordingStatus() != rsPreviousRecording &&
00373 recinfo.GetRecordingStatus() != rsCurrentRecording &&
00374 recinfo.GetRecordingStatus() != rsNeverRecord &&
00375 recinfo.GetRecordingStatus() != rsNotListed)
00376 {
00377 if (recinfo.GetRecordingStartTime() > now)
00378 {
00379 menuPopup->AddButton(tr("Don't record"),
00380 qVariantFromValue(recinfo));
00381 }
00382
00383 const RecordingDupMethodType dupmethod =
00384 recinfo.GetDuplicateCheckMethod();
00385
00386 if (recinfo.GetRecordingRuleType() != kFindOneRecord &&
00387 !((recinfo.GetFindID() == 0 ||
00388 !IsFindApplicable(recinfo)) &&
00389 recinfo.GetCategoryType() == "series" &&
00390 recinfo.GetProgramID().contains(QRegExp("0000$"))) &&
00391 ((!(dupmethod & kDupCheckNone) &&
00392 !recinfo.GetProgramID().isEmpty() &&
00393 (recinfo.GetFindID() != 0 ||
00394 !IsFindApplicable(recinfo))) ||
00395 ((dupmethod & kDupCheckSub) &&
00396 !recinfo.GetSubtitle().isEmpty()) ||
00397 ((dupmethod & kDupCheckDesc) &&
00398 !recinfo.GetDescription().isEmpty()) ||
00399 ((dupmethod & kDupCheckSubThenDesc) &&
00400 (!recinfo.GetSubtitle().isEmpty() ||
00401 !recinfo.GetDescription().isEmpty())) ))
00402 {
00403 menuPopup->AddButton(tr("Never record"),
00404 qVariantFromValue(recinfo));
00405 }
00406 }
00407
00408 menuPopup->AddButton(tr("Edit Options"),
00409 qVariantFromValue(recinfo));
00410
00411 if (recinfo.GetRecordingRuleType() != kSingleRecord &&
00412 recinfo.GetRecordingRuleType() != kFindOneRecord &&
00413 recinfo.GetRecordingStatus() != rsNotListed)
00414 {
00415 menuPopup->AddButton(tr("Add Override"),
00416 qVariantFromValue(recinfo));
00417 }
00418 }
00419
00420 if (recinfo.GetRecordingRuleType() == kOverrideRecord ||
00421 recinfo.GetRecordingRuleType() == kDontRecord)
00422 {
00423 menuPopup->AddButton(tr("Edit Override"),
00424 qVariantFromValue(recinfo));
00425 menuPopup->AddButton(tr("Clear Override"),
00426 qVariantFromValue(recinfo));
00427 }
00428 }
00429
00430 popupStack->AddScreen(menuPopup);
00431 }
00432 else
00433 delete menuPopup;
00434 }
00435
00436 void ScheduleCommon::customEvent(QEvent *event)
00437 {
00438 if (event->type() == DialogCompletionEvent::kEventType)
00439 {
00440 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00441
00442 QString resultid = dce->GetId();
00443 QString resulttext = dce->GetResultText();
00444
00445 if (resultid == "schedulenotrecording")
00446 {
00447 if (!qVariantCanConvert<RecordingInfo>(dce->GetData()))
00448 return;
00449
00450 RecordingInfo recInfo = qVariantValue<RecordingInfo>
00451 (dce->GetData());
00452
00453 if (resulttext == tr("Reactivate"))
00454 recInfo.ReactivateRecording();
00455 else if (resulttext == tr("Record anyway"))
00456 {
00457 recInfo.ApplyRecordStateChange(kOverrideRecord);
00458 if (recInfo.GetRecordingStartTime() < QDateTime::currentDateTime())
00459 recInfo.ReactivateRecording();
00460 }
00461 else if (resulttext == tr("Forget Previous"))
00462 recInfo.ForgetHistory();
00463 else if (resulttext == tr("Don't record"))
00464 recInfo.ApplyRecordStateChange(kDontRecord);
00465 else if (resulttext == tr("Never record"))
00466 {
00467 recInfo.SetRecordingStatus(rsNeverRecord);
00468 recInfo.SetScheduledStartTime(QDateTime::currentDateTime());
00469 recInfo.SetScheduledEndTime(recInfo.GetRecordingStartTime());
00470 recInfo.AddHistory(true, true);
00471 }
00472 else if (resulttext == tr("Clear Override"))
00473 recInfo.ApplyRecordStateChange(kNotRecording);
00474 else if (resulttext == tr("Edit Override") ||
00475 resulttext == tr("Edit Options"))
00476 {
00477 EditScheduled(&recInfo);
00478 }
00479 else if (resulttext == tr("Add Override"))
00480 {
00481 MakeOverride(&recInfo);
00482 }
00483 }
00484 else if (resultid == "schedulerecording")
00485 {
00486 if (!qVariantCanConvert<RecordingInfo>(dce->GetData()))
00487 return;
00488
00489 RecordingInfo recInfo = qVariantValue<RecordingInfo>
00490 (dce->GetData());
00491
00492 if (resulttext == tr("Reactivate"))
00493 recInfo.ReactivateRecording();
00494 else if (resulttext == tr("Stop recording"))
00495 {
00496 ProgramInfo pginfo(
00497 recInfo.GetChanID(), recInfo.GetRecordingStartTime());
00498 if (pginfo.GetChanID())
00499 RemoteStopRecording(&pginfo);
00500 }
00501 else if (resulttext == tr("Don't record"))
00502 recInfo.ApplyRecordStateChange(kDontRecord);
00503 else if (resulttext == tr("Never record"))
00504 {
00505 recInfo.SetRecordingStatus(rsNeverRecord);
00506 recInfo.SetScheduledStartTime(QDateTime::currentDateTime());
00507 recInfo.SetScheduledEndTime(recInfo.GetRecordingStartTime());
00508 recInfo.AddHistory(true, true);
00509 }
00510 else if (resulttext == tr("Clear Override"))
00511 recInfo.ApplyRecordStateChange(kNotRecording);
00512 else if (resulttext == tr("Modify Recording Options"))
00513 {
00514 if (recInfo.GetRecordingRuleType() == kSingleRecord ||
00515 recInfo.GetRecordingRuleType() == kOverrideRecord ||
00516 recInfo.GetRecordingRuleType() == kFindOneRecord)
00517 EditScheduled(&recInfo);
00518 else
00519 MakeOverride(&recInfo, true);
00520 }
00521 else if (resulttext == tr("Edit Override") ||
00522 resulttext == tr("Edit Options"))
00523 {
00524 EditScheduled(&recInfo);
00525 }
00526 else if (resulttext == tr("Add Override"))
00527 {
00528 MakeOverride(&recInfo);
00529 }
00530 }
00531 }
00532 }
00533
00538 bool ScheduleCommon::IsFindApplicable(const RecordingInfo& recInfo) const
00539 {
00540 return recInfo.GetRecordingRuleType() == kFindDailyRecord ||
00541 recInfo.GetRecordingRuleType() == kFindWeeklyRecord;
00542 }