|
MythTV
0.26-pre
|
00001 00002 #include "viewscheduled.h" 00003 00004 #include <QCoreApplication> 00005 00006 #include "customedit.h" 00007 #include "recordinginfo.h" 00008 #include "tv_play.h" 00009 #include "recordingrule.h" 00010 #include "mythlogging.h" 00011 #include "mythcorecontext.h" 00012 #include "remoteutil.h" 00013 #include "mythuitext.h" 00014 #include "mythuistatetype.h" 00015 #include "mythuibuttonlist.h" 00016 #include "mythdialogbox.h" 00017 #include "mythmainwindow.h" 00018 00019 void *ViewScheduled::RunViewScheduled(void *player, bool showTV) 00020 { 00021 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00022 ViewScheduled *vsb = new ViewScheduled(mainStack, static_cast<TV*>(player), 00023 showTV); 00024 00025 if (vsb->Create()) 00026 mainStack->AddScreen(vsb, (player == NULL)); 00027 else 00028 delete vsb; 00029 00030 return NULL; 00031 } 00032 00033 ViewScheduled::ViewScheduled(MythScreenStack *parent, TV* player, bool showTV) 00034 : ScheduleCommon(parent, "ViewScheduled") 00035 { 00036 m_showAll = !gCoreContext->GetNumSetting("ViewSchedShowLevel", 0); 00037 00038 m_player = player; 00039 00040 m_inEvent = false; 00041 m_inFill = false; 00042 m_needFill = false; 00043 00044 m_curcard = 0; 00045 m_maxcard = 0; 00046 m_curinput = 0; 00047 m_maxinput = 0; 00048 00049 m_defaultGroup = QDate(); 00050 m_currentGroup = m_defaultGroup; 00051 00052 gCoreContext->addListener(this); 00053 } 00054 00055 ViewScheduled::~ViewScheduled() 00056 { 00057 gCoreContext->removeListener(this); 00058 gCoreContext->SaveSetting("ViewSchedShowLevel", !m_showAll); 00059 00060 // if we have a player, we need to tell we are done 00061 if (m_player) 00062 { 00063 QString message = QString("VIEWSCHEDULED_EXITING"); 00064 qApp->postEvent(m_player, new MythEvent(message)); 00065 } 00066 } 00067 00068 bool ViewScheduled::Create() 00069 { 00070 if (!LoadWindowFromXML("schedule-ui.xml", "viewscheduled", this)) 00071 return false; 00072 00073 //if (m_player && m_player->IsRunning() && showTV) 00074 00075 m_groupList = dynamic_cast<MythUIButtonList *> (GetChild("groups")); 00076 m_schedulesList = dynamic_cast<MythUIButtonList *> (GetChild("schedules")); 00077 00078 if (!m_schedulesList) 00079 { 00080 LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements."); 00081 return false; 00082 } 00083 00084 connect(m_schedulesList, SIGNAL(itemSelected(MythUIButtonListItem*)), 00085 SLOT(updateInfo(MythUIButtonListItem*))); 00086 connect(m_schedulesList, SIGNAL(itemClicked(MythUIButtonListItem*)), 00087 SLOT(selected(MythUIButtonListItem*))); 00088 00089 m_schedulesList->SetLCDTitles(tr("Scheduled Recordings"), 00090 "shortstarttimedate|channel|titlesubtitle|card"); 00091 m_schedulesList->SetSearchFields("titlesubtitle"); 00092 00093 if (m_groupList) 00094 { 00095 connect(m_groupList, SIGNAL(itemSelected(MythUIButtonListItem*)), 00096 SLOT(ChangeGroup(MythUIButtonListItem*))); 00097 connect(m_groupList, SIGNAL(itemClicked(MythUIButtonListItem*)), 00098 SLOT(SwitchList())); 00099 m_groupList->SetLCDTitles(tr("Group List"), ""); 00100 } 00101 00102 BuildFocusList(); 00103 LoadInBackground(); 00104 00105 EmbedTVWindow(); 00106 00107 return true; 00108 } 00109 00110 void ViewScheduled::Load(void) 00111 { 00112 LoadFromScheduler(m_recList, m_conflictBool); 00113 } 00114 00115 void ViewScheduled::Init() 00116 { 00117 LoadList(true); 00118 } 00119 00120 void ViewScheduled::Close() 00121 { 00122 // don't fade the screen if we are returning to the player 00123 if (m_player) 00124 GetScreenStack()->PopScreen(this, false); 00125 else 00126 GetScreenStack()->PopScreen(this, true); 00127 } 00128 00129 void ViewScheduled::SwitchList() 00130 { 00131 if (GetFocusWidget() == m_groupList) 00132 SetFocusWidget(m_schedulesList); 00133 else if (GetFocusWidget() == m_schedulesList) 00134 SetFocusWidget(m_groupList); 00135 } 00136 00137 bool ViewScheduled::keyPressEvent(QKeyEvent *event) 00138 { 00139 // FIXME: Blackholes keypresses, not good 00140 if (m_inEvent) 00141 return true; 00142 00143 m_inEvent = true; 00144 00145 if (GetFocusWidget()->keyPressEvent(event)) 00146 { 00147 m_inEvent = false; 00148 return true; 00149 } 00150 00151 bool handled = false; 00152 QStringList actions; 00153 handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, 00154 actions); 00155 00156 for (int i = 0; i < actions.size() && !handled; i++) 00157 { 00158 QString action = actions[i]; 00159 handled = true; 00160 00161 if (action == "EDIT") 00162 edit(); 00163 else if (action == "CUSTOMEDIT") 00164 customEdit(); 00165 else if (action == "DELETE") 00166 deleteRule(); 00167 else if (action == "UPCOMING") 00168 upcoming(); 00169 else if (action == "VIEWSCHEDULED") 00170 upcomingScheduled(); 00171 else if (action == "DETAILS" || action == "INFO") 00172 details(); 00173 else if (action == "1") 00174 setShowAll(true); 00175 else if (action == "2") 00176 setShowAll(false); 00177 else if (action == "PREVVIEW" || action == "NEXTVIEW") 00178 setShowAll(!m_showAll); 00179 else if (action == "VIEWCARD") 00180 viewCards(); 00181 else if (action == "VIEWINPUT") 00182 viewInputs(); 00183 else 00184 handled = false; 00185 } 00186 00187 if (m_needFill) 00188 LoadList(); 00189 00190 if (!handled && MythScreenType::keyPressEvent(event)) 00191 handled = true; 00192 00193 m_inEvent = false; 00194 00195 return handled; 00196 } 00197 00198 void ViewScheduled::ShowMenu(void) 00199 { 00200 QString label = tr("Options"); 00201 00202 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00203 MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, 00204 "menuPopup"); 00205 00206 if (menuPopup->Create()) 00207 { 00208 menuPopup->SetReturnEvent(this, "menu"); 00209 00210 if (m_showAll) 00211 menuPopup->AddButton(tr("Show Important")); 00212 else 00213 menuPopup->AddButton(tr("Show All")); 00214 menuPopup->AddButton(tr("Program Details")); 00215 menuPopup->AddButton(tr("Upcoming by title")); 00216 menuPopup->AddButton(tr("Upcoming scheduled")); 00217 menuPopup->AddButton(tr("Custom Edit")); 00218 menuPopup->AddButton(tr("Delete Rule")); 00219 menuPopup->AddButton(tr("Show Cards")); 00220 menuPopup->AddButton(tr("Show Inputs")); 00221 00222 popupStack->AddScreen(menuPopup); 00223 } 00224 else 00225 { 00226 delete menuPopup; 00227 } 00228 } 00229 00230 void ViewScheduled::LoadList(bool useExistingData) 00231 { 00232 if (m_inFill) 00233 return; 00234 00235 m_inFill = true; 00236 00237 MythUIButtonListItem *currentItem = m_schedulesList->GetItemCurrent(); 00238 00239 QString callsign; 00240 QDateTime startts, recstartts; 00241 00242 if (currentItem) 00243 { 00244 ProgramInfo *currentpginfo = qVariantValue<ProgramInfo*> 00245 (currentItem->GetData()); 00246 if (currentpginfo) 00247 { 00248 callsign = currentpginfo->GetChannelSchedulingID(); 00249 startts = currentpginfo->GetScheduledStartTime(); 00250 recstartts = currentpginfo->GetRecordingStartTime(); 00251 } 00252 } 00253 00254 QDateTime now = QDateTime::currentDateTime(); 00255 00256 QMap<int, int> toomanycounts; 00257 00258 m_schedulesList->Reset(); 00259 if (m_groupList) 00260 m_groupList->Reset(); 00261 00262 m_recgroupList.clear(); 00263 00264 if (!useExistingData) 00265 LoadFromScheduler(m_recList, m_conflictBool); 00266 00267 ProgramList::iterator pit = m_recList.begin(); 00268 QString currentDate; 00269 m_recgroupList[m_defaultGroup] = ProgramList(false); 00270 m_recgroupList[m_defaultGroup].setAutoDelete(false); 00271 while (pit != m_recList.end()) 00272 { 00273 ProgramInfo *pginfo = *pit; 00274 const RecStatusType recstatus = pginfo->GetRecordingStatus(); 00275 if ((pginfo->GetRecordingEndTime() >= now || 00276 pginfo->GetScheduledEndTime() >= now) && 00277 (m_showAll || 00278 recstatus <= rsWillRecord || 00279 recstatus == rsDontRecord || 00280 (recstatus == rsTooManyRecordings && 00281 ++toomanycounts[pginfo->GetRecordingRuleID()] <= 1) || 00282 (recstatus > rsTooManyRecordings && 00283 recstatus != rsRepeat && 00284 recstatus != rsNeverRecord))) 00285 { 00286 m_cardref[pginfo->GetCardID()]++; 00287 if (pginfo->GetCardID() > m_maxcard) 00288 m_maxcard = pginfo->GetCardID(); 00289 00290 m_inputref[pginfo->GetInputID()]++; 00291 if (pginfo->GetInputID() > m_maxinput) 00292 m_maxinput = pginfo->GetInputID(); 00293 00294 QDate date = (pginfo->GetRecordingStartTime()).date(); 00295 m_recgroupList[date].push_back(pginfo); 00296 m_recgroupList[date].setAutoDelete(false); 00297 00298 m_recgroupList[m_defaultGroup].push_back(pginfo); 00299 00300 ++pit; 00301 } 00302 else 00303 { 00304 pit = m_recList.erase(pit); 00305 continue; 00306 } 00307 } 00308 00309 if (m_groupList) 00310 { 00311 QString label; 00312 QMap<QDate,ProgramList>::iterator dateit = m_recgroupList.begin(); 00313 while (dateit != m_recgroupList.end()) 00314 { 00315 if (dateit.key().isNull()) 00316 label = tr("All"); 00317 else 00318 label = MythDateToString(dateit.key(), kDateFull | kSimplify); 00319 00320 new MythUIButtonListItem(m_groupList, label, 00321 qVariantFromValue(dateit.key())); 00322 ++dateit; 00323 } 00324 if (!m_recgroupList.contains(m_currentGroup)) 00325 m_groupList->SetValueByData(qVariantFromValue(m_currentGroup)); 00326 } 00327 00328 FillList(); 00329 00330 // Restore position after a list update 00331 if (!callsign.isEmpty()) 00332 { 00333 ProgramList plist; 00334 00335 if (!m_recgroupList.contains(m_currentGroup)) 00336 m_currentGroup = m_defaultGroup; 00337 00338 plist = m_recgroupList[m_currentGroup]; 00339 00340 int listPos = ((int) plist.size()) - 1; 00341 int i; 00342 for (i = listPos; i >= 0; --i) 00343 { 00344 ProgramInfo *pginfo = plist[i]; 00345 if (callsign == pginfo->GetChannelSchedulingID() && 00346 startts == pginfo->GetScheduledStartTime()) 00347 { 00348 listPos = i; 00349 break; 00350 } 00351 else if (recstartts <= pginfo->GetRecordingStartTime()) 00352 listPos = i; 00353 } 00354 m_schedulesList->SetItemCurrent(listPos); 00355 } 00356 00357 m_inFill = false; 00358 m_needFill = false; 00359 } 00360 00361 00362 void ViewScheduled::ChangeGroup(MythUIButtonListItem* item) 00363 { 00364 if (!item || m_recList.empty()) 00365 return; 00366 00367 QDate group = qVariantValue<QDate>(item->GetData()); 00368 00369 m_currentGroup = group; 00370 00371 if (!m_inFill) 00372 FillList(); 00373 } 00374 00375 void ViewScheduled::FillList() 00376 { 00377 m_schedulesList->Reset(); 00378 00379 MythUIText *norecordingText = dynamic_cast<MythUIText*> 00380 (GetChild("norecordings_info")); 00381 00382 if (norecordingText) 00383 norecordingText->SetVisible(m_recList.empty()); 00384 00385 if (m_recList.empty()) 00386 return; 00387 00388 ProgramList plist; 00389 00390 if (!m_recgroupList.contains(m_currentGroup)) 00391 m_currentGroup = m_defaultGroup; 00392 00393 plist = m_recgroupList[m_currentGroup]; 00394 00395 ProgramList::iterator pit = plist.begin(); 00396 while (pit != plist.end()) 00397 { 00398 ProgramInfo *pginfo = *pit; 00399 if (!pginfo) 00400 { 00401 ++pit; 00402 continue; 00403 } 00404 00405 QString state; 00406 00407 const RecStatusType recstatus = pginfo->GetRecordingStatus(); 00408 if (recstatus == rsRecording || 00409 recstatus == rsTuning || 00410 recstatus == rsOtherRecording || 00411 recstatus == rsOtherTuning) 00412 state = "running"; 00413 else if (recstatus == rsConflict || 00414 recstatus == rsOffLine || 00415 recstatus == rsTunerBusy || 00416 recstatus == rsFailed || 00417 recstatus == rsAborted || 00418 recstatus == rsMissed) 00419 state = "error"; 00420 else if (recstatus == rsWillRecord || 00421 recstatus == rsOtherShowing) 00422 { 00423 if ((m_curcard == 0 && m_curinput == 0) || 00424 pginfo->GetCardID() == m_curcard || 00425 pginfo->GetInputID() == m_curinput) 00426 { 00427 if (pginfo->GetRecordingPriority2() < 0) 00428 state = "warning"; 00429 else 00430 state = "normal"; 00431 } 00432 } 00433 else if (recstatus == rsRepeat || 00434 recstatus == rsNeverRecord || 00435 recstatus == rsDontRecord || 00436 (recstatus != rsDontRecord && 00437 recstatus <= rsEarlierShowing)) 00438 state = "disabled"; 00439 else 00440 state = "warning"; 00441 00442 MythUIButtonListItem *item = 00443 new MythUIButtonListItem(m_schedulesList,"", 00444 qVariantFromValue(pginfo)); 00445 00446 InfoMap infoMap; 00447 pginfo->ToMap(infoMap); 00448 item->SetTextFromMap(infoMap, state); 00449 00450 QString rating = QString::number(pginfo->GetStars(10)); 00451 item->DisplayState(rating, "ratingstate"); 00452 item->DisplayState(state, "status"); 00453 00454 ++pit; 00455 } 00456 00457 MythUIText *statusText = dynamic_cast<MythUIText*>(GetChild("status")); 00458 if (statusText) 00459 { 00460 if (m_conflictBool) 00461 { 00462 // Find first conflict and store in m_conflictDate field 00463 ProgramList::const_iterator it = plist.begin(); 00464 for (; it != plist.end(); ++it) 00465 { 00466 ProgramInfo &p = **it; 00467 if (p.GetRecordingStatus() == rsConflict) 00468 { 00469 m_conflictDate = p.GetRecordingStartTime().date(); 00470 break; 00471 } 00472 } 00473 00474 // TODO: This can be templated instead of hardcoding 00475 // Conflict/No Conflict 00476 QString cstring = QString(tr("Conflict %1")) 00477 .arg(MythDateToString(m_conflictDate, 00478 kDateFull | kSimplify)); 00479 00480 statusText->SetText(cstring); 00481 } 00482 else 00483 statusText->SetText(tr("No Conflicts")); 00484 } 00485 00486 MythUIText *filterText = dynamic_cast<MythUIText*>(GetChild("filter")); 00487 if (filterText) 00488 { 00489 if (m_showAll) 00490 filterText->SetText(tr("All")); 00491 else 00492 filterText->SetText(tr("Important")); 00493 } 00494 } 00495 00496 void ViewScheduled::updateInfo(MythUIButtonListItem *item) 00497 { 00498 if (!item) 00499 return; 00500 00501 ProgramInfo *pginfo = qVariantValue<ProgramInfo*> (item->GetData()); 00502 if (pginfo) 00503 { 00504 InfoMap infoMap; 00505 pginfo->ToMap(infoMap); 00506 SetTextFromMap(infoMap); 00507 00508 MythUIStateType *ratingState = dynamic_cast<MythUIStateType*> 00509 (GetChild("ratingstate")); 00510 if (ratingState) 00511 { 00512 QString rating = QString::number(pginfo->GetStars(10)); 00513 ratingState->DisplayState(rating); 00514 } 00515 } 00516 } 00517 00518 void ViewScheduled::edit() 00519 { 00520 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00521 00522 if (!item) 00523 return; 00524 00525 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00526 if (!pginfo) 00527 return; 00528 00529 EditScheduled(pginfo); 00530 } 00531 00532 void ViewScheduled::customEdit() 00533 { 00534 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00535 00536 if (!item) 00537 return; 00538 00539 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00540 EditCustom(pginfo); 00541 } 00542 00543 void ViewScheduled::deleteRule() 00544 { 00545 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00546 00547 if (!item) 00548 return; 00549 00550 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00551 if (!pginfo) 00552 return; 00553 00554 RecordingRule *record = new RecordingRule(); 00555 if (!record->LoadByProgram(pginfo)) 00556 { 00557 delete record; 00558 return; 00559 } 00560 00561 QString message = tr("Delete '%1' %2 rule?").arg(record->m_title) 00562 .arg(toString(pginfo->GetRecordingRuleType())); 00563 00564 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00565 00566 MythConfirmationDialog *okPopup = new MythConfirmationDialog(popupStack, 00567 message, true); 00568 00569 okPopup->SetReturnEvent(this, "deleterule"); 00570 okPopup->SetData(qVariantFromValue(record)); 00571 00572 if (okPopup->Create()) 00573 popupStack->AddScreen(okPopup); 00574 else 00575 delete okPopup; 00576 } 00577 00578 void ViewScheduled::upcoming() 00579 { 00580 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00581 if (!item) 00582 return; 00583 00584 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00585 00586 ShowUpcoming(pginfo); 00587 00588 //FIXME: 00589 //EmbedTVWindow(); 00590 } 00591 00592 void ViewScheduled::upcomingScheduled() 00593 { 00594 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00595 if (!item) 00596 return; 00597 00598 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00599 00600 ShowUpcomingScheduled(pginfo); 00601 00602 //FIXME: 00603 //EmbedTVWindow(); 00604 } 00605 00606 void ViewScheduled::details() 00607 { 00608 MythUIButtonListItem *item = m_schedulesList->GetItemCurrent(); 00609 00610 if (!item) 00611 return; 00612 00613 ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData()); 00614 if (pginfo) 00615 ShowDetails(pginfo); 00616 00617 EmbedTVWindow(); 00618 } 00619 00620 void ViewScheduled::selected(MythUIButtonListItem *item) 00621 { 00622 if (!item) 00623 return; 00624 00625 ProgramInfo *pginfo = qVariantValue<ProgramInfo*> (item->GetData()); 00626 if (!pginfo) 00627 return; 00628 00629 EditRecording(pginfo); 00630 } 00631 00632 void ViewScheduled::setShowAll(bool all) 00633 { 00634 m_showAll = all; 00635 m_needFill = true; 00636 } 00637 00638 void ViewScheduled::viewCards() 00639 { 00640 m_curinput = 0; 00641 m_needFill = true; 00642 00643 m_curcard++; 00644 while (m_curcard <= m_maxcard) 00645 { 00646 if (m_cardref[m_curcard] > 0) 00647 return; 00648 m_curcard++; 00649 } 00650 m_curcard = 0; 00651 } 00652 00653 void ViewScheduled::viewInputs() 00654 { 00655 m_curcard = 0; 00656 m_needFill = true; 00657 00658 m_curinput++; 00659 while (m_curinput <= m_maxinput) 00660 { 00661 if (m_inputref[m_curinput] > 0) 00662 return; 00663 m_curinput++; 00664 } 00665 m_curinput = 0; 00666 } 00667 00668 void ViewScheduled::EmbedTVWindow(void) 00669 { 00670 if (m_player) 00671 m_player->StartEmbedding(QRect()); 00672 } 00673 00674 void ViewScheduled::customEvent(QEvent *event) 00675 { 00676 if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage) 00677 { 00678 MythEvent *me = (MythEvent *)event; 00679 QString message = me->Message(); 00680 00681 if (message != "SCHEDULE_CHANGE") 00682 return; 00683 00684 m_needFill = true; 00685 00686 if (m_inEvent) 00687 return; 00688 00689 m_inEvent = true; 00690 00691 LoadList(); 00692 00693 m_inEvent = false; 00694 } 00695 else if (event->type() == DialogCompletionEvent::kEventType) 00696 { 00697 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); 00698 00699 QString resultid = dce->GetId(); 00700 QString resulttext = dce->GetResultText(); 00701 int buttonnum = dce->GetResult(); 00702 00703 if (resultid == "deleterule") 00704 { 00705 RecordingRule *record = 00706 qVariantValue<RecordingRule *>(dce->GetData()); 00707 if (record) 00708 { 00709 if (buttonnum > 0) 00710 { 00711 if (!record->Delete()) 00712 LOG(VB_GENERAL, LOG_ERR, 00713 "Failed to delete recording rule"); 00714 } 00715 delete record; 00716 } 00717 00718 EmbedTVWindow(); 00719 } 00720 else if (resultid == "menu") 00721 { 00722 if (resulttext == tr("Show Important")) 00723 { 00724 setShowAll(false); 00725 } 00726 else if (resulttext == tr("Show All")) 00727 { 00728 setShowAll(true); 00729 } 00730 else if (resulttext == tr("Program Details")) 00731 { 00732 details(); 00733 } 00734 else if (resulttext == tr("Upcoming by title")) 00735 { 00736 upcoming(); 00737 } 00738 else if (resulttext == tr("Upcoming scheduled")) 00739 { 00740 upcomingScheduled(); 00741 } 00742 else if (resulttext == tr("Custom Edit")) 00743 { 00744 customEdit(); 00745 } 00746 else if (resulttext == tr("Delete Rule")) 00747 { 00748 deleteRule(); 00749 } 00750 else if (resulttext == tr("Show Cards")) 00751 { 00752 viewCards(); 00753 } 00754 else if (resulttext == tr("Show Inputs")) 00755 { 00756 viewInputs(); 00757 } 00758 00759 if (m_needFill) 00760 LoadList(); 00761 } 00762 else 00763 ScheduleCommon::customEvent(event); 00764 } 00765 }
1.7.6.1