diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-01-27 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-01-27 18:00:00 +0100 |
commit | 27919ee969866b68fc95b327a047a9989e4b4153 (patch) | |
tree | 1857862abf169ff6e9287152cd6fec6a1d9dbc41 /menu.c | |
parent | b420457467ad0c8ae71f8b985914e85b7a0ff5aa (diff) | |
download | vdr-patch-lnbsharing-27919ee969866b68fc95b327a047a9989e4b4153.tar.gz vdr-patch-lnbsharing-27919ee969866b68fc95b327a047a9989e4b4153.tar.bz2 |
Version 0.99pre2vdr-0.99pre2
- Fixed setting the OSD size in the 'Confirm' interface call (thanks to
Deti Fliegl).
- Removed the 'read incomplete section...' error message in the EIT processor.
- Fixed channel data for "DW TV" (thanks to Axel Gruber).
- Added DPID to "PREMIERE MOVIE 1" in channels.conf.cable (thanks to Stephan
Schreiber).
- Prepared the OSD functions for multiple overlapping windows.
- Removed the check to see whether the system time is running linearly.
- Improved performance of SVDRP command entry.
- Removed EPGBugfixLevel '3' - after more than a year Pro-7 finally managed to
broadcast the correct timestamps for EPG events between 0:00 and 6:00!
- Fixed failing watchdog timer if program hangs in OSD activities (thanks to
Carsten Koch).
- No longer requiring 'libncurses' if compiling without DEBUG_OSD=1 and
REMOTE=KBD (thanks to Lauri Pesonen).
- The "Recordings" menu now displays a hierarchical structure if there are
subdirectories for the recordings. This can be controlled through the
"RecordingDirs" parameter in the "Setup" menu.
See "MANUAL/Replaying a Recording" for details.
- Improved speed of setting the Help button texts.
- Fixed handling file names that contain single quotes (') or dollar signs ($)
in the call to the shutdown command (option '-s') and the recording command
(option '-r').
- Improved error handling in the editing process; the resulting file will be
deleted if an error occured.
- A message is now prompted at the end of the editing process, indicating
whether the process succeeded or failed.
- Fixed setting the LastActivity timestamp after a shutdown prompt (thanks to
Sergei Haller).
- A message is now prompted if free disk space becomes low during recording.
- The editing process now calls AssertFreeDiskSpace() to remove deleted
recordings if the disk becomes full.
- The "Main" menu now displays in its title the used disk space (in percent)
and the estimated free disk space (in hh:mm), assuming a data rate of 30 MB
per minute.
- Activating the "Recordings" menu now displays "scanning recordings..." to
give the user some feedback in case this takes longer.
- Status messages are now displayed centered.
- Removed the 'Tools' subdirectory from the VDR archive. All contributed tools
can now be found at ftp://ftp.cadsoft.de/pub/people/kls/vdr/Tools.
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 208 |
1 files changed, 173 insertions, 35 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.141 2001/11/24 13:20:37 kls Exp $ + * $Id: menu.c 1.146 2002/01/27 15:50:50 kls Exp $ */ #include "menu.h" @@ -15,6 +15,7 @@ #include "config.h" #include "eit.h" #include "i18n.h" +#include "videodir.h" #define MENUTIMEOUT 120 // seconds #define MAXWAIT4EPGINFO 10 // seconds @@ -1494,46 +1495,161 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) // --- cMenuRecordingItem ---------------------------------------------------- class cMenuRecordingItem : public cOsdItem { +private: + char *fileName; + char *name; + int totalEntries, newEntries; public: - cRecording *recording; - cMenuRecordingItem(cRecording *Recording); - virtual void Set(void); + cMenuRecordingItem(cRecording *Recording, int Level); + ~cMenuRecordingItem(); + void IncrementCounter(bool New); + const char *Name(void) { return name; } + const char *FileName(void) { return fileName; } + bool IsDirectory(void) { return name != NULL; } }; -cMenuRecordingItem::cMenuRecordingItem(cRecording *Recording) +cMenuRecordingItem::cMenuRecordingItem(cRecording *Recording, int Level) { - recording = Recording; - Set(); + fileName = strdup(Recording->FileName()); + name = NULL; + totalEntries = newEntries = 0; + SetText(Recording->Title('\t', true, Level)); + if (*Text() == '\t') + name = strdup(Text() + 2); // 'Text() + 2' to skip the two '\t' } -void cMenuRecordingItem::Set(void) +cMenuRecordingItem::~cMenuRecordingItem() { - SetText(recording->Title('\t', true)); + delete fileName; + delete name; +} + +void cMenuRecordingItem::IncrementCounter(bool New) +{ + totalEntries++; + if (New) + newEntries++; + char *buffer = NULL; + asprintf(&buffer, "%d\t%d\t%s", totalEntries, newEntries, name); + SetText(buffer, false); } // --- cMenuRecordings ------------------------------------------------------- -cMenuRecordings::cMenuRecordings(void) -:cOsdMenu(tr("Recordings"), 6, 6) +cRecordings cMenuRecordings::Recordings; +int cMenuRecordings::helpKeys = -1; + +cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) +:cOsdMenu(Base ? Base : tr("Recordings"), 6, 6) { - if (Recordings.Load()) { - const char *lastReplayed = cReplayControl::LastReplayed(); - cRecording *recording = Recordings.First(); - while (recording) { - Add(new cMenuRecordingItem(recording), lastReplayed && strcmp(lastReplayed, recording->FileName()) == 0); - recording = Recordings.Next(recording); - } + base = Base ? strdup(Base) : NULL; + level = Setup.RecordingDirs ? Level : -1; + if (!Base) { + Interface->Status(tr("scanning recordings...")); + Interface->Flush(); } - SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), tr("Summary")); - Display(); + if (Base || Recordings.Load()) { + const char *LastReplayed = cReplayControl::LastReplayed(); + cMenuRecordingItem *LastItem = NULL; + char *LastItemText = NULL; + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + if (!Base || strstr(recording->Name(), Base) == recording->Name()) { + cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); + if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) { + Add(Item); + LastItem = Item; + delete LastItemText; + LastItemText = strdup(LastItem->Text()); // must use a copy because of the counters! + } + else + delete Item; + if (LastItem) { + if (LastReplayed && strcmp(LastReplayed, recording->FileName()) == 0) + SetCurrent(LastItem); + if (LastItem->IsDirectory()) + LastItem->IncrementCounter(recording->IsNew()); + } + } + } + delete LastItemText; + if (Current() < 0) + SetCurrent(First()); + else if (OpenSubMenus && Open(true)) + return; + } + Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay + SetHelpKeys(); +} + +cMenuRecordings::~cMenuRecordings() +{ + helpKeys = -1; + delete base; +} + +void cMenuRecordings::SetHelpKeys(void) +{ + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + int NewHelpKeys = helpKeys; + if (ri) { + if (ri->IsDirectory()) + NewHelpKeys = 1; + else { + NewHelpKeys = 2; + cRecording *recording = GetRecording(ri); + if (recording && recording->Summary()) + NewHelpKeys = 3; + } + } + if (NewHelpKeys != helpKeys) { + switch (NewHelpKeys) { + case 0: SetHelp(NULL); break; + case 1: SetHelp(tr("Open")); break; + case 2: + case 3: SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); + } + helpKeys = NewHelpKeys; + } +} + +cRecording *cMenuRecordings::GetRecording(cMenuRecordingItem *Item) +{ + cRecording *recording = Recordings.GetByName(Item->FileName()); + if (!recording) + Interface->Error(tr("Error while accessing recording!")); + return recording; +} + +bool cMenuRecordings::Open(bool OpenSubMenus) +{ + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + if (ri && ri->IsDirectory()) { + const char *t = ri->Name(); + char *buffer = NULL; + if (base) { + asprintf(&buffer, "%s~%s", base, t); + t = buffer; + } + AddSubMenu(new cMenuRecordings(t, level + 1, OpenSubMenus)); + delete buffer; + return true; + } + return false; } eOSState cMenuRecordings::Play(void) { cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri) { - cReplayControl::SetRecording(ri->recording->FileName(), ri->recording->Title()); - return osReplay; + if (ri->IsDirectory()) + Open(); + else { + cRecording *recording = GetRecording(ri); + if (recording) { + cReplayControl::SetRecording(recording->FileName(), recording->Title()); + return osReplay; + } + } } return osContinue; } @@ -1541,9 +1657,9 @@ eOSState cMenuRecordings::Play(void) eOSState cMenuRecordings::Rewind(void) { cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); - if (ri) { + if (ri && !ri->IsDirectory()) { cDvbApi::PrimaryDvbApi->StopReplay(); // must do this first to be able to rewind the currently replayed recording - cResumeFile ResumeFile(ri->recording->FileName()); + cResumeFile ResumeFile(ri->FileName()); ResumeFile.Delete(); return Play(); } @@ -1553,17 +1669,21 @@ eOSState cMenuRecordings::Rewind(void) eOSState cMenuRecordings::Del(void) { cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); - if (ri) { + 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?"))) { - if (ri->recording->Delete()) { - cReplayControl::ClearLastReplayed(ri->recording->FileName()); - cOsdMenu::Del(Current()); - Display(); + cRecording *recording = GetRecording(ri); + if (recording) { + if (recording->Delete()) { + cReplayControl::ClearLastReplayed(ri->FileName()); + cOsdMenu::Del(Current()); + Recordings.Del(recording); + Display(); + } + else + Interface->Error(tr("Error while deleting recording!")); } - else - Interface->Error(tr("Error while deleting recording!")); } //XXX } //XXX else @@ -1577,8 +1697,11 @@ eOSState cMenuRecordings::Summary(void) if (HasSubMenu() || Count() == 0) return osContinue; cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); - if (ri && ri->recording->Summary() && *ri->recording->Summary()) - return AddSubMenu(new cMenuText(tr("Summary"), ri->recording->Summary())); + if (ri && !ri->IsDirectory()) { + cRecording *recording = GetRecording(ri); + if (recording && recording->Summary() && *recording->Summary()) + return AddSubMenu(new cMenuText(tr("Summary"), recording->Summary())); + } return osContinue; } @@ -1597,6 +1720,8 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) default: break; } } + if (!HasSubMenu() && Key != kNone) + SetHelpKeys(); return state; } @@ -1712,13 +1837,14 @@ void cMenuSetup::Set(void) Add(new cMenuEditIntItem( tr("MarginStart"), &data.MarginStart)); Add(new cMenuEditIntItem( tr("MarginStop"), &data.MarginStop)); Add(new cMenuEditIntItem( tr("EPGScanTimeout"), &data.EPGScanTimeout)); - Add(new cMenuEditIntItem( tr("EPGBugfixLevel"), &data.EPGBugfixLevel, 0, 3)); + Add(new cMenuEditIntItem( tr("EPGBugfixLevel"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL)); Add(new cMenuEditIntItem( tr("SVDRPTimeout"), &data.SVDRPTimeout)); Add(new cMenuEditBoolItem(tr("SortTimers"), &data.SortTimers)); Add(new cMenuEditIntItem( tr("PrimaryLimit"), &data.PrimaryLimit, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("DefaultPriority"), &data.DefaultPriority, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("DefaultLifetime"), &data.DefaultLifetime, 0, MAXLIFETIME)); 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("ChannelInfoPos"), &data.ChannelInfoPos, tr("bottom"), tr("top"))); Add(new cMenuEditIntItem( tr("OSDwidth"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH)); @@ -1815,6 +1941,18 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State) { digit = 0; + // Title with disk usage: + +#define MB_PER_MINUTE 30 // this is just an estimate! + + char buffer[40]; + int FreeMB; + int Percent = VideoDiskSpace(&FreeMB); + int Hours = int(double(FreeMB) / MB_PER_MINUTE / 60); + int Minutes = (FreeMB / MB_PER_MINUTE) % 60; + snprintf(buffer, sizeof(buffer), "%s - Disk %d%% - %2d:%02d %s", tr("Main"), Percent, Hours, Minutes, tr("free")); + SetTitle(buffer); + // Basic menu items: Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); @@ -1871,7 +2009,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State) // Initial submenus: switch (State) { - case osRecordings: AddSubMenu(new cMenuRecordings); break; + case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; #ifdef DVDSUPPORT case osDVD: AddSubMenu(new cMenuDVD); break; #endif //DVDSUPPORT |