summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c163
1 files changed, 80 insertions, 83 deletions
diff --git a/menu.c b/menu.c
index 6a7907f..c153151 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.284 2004/02/08 15:06:42 kls Exp $
+ * $Id: menu.c 1.292 2004/02/22 14:14:55 kls Exp kls $
*/
#include "menu.h"
@@ -18,6 +18,7 @@
#include "cutter.h"
#include "eitscan.h"
#include "i18n.h"
+#include "libsi/si.h"
#include "menuitems.h"
#include "plugin.h"
#include "recording.h"
@@ -557,8 +558,12 @@ cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
channel = Channel;
if (channel) {
data = *channel;
- if (New)
+ if (New) {
channel = NULL;
+ data.nid = 0;
+ data.tid = 0;
+ data.rid = 0;
+ }
Setup();
}
}
@@ -583,7 +588,7 @@ void cMenuEditChannel::Setup(void)
Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpids[1], 0, 0x1FFF));
Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF));
Add(new cMenuEditCaItem( tr("CA"), &data.caids[0], true));//XXX
- Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 0));
+ Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 1, 0xFFFF));
/* XXX not yet used
Add(new cMenuEditIntItem( tr("Nid"), &data.nid, 0));
Add(new cMenuEditIntItem( tr("Tid"), &data.tid, 0));
@@ -867,13 +872,14 @@ cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
if (timer) {
data = *timer;
if (New)
- data.active = 1;
+ data.SetFlags(tfActive);
channel = data.Channel()->Number();
- Add(new cMenuEditBoolItem(tr("Active"), &data.active));
+ Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive));
Add(new cMenuEditChanItem(tr("Channel"), &channel));
Add(new cMenuEditDayItem( tr("Day"), &data.day));
Add(new cMenuEditTimeItem(tr("Start"), &data.start));
Add(new cMenuEditTimeItem(tr("Stop"), &data.stop));
+ Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps));
Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME));
Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file), tr(FileNameChars)));
@@ -922,13 +928,13 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
if (timer) {
if (memcmp(timer, &data, sizeof(data)) != 0) {
*timer = data;
- if (timer->active)
- timer->active = 1; // allows external programs to mark active timers with values > 1 and recognize if the user has modified them
+ if (timer->HasFlags(tfActive))
+ timer->ClrFlags(~tfAll); // allows external programs to mark active timers with values > 0xFFFF and recognize if the user has modified them
}
if (addIfConfirmed)
Timers.Add(timer);
Timers.Save();
- isyslog("timer %d %s (%s)", timer->Index() + 1, addIfConfirmed ? "added" : "modified", timer->active ? "active" : "inactive");
+ isyslog("timer %d %s (%s)", timer->Index() + 1, addIfConfirmed ? "added" : "modified", timer->HasFlags(tfActive) ? "active" : "inactive");
addIfConfirmed = false;
}
}
@@ -972,7 +978,7 @@ void cMenuTimerItem::Set(void)
{
char *buffer = NULL;
asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
- !timer->Active() ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
+ !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
timer->Channel()->Number(),
timer->PrintDay(timer->Day()),
timer->Start() / 100,
@@ -1037,7 +1043,7 @@ eOSState cMenuTimers::OnOff(void)
if (timer->FirstDay())
isyslog("timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay());
else
- isyslog("timer %d %sactivated", timer->Index() + 1, timer->Active() ? "" : "de");
+ isyslog("timer %d %sactivated", timer->Index() + 1, timer->HasFlags(tfActive) ? "" : "de");
Timers.Save();
}
return osContinue;
@@ -1164,6 +1170,13 @@ cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch)
Add(item = new cMenuTextItem(Subtitle, 1, Line, Setup.OSDwidth - 2, -1, clrYellow));
Line += item->Height() + 1;
}
+ if (Event->Vps() && Event->Vps() != Event->StartTime()) {
+ char *buffer;
+ asprintf(&buffer, "VPS: %s", Event->GetVpsString());
+ Add(item = new cMenuTextItem(buffer, 1, Line, Setup.OSDwidth - 2, -1, clrYellow));
+ free(buffer);
+ Line += item->Height() + 1;
+ }
if (!isempty(ExtendedDescription))
Add(new cMenuTextItem(ExtendedDescription, 1, Line, Setup.OSDwidth - 2, Height() - Line - 2, clrCyan), true);
SetHelp(tr("Record"), NULL, NULL, CanSwitch ? tr("Switch") : NULL);
@@ -1191,15 +1204,20 @@ eOSState cMenuEvent::ProcessKey(eKeys Key)
class cMenuWhatsOnItem : public cOsdItem {
public:
const cEvent *event;
- cMenuWhatsOnItem(const cEvent *Event);
+ const cChannel *channel;
+ cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel);
};
-cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event)
+cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel)
{
event = Event;
+ channel = Channel;
char *buffer = NULL;
- cChannel *channel = Channels.GetByNumber(event->ChannelNumber());
- asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", event->ChannelNumber(), 6, channel ? channel->Name() : "???", 5, event->GetTimeString(), event->Title());
+ int TimerMatch;
+ char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
+ char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
+ char r = event->RunningStatus() > SI::RunningStatusNotRunning ? '*' : ' ';
+ asprintf(&buffer, "%d\t%.*s\t%.*s\t%c%c%c\t%s", channel->Number(), 6, channel->Name(), 5, event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1222,39 +1240,20 @@ public:
int cMenuWhatsOn::currentChannel = 0;
const cEvent *cMenuWhatsOn::scheduleEvent = NULL;
-static int CompareEventChannel(const void *p1, const void *p2)
-{
- return (int)( (*(const cEvent **)p1)->ChannelNumber() - (*(const cEvent **)p2)->ChannelNumber());
-}
-
cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr)
-:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6)
-{
- const cSchedule *Schedule = Schedules->First();
- const cEvent **pArray = NULL;
- int num = 0;
-
- while (Schedule) {
- pArray = (const cEvent **)realloc(pArray, (num + 1) * sizeof(cEvent *));
-
- pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
- if (pArray[num]) {
- cChannel *channel = Channels.GetByChannelID(pArray[num]->ChannelID(), true);
- if (channel) {
- pArray[num]->SetChannelNumber(channel->Number());
- num++;
- }
- }
- Schedule = (const cSchedule *)Schedules->Next(Schedule);
- }
-
- qsort(pArray, num, sizeof(cEvent *), CompareEventChannel);
-
- for (int a = 0; a < num; a++)
- Add(new cMenuWhatsOnItem(pArray[a]), pArray[a]->ChannelNumber() == CurrentChannelNr);
-
+:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4)
+{
+ for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
+ if (!Channel->GroupSep()) {
+ const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
+ if (Schedule) {
+ const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
+ if (Event)
+ Add(new cMenuWhatsOnItem(Event, Channel), Channel->Number() == CurrentChannelNr);
+ }
+ }
+ }
currentChannel = CurrentChannelNr;
- free(pArray);
SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch"));
}
@@ -1306,7 +1305,7 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current());
if (mi) {
scheduleEvent = mi->event;
- currentChannel = mi->event->ChannelNumber();
+ currentChannel = mi->channel->Number();
}
}
break;
@@ -1332,7 +1331,11 @@ cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event)
{
event = Event;
char *buffer = NULL;
- asprintf(&buffer, "%.*s\t%.*s\t%s", 5, event->GetDateString(), 5, event->GetTimeString(), event->Title());
+ int TimerMatch;
+ char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
+ char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
+ char r = event->RunningStatus() > SI::RunningStatusNotRunning ? '*' : ' ';
+ asprintf(&buffer, "%.*s\t%.*s\t%c%c%c\t%s", 5, event->GetDateString(), 5, event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1354,7 +1357,7 @@ public:
};
cMenuSchedule::cMenuSchedule(void)
-:cOsdMenu("", 6, 6)
+:cOsdMenu("", 6, 6, 4)
{
now = next = false;
otherChannel = 0;
@@ -1372,11 +1375,6 @@ cMenuSchedule::~cMenuSchedule()
cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared
}
-static int CompareEventTime(const void *p1, const void *p2)
-{
- return (int)((*(cEvent **)p1)->StartTime() - (*(cEvent **)p2)->StartTime());
-}
-
void cMenuSchedule::PrepareSchedule(cChannel *Channel)
{
Clear();
@@ -1387,23 +1385,14 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
if (schedules) {
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
if (Schedule) {
+ const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel());
int num = Schedule->NumEvents();
- const cEvent **pArray = MALLOC(const cEvent *, num);
- if (pArray) {
- time_t now = time(NULL);
- int numreal = 0;
- for (int a = 0; a < num; a++) {
- const cEvent *Event = Schedule->GetEventNumber(a);
- if (Event->StartTime() + Event->Duration() > now)
- pArray[numreal++] = Event;
- }
-
- qsort(pArray, numreal, sizeof(cEvent *), CompareEventTime);
-
- for (int a = 0; a < numreal; a++)
- Add(new cMenuScheduleItem(pArray[a]));
- free(pArray);
- }
+ time_t now = time(NULL) - Setup.EPGLinger * 60;
+ for (int a = 0; a < num; a++) {
+ const cEvent *Event = Schedule->GetEventNumber(a);
+ if (Event->StartTime() + Event->Duration() > now || Event == PresentEvent)
+ Add(new cMenuScheduleItem(Event), Event == PresentEvent);
+ }
}
}
}
@@ -2057,6 +2046,7 @@ void cMenuSetupEPG::Setup(void)
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout));
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL));
+ Add(new cMenuEditIntItem( tr("Setup.EPG$EPG linger time (min)"), &data.EPGLinger, 0));
Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime));
if (data.SetSystemTime)
Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder));
@@ -2314,6 +2304,8 @@ cMenuSetupRecord::cMenuSetupRecord(void)
Add(new cMenuEditIntItem( tr("Setup.Recording$Pause priority"), &data.PausePriority, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("Setup.Recording$Pause lifetime (d)"), &data.PauseLifetime, 0, MAXLIFETIME));
Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle));
+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps));
+ Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0));
Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord));
Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord), tr(FileNameChars)));
Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME));
@@ -2784,7 +2776,7 @@ void cDisplayChannel::DisplayInfo(void)
if (Schedule) {
const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL;
int Lines = 0;
- if ((Present = Schedule->GetPresentEvent()) != NULL) {
+ if ((Present = Schedule->GetPresentEvent(true)) != NULL) {
PresentTitle = Present->Title();
if (!isempty(PresentTitle))
Lines++;
@@ -2792,7 +2784,7 @@ void cDisplayChannel::DisplayInfo(void)
if (!isempty(PresentSubtitle))
Lines++;
}
- if ((Following = Schedule->GetFollowingEvent()) != NULL) {
+ if ((Following = Schedule->GetFollowingEvent(true)) != NULL) {
FollowingTitle = Following->Title();
if (!isempty(FollowingTitle))
Lines++;
@@ -3076,11 +3068,12 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
}
timer->SetPending(true);
timer->SetRecording(true);
+ event = timer->Event();
const char *Title = NULL;
const char *Subtitle = NULL;
const char *Summary = NULL;
- if (GetEvent()) {
+ if (event || GetEvent()) {
Title = event->Title();
Subtitle = event->ShortText();
Summary = event->Description();
@@ -3135,7 +3128,7 @@ cRecordControl::~cRecordControl()
bool cRecordControl::GetEvent(void)
{
const cChannel *channel = timer->Channel();
- time_t Time = timer->Active() == taActInst ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
+ time_t Time = timer->HasFlags(tfInstant) ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) {
{
cSchedulesLock SchedulesLock;
@@ -3207,12 +3200,14 @@ bool cRecordControls::Start(cTimer *Timer, bool Pause)
cThread::EmergencyExit(true);
return false;
}
- for (int i = 0; i < MAXRECORDCONTROLS; i++) {
- if (!RecordControls[i]) {
- RecordControls[i] = new cRecordControl(device, Timer, Pause);
- return true;
+ if (!Timer || Timer->Matches()) {
+ for (int i = 0; i < MAXRECORDCONTROLS; i++) {
+ if (!RecordControls[i]) {
+ RecordControls[i] = new cRecordControl(device, Timer, Pause);
+ return true;
+ }
}
- }
+ }
}
else if (!Timer || (Timer->Priority() >= Setup.PrimaryLimit && !Timer->Pending()))
isyslog("no free DVB device to record channel %d!", ch);
@@ -3237,7 +3232,7 @@ void cRecordControls::Stop(cDevice *Device)
{
for (int i = 0; i < MAXRECORDCONTROLS; i++) {
if (RecordControls[i]) {
- if (RecordControls[i]->Uses(Device)) {
+ if (RecordControls[i]->Device() == Device) {
isyslog("stopping recording on DVB device %d due to higher priority", Device->CardIndex() + 1);
RecordControls[i]->Stop(true);
}
@@ -3316,10 +3311,12 @@ void cRecordControls::ChannelDataModified(cChannel *Channel)
for (int i = 0; i < MAXRECORDCONTROLS; i++) {
if (RecordControls[i]) {
if (RecordControls[i]->Timer() && RecordControls[i]->Timer()->Channel() == Channel) {
- isyslog("stopping recording due to modification of channel %d", Channel->Number());
- RecordControls[i]->Stop(true);
- // This will restart the recording, maybe even from a different
- // device in case conditional access has changed.
+ if (RecordControls[i]->Device()->ProvidesTransponder(Channel)) { // avoids retune on devices that don't really access the transponder
+ isyslog("stopping recording due to modification of channel %d", Channel->Number());
+ RecordControls[i]->Stop(true);
+ // This will restart the recording, maybe even from a different
+ // device in case conditional access has changed.
+ }
}
}
}