vdr/menu.h
Klaus Schmidinger ec0ec6da01 Version 2.3.2
Merry Christmas to all VDR users!

It's been a very busy year for me, in which I was unable to
spend as much time on VDR as I would have liked to. But now things
are settled again and I managed to prepare a new developer version
with the most important fixes and improvements. Please feel free
to tell me if I missed something important - some things may well
have slipped under my radar ;-).

So here's my Christmas gift for you!

VDR developer version 2.3.2 is now available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-2.3.2.tar.bz2

A 'diff' against the previous version is available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-2.3.1-2.3.2.diff

MD5 checksums:

6dbb208ea3d59658a18912b49af175b3  vdr-2.3.2.tar.bz2
68a0ed9f01048026333939d30e0a6474  vdr-2.3.1-2.3.2.diff

WARNING:
========

This is a *developer* version. Even though *I* use it in my productive
environment, I strongly recommend that you only use it under controlled
conditions and for testing and debugging.

From the HISTORY file:
- Fixed a crash when deleting a recording (reported by Oliver Endriss).
- Fixed an overflow of PIDs in a receiver (thanks to Robert Hannebauer).
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Fixed initializing device specific parameters in cDvbTransponderParameters.
- The function SetCurrentChannel(const cChannel *Channel) is now deprecated and
  may be removed in a future version. Use SetCurrentChannel(int ChannelNumber)
  instead.
- The SVDRP command DELC now refuses to delete the very last channel in the list,
  to avoid ending up with an empty channel list.
- The cRwLock class now allows nested read locks within a write lock from the
  same thread. This fixes possible crashes when moving or deleting channels in
  the menu or through SVDRP (as well as other operations that try to acquire a
  read lock within a write lock).
- Fixed a crash when trying to delete a channel that is being used by a timer.
- Fixed setting the current item and counter values in the Recordings menu after
  deleting the last recording in a subfolder.
- Fixed a crash when deleting a recording that is currently being replayed.
- Fixed a crash when moving a recording to a folder on a different volume.
  The cRecordingsHandler now performs its actual operations in a separate thread,
  thus avoiding locking problems and reducing the time between subsequent
  operations.
- Added a note to the description of cFont::Size(), regarding possible differences
  between it and cFont::Height() (suggested to Thomas Reufer).
- Made the cPlayer member functions FramesPerSecond, GetIndex and GetReplayMode
  'const' (thanks to Thomas Reufer).
- Fixed resuming replay at a given position, which was off by one frame (thanks
  to Thomas Reufer).
- Improved handling frame numbers to have a smoother progress display during
  replay of recordings with B-frames (thanks to Thomas Reufer).
- Fixed replaying recordings to their very end, if they don't end with an I-frame
  (thanks to Thomas Reufer).
- Implemented a frame parser for H.265 (HEVC) recordings (thanks to Thomas Reufer).
- Added cFont::Width(void) to get the default character width and allow stretched
  font drawing in high level OSDs (thanks to Thomas Reufer).
- Fixed regenerating the index of audio recordings (thanks to Thomas Reufer).
- Fixed building VDR with systemd >= 230 (thanks to Ville Skyttä).
- Sorted sources.conf by continous azimuth (thanks to Lucian Muresan).
- Added 'S58.5E Kazsat 3' to sources.conf (thanks to Aitugan Sarbassov).
- Fixed truncated date/time strings in the skins on multi-byte UTF-8 systems
  (reported by Sergey Chernyavskiy).
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Added a 'const' version of cTimers::GetTimer() (thanks to Lars Hanisch).
- Fixed a typo in the description of cTimers::GetTimersRead() (thanks to Lars
  Hanisch).
- Fixed a possible buffer overflow in handling CA descriptors (suggested by
  Lars Hanisch).
- Avoiding some duplicate code and unnecessary work in nit.c (thanks to Ville
  Skyttä).
- Added support for the systemd watchdog (thanks to Marc Perrudin),
- Added a short sleep to cTSBuffer::Action() to avoid high CPU usage (thanks to
  Sergey Chernyavskiy).
2017-02-01 00:05:46 +01:00

336 lines
9.4 KiB
C++

