diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2006-01-15 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2006-01-15 18:00:00 +0100 |
commit | 78e3da813cb4345e57934a9a60f6316f1e257307 (patch) | |
tree | 2ce53c2872dd7451c0647ad50fe81306ad985bc0 /menu.c | |
parent | da948a50d2318fd9c818a4b969b74555ce577b1e (diff) | |
download | vdr-patch-lnbsharing-78e3da813cb4345e57934a9a60f6316f1e257307.tar.gz vdr-patch-lnbsharing-78e3da813cb4345e57934a9a60f6316f1e257307.tar.bz2 |
Version 1.3.39vdr-1.3.39
- The SVDRP command LSTT now accepts the new option 'id' to have the channels
of the timers listed with their unique channel ids instead of their numbers
(suggested by Matthias Schniedermeyer).
- Added a missing #include <linux/unistd.h> to thread.c (thanks to Ville Skyttä).
- Fixed the "plugins-clean" and "plugins-install" targets in the Makefile (thanks
to Andreas Brachold).
- Fixed handling "more than 3 byte" key sequences in cKbdRemote::ReadKeySequence()
(thanks to Peter Bieringer). If you are using the PC keyboard as remote control
input you may need to make VDR newly learn the keys by removing the remote.conf
file.
- To avoid problems with access rights when VDR shall run as 'root' it now skips
all SetCaps() and SetUser() calls when it is started as 'root' and "-u root"
is given.
- Added missing i18n entry for the "Timer" button (thanks to Ville Skyttä)
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Making the "Menu" key behave consistently has not been well received by several
users, so the new option "Setup/OSD/Menu button closes" can be used to get the
old behavior back (which also is the default value of this option).
- Dropped the default vdr user. The program now always runs under the user id
it was started from, unless the '-u' option is given and it was started from
the 'root' user. If you want to have a default vdr user, you can activate and
adjust the "VDR_USER = vdr" line in your Make.config file (from the original
patch by Ludwig Nussel).
- Key macros can now be defined for all non-modeless keys (suggested by Mirko Dölle).
- Adjusted the "KEY MACROS" section of vdr.5 to the new plugin calling mechanism
introduced in version 1.3.32.
- Removed the now obsolete "ca.conf" section from vdr.1 (thanks to Ville Skyttä).
- Added missing description of L and R circular polarization to 'diseqc.conf'.
- Added a note about "modprobe capability" to INSTALL (suggested by Patrick Cernko).
- Fixed canonicalizing the file name in the SVDRP command GRAB to allow full path
names (thanks to Stefan Huelswitt).
- Added a missing '-' to the example for viewing a grabbed image on a remote host
(reported by Philippe Gramoullé).
- Made the "What's on now/next?" menus a lot faster by storing a pointer to each
channel's schedule in the cChannel data.
- Made the log messages regarding lost lock of devices "info" instead of "error"
(suggested by Andreas Brachold).
- The SVDRP command GRAB allows file names without extension again (suggested by
Stefan Huelswitt).
- Pressing '0' in the "Schedule" menu now rotates through displaying "This event on
this channel", "This event on all channels" and "All events on all channels".
This can be used to find reruns of a given show, or the episodes of a series.
Note that if there are many channels in your channels.conf, displaying the
"All events on all channels" page may take a while.
- The status markers in the "Schedule" menu are now only updated if a submenu is
closed in which a timer has been modified, which speeds up closing submenus.
- Now only writing Dolby Digital tracks into the 'info.vdr' file of a recording
if Setup.UseDolbyDigital is true (suggested by André Weidemann).
- Added a leading '0' to the day in the DayDateTime() function (thanks to Rolf
Ahrenberg).
- No longer displaying color buttons in the recording info menu if it has been
invoked from a player (reported by Jürgen Schilling).
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 204 |
1 files changed, 167 insertions, 37 deletions
@@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.390 2006/01/08 11:39:57 kls Exp $ + * $Id: menu.c 1.396 2006/01/15 15:02:36 kls Exp $ */ #include "menu.h" @@ -323,10 +323,10 @@ public: cMenuChannelItem(cChannel *Channel); static void SetSortMode(eChannelSortMode SortMode) { sortMode = SortMode; } static void IncSortMode(void) { sortMode = eChannelSortMode((sortMode == csmProvider) ? csmNumber : sortMode + 1); } + static eChannelSortMode SortMode(void) { return sortMode; } virtual int Compare(const cListObject &ListObject) const; virtual void Set(void); cChannel *Channel(void) { return channel; } - static eChannelSortMode SortMode(void) { return sortMode; } }; cMenuChannelItem::eChannelSortMode cMenuChannelItem::sortMode = csmNumber; @@ -916,7 +916,7 @@ cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch) SetTitle(channel->Name()); int TimerMatch = tmNone; Timers.GetMatch(event, &TimerMatch); - SetHelp(TimerMatch == tmFull ? tr("Timer") : tr("Button$Record"), NULL, NULL, CanSwitch ? tr("Button$Switch") : NULL); + SetHelp(TimerMatch == tmFull ? tr("Button$Timer") : tr("Button$Record"), NULL, NULL, CanSwitch ? tr("Button$Switch") : NULL); } } } @@ -962,21 +962,44 @@ eOSState cMenuEvent::ProcessKey(eKeys Key) class cMenuScheduleItem : public cOsdItem { public: + enum eScheduleSortMode { ssmAllThis, ssmThisThis, ssmThisAll, ssmAllAll }; // "which event(s) on which channel(s)" +private: + static eScheduleSortMode sortMode; +public: const cEvent *event; const cChannel *channel; + bool withDate; int timerMatch; - cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL); + cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false); + static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; } + static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); } + static eScheduleSortMode SortMode(void) { return sortMode; } + virtual int Compare(const cListObject &ListObject) const; bool Update(bool Force = false); -}; + }; + +cMenuScheduleItem::eScheduleSortMode cMenuScheduleItem::sortMode = ssmAllThis; -cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel) +cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate) { event = Event; channel = Channel; + withDate = WithDate; timerMatch = tmNone; Update(true); } +int cMenuScheduleItem::Compare(const cListObject &ListObject) const +{ + cMenuScheduleItem *p = (cMenuScheduleItem *)&ListObject; + int r = -1; + if (sortMode != ssmAllThis) + r = strcoll(event->Title(), p->event->Title()); + if (sortMode == ssmAllThis || r == 0) + r = event->StartTime() - p->event->StartTime(); + return r; +} + static char *TimerMatchChars = " tT"; bool cMenuScheduleItem::Update(bool Force) @@ -989,7 +1012,9 @@ bool cMenuScheduleItem::Update(bool Force) char t = TimerMatchChars[timerMatch]; char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; char r = event->IsRunning() ? '*' : ' '; - if (channel) + if (channel && withDate) + asprintf(&buffer, "%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title()); + else if (channel) asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), *event->GetTimeString(), t, v, r, event->Title()); else asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title()); @@ -1005,6 +1030,7 @@ class cMenuWhatsOn : public cOsdMenu { private: bool now; int helpKeys; + int timerState; eOSState Record(void); eOSState Switch(void); static int currentChannel; @@ -1027,9 +1053,11 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha { now = Now; helpKeys = -1; + timerState = 0; + Timers.Modified(timerState); for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { if (!Channel->GroupSep()) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); if (Event) @@ -1044,10 +1072,12 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha bool cMenuWhatsOn::Update(void) { bool result = false; - for (cOsdItem *item = First(); item; item = Next(item)) { - if (((cMenuScheduleItem *)item)->Update()) - result = true; - } + if (Timers.Modified(timerState)) { + for (cOsdItem *item = First(); item; item = Next(item)) { + if (((cMenuScheduleItem *)item)->Update()) + result = true; + } + } return result; } @@ -1163,9 +1193,14 @@ private: bool now, next; int otherChannel; int helpKeys; + int timerState; + eOSState Number(void); eOSState Record(void); eOSState Switch(void); - void PrepareSchedule(cChannel *Channel); + void PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleThisThis(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleThisAll(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleAllAll(const cEvent *Event, const cChannel *Channel); bool Update(void); void SetHelpKeys(void); public: @@ -1175,16 +1210,19 @@ public: }; cMenuSchedule::cMenuSchedule(void) -:cOsdMenu("", 7, 6, 4) +:cOsdMenu("") { now = next = false; otherChannel = 0; helpKeys = -1; + timerState = 0; + Timers.Modified(timerState); + cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { cMenuWhatsOn::SetCurrentChannel(channel->Number()); schedules = cSchedules::Schedules(schedulesLock); - PrepareSchedule(channel); + PrepareScheduleAllThis(NULL, channel); SetHelpKeys(); } } @@ -1194,33 +1232,94 @@ cMenuSchedule::~cMenuSchedule() cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared } -void cMenuSchedule::PrepareSchedule(cChannel *Channel) +void cMenuSchedule::PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel) { Clear(); + SetCols(7, 6, 4); char *buffer = NULL; asprintf(&buffer, tr("Schedule - %s"), Channel->Name()); SetTitle(buffer); free(buffer); - if (schedules) { - const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); + if (schedules && Channel) { + const cSchedule *Schedule = schedules->GetSchedule(Channel); + if (Schedule) { + const cEvent *PresentEvent = Event ? Event : Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if (ev->EndTime() > now || ev == PresentEvent) + Add(new cMenuScheduleItem(ev), ev == PresentEvent); + } + } + } +} + +void cMenuSchedule::PrepareScheduleThisThis(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(7, 6, 4); + char *buffer = NULL; + asprintf(&buffer, tr("This event - %s"), Channel->Name()); + SetTitle(buffer); + free(buffer); + if (schedules && Channel && Event) { + const cSchedule *Schedule = schedules->GetSchedule(Channel); if (Schedule) { - const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); time_t now = time(NULL) - Setup.EPGLinger * 60; - for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) { - if (Event->EndTime() > now || Event == PresentEvent) - Add(new cMenuScheduleItem(Event), Event == PresentEvent); + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if ((ev->EndTime() > now || ev == Event) && !strcmp(ev->Title(), Event->Title())) + Add(new cMenuScheduleItem(ev), ev == Event); } } } } +void cMenuSchedule::PrepareScheduleThisAll(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(CHNUMWIDTH, 7, 7, 6, 4); + SetTitle(tr("This event - all channels")); + if (schedules && Event) { + for (cChannel *ch = Channels.First(); ch; ch = Channels.Next(ch)) { + const cSchedule *Schedule = schedules->GetSchedule(ch); + if (Schedule) { + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if ((ev->EndTime() > now || ev == Event) && !strcmp(ev->Title(), Event->Title())) + Add(new cMenuScheduleItem(ev, ch, true), ev == Event && ch == Channel); + } + } + } + } +} + +void cMenuSchedule::PrepareScheduleAllAll(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(CHNUMWIDTH, 7, 7, 6, 4); + SetTitle(tr("All events - all channels")); + if (schedules) { + for (cChannel *ch = Channels.First(); ch; ch = Channels.Next(ch)) { + const cSchedule *Schedule = schedules->GetSchedule(ch); + if (Schedule) { + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if (ev->EndTime() > now || ev == Event) + Add(new cMenuScheduleItem(ev, ch, true), ev == Event && ch == Channel); + } + } + } + } +} + bool cMenuSchedule::Update(void) { bool result = false; - for (cOsdItem *item = First(); item; item = Next(item)) { - if (((cMenuScheduleItem *)item)->Update()) - result = true; - } + if (Timers.Modified(timerState)) { + for (cOsdItem *item = First(); item; item = Next(item)) { + if (((cMenuScheduleItem *)item)->Update()) + result = true; + } + } return result; } @@ -1241,6 +1340,29 @@ void cMenuSchedule::SetHelpKeys(void) } } +eOSState cMenuSchedule::Number(void) +{ + cMenuScheduleItem::IncSortMode(); + cMenuScheduleItem *CurrentItem = (cMenuScheduleItem *)Get(Current()); + const cChannel *Channel = NULL; + const cEvent *Event = NULL; + if (CurrentItem) { + Event = CurrentItem->event; + Channel = Channels.GetByChannelID(Event->ChannelID(), true); + } + switch (cMenuScheduleItem::SortMode()) { + case cMenuScheduleItem::ssmAllThis: PrepareScheduleAllThis(Event, Channel); break; + case cMenuScheduleItem::ssmThisThis: PrepareScheduleThisThis(Event, Channel); break; + case cMenuScheduleItem::ssmThisAll: PrepareScheduleThisAll(Event, Channel); break; + case cMenuScheduleItem::ssmAllAll: PrepareScheduleAllAll(Event, Channel); break; + } + CurrentItem = (cMenuScheduleItem *)Get(Current()); + Sort(); + SetCurrent(CurrentItem); + Display(); + return osContinue; +} + eOSState cMenuSchedule::Record(void) { cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current()); @@ -1290,6 +1412,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { + case k0: return Number(); case kRecord: case kRed: return Record(); case kGreen: if (schedules) { @@ -1325,7 +1448,8 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) if (ei) { cChannel *channel = Channels.GetByChannelID(ei->ChannelID(), true); if (channel) { - PrepareSchedule(channel); + cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis); + PrepareScheduleAllThis(NULL, channel); if (channel->Number() != cDevice::CurrentChannel()) { otherChannel = channel->Number(); SetHelp(Count() ? tr("Button$Record") : NULL, tr("Button$Now"), tr("Button$Next"), tr("Button$Switch")); @@ -1578,17 +1702,19 @@ cOsdObject *CamControl(void) class cMenuRecording : public cOsdMenu { private: const cRecording *recording; + bool withButtons; public: - cMenuRecording(const cRecording *Recording); + cMenuRecording(const cRecording *Recording, bool WithButtons = false); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); }; -cMenuRecording::cMenuRecording(const cRecording *Recording) +cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) :cOsdMenu(tr("Recording info")) { recording = Recording; - if (recording) + withButtons = WithButtons; + if (withButtons) SetHelp(tr("Button$Play"), tr("Button$Rewind")); } @@ -1620,8 +1746,11 @@ eOSState cMenuRecording::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kRed: Key = kOk; // will play the recording, even if recording commands are defined - case kGreen: cRemote::Put(Key, true); + case kRed: if (withButtons) + Key = kOk; // will play the recording, even if recording commands are defined + case kGreen: if (!withButtons) + break; + cRemote::Put(Key, true); // continue with osBack to close the info menu and process the key case kOk: return osBack; default: break; @@ -1869,7 +1998,7 @@ eOSState cMenuRecordings::Info(void) if (ri && !ri->IsDirectory()) { cRecording *recording = GetRecording(ri); if (recording && recording->Info()->Title()) - return AddSubMenu(new cMenuRecording(recording)); + return AddSubMenu(new cMenuRecording(recording, true)); } return osContinue; } @@ -2007,6 +2136,7 @@ void cMenuSetupOSD::Set(void) Add(new cMenuEditBoolItem(tr("Setup.OSD$Timeout requested channel info"), &data.TimeoutRequChInfo)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll pages"), &data.MenuScrollPage)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll wraps"), &data.MenuScrollWrap)); + Add(new cMenuEditBoolItem(tr("Setup.OSD$Menu button closes"), &data.MenuButtonCloses)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Sort timers"), &data.SortTimers)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); SetCurrent(Get(current)); @@ -2832,7 +2962,7 @@ static void SetTrackDescriptions(bool Live) if (Channel) { const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); if (Present) @@ -2915,7 +3045,7 @@ void cDisplayChannel::DisplayInfo(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); const cEvent *Following = Schedule->GetFollowingEvent(true); @@ -3345,7 +3475,7 @@ bool cRecordControl::GetEvent(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { event = Schedule->GetEventAround(Time); if (event) { @@ -3868,7 +3998,7 @@ cOsdObject *cReplayControl::GetInfo(void) { cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed()); if (Recording) - return new cMenuRecording(Recording); + return new cMenuRecording(Recording, false); return NULL; } |