vdr-plugin-tvguide/recmenumanager.c

554 lines
21 KiB
C

#include "recmenu.h"
#include "recmenus.h"
#include "switchtimer.h"
#include "recmenumanager.h"
cRecMenuManager::cRecMenuManager(void) {
active = false;
activeMenu = NULL;
activeMenuBuffer = NULL;
recManager = new cRecManager();
recManager->SetEPGSearchPlugin();
instantRecord = false;
folderChoosen = false;
currentConflict = -1;
templateID = -1;
timer = NULL;
recFolder = "";
searchWithOptions = false;
detailViewActive = false;
}
cRecMenuManager::~cRecMenuManager(void) {
if (activeMenu) {
active = false;
delete activeMenu;
activeMenu = NULL;
}
delete recManager;
}
void cRecMenuManager::Start(const cEvent *event) {
active = true;
activeMenuBuffer = NULL;
instantRecord = false;
folderChoosen = false;
currentConflict = -1;
templateID = -1;
timer = NULL;
recFolder = "";
searchWithOptions = false;
detailViewActive = false;
SetBackground();
this->event = event;
activeMenu = new cRecMenuMain(recManager->EpgSearchAvailable(), recManager->CheckEventForTimer(event), SwitchTimers.EventInSwitchList(event));
activeMenu->Display();
osdManager.flush();
}
void cRecMenuManager::Close(void) {
event = NULL;
active = false;
if (activeMenu) {
delete activeMenu;
activeMenu = NULL;
}
DeleteBackground();
}
void cRecMenuManager::SetBackground(void) {
int backgroundWidth = geoManager.osdWidth;
int backgroundHeight = geoManager.osdHeight;
pixmapBackground = osdManager.requestPixmap(3, cRect(0, 0, backgroundWidth, backgroundHeight));
pixmapBackground->Fill(theme.Color(clrRecMenuBackground));
if (tvguideConfig.scaleVideo) {
int tvHeight = geoManager.statusHeaderHeight;
int tvWidth = tvHeight * 16 / 9;
int tvX = geoManager.osdWidth - tvWidth;
pixmapBackground->DrawRectangle(cRect(tvX, 0, tvWidth, tvHeight), clrTransparent);
}
}
void cRecMenuManager::DeleteBackground(void) {
osdManager.releasePixmap(pixmapBackground);
}
eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
eOSState state = osContinue;
switch (nextState) {
/*
* --------- INSTANT RECORDING ---------------------------
*/
case rmsInstantRecord: {
//Creating timer for active Event
//if no conflict, confirm and exit
instantRecord = true;
cString folder = "";
if (folderChoosen) {
int activeItem = activeMenu->GetActive(false);
if (activeItem > 0)
folder = activeMenu->GetStringValue(activeItem);
}
delete activeMenu;
cTimer *timer = recManager->createTimer(event, *folder);
if (!displayTimerConflict(timer)) {
activeMenu = new cRecMenuConfirmTimer(event);
activeMenu->Display();
}
break; }
case rmsInstantRecordFolder:
//Asking for Folder
folderChoosen = true;
delete activeMenu;
activeMenu = new cRecMenuAskFolder(event, rmsInstantRecord);
activeMenu->Display();
break;
case rmsIgnoreTimerConflict:
//Confirming created Timer
if (instantRecord) {
delete activeMenu;
activeMenu = new cRecMenuConfirmTimer(event);
activeMenu->Display();
} else {
state = osEnd;
Close();
}
break;
case rmsTimerConflictShowInfo: {
int timerIndex = activeMenu->GetActive(true);
int timerID = conflictList[currentConflict].timerIDs[timerIndex];
cTimer *t = Timers.Get(timerID);
if (t) {
const cEvent *ev = t->Event();
if (ev) {
activeMenu->Hide();
detailView = new cDetailView(ev);
detailView->drawHeader();
detailView->drawContent();
detailView->drawScrollbar();
detailViewActive = true;
}
}
break;}
case rmsDeleteTimerConflictMenu: {
//delete timer out of current timer conflict
//active menu: cRecMenuTimerConflict
int timerIndex = activeMenu->GetActive(true);
int timerID = conflictList[currentConflict].timerIDs[timerIndex];
recManager->DeleteTimer(timerID);
delete activeMenu;
if (!displayTimerConflict(timerID)) {
activeMenu = new cRecMenuConfirmTimer(event);
activeMenu->Display();
}
break; }
case rmsEditTimerConflictMenu: {
//edit timer out of current timer conflict
//active menu: cRecMenuTimerConflict
int activeItem = activeMenu->GetActive(true);
int timerID = conflictList[currentConflict].timerIDs[activeItem];
timer = Timers.Get(timerID);
if (timer) {
delete activeMenu;
activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimerConflictMenu);
activeMenu->Display();
}
break; }
case rmsSaveTimerConflictMenu: {
//save timer from current timer conflict
recManager->SaveTimer(timer, activeMenu);
delete activeMenu;
if (!displayTimerConflict(timer)) {
activeMenu = new cRecMenuConfirmTimer(event);
activeMenu->Display();
}
break; }
case rmsDeleteTimer:
//delete timer for active event
delete activeMenu;
if (recManager->IsRecorded(event)) {
activeMenu = new cRecMenuAskDeleteTimer(event);
} else {
recManager->DeleteTimer(event);
activeMenu = new cRecMenuConfirmDeleteTimer(event);
}
activeMenu->Display();
break;
case rmsDeleteTimerConfirmation:
//delete running timer for active event
recManager->DeleteTimer(event);
delete activeMenu;
activeMenu = new cRecMenuConfirmDeleteTimer(event);
activeMenu->Display();
break;
case rmsEditTimer: {
//edit timer for active event
timer = recManager->GetTimerForEvent(event);
if (timer) {
delete activeMenu;
activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimer);
activeMenu->Display();
}
break; }
case rmsSaveTimer: {
//save timer for active event
recManager->SaveTimer(timer, activeMenu);
state = osEnd;
Close();
break; }
/*
* --------- SERIES TIMER ---------------------------------
*/
case rmsSeriesTimer: {
recFolder = "";
if (folderChoosen) {
int activeItem = activeMenu->GetActive(false);
if (activeItem > 0)
recFolder = activeMenu->GetStringValue(activeItem);
}
delete activeMenu;
cChannel *channel = Channels.GetByChannelID(event->ChannelID());
activeMenu = new cRecMenuSeriesTimer(channel, event);
activeMenu->Display();
break; }
case rmsSeriesTimerFolder:
//Asking for Folder
folderChoosen = true;
delete activeMenu;
activeMenu = new cRecMenuAskFolder(event, rmsSeriesTimer);
activeMenu->Display();
break;
case rmsSeriesTimerCreate: {
cTimer *seriesTimer = recManager->CreateSeriesTimer(activeMenu, *recFolder);
delete activeMenu;
activeMenu = new cRecMenuConfirmSeriesTimer(seriesTimer);
activeMenu->Display();
break; }
/*
* --------- SEARCH TIMER ---------------------------------
*/
case rmsSearchTimer:
delete activeMenu;
activeMenu = new cRecMenuSearchTimer(event);
activeMenu->Display();
break;
case rmsSearchTimerOptions: {
searchString = *activeMenu->GetStringValue(1);
delete activeMenu;
if (isempty(*searchString)) {
activeMenu = new cRecMenuSearchTimer(event);
} else {
epgSearchTemplates = recManager->ReadEPGSearchTemplates();
int numTemplates = epgSearchTemplates.size();
if (numTemplates > 0) {
activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates);
} else {
activeMenu = new cRecMenuSearchTimerOptions(searchString);
}
}
activeMenu->Display();
break; }
case rmsSearchTimerOptionsReload: {
int numTemplates = epgSearchTemplates.size();
delete activeMenu;
activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates);
activeMenu->Display();
break; }
case rmsSearchTimerUseTemplate: {
templateID = activeMenu->GetActive(true) - 1;
delete activeMenu;
activeMenu = new cRecMenuSearchTimerTemplatesCreate(searchString, epgSearchTemplates[templateID].name.c_str());
activeMenu->Display();
break; }
case rmsSearchTimerOptionsManually:
delete activeMenu;
activeMenu = new cRecMenuSearchTimerOptions(searchString);
activeMenu->Display();
break;
case rmsSearchTimerTestTemplate: {
std::string epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue);
int numSearchResults = 0;
const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults);
if (searchResult) {
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, epgSearchTemplates[templateID].name);
activeMenu->Display();
} else {
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchTimerNothingFound(searchString, epgSearchTemplates[templateID].name);
activeMenu->Display();
}
break; }
case rmsSearchTimerTestManually: {
std::string epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu);
int numSearchResults = 0;
const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults);
if (searchResult) {
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, "");
activeMenu->Display();
} else {
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchTimerNothingFound(searchString, "");
activeMenu->Display();
}
break; }
case rmsSearchTimerNothingFoundConfirm:
delete activeMenu;
activeMenu = activeMenuBuffer;
activeMenuBuffer = NULL;
activeMenu->Show();
break;
case rmsSearchTimerCreateManually:
case rmsSearchTimerCreateTemplate: {
std::string epgSearchString;
if (nextState == rmsSearchTimerCreateManually) {
epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu);
} else if (nextState = rmsSearchTimerCreateTemplate) {
epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue);
}
bool success = createSearchTimer(epgSearchString);
delete activeMenu;
activeMenu = new cRecMenuSearchTimerCreateConfirm(success);
activeMenu->Display();
break; }
/*
* --------- SWITCH TIMER ---------------------------------
*/
case rmsSwitchTimer:
delete activeMenu;
activeMenu = new cRecMenuSwitchTimer();
activeMenu->Display();
break;
case rmsSwitchTimerCreate: {
bool success = recManager->CreateSwitchTimer(event, activeMenu);
delete activeMenu;
activeMenu = new cRecMenuSwitchTimerConfirm(success);
activeMenu->Display();
break; }
case rmsSwitchTimerDelete:
recManager->DeleteSwitchTimer(event);
delete activeMenu;
activeMenu = new cRecMenuSwitchTimerDelete();
activeMenu->Display();
break;
/*
* --------- RECORDINGS SEARCH ---------------------------------
*/
case rmsRecordingSearch:
delete activeMenu;
activeMenu = new cRecMenuRecordingSearch(event);
activeMenu->Display();
break;
case rmsRecordingSearchResult: {
searchString = activeMenu->GetStringValue(1);
delete activeMenu;
if (isempty(*searchString)) {
activeMenu = new cRecMenuRecordingSearch(event);
} else {
int numSearchResults = 0;
cRecording **searchResult = recManager->SearchForRecordings(searchString, numSearchResults);
if (numSearchResults == 0) {
activeMenu = new cRecMenuRecordingSearchNotFound(searchString);
} else {
activeMenu = new cRecMenuRecordingSearchResults(searchString, searchResult, numSearchResults);
}
}
activeMenu->Display();
break; }
/*
* --------- SEARCH ---------------------------------
*/
case rmsSearch:
delete activeMenu;
activeMenu = new cRecMenuSearch(event);
activeMenu->Display();
searchWithOptions = false;
break;
case rmsSearchWithOptions: {
cString searchString = activeMenu->GetStringValue(1);
delete activeMenu;
if (isempty(*searchString)) {
activeMenu = new cRecMenuSearch(event);
} else {
activeMenu = new cRecMenuSearch(event, *searchString);
searchWithOptions = true;
}
activeMenu->Display();
break; }
case rmsSearchPerform: {
cString searchString = activeMenu->GetStringValue(1);
if (isempty(*searchString)) {
delete activeMenu;
activeMenu = new cRecMenuSearch(event);
} else {
int numSearchResults = 0;
const cEvent **searchResult = recManager->PerformSearch(activeMenu, searchWithOptions, numSearchResults);
if (searchResult) {
delete activeMenu;
activeMenu = new cRecMenuSearchResults(searchString, searchResult, numSearchResults);
} else {
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchNothingFound(searchString);
}
}
activeMenu->Display();
break; }
case rmsSearchNothingFoundConfirm:
delete activeMenu;
activeMenu = activeMenuBuffer;
activeMenuBuffer = NULL;
activeMenu->Show();
break;
case rmsSearchShowInfo: {
const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false));
if (ev) {
activeMenu->Hide();
detailView = new cDetailView(ev);
detailView->drawHeader();
detailView->drawContent();
detailView->drawScrollbar();
detailViewActive = true;
}
break;}
case rmsSearchRecord: {
const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false));
cTimer *timer = recManager->createTimer(ev, "");
activeMenuBuffer = activeMenu;
activeMenuBuffer->Hide();
activeMenu = new cRecMenuSearchConfirmTimer(ev);
activeMenu->Display();
break;}
case rmsSearchRecordConfirm:
delete activeMenu;
activeMenu = activeMenuBuffer;
activeMenuBuffer = NULL;
activeMenu->Show();
break;
/*
* --------- CHECK FOR TIMER CONFLICTS ---------------------------------
*/
case rmsTimerConflicts: {
//Show timer conflict
//active menu: cRecMenuTimerConflicts
conflictList = recManager->CheckTimerConflict();
delete activeMenu;
int numConflicts = conflictList.size();
if (numConflicts > 0) {
activeMenu = new cRecMenuTimerConflicts(conflictList);
} else {
activeMenu = new cRecMenuNoTimerConflict();
}
activeMenu->Display();
break; }
case rmsTimerConflict:
//Show timer conflict
//active menu: cRecMenuTimerConflicts
currentConflict = activeMenu->GetActive(true);
delete activeMenu;
activeMenu = new cRecMenuTimerConflict(conflictList[currentConflict]);
activeMenu->Display();
break;
/*
* --------- COMMON ---------------------------------
*/
case rmsClose: {
if (activeMenuBuffer == NULL) {
state = osEnd;
Close();
} else {
delete activeMenu;
activeMenu = activeMenuBuffer;
activeMenuBuffer = NULL;
activeMenu->Show();
state = osContinue;
}
break; }
default:
break;
}
return state;
}
bool cRecMenuManager::displayTimerConflict(cTimer *timer) {
int timerID = 0;
for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) {
if (t == timer)
return displayTimerConflict(timerID);
timerID++;
}
return false;
}
bool cRecMenuManager::displayTimerConflict(int timerID) {
conflictList = recManager->CheckTimerConflict();
int numConflicts = conflictList.size();
int showTimerConflict = -1;
if (numConflicts > 0) {
for (int i=0; i<numConflicts; i++) {
if (conflictList[i].timerInvolved(timerID)) {
showTimerConflict = i;
break;
}
}
}
if (showTimerConflict > -1) {
currentConflict = showTimerConflict;
activeMenu = new cRecMenuTimerConflict(conflictList[currentConflict]);
activeMenu->Display();
return true;
}
return false;
}
bool cRecMenuManager::createSearchTimer(std::string epgSearchString) {
int newTimerID = recManager->CreateSearchTimer(epgSearchString);
bool success = false;
if (newTimerID > -1) {
recManager->UpdateSearchTimers();
success = true;
}
return success;
}
eOSState cRecMenuManager::ProcessKey(eKeys Key) {
eOSState state = osContinue;
eRecMenuState nextState = rmsContinue;
if (!activeMenu)
return state;
if (detailViewActive) {
state = detailView->ProcessKey(Key);
if (state == osEnd) {
delete detailView;
detailView = NULL;
detailViewActive = false;
activeMenu->Show();
state = osContinue;
}
} else {
nextState = activeMenu->ProcessKey(Key);
if ((nextState == rmsClose) || ((nextState == rmsNotConsumed)&&(Key == kBack))){
if (activeMenuBuffer == NULL) {
state = osEnd;
Close();
} else {
delete activeMenu;
activeMenu = activeMenuBuffer;
activeMenuBuffer = NULL;
activeMenu->Show();
state = osContinue;
osdManager.flush();
}
return state;
}
state = StateMachine(nextState);
}
osdManager.flush();
return state;
}