diff options
author | Christian Wieninger <winni@debian.(none)> | 2007-11-11 15:40:28 +0100 |
---|---|---|
committer | Christian Wieninger <winni@debian.(none)> | 2007-11-11 15:40:28 +0100 |
commit | 8d4f8607dc1558ce73eb4c376bdbf78ddb65da83 (patch) | |
tree | d0c5dde81a36ab2e8a2edc7c1e6922556518b312 /menu_main.c | |
download | vdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.gz vdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.bz2 |
Initial commit
Diffstat (limited to 'menu_main.c')
-rw-r--r-- | menu_main.c | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/menu_main.c b/menu_main.c new file mode 100644 index 0000000..85c8ee0 --- /dev/null +++ b/menu_main.c @@ -0,0 +1,519 @@ +/* +Copyright (C) 2004-2007 Christian Wieninger + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + +The author can be reached at cwieninger@gmx.de + +The project's page is at http://winni.vdr-developer.org/epgsearch +*/ + + +#include <vector> +#include "menu_main.h" +#include "menu_whatson.h" +#include "menu_myedittimer.h" +#include "epgsearchext.h" +#include "menu_event.h" +#include "menu_searchresults.h" +#include "menu_search.h" +#include "menu_commands.h" +#include "epgsearchcfg.h" +#include "epgsearchtools.h" +#include <vdr/menu.h> +#include "menu_conflictcheck.h" +#include "menu_favorites.h" +#include "menu_deftimercheckmethod.h" + +int toggleKeys=0; +int exitToMainMenu = 0; +extern int gl_InfoConflict; + +// --- cMenuSearchMain --------------------------------------------------------- +cMenuSearchMain::cMenuSearchMain(void) +:cOsdMenu("", GetTab(1), GetTab(2), GetTab(3), GetTab(4), GetTab(5)) +{ + helpKeys = -1; + otherChannel = 0; + toggleKeys = 0; + shiftTime = 0; + InWhatsOnMenu = false; + InFavoritesMenu = false; + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + if (channel) { + cMenuWhatsOnSearch::SetCurrentChannel(channel->Number()); + schedules = cSchedules::Schedules(schedulesLock); + PrepareSchedule(channel); + SetHelpKeys(); + cMenuWhatsOnSearch::currentShowMode = showNow; + } + if (EPGSearchConfig.StartMenu == 1) + { + InWhatsOnMenu = true; + AddSubMenu(new cMenuWhatsOnSearch(schedules, cDevice::CurrentChannel())); + } +} + +cMenuSearchMain::~cMenuSearchMain() +{ + cMenuWhatsOnSearch::ScheduleChannel(); // makes sure any posted data is cleared +} + +int cMenuSearchMain::GetTab(int Tab) +{ + return cTemplFile::GetTemplateByName("MenuSchedule")->Tab(Tab-1); +} + +void cMenuSearchMain::PrepareSchedule(cChannel *Channel) +{ + Clear(); + char *buffer = NULL; + asprintf(&buffer, "%s - %s", tr("Schedule"), Channel->Name()); + SetTitle(buffer); + free(buffer); + + cMenuTemplate* ScheduleTemplate = cTemplFile::GetTemplateByName("MenuSchedule"); + eventObjects.Clear(); + + if (schedules) { + const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); + currentChannel = Channel->Number(); + if (Schedule && Schedule->Events()->First()) + { + const cEvent *PresentEvent = Schedule->GetPresentEvent(); + time_t now; + if (shiftTime == 0) + now = time(NULL) - Setup.EPGLinger * 60; + else + now = time(NULL) + shiftTime * 60; + time_t lastEventDate = Schedule->Events()->First()->StartTime(); + for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) { + if (Event->EndTime() > now || (shiftTime==0 && Event == PresentEvent)) + { + if (EPGSearchConfig.showDaySeparators) + { + struct tm tm_rEvent; + struct tm tm_rLastEvent; + time_t EventDate = Event->StartTime(); + struct tm *t_event = localtime_r(&EventDate, &tm_rEvent); + struct tm *t_lastevent = localtime_r(&lastEventDate, &tm_rLastEvent); + if (t_event->tm_mday != t_lastevent->tm_mday) + { + char* szSep = NULL; + asprintf(&szSep, "----------------------------------\t %s ----------------------------------------------------------------------------------------------", GETDATESTRING(Event)); + cOsdItem* pSepItem = new cOsdItem(szSep); + free(szSep); + pSepItem->SetSelectable(false); + Add(pSepItem); + } + lastEventDate = EventDate; + } + Add(new cMenuMyScheduleItem(Event, NULL, showNow, ScheduleTemplate), Event == PresentEvent); + eventObjects.Add(Event); + } + } + } + } + if (shiftTime) + { + char *buffer = NULL; + asprintf(&buffer, "%s (%s%dh %dm)", Channel->Name(), shiftTime>0?"+":"", shiftTime/60, shiftTime%60); + SetTitle(buffer); + free(buffer); + } +} + +bool cMenuSearchMain::Update(void) +{ + bool result = false; + for (cOsdItem *item = First(); item; item = Next(item)) { + if (item->Selectable() && ((cMenuMyScheduleItem *)item)->Update()) + result = true; + } + return result; +} + +eOSState cMenuSearchMain::Record(void) +{ + cMenuMyScheduleItem *item = (cMenuMyScheduleItem *)Get(Current()); + if (item) { + if (item->timerMatch == tmFull) + { + int tm = tmNone; + cTimer *timer = Timers.GetMatch(item->event, &tm); + if (timer) + if (EPGSearchConfig.useVDRTimerEditMenu) + return AddSubMenu(new cMenuEditTimer(timer)); + else + return AddSubMenu(new cMenuMyEditTimer(timer, false, item->event, item->channel)); + } + + cTimer *timer = new cTimer(item->event); + PrepareTimerFile(item->event, timer); + cTimer *t = Timers.GetTimer(timer); + if (EPGSearchConfig.onePressTimerCreation == 0 || t || !item->event || (!t && item->event && item->event->StartTime() - (Setup.MarginStart+2) * 60 < time(NULL))) + { + if (t) + { + delete timer; + timer = t; + } + if (EPGSearchConfig.useVDRTimerEditMenu) + return AddSubMenu(new cMenuEditTimer(timer, !t)); + else + return AddSubMenu(new cMenuMyEditTimer(timer, !t, item->event)); + } + else + { + string fullaux = ""; + string aux = ""; + if (item->event) + { + const cEvent* event = item->event; + int bstart = event->StartTime() - timer->StartTime(); + int bstop = timer->StopTime() - event->EndTime(); + int checkmode = DefTimerCheckModes.GetMode(timer->Channel()); + aux = UpdateAuxValue(aux, "channel", NumToString(timer->Channel()->Number()) + " - " + CHANNELNAME(timer->Channel())); + aux = UpdateAuxValue(aux, "update", checkmode); + aux = UpdateAuxValue(aux, "eventid", event->EventID()); + aux = UpdateAuxValue(aux, "bstart", bstart); + aux = UpdateAuxValue(aux, "bstop", bstop); + fullaux = UpdateAuxValue(fullaux, "epgsearch", aux); + } +#ifdef USE_PINPLUGIN + aux = ""; + aux = UpdateAuxValue(aux, "protected", timer->FskProtection() ? "yes" : "no"); + fullaux = UpdateAuxValue(fullaux, "pin-plugin", aux); +#endif + + SetAux(timer, fullaux); + Timers.Add(timer); + timer->Matches(); + Timers.SetModified(); + LogFile.iSysLog("timer %s added (active)", *timer->ToDescr()); + + if (HasSubMenu()) + CloseSubMenu(); + if (Update()) + Display(); + SetHelpKeys(); + } + } + return osContinue; +} + +eOSState cMenuSearchMain::Switch(void) +{ + cMenuMyScheduleItem *item = (cMenuMyScheduleItem *)Get(Current()); + if (item) { + cChannel *channel = Channels.GetByChannelID(item->event->ChannelID(), true, true); + if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true)) + return osEnd; + } + Skins.Message(mtInfo, tr("Can't switch channel!")); + return osContinue; +} + +eOSState cMenuSearchMain::ExtendedSearch(void) +{ + return AddSubMenu(new cMenuEPGSearchExt()); +} + +eOSState cMenuSearchMain::Commands(eKeys Key) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuMyScheduleItem *mi = (cMenuMyScheduleItem *)Get(Current()); + if (mi && mi->event) { + cMenuSearchCommands *menu; + eOSState state = AddSubMenu(menu = new cMenuSearchCommands(tr("EPG Commands"), mi->event, true)); + if (Key != kNone) + state = menu->ProcessKey(Key); + return state; + } + return osContinue; +} + +eOSState cMenuSearchMain::ShowSummary() +{ + if (Count()) + { + cMenuMyScheduleItem *mi = (cMenuMyScheduleItem *)Get(Current()); + if (mi && mi->event) + return AddSubMenu(new cMenuEventSearch(mi->event, eventObjects, SurfModeTime)); + } + return osContinue; +} + +void cMenuSearchMain::SetHelpKeys(bool Force) +{ + cMenuMyScheduleItem *item = (cMenuMyScheduleItem *)Get(Current()); + int NewHelpKeys = 0; + if (item) { + if (item->Selectable() && item->timerMatch == tmFull) + NewHelpKeys = 2; + else + NewHelpKeys = 1; + } + + bool hasTimer = (NewHelpKeys == 2); + if (NewHelpKeys != helpKeys || Force) + { + if (toggleKeys==0) + SetHelp((EPGSearchConfig.redkeymode==0?(hasTimer?trVDR("Button$Timer"):trVDR("Button$Record")):tr("Button$Commands")), trVDR("Button$Now"), trVDR("Button$Next"), EPGSearchConfig.bluekeymode==0?trVDR("Button$Switch"):tr("Button$Search")); + else + { + const char* szGreenToggled = CHANNELNAME(Channels.GetByNumber(currentChannel-1,-1)); + const char* szYellowToggled = CHANNELNAME(Channels.GetByNumber(currentChannel+1,1)); + + SetHelp((EPGSearchConfig.redkeymode==1?(hasTimer?trVDR("Button$Timer"):trVDR("Button$Record")):tr("Button$Commands")), (EPGSearchConfig.toggleGreenYellow==0?trVDR("Button$Now"):szGreenToggled), (EPGSearchConfig.toggleGreenYellow==0?trVDR("Button$Next"):szYellowToggled), EPGSearchConfig.bluekeymode==1?trVDR("Button$Switch"):tr("Button$Search")); + + } + helpKeys = NewHelpKeys; + } +} + +eOSState cMenuSearchMain::Shift(int iMinutes) +{ + shiftTime += iMinutes; + cChannel *channel = Channels.GetByNumber(currentChannel); + PrepareSchedule(channel); + Display(); + SetHelpKeys(); + return osContinue; +} + +void cMenuSearchMain::UpdateCurrent() +{ + // navigation in summary could have changed current item, so update it + cEventObj* cureventObj = eventObjects.GetCurrent(); + if (cureventObj && cureventObj->Event()) + for (cMenuMyScheduleItem *item = (cMenuMyScheduleItem *)First(); item; item = (cMenuMyScheduleItem *)Next(item)) + if (item->event == cureventObj->Event()) + { + cureventObj->Select(false); + SetCurrent(item); + Display(); + break; + } +} + +eOSState cMenuSearchMain::ProcessKey(eKeys Key) +{ + bool HadSubMenu = HasSubMenu(); + eOSState state = cOsdMenu::ProcessKey(Key); + + if (exitToMainMenu == 1) + { + exitToMainMenu = 0; + return osBack; + } + + if (!HasSubMenu() && HadSubMenu) + UpdateCurrent(); + + if (state == osUnknown) { + switch (Key) { + case kFastRew: + if (HasSubMenu() && !InWhatsOnMenu && !InFavoritesMenu) + { +/* if (Count()) + { + CursorUp(); + return ShowSummary(); + } +*/ } + else + return Shift(-EPGSearchConfig.timeShiftValue); + case kFastFwd: + if (HasSubMenu() && !InWhatsOnMenu && !InFavoritesMenu) + { +/* if (Count()) + { + CursorDown(); + return ShowSummary(); + } +*/ } + else + return Shift(EPGSearchConfig.timeShiftValue); + case kRecord: + case kRed: + if(HasSubMenu()) { + UpdateCurrent(); + state = Record(); + break; + } + if (Count()) + { + if (EPGSearchConfig.redkeymode==toggleKeys) + state = Record(); + else + { + cMenuMyScheduleItem *mi = (cMenuMyScheduleItem *)Get(Current()); + if (mi) { + if (mi->event) { + return AddSubMenu(new cMenuSearchCommands(tr("EPG Commands"),mi->event)); + } + } + } + } + break; + case k0: + if(!HasSubMenu()) + { + toggleKeys = 1 - toggleKeys; + SetHelpKeys(true); + } + state = osContinue; + break; + case k1...k9: + if (!HasSubMenu()) + return Commands(Key); + else + state = osContinue; + break; + case kGreen: + if (schedules) + { + if (HasSubMenu() && !InWhatsOnMenu && !InFavoritesMenu) + { + if (Count()) + { +// CursorUp(); +// return ShowSummary(); + } + } + else if (toggleKeys == 0 || (toggleKeys == 1 && EPGSearchConfig.toggleGreenYellow == 0)) + { + int ChannelNr = cDevice::CurrentChannel(); + if (Count()) { + cMenuMyScheduleItem* Item = (cMenuMyScheduleItem *)Get(Current()); + if (Item && Item->event) + { + cChannel *channel = Channels.GetByChannelID(Item->event->ChannelID(), true, true); + if (channel) + ChannelNr = channel->Number(); + } + } + if (cMenuWhatsOnSearch::currentShowMode == showFavorites) + { + InFavoritesMenu = true; + return AddSubMenu(new cMenuFavorites()); + } + else + { + InWhatsOnMenu = true; + return AddSubMenu(new cMenuWhatsOnSearch(schedules, ChannelNr)); + } + } + else + { + cChannel *channel = Channels.GetByNumber(currentChannel-1,-1); + + if (channel) { + PrepareSchedule(channel); + if (channel->Number() != cDevice::CurrentChannel()) { + otherChannel = channel->Number(); + } + Display(); + } + SetHelpKeys(); + return osContinue; + } + } + case kYellow: + if (schedules) + { + if (HasSubMenu()) + { + if (Count()) + { +// CursorDown(); +// return ShowSummary(); + } + } + else if (toggleKeys == 0 || (toggleKeys == 1 && EPGSearchConfig.toggleGreenYellow == 0)) + { + cMenuWhatsOnSearch::currentShowMode = showNext; + InWhatsOnMenu = true; + return AddSubMenu(new cMenuWhatsOnSearch(schedules, cMenuWhatsOnSearch::CurrentChannel())); + } + else + { + cChannel *channel = Channels.GetByNumber(currentChannel+1,1); + if (channel) { + PrepareSchedule(channel); + if (channel->Number() != cDevice::CurrentChannel()) { + otherChannel = channel->Number(); + } + Display(); + } + SetHelpKeys(); + return osContinue; + } + } + break; + case kBlue: + if (HasSubMenu()) + { + UpdateCurrent(); + return Switch(); + } + if (EPGSearchConfig.bluekeymode==toggleKeys) + return Switch(); + else + return ExtendedSearch(); + break; + case kOk: + if (Count()) + return ShowSummary(); + break; + default: + break; + } + } + if (!HasSubMenu()) { + cChannel *ch = cMenuWhatsOnSearch::ScheduleChannel(); + InWhatsOnMenu = false; + InFavoritesMenu = false; + if (ch) { + PrepareSchedule(ch); + if (ch->Number() != cDevice::CurrentChannel()) { + otherChannel = ch->Number(); + } + Display(); + } + else if ((HadSubMenu || gl_TimerProgged) && Update()) + { + if (gl_TimerProgged) // when using epgsearch's timer edit menu, update is delayed because of SVDRP + { + gl_TimerProgged = 0; + SetHelpKeys(); + } + Display(); + } + if (Key != kNone) + SetHelpKeys(); + if (gl_InfoConflict) + { + gl_InfoConflict = 0; + if (Interface->Confirm(tr("Timer conflict! Show?"))) + return AddSubMenu(new cMenuConflictCheck()); + } + } + return state; +} + |