summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c323
1 files changed, 146 insertions, 177 deletions
diff --git a/menu.c b/menu.c
index a7a98ec..28e5d4d 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.152 2002/02/10 11:52:34 kls Exp $
+ * $Id: menu.c 1.159 2002/02/24 12:55:49 kls Exp $
*/
#include "menu.h"
@@ -254,6 +254,62 @@ eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
return osContinue;
}
+// --- cMenuEditDateItem -----------------------------------------------------
+
+class cMenuEditDateItem : public cMenuEditItem {
+protected:
+ time_t *value;
+ virtual void Set(void);
+public:
+ cMenuEditDateItem(const char *Name, time_t *Value);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditDateItem::cMenuEditDateItem(const char *Name, time_t *Value)
+:cMenuEditItem(Name)
+{
+ value = Value;
+ Set();
+}
+
+void cMenuEditDateItem::Set(void)
+{
+#define DATEBUFFERSIZE 32
+ char buf[DATEBUFFERSIZE];
+ if (*value) {
+ struct tm tm_r;
+ localtime_r(value, &tm_r);
+ strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r);
+ strcat(buf, WeekDayName(tm_r.tm_wday));
+ }
+ else
+ *buf = 0;
+ SetValue(buf);
+}
+
+eOSState cMenuEditDateItem::ProcessKey(eKeys Key)
+{
+ eOSState state = cMenuEditItem::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
+ *value -= SECSINDAY;
+ if (*value < time(NULL))
+ *value = 0;
+ }
+ else if (NORMALKEY(Key) == kRight) {
+ if (!*value)
+ *value = cTimer::SetTime(time(NULL), 0);
+ *value += SECSINDAY;
+ }
+ else
+ return state;
+ Set();
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cMenuEditTimeItem -----------------------------------------------------
class cMenuEditTimeItem : public cMenuEditItem {
@@ -905,6 +961,8 @@ class cMenuEditTimer : public cOsdMenu {
private:
cTimer *timer;
cTimer data;
+ cMenuEditDateItem *firstday;
+ void SetFirstDayItem(void);
public:
cMenuEditTimer(int Index, bool New = false);
virtual eOSState ProcessKey(eKeys Key);
@@ -913,6 +971,7 @@ public:
cMenuEditTimer::cMenuEditTimer(int Index, bool New)
:cOsdMenu(tr("Edit Timer"), 12)
{
+ firstday = NULL;
timer = Timers.Get(Index);
if (timer) {
data = *timer;
@@ -927,6 +986,21 @@ cMenuEditTimer::cMenuEditTimer(int Index, bool New)
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), FileNameChars));
+ SetFirstDayItem();
+ }
+}
+
+void cMenuEditTimer::SetFirstDayItem(void)
+{
+ if (!firstday && !data.IsSingleEvent()) {
+ Add(firstday = new cMenuEditDateItem(tr("First day"), &data.firstday));
+ Display();
+ }
+ else if (firstday && data.IsSingleEvent()) {
+ Del(firstday->Index());
+ firstday = NULL;
+ data.firstday = 0;
+ Display();
}
}
@@ -953,6 +1027,8 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
default: break;
}
}
+ if (Key != kNone)
+ SetFirstDayItem();
return state;
}
@@ -983,7 +1059,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->recording ? '#' : '>' : ' ',
+ !timer->active ? ' ' : timer->firstday ? '!' : timer->recording ? '#' : '>',
timer->channel,
timer->PrintDay(timer->day),
timer->start / 100,
@@ -998,10 +1074,10 @@ void cMenuTimerItem::Set(void)
class cMenuTimers : public cOsdMenu {
private:
- eOSState Activate(bool On);
eOSState Edit(void);
eOSState New(void);
eOSState Del(void);
+ eOSState OnOff(void);
virtual void Move(int From, int To);
eOSState Summary(void);
cTimer *CurrentTimer(void);
@@ -1022,7 +1098,7 @@ cMenuTimers::cMenuTimers(void)
}
if (Setup.SortTimers)
Sort();
- SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? NULL : tr("Mark"));
+ SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? tr("On/Off") : tr("Mark"));
}
cTimer *cMenuTimers::CurrentTimer(void)
@@ -1031,14 +1107,27 @@ cTimer *cMenuTimers::CurrentTimer(void)
return item ? item->Timer() : NULL;
}
-eOSState cMenuTimers::Activate(bool On)
+eOSState cMenuTimers::OnOff(void)
{
cTimer *timer = CurrentTimer();
- if (timer && timer->active != On) {
- timer->active = On;
+ if (timer) {
+ if (timer->IsSingleEvent())
+ timer->active = !timer->active;
+ else if (timer->firstday) {
+ timer->firstday = 0;
+ timer->active = false;
+ }
+ else if (timer->active)
+ timer->SkipToday();
+ else
+ timer->active = true;
+ timer->Matches(); // refresh start and end time
RefreshCurrent();
DisplayCurrent(true);
- isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
+ if (timer->firstday)
+ isyslog(LOG_INFO, "timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay());
+ else
+ isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
Timers.Save();
}
return osContinue;
@@ -1106,27 +1195,17 @@ eOSState cMenuTimers::Summary(void)
eOSState cMenuTimers::ProcessKey(eKeys Key)
{
- // Must do these before calling cOsdMenu::ProcessKey() because cOsdMenu
- // uses them to page up/down:
- if (!HasSubMenu()) {
- switch (Key) {
- case kLeft:
- case kRight: return Activate(Key == kRight);
- default: break;
- }
- }
-
eOSState state = cOsdMenu::ProcessKey(Key);
if (state == osUnknown) {
switch (Key) {
- case kLeft:
- case kRight: return Activate(Key == kRight);
case kOk: return Summary();
case kRed: return Edit();
case kGreen: return New();
case kYellow: return Del();
- case kBlue: if (!Setup.SortTimers)
+ case kBlue: if (Setup.SortTimers)
+ OnOff();
+ else
Mark();
break;
default: break;
@@ -1350,7 +1429,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo)
class cMenuSchedule : public cOsdMenu {
private:
- cThreadLock threadLock;
+ cMutexLock mutexLock;
const cSchedules *schedules;
bool now, next;
int otherChannel;
@@ -1370,7 +1449,7 @@ cMenuSchedule::cMenuSchedule(void)
cChannel *channel = Channels.GetByNumber(cDvbApi::CurrentChannel());
if (channel) {
cMenuWhatsOn::SetCurrentChannel(channel->number);
- schedules = cDvbApi::PrimaryDvbApi->Schedules(&threadLock);
+ schedules = cSIProcessor::Schedules(mutexLock);
PrepareSchedule(channel);
SetHelp(tr("Record"), tr("Now"), tr("Next"));
}
@@ -1670,26 +1749,34 @@ eOSState cMenuRecordings::Del(void)
{
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
if (ri && !ri->IsDirectory()) {
-//XXX what if this recording's file is currently in use???
-//XXX if (!ti->recording) {
- if (Interface->Confirm(tr("Delete recording?"))) {
- cRecording *recording = GetRecording(ri);
- if (recording) {
- if (recording->Delete()) {
- cReplayControl::ClearLastReplayed(ri->FileName());
- cOsdMenu::Del(Current());
- Recordings.Del(recording);
- Display();
- if (!Count())
- return osBack;
+ if (Interface->Confirm(tr("Delete recording?"))) {
+ cRecordControl *rc = cRecordControls::GetRecordControl(ri->FileName());
+ if (rc) {
+ if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
+ cTimer *timer = rc->Timer();
+ if (timer) {
+ timer->SkipToday();
+ cRecordControls::Process(time(NULL));
+ Timers.Save();
}
- else
- Interface->Error(tr("Error while deleting recording!"));
}
+ else
+ return osContinue;
}
-//XXX }
-//XXX else
-//XXX Interface->Error(tr("Timer is recording!"));
+ cRecording *recording = GetRecording(ri);
+ if (recording) {
+ if (recording->Delete()) {
+ cReplayControl::ClearLastReplayed(ri->FileName());
+ cOsdMenu::Del(Current());
+ Recordings.Del(recording);
+ Display();
+ if (!Count())
+ return osBack;
+ }
+ else
+ Interface->Error(tr("Error while deleting recording!"));
+ }
+ }
}
return osContinue;
}
@@ -1735,81 +1822,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
return state;
}
-#ifdef DVDSUPPORT
-// --- cMenuDVDItem ----------------------------------------------------------
-
-class cMenuDVDItem : public cOsdItem {
- private:
- int title;
- int chapters;
- virtual void Set(void);
-public:
- cMenuDVDItem(int Title, int Chapters);
- int Title(void) { return title; }
- };
-
-cMenuDVDItem::cMenuDVDItem(int Title, int Chapters)
-{
- title = Title;
- chapters = Chapters;
- Set();
-}
-
-void cMenuDVDItem::Set(void)
-{
- char *buffer = NULL;
- asprintf(&buffer, " %2d.\tTitle - \t%2d\tChapters", title + 1, chapters);
- SetText(buffer, false);
-}
-
-// --- cMenuDVD --------------------------------------------------------------
-
-cMenuDVD::cMenuDVD(void)
-:cOsdMenu(tr("DVD"), 5, 8, 3)
-{
- if ((dvd = cDVD::getDVD())) {
- dvd->Open();
- ifo_handle_t *vmg = dvd->openVMG();
- if (vmg) {
- int lastTitleID = cReplayControl::LastTitleID();
- dsyslog(LOG_INFO, "DVD: vmg: %p", vmg);//XXX
- tt_srpt_t *tt_srpt = vmg->tt_srpt;
- dsyslog(LOG_INFO, "DVD: tt_srpt: %p", tt_srpt);//XXX
- for (int i = 0; i < tt_srpt->nr_of_srpts; i++)
- Add(new cMenuDVDItem(i, tt_srpt->title[i].nr_of_ptts), i == lastTitleID);
- }
- }
- SetHelp(tr("Play"), NULL, NULL, NULL);
- Display();
-}
-
-eOSState cMenuDVD::Play(void)
-{
- cMenuDVDItem *ri = (cMenuDVDItem *)Get(Current());
- if (ri) {
- cReplayControl::SetDVD(dvd, ri->Title());
- isyslog(LOG_INFO, "DVD: playing title %d", ri->Title());
- return osReplay;
- }
- return osContinue;
-}
-
-eOSState cMenuDVD::ProcessKey(eKeys Key)
-{
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if (state == osUnknown) {
- switch (Key) {
- case kOk:
- case kRed: return Play();
- case kMenu: return osEnd;
- default: break;
- }
- }
- return state;
-}
-#endif //DVDSUPPORT
-
// --- cMenuSetup ------------------------------------------------------------
class cMenuSetup : public cOsdMenu {
@@ -1857,6 +1869,7 @@ void cMenuSetup::Set(void)
Add(new cMenuEditBoolItem(tr("UseSubtitle"), &data.UseSubtitle));
Add(new cMenuEditBoolItem(tr("RecordingDirs"), &data.RecordingDirs));
Add(new cMenuEditBoolItem(tr("VideoFormat"), &data.VideoFormat, "4:3", "16:9"));
+ Add(new cMenuEditBoolItem(tr("RecordDolbyDigital"), &data.RecordDolbyDigital));
Add(new cMenuEditBoolItem(tr("ChannelInfoPos"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
Add(new cMenuEditIntItem( tr("OSDwidth"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
Add(new cMenuEditIntItem( tr("OSDheight"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
@@ -1971,10 +1984,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
Add(new cOsdItem(hk(tr("Channels")), osChannels));
Add(new cOsdItem(hk(tr("Timers")), osTimers));
Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
-#ifdef DVDSUPPORT
- if (cDVD::DriveExists())
- Add(new cOsdItem(hk(tr("DVD")), osDVD));
-#endif //DVDSUPPORT
Add(new cOsdItem(hk(tr("Setup")), osSetup));
if (Commands.Count())
Add(new cOsdItem(hk(tr("Commands")), osCommands));
@@ -2007,13 +2016,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
// Color buttons:
- const char *DVDbutton =
-#ifdef DVDSUPPORT
- cDVD::DiscOk() ? tr("Eject") : NULL;
-#else
- NULL;
-#endif //DVDSUPPORT
- SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, DVDbutton, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
+ SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
Display();
lastActivity = time(NULL);
SetHasHotkeys();
@@ -2022,9 +2025,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
switch (State) {
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break;
-#ifdef DVDSUPPORT
- case osDVD: AddSubMenu(new cMenuDVD); break;
-#endif //DVDSUPPORT
default: break;
}
}
@@ -2049,9 +2049,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
case osChannels: return AddSubMenu(new cMenuChannels);
case osTimers: return AddSubMenu(new cMenuTimers);
case osRecordings: return AddSubMenu(new cMenuRecordings);
-#ifdef DVDSUPPORT
- case osDVD: return AddSubMenu(new cMenuDVD);
-#endif //DVDSUPPORT
case osSetup: return AddSubMenu(new cMenuSetup);
case osCommands: return AddSubMenu(new cMenuCommands);
case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
@@ -2084,23 +2081,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
}
break;
-#ifdef DVDSUPPORT
- case kYellow: if (!HasSubMenu()) {
- if (cDVD::DiscOk()) {
- // We need to stop replaying a DVD before ejecting,
- // otherwise the replay thread crashes. Currently
- // checking LastReplayed() is pretty much the only way
- // of finding out whether we are currently replaying a DVD
- // (i.e. if LastReplayed() returns non-NULL, we are either
- // replaying a normal recording, or nothing at all):
- if (!cReplayControl::LastReplayed())
- cDvbApi::PrimaryDvbApi->StopReplay();
- cDVD::Eject();
- state = osEnd;
- }
- }
- break;
-#endif //DVDSUPPORT
case kBlue: if (!HasSubMenu())
state = osReplay;
break;
@@ -2175,8 +2155,8 @@ void cDisplayChannel::DisplayInfo(void)
{
if (withInfo) {
const cEventInfo *Present = NULL, *Following = NULL;
- cThreadLock ThreadLock;
- const cSchedules *Schedules = cDvbApi::PrimaryDvbApi->Schedules(&ThreadLock);
+ cMutexLock MutexLock;
+ const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
const cSchedule *Schedule = Schedules->GetSchedule();
if (Schedule) {
@@ -2350,14 +2330,16 @@ cRecordControl::~cRecordControl()
delete fileName;
}
+#define INSTANT_REC_EPG_LOOKAHEAD 300 // seconds to look into the EPG data for an instant recording
+
bool cRecordControl::GetEventInfo(void)
{
cChannel *channel = Channels.GetByNumber(timer->channel);
- time_t Time = timer->IsSingleEvent() ? timer->StartTime() + ((Setup.MarginStart * 2) + 1) * 60 : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
+ time_t Time = timer->active == taActInst ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) {
{
- cThreadLock ThreadLock;
- const cSchedules *Schedules = dvbApi->Schedules(&ThreadLock);
+ cMutexLock MutexLock;
+ const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
const cSchedule *Schedule = Schedules->GetSchedule(channel->pnr);
if (Schedule) {
@@ -2481,6 +2463,15 @@ const char *cRecordControls::GetInstantId(const char *LastInstantId)
return NULL;
}
+cRecordControl *cRecordControls::GetRecordControl(const char *FileName)
+{
+ for (int i = 0; i < MAXDVBAPI; i++) {
+ if (RecordControls[i] && strcmp(RecordControls[i]->FileName(), FileName) == 0)
+ return RecordControls[i];
+ }
+ return NULL;
+}
+
void cRecordControls::Process(time_t t)
{
for (int i = 0; i < MAXDVBAPI; i++) {
@@ -2548,10 +2539,6 @@ void cProgressBar::Mark(int x, bool Start, bool Current)
char *cReplayControl::fileName = NULL;
char *cReplayControl::title = NULL;
-#ifdef DVDSUPPORT
-cDVD *cReplayControl::dvd = NULL;//XXX
-int cReplayControl::titleid = 0;//XXX
-#endif //DVDSUPPORT
cReplayControl::cReplayControl(void)
{
@@ -2565,10 +2552,6 @@ cReplayControl::cReplayControl(void)
if (!dvbApi->StartReplay(fileName))
Interface->Error(tr("Channel locked (recording)!"));
}
-#ifdef DVDSUPPORT
- else if (dvd)
- dvbApi->StartDVDplay(dvd, titleid);//XXX
-#endif //DVDSUPPORT
}
cReplayControl::~cReplayControl()
@@ -2585,20 +2568,6 @@ void cReplayControl::SetRecording(const char *FileName, const char *Title)
title = Title ? strdup(Title) : NULL;
}
-#ifdef DVDSUPPORT
-void cReplayControl::SetDVD(cDVD *DVD, int Title)//XXX
-{
- SetRecording(NULL, NULL);
- dvd = DVD;
- titleid = Title;
-}
-
-int cReplayControl::LastTitleID(void)
-{
- return titleid;
-}
-#endif //DVDSUPPORT
-
const char *cReplayControl::LastReplayed(void)
{
return fileName;
@@ -2966,7 +2935,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
else
Show();
break;
- case kBack: return fileName ? osRecordings : osDVD;
+ case kBack: return osRecordings;
default: return osUnknown;
}
}