diff options
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 304 |
1 files changed, 303 insertions, 1 deletions
@@ -4,15 +4,17 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.36 2000/10/08 16:11:22 kls Exp $ + * $Id: menu.c 1.37 2000/10/29 11:23:33 kls Exp $ */ #include "menu.h" #include <ctype.h> #include <limits.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "config.h" +#include "eit.h" #define MENUTIMEOUT 120 // seconds @@ -973,6 +975,300 @@ eOSState cMenuTimers::ProcessKey(eKeys Key) return state; } +// --- cMenuEventItem -------------------------------------------------------- + +class cMenuEventItem : public cOsdItem { +public: + cMenuEventItem(const char *Text); +}; + +cMenuEventItem::cMenuEventItem(const char *Text) +:cOsdItem(Text, osBack) +{ +} + +// --- cMenuEvent ------------------------------------------------------------ + +class cMenuEvent : public cOsdMenu { +private: + void AddParagraph(const char *text); + const cEventInfo *eventInfo; +public: + cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch = false); +}; + +cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch) +:cOsdMenu("Event", 1) +{ + const char *p; + char buffer[MenuColumns + 1]; + + eventInfo = EventInfo; + + cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID()); + + snprintf(buffer, sizeof(buffer), "\t%-17.*s %.*s %s - %s", 17, channel->name, 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString()); + Add(new cMenuEventItem(buffer)); + if ((p = eventInfo->GetTitle()) != NULL && *p) { + Add(new cMenuEventItem("")); + AddParagraph(p); + } + if ((p = eventInfo->GetSubtitle()) != NULL && *p) { + Add(new cMenuEventItem("")); + AddParagraph(p); + } + if ((p = eventInfo->GetExtendedDescription()) != NULL && *p) { + Add(new cMenuEventItem("")); + AddParagraph(p); + } + SetHelp("Record", NULL, NULL, CanSwitch ? "Switch" : NULL); +} + +void cMenuEvent::AddParagraph(const char *text) +{ + char *ptextsave = strdup(text); + + if (ptextsave) { + + int column = 1; + char buffer[MenuColumns + 1]; + char *pStart = ptextsave; + char *pEndText = &ptextsave[strlen(text) - 1]; + + while (pStart < pEndText) { + char *pEnd; + if (strlen(pStart) > (unsigned)(MenuColumns - column - 2)) + pEnd = &pStart[MenuColumns - column - 2]; + else + pEnd = &pStart[strlen(pStart)]; + + while (*pEnd && *pEnd != ' ' && pEnd > pStart) + pEnd--; + + *pEnd = 0; + sprintf(buffer, "\t%s", pStart); + Add(new cMenuEventItem(buffer)); + pStart = pEnd + 1; + } + } + + delete ptextsave; +} + +// --- cMenuWhatsOnItem ------------------------------------------------------ + +class cMenuWhatsOnItem : public cOsdItem { +public: + const cEventInfo *eventInfo; + cMenuWhatsOnItem(const cEventInfo *EventInfo); +}; + +cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo) +{ + eventInfo = EventInfo; + char *buffer = NULL; + cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber()); + asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->name : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); + SetText(buffer, false); +} + +// --- cMenuWhatsOn ---------------------------------------------------------- + +class cMenuWhatsOn : public cOsdMenu { +private: + eOSState Record(void); + eOSState Switch(void); +public: + cMenuWhatsOn(const cSchedules *Schedules, bool Now); + virtual eOSState ProcessKey(eKeys Key); + }; + +static int CompareEventChannel(const void *p1, const void *p2) +{ + return (int)( (*(const cEventInfo **)p1)->GetChannelNumber() - (*(const cEventInfo **)p2)->GetChannelNumber()); +} + +cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now) +:cOsdMenu(Now ? "What's on now?" : "What's on next?", 4, 7, 6) +{ + const cSchedule *Schedule = Schedules->First(); + const cEventInfo **pArray = NULL; + int num = 0; + + while (Schedule) { + pArray = (const cEventInfo **)realloc(pArray, (num + 1) * sizeof(cEventInfo *)); + + pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); + if (pArray[num]) { + cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID()); + if (channel) { + pArray[num]->SetChannelNumber(channel->number); + num++; + } + } + Schedule = (const cSchedule *)Schedules->Next(Schedule); + } + + qsort(pArray, num, sizeof(cEventInfo *), CompareEventChannel); + + for (int a = 0; a < num; a++) + Add(new cMenuWhatsOnItem(pArray[a])); + + delete pArray; + SetHelp("Record", Now ? "Next" : "Now", "Schedule", "Switch"); +} + +eOSState cMenuWhatsOn::Switch(void) +{ + cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current()); + if (item) { + cChannel *channel = Channels.GetByServiceID(item->eventInfo->GetServiceID()); + if (channel && channel->Switch()) + return osEnd; + } + Interface->Error("Can't switch channel!"); + return osContinue; +} + +eOSState cMenuWhatsOn::Record(void) +{ + cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current()); + if (item) { + cTimer *timer = new cTimer(item->eventInfo); + Timers.Add(timer); + Timers.Save(); + isyslog(LOG_INFO, "timer %d added", timer->Index() + 1); + return AddSubMenu(new cMenuEditTimer(timer->Index(), true)); + } + return osContinue; +} + +eOSState cMenuWhatsOn::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kRed: return Record(); + case kYellow: return osBack; + case kBlue: return Switch(); + case kOk: return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->eventInfo, true)); + default: break; + } + } + return state; +} + +// --- cMenuScheduleItem ----------------------------------------------------- + +class cMenuScheduleItem : public cOsdItem { +public: + const cEventInfo *eventInfo; + cMenuScheduleItem(const cEventInfo *EventInfo); +}; + +cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo) +{ + eventInfo = EventInfo; + char *buffer = NULL; + asprintf(&buffer, "%.*s\t%.*s\t%s", 5, eventInfo->GetDate(), 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); + SetText(buffer, false); +} + +// --- cMenuSchedule --------------------------------------------------------- + +class cMenuSchedule : public cOsdMenu { +private: + cThreadLock threadLock; + const cSchedules *schedules; + bool now, next; + eOSState Record(void); + void PrepareSchedule(void); + void PrepareWhatsOnNext(bool On); +public: + cMenuSchedule(void); + virtual eOSState ProcessKey(eKeys Key); + }; + +cMenuSchedule::cMenuSchedule(void) +:cOsdMenu("Schedule", 6, 6) +{ + now = next = false; + cChannel *channel = Channels.GetByNumber(CurrentChannel); + if (channel) { + char *buffer = NULL; + asprintf(&buffer, "Schedule - %s", channel->name); + SetTitle(buffer, false); + } + PrepareSchedule(); + SetHelp("Record", "Now", "Next"); +} + +static int CompareEventTime(const void *p1, const void *p2) +{ + return (int)((*(cEventInfo **)p1)->GetTime() - (*(cEventInfo **)p2)->GetTime()); +} + +void cMenuSchedule::PrepareSchedule(void) +{ + schedules = cDvbApi::PrimaryDvbApi->Schedules(&threadLock); + if (schedules) { + const cSchedule *Schedule = schedules->GetSchedule(); + int num = Schedule->NumEvents(); + const cEventInfo **pArray = (const cEventInfo **)malloc(num * sizeof(cEventInfo *)); + if (pArray) { + time_t now = time(NULL); + int numreal = 0; + for (int a = 0; a < num; a++) { + const cEventInfo *EventInfo = Schedule->GetEventNumber(a); + if (EventInfo->GetTime() + EventInfo->GetDuration() > now) + pArray[numreal++] = EventInfo; + } + + qsort(pArray, numreal, sizeof(cEventInfo *), CompareEventTime); + + for (int a = 0; a < numreal; a++) + Add(new cMenuScheduleItem(pArray[a])); + delete pArray; + } + } +} + +eOSState cMenuSchedule::Record(void) +{ + cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current()); + if (item) { + cTimer *timer = new cTimer(item->eventInfo); + Timers.Add(timer); + Timers.Save(); + isyslog(LOG_INFO, "timer %d added", timer->Index() + 1); + return AddSubMenu(new cMenuEditTimer(timer->Index(), true)); + } + return osContinue; +} + +eOSState cMenuSchedule::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kRed: return Record(); + case kGreen: if (!now && !next) { + now = true; + return AddSubMenu(new cMenuWhatsOn(schedules, true)); + } + now = !now; + next = !next; + return AddSubMenu(new cMenuWhatsOn(schedules, now)); + case kYellow: return AddSubMenu(new cMenuWhatsOn(schedules, false)); + case kOk: return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->eventInfo)); + default: break; + } + } + return state; +} + // --- cMenuRecordingItem ---------------------------------------------------- class cMenuRecordingItem : public cOsdItem { @@ -1089,6 +1385,9 @@ cMenuSetup::cMenuSetup(void) Add(new cMenuEditBoolItem("MarkInstantRecord", &data.MarkInstantRecord)); Add(new cMenuEditIntItem( "LnbFrequLo", &data.LnbFrequLo)); Add(new cMenuEditIntItem( "LnbFrequHi", &data.LnbFrequHi)); + Add(new cMenuEditIntItem( "SetSystemTime", &data.SetSystemTime)); + Add(new cMenuEditIntItem( "MarginStart", &data.MarginStart)); + Add(new cMenuEditIntItem( "MarginStop", &data.MarginStop)); } eOSState cMenuSetup::ProcessKey(eKeys Key) @@ -1098,6 +1397,7 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack; + cDvbApi::PrimaryDvbApi->SetUseTSTime(data.SetSystemTime); Setup = data; Setup.Save(); break; @@ -1114,6 +1414,7 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) cMenuMain::cMenuMain(bool Replaying) :cOsdMenu("Main") { + Add(new cOsdItem("Schedule", osSchedule)); Add(new cOsdItem("Channels", osChannels)); Add(new cOsdItem("Timer", osTimer)); Add(new cOsdItem("Recordings", osRecordings)); @@ -1137,6 +1438,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key) eOSState state = cOsdMenu::ProcessKey(Key); switch (state) { + case osSchedule: return AddSubMenu(new cMenuSchedule); case osChannels: return AddSubMenu(new cMenuChannels); case osTimer: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); |