/*
* menu.h: The actual menu implementations
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.h 4.5 2016/12/22 10:55:36 kls Exp $
*/
#ifndef __MENU_H
#define __MENU_H
#include "ci.h"
#include "device.h"
#include "epg.h"
#include "osdbase.h"
#include "dvbplayer.h"
#include "menuitems.h"
#include "recorder.h"
#include "skins.h"
class cMenuText : public cOsdMenu {
private:
char *text;
eDvbFont font;
public:
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
virtual ~cMenuText();
void SetText(const char *Text);
virtual void Display(void);
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuFolder : public cOsdMenu {
private:
cNestedItemList *nestedItemList;
cList<cNestedItem> *list;
cString dir;
cOsdItem *firstFolder;
bool editing;
int helpKeys;
void SetHelpKeys(void);
void Set(const char *CurrentFolder = NULL);
void DescendPath(const char *Path);
eOSState SetFolder(void);
eOSState Select(bool Open);
eOSState New(void);
eOSState Delete(void);
eOSState Edit(void);
cMenuFolder(const char *Title, cList<cNestedItem> *List, cNestedItemList *NestedItemList, const char *Dir, const char *Path = NULL);
public:
cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path = NULL);
cString GetFolder(void);
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuCommands : public cOsdMenu {
private:
cList<cNestedItem> *commands;
cString parameters;
cString title;
cString command;
bool confirm;
char *result;
bool Parse(const char *s);
eOSState Execute(void);
public:
cMenuCommands(const char *Title, cList<cNestedItem> *Commands, const char *Parameters = NULL);
virtual ~cMenuCommands();
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuEditTimer : public cOsdMenu {
private:
static const cTimer *addedTimer;
cTimer *timer;
cTimer data;
int channel;
bool addIfConfirmed;
cStringList svdrpServerNames;
char remote[HOST_NAME_MAX];
cMenuEditStrItem *file;
cMenuEditDateItem *day;
cMenuEditDateItem *firstday;
eOSState SetFolder(void);
void SetFirstDayItem(void);
void SetHelpKeys(void);
public:
cMenuEditTimer(cTimer *Timer, bool New = false);
virtual ~cMenuEditTimer();
virtual eOSState ProcessKey(eKeys Key);
static const cTimer *AddedTimer(void);
};
class cMenuEvent : public cOsdMenu {
private:
const cEvent *event;
public:
cMenuEvent(const cTimers *Timers, const cChannels *Channels, const cEvent *Event, bool CanSwitch = false, bool Buttons = false);
virtual void Display(void);
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuMain : public cOsdMenu {
private:
bool replaying;
cOsdItem *stopReplayItem;
cOsdItem *cancelEditingItem;
cOsdItem *stopRecordingItem;
int recordControlsState;
static cOsdObject *pluginOsdObject;
void Set(void);
bool Update(bool Force = false);
public:
cMenuMain(eOSState State = osUnknown, bool OpenSubMenus = false);
virtual eOSState ProcessKey(eKeys Key);
static cOsdObject *PluginOsdObject(void);
};
class cDisplayChannel : public cOsdObject {
private:
cSkinDisplayChannel *displayChannel;
int group;
bool withInfo;
cTimeMs lastTime;
int number;
bool timeout;
int osdState;
const cPositioner *positioner;
const cChannel *channel;
const cEvent *lastPresent;
const cEvent *lastFollowing;
static cDisplayChannel *currentDisplayChannel;
void DisplayChannel(void);
void DisplayInfo(void);
void Refresh(void);
const cChannel *NextAvailableChannel(const cChannel *Channel, int Direction);
public:
cDisplayChannel(int Number, bool Switched);
cDisplayChannel(eKeys FirstKey);
virtual ~cDisplayChannel();
virtual eOSState ProcessKey(eKeys Key);
static bool IsOpen(void) { return currentDisplayChannel != NULL; }
};
class cDisplayVolume : public cOsdObject {
private:
cSkinDisplayVolume *displayVolume;
cTimeMs timeout;
static cDisplayVolume *currentDisplayVolume;
virtual void Show(void);
cDisplayVolume(void);
public:
virtual ~cDisplayVolume();
static cDisplayVolume *Create(void);
static void Process(eKeys Key);
eOSState ProcessKey(eKeys Key);
};
class cDisplayTracks : public cOsdObject {
private:
cSkinDisplayTracks *displayTracks;
cTimeMs timeout;
eTrackType types[ttMaxTrackTypes];
char *descriptions[ttMaxTrackTypes + 1]; // list is NULL terminated
int numTracks, track, audioChannel;
static cDisplayTracks *currentDisplayTracks;
virtual void Show(void);
cDisplayTracks(void);
public:
virtual ~cDisplayTracks();
static bool IsOpen(void) { return currentDisplayTracks != NULL; }
static cDisplayTracks *Create(void);
static void Process(eKeys Key);
eOSState ProcessKey(eKeys Key);
};
class cDisplaySubtitleTracks : public cOsdObject {
private:
cSkinDisplayTracks *displayTracks;
cTimeMs timeout;
eTrackType types[ttMaxTrackTypes];
char *descriptions[ttMaxTrackTypes + 1]; // list is NULL terminated
int numTracks, track;
static cDisplaySubtitleTracks *currentDisplayTracks;
virtual void Show(void);
cDisplaySubtitleTracks(void);
public:
virtual ~cDisplaySubtitleTracks();
static bool IsOpen(void) { return currentDisplayTracks != NULL; }
static cDisplaySubtitleTracks *Create(void);
static void Process(eKeys Key);
eOSState ProcessKey(eKeys Key);
};
cOsdObject *CamControl(void);
bool CamMenuActive(void);
class cRecordingFilter {
public:
virtual ~cRecordingFilter(void) {};
virtual bool Filter(const cRecording *Recording) const = 0;
///< Returns true if the given Recording shall be displayed in the Recordings menu.
};
class cMenuRecordingItem;
class cMenuRecordings : public cOsdMenu {
private:
char *base;
int level;
cStateKey recordingsStateKey;
int helpKeys;
const cRecordingFilter *filter;
static cString path;
static cString fileName;
void SetHelpKeys(void);
void Set(bool Refresh = false);
bool Open(bool OpenSubMenus = false);
eOSState Play(void);
eOSState Rewind(void);
eOSState Delete(void);
eOSState Info(void);
eOSState Sort(void);
eOSState Commands(eKeys Key = kNone);
protected:
cString DirectoryName(void);
public:
cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false, const cRecordingFilter *Filter = NULL);
~cMenuRecordings();
virtual eOSState ProcessKey(eKeys Key);
static void SetPath(const char *Path);
static void SetRecording(const char *FileName);
};
class cRecordControl {
private:
cDevice *device;
cTimer *timer;
cRecorder *recorder;
const cEvent *event;
cString instantId;
char *fileName;
bool GetEvent(void);
public:
cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer = NULL, bool Pause = false);
virtual ~cRecordControl();
bool Process(time_t t);
cDevice *Device(void) { return device; }
void Stop(bool ExecuteUserCommand = true);
const char *InstantId(void) { return instantId; }
const char *FileName(void) { return fileName; }
cTimer *Timer(void) { return timer; }
};
class cRecordControls {
private:
static cRecordControl *RecordControls[];
static int state;
public:
static bool Start(cTimers *Timers, cTimer *Timer, bool Pause = false);
static bool Start(bool Pause = false);
static void Stop(const char *InstantId);
static void Stop(cTimer *Timer);
static bool PauseLiveVideo(void);
static const char *GetInstantId(const char *LastInstantId);
static cRecordControl *GetRecordControl(const char *FileName);
static cRecordControl *GetRecordControl(const cTimer *Timer);
///< Returns the cRecordControl for the given Timer.
///< If there is no cRecordControl for Timer, NULL is returned.
static bool Process(cTimers *Timers, time_t t);
static void ChannelDataModified(const cChannel *Channel);
static bool Active(void);
static void Shutdown(void);
static void ChangeState(void) { state++; }
static bool StateChanged(int &State);
};
class cAdaptiveSkipper {
private:
int *initialValue;
int currentValue;
double framesPerSecond;
eKeys lastKey;
cTimeMs timeout;
public:
cAdaptiveSkipper(void);
void Initialize(int *InitialValue, double FramesPerSecond);
int GetValue(eKeys Key);
};
class cReplayControl : public cDvbPlayerControl {
private:
cSkinDisplayReplay *displayReplay;
cAdaptiveSkipper adaptiveSkipper;
cMarks marks;
bool marksModified;
bool visible, modeOnly, shown, displayFrames;
int lastCurrent, lastTotal;
bool lastPlay, lastForward;
int lastSpeed;
time_t timeoutShow;
time_t lastProgressUpdate;
bool timeSearchActive, timeSearchHide;
int timeSearchTime, timeSearchPos;
void TimeSearchDisplay(void);
void TimeSearchProcess(eKeys Key);
void TimeSearch(void);
void ShowTimed(int Seconds = 0);
static cReplayControl *currentReplayControl;
static cString fileName;
void ShowMode(void);
bool ShowProgress(bool Initial);
void MarkToggle(void);
void MarkJump(bool Forward);
void MarkMove(int Frames, bool MarkRequired);
void EditCut(void);
void EditTest(void);
public:
cReplayControl(bool PauseLive = false);
virtual ~cReplayControl();
void Stop(void);
virtual cOsdObject *GetInfo(void);
virtual const cRecording *GetRecording(void);
virtual eOSState ProcessKey(eKeys Key);
virtual void Show(void);
virtual void Hide(void);
bool Visible(void) { return visible; }
static void SetRecording(const char *FileName);
static const char *NowReplaying(void);
static const char *LastReplayed(void);
static void ClearLastReplayed(const char *FileName);
};
#endif //__MENU_H