36#define MAXWAIT4EPGINFO 3
38#define NEWTIMERLIMIT 120
43#define MAXRECORDCONTROLS (MAXDEVICES * MAXRECEIVERS)
44#define MAXINSTANTRECTIME (24 * 60 - 1)
45#define MAXWAITFORCAMMENU 10
46#define CAMMENURETRYTIMEOUT 3
47#define CAMRESPONSETIMEOUT 5
48#define PROGRESSTIMEOUT 100
49#define MINFREEDISK 300
50#define NODISKSPACEDELTA 300
51#define MAXCHNAMWIDTH 16
53#define CHNUMWIDTH (numdigits(cChannels::MaxNumber()) + 1)
54#define CHNAMWIDTH (min(MAXCHNAMWIDTH, cChannels::MaxShortChannelNameLength() + 1))
60 virtual void Set(
void);
103 virtual void Set(
void);
195 *
data.portalName = 0;
242 int oldSource =
data.source;
248 bool Modified =
false;
299 virtual void Set(
void);
352#define CHANNELNUMBERTIMEOUT 1000
359 void Set(
bool Force =
false);
368 virtual void Move(
int From,
int To);
397 for (
const cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel)) {
401 if (Channel == CurrentChannel)
411 SetHelp(
tr(
"Button$Edit"),
tr(
"Button$New"),
tr(
"Button$Delete"),
tr(
"Button$Mark"));
446 if (!ci->Channel()->GroupSep() && ci->Channel()->Number() ==
number) {
500 bool Deleted =
false;
503 int DeletedChannel = Channel->
Number();
505 if (Timers->UsesChannel(Channel)) {
511 if (CurrentChannel && Channel == CurrentChannel) {
515 CurrentChannel = Channels->
Get(n);
516 CurrentChannelNr = 0;
518 Channels->
Del(Channel);
521 isyslog(
"channel %d deleted", DeletedChannel);
523 if (CurrentChannel && CurrentChannel->
Number() != CurrentChannelNr) {
539 cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
542 if (FromChannel && ToChannel) {
543 int FromNumber = FromChannel->
Number();
544 int ToNumber = ToChannel->
Number();
545 if (Channels->MoveNeedsDecrement(FromChannel, ToChannel)) {
546 ToChannel = Channels->
Prev(ToChannel);
549 Channels->Move(FromChannel, ToChannel);
553 isyslog(
"channel %d moved to %d", FromNumber, ToNumber);
554 if (CurrentChannel && CurrentChannel->
Number() != CurrentChannelNr) {
556 Channels->SwitchTo(CurrentChannel->
Number());
574 if (
cChannel *Channel = MenuEditChannel->Channel()) {
601 if (!ci->Channel()->GroupSep() && ci->Channel()->Number() == CurrentChannelNr) {
634 text = Text ? strdup(Text) : NULL;
679 virtual void Set(
void);
714:
cOsdMenu(Folder ?
tr(
"Edit folder") :
tr(
"New folder"), 12)
743 if (strcmp(Folder->Text(),
name) == 0) {
748 char *p = strpbrk(
name,
"\\{}#~");
823#define FOLDERDELIMCHARSUBST 0x01
831 for (Folder =
List->First(); Folder; Folder =
List->Next(Folder)) {
832 if (strcmp(Path, Folder->
Text()) == 0)
844 for (
const cRecording *Recording = Recordings->
First(); Recording; Recording = Recordings->
Next(Recording)) {
845 cString Folder = Recording->Folder();
847 if (Dirs.
Find(Folder) < 0)
848 Dirs.
Append(strdup(Folder));
851 for (
int i = 0; i < Dirs.
Size(); i++) {
852 if (
char *s = Dirs[i])
864 RecordingsStateKey.
Remove();
877 Add(FolderItem, CurrentFolder ? strcmp(Folder->Text(), CurrentFolder) == 0 :
false);
889 if (strncmp(Folder->Folder()->Text(), Path, p - Path) == 0) {
926 if (Folder &&
Interface->Confirm(Folder->
Folder()->
SubItems() ?
tr(
"Delete folder and all sub folders?") :
tr(
"Delete folder?"))) {
953 Set(mef->GetFolder());
1071 SetHelp(
tr(
"Button$Folder"),
data.weekdays ?
tr(
"Button$Single") :
tr(
"Button$Repeating"), *
data.pattern ?
tr(
"Button$Regular") :
tr(
"Button$Pattern"));
1089 if (Initial && !*
data.pattern) {
1098 if (!*
data.pattern) {
1120 cString Folder = mf->GetFolder();
1124 else if (p !=
data.file)
1125 memmove(
data.file, p, strlen(p) + 1);
1166 data.channel = Channel;
1172 strcpy(
data.file,
data.Channel()->ShortName(
true));
1180 Timers->Del(
timer,
false);
1192 if (
data.Local() && !
timer->IsPatternTimer() &&
data.IsPatternTimer())
1193 data.SetEvent(NULL);
1196 timer->TriggerRespawn();
1198 timer->SetEventFromSchedule(Schedules);
1205 day->ToggleRepeating();
1233 virtual void Set(
void);
1252 if (
timer->WeekDays())
1253 day =
timer->PrintDay(0,
timer->WeekDays(),
false);
1260 time_t Day =
timer->Day();
1261 localtime_r(&Day, &tm_r);
1263 strftime(buffer,
sizeof(buffer),
"%Y%m%d", &tm_r);
1266 const char *File =
timer->Pattern();
1270 File =
timer->Event()->Title();
1276 File =
timer->File();
1281 timer->Channel()->Number(),
1283 *name && **name ?
" " :
"",
1285 timer->Start() / 100,
1286 timer->Start() % 100,
1287 timer->Stop() / 100,
1288 timer->Stop() % 100,
1290 timer->IsPatternTimer() ?
"{" :
"",
1292 timer->IsPatternTimer() ?
"}" :
""));
1343 for (
const cTimer *Timer = Timers->First(); Timer; Timer = Timers->
Next(Timer)) {
1346 if (CurrentTimer && Timer->
Id() == CurrentTimer->
Id() && (!Timer->Remote() && !CurrentTimer->
Remote() || Timer->Remote() && CurrentTimer->
Remote() && strcmp(Timer->Remote(), CurrentTimer->
Remote()) == 0))
1366 int NewHelpKeys = 0;
1405 StateKey.
Remove(Timer != NULL);
1421 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1432 bool TimerRecording = Timer->
Recording();
1434 if (
Interface->Confirm(
tr(
"Delete timer?")) && (!TimerRecording ||
Interface->Confirm(
tr(
"Timer still recording - really delete?")))) {
1466 if (Timer && Timer->
Event())
1492 Add(CurrentItem,
true);
1516 SetHelp(TimerMatch ==
tmFull ?
tr(
"Button$Timer") :
tr(
"Button$Record"), NULL, NULL, CanSwitch ?
tr(
"Button$Switch") : NULL);
1527 if (
event->Description())
1616 if (
event->EndTime() < time(NULL) && !
event->IsRunning() && (!Timer || !Timer->
Recording()))
1622 char v =
event->Vps() && (
event->Vps() -
event->StartTime()) ?
'V' :
' ';
1623 char r =
event->SeenWithin(30) &&
event->IsRunning() ?
'*' :
' ';
1625 cString eds =
event->GetDateString();
1627 buffer =
cString::sprintf(
"%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s",
channel->Number(),
Utf8SymChars(csn, 999), csn,
Utf8SymChars(eds, 6), *eds, *
event->GetTimeString(), t, v, r,
event->Title());
1678 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1679 if (!Channel->GroupSep()) {
1681 if (
const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent())
1692 bool result =
false;
1707 int NewHelpKeys = 0;
1710 NewHelpKeys |= 0x02;
1712 NewHelpKeys |= 0x01;
1714 NewHelpKeys |= 0x04;
1716 NewHelpKeys |= 0x08;
1719 NewHelpKeys |= 0x10;
1725 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
1726 SetHelp(Red[NewHelpKeys & 0x03],
now ?
tr(
"Button$Next") :
tr(
"Button$Now"),
tr(
"Button$Schedule"),
canSwitch ?
tr(
"Button$Switch") : NULL);
1761 Timers->SetExplicitModify();
1762 if (item->timerMatch ==
tmFull) {
1763 if (
cTimer *Timer = Timers->GetMatch(item->event))
1767 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1769 if (
cTimer *t = Timers->GetTimer(Timer)) {
1777 Timers->SetModified();
1782 else if (Timer->
Remote())
1844 if (HadSubMenu &&
Update())
1892 Set(Timers, Channels, NULL,
true);
1908 const cEvent *Event = NULL;
1911 Event = CurrentItem->
event;
1917 bool Refresh =
false;
1943 const cEvent *PresentEvent = Event ? Event : Schedule->GetPresentEvent();
1944 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1945 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1946 if (ev->EndTime() >
now || ev == PresentEvent)
1963 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1964 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1965 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
1982 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
1984 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1985 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1986 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
2002 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
2004 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
2005 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
2006 if (ev->EndTime() >
now || ev == Event)
2016 bool result =
false;
2031 int NewHelpKeys = 0;
2034 NewHelpKeys |= 0x02;
2036 NewHelpKeys |= 0x01;
2040 NewHelpKeys |= 0x10;
2046 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
2047 SetHelp(Red[NewHelpKeys & 0x03],
tr(
"Button$Now"),
tr(
"Button$Next"),
canSwitch ?
tr(
"Button$Switch") : NULL);
2057 Set(Timers, Channels, NULL,
true);
2067 Timers->SetExplicitModify();
2068 if (item->timerMatch ==
tmFull) {
2069 if (
cTimer *Timer = Timers->GetMatch(item->event))
2073 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
2075 if (
cTimer *t = Timers->GetTimer(Timer)) {
2083 Timers->SetModified();
2088 else if (Timer->
Remote())
2105 if ((Channel = Channels->GetByChannelID(item->
event->
ChannelID(),
true)) != NULL) {
2106 if (!Channels->SwitchTo(Channel->
Number()))
2121 Set(Timers, Channels);
2139 ChannelNr = Channel->Number();
2164 Set(Timers, Channels, Channel,
true);
2183 if (
const cChannel *Channel = Channels->GetByChannelID(ei->ChannelID(),
true)) {
2185 Set(Timers, Channels, Channel,
true);
2188 else if (HadSubMenu &&
Update())
2207 const char *s = Command->Text();
2208 if (Command->SubItems())
2222 const char *p = strchr(s,
':');
2229 if (l > 1 && t[l - 1] ==
'?') {
2257 const char *cmd = *cmdbuf ? *cmdbuf : *
command;
2258 dsyslog(
"executing command '%s'", cmd);
2260 if (p.
Open(cmd,
"r")) {
2263 while ((c = fgetc(p)) != EOF) {
2265 if (
char *NewBuffer = (
char *)realloc(
result, l + 21))
2268 esyslog(
"ERROR: out of memory");
2279 esyslog(
"ERROR: can't open pipe for command '%s'", cmd);
2381 dsyslog(
"CAM %d: Menu ------------------",
camSlot->SlotNumber());
2391 for (
int i = 0; i <
ciMenu->NumEntries(); i++) {
2403 int Length =
ciEnquiry->ExpectedLength();
2407 dsyslog(
"CAM %d: Enquiry ------------------",
camSlot->SlotNumber());
2420 const char *p = strchr(s,
'\n');
2421 int l = p ? p - s : strlen(s);
2424 item->
SetText(strndup(s, l),
false);
2433 if (
ciMenu->Selectable()) {
2443 snprintf(buffer,
sizeof(buffer),
tr(
"Please enter %d digits!"),
ciEnquiry->ExpectedLength());
2469 else if (state ==
osBack) {
2496 if (CamSlot->HasUserIO())
2509#define osUserRecRenamed osUser1
2510#define osUserRecMoved osUser2
2511#define osUserRecRemoved osUser3
2512#define osUserRecEmpty osUser4
2559 for (
const cRecording *Recording = Recordings->First(); Recording; Recording = Recordings->
Next(Recording)) {
2560 if (Recording->IsInPath(
path)) {
2561 int FileSizeMB = Recording->FileSizeMB();
2562 if (FileSizeMB > 0 )
2563 DirSize += FileSizeMB;
2604 if (strcmp(NewPath,
path)) {
2605 int NumRecordings = 0;
2608 NumRecordings = Recordings->GetNumRecordingsInPath(
path);
2610 if (NumRecordings > 1 && !
Interface->Confirm(
cString::sprintf(
tr(
"Move entire folder containing %d recordings?"), NumRecordings)))
2615 Recordings->SetExplicitModify();
2616 Error = !Recordings->MoveRecordings(
path, NewPath);
2618 Recordings->SetModified();
2642 else if (Key ==
kOk)
2724 Add(
new cOsdItem(
tr(
"This recording is currently in use - no changes are possible!"),
osUnknown,
false));
2794 Skins.Message(
mtError,
tr(
"Not enough free disk space to start editing process!"));
2796 Skins.Message(
mtError,
tr(
"Error while queueing recording for cutting!"));
2804 if (strcmp(NewName,
recording->Name())) {
2808 if (access(*FileName, F_OK) != 0 ||
Interface->Confirm(
tr(
"Edited version already exists - overwrite?"))) {
2810 Skins.Message(
mtError,
tr(
"Error while queueing recording for copying!"));
2813 Recordings->AddByName(FileName);
2827 if (
Interface->Confirm(
tr(
"Rename recording to folder name?"))) {
2857 if (
const cRecording *Recording = Control->GetRecording()) {
2858 if (strcmp(
recording->FileName(), Recording->FileName()) == 0)
2859 Control->ClearEditingMarks();
2864 Skins.Message(
mtError,
tr(
"Error while deleting editing marks!"));
2880 bool Modified =
false;
2883 StateKey.
Remove(Modified);
2884 Skins.Message(
mtError,
tr(
"Error while changing priority/lifetime!"));
2896 if (strcmp(NewName, Recording->
Name())) {
2898 StateKey.
Remove(Modified);
2906 if (strcmp(Recording->
Folder(), OldFolder))
2909 StateKey.
Remove(Modified);
2912 StateKey.
Remove(Modified);
2964 SetHelp(
tr(
"Button$Play"),
tr(
"Button$Rewind"), NULL,
tr(
"Button$Edit"));
3063 if (*
Text() ==
'\t')
3098:
cOsdMenu(Base ? Base :
tr(
"Recordings"), 9, 6, 6)
3101 base = Base ? strdup(Base) : NULL;
3121 if (!ri->IsDirectory())
3130 int NewHelpKeys = 0;
3138 switch (NewHelpKeys) {
3140 case 1:
SetHelp(
tr(
"Button$Open"), NULL, NULL,
tr(
"Button$Edit"));
break;
3153 const char *CurrentRecording = NULL;
3155 CurrentRecording = ri->Recording()->FileName();
3156 if (!CurrentRecording)
3164 for (
const cRecording *Recording = Recordings->
First(); Recording; Recording = Recordings->
Next(Recording)) {
3171 if (p->Name() && strcmp(p->Name(), Item->
Name()) == 0) {
3177 if (*Item->
Text() && !LastDir) {
3185 if (LastItem || LastDir) {
3187 if (strcmp(
path, Recording->Folder()) == 0)
3188 CurrentItem = LastDir ? LastDir : LastItem;
3190 else if (CurrentRecording && strcmp(CurrentRecording, Recording->FileName()) == 0)
3191 CurrentItem = LastDir ? LastDir : LastItem;
3227 const char *t = ri->
Name();
3271 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3273 if (
cTimer *Timer = rc->Timer()) {
3276 if (Timer->IsSingleEvent()) {
3278 isyslog(
"deleted timer %s", *Timer->ToDescr());
3290 char *RemoteBuf = NULL;
3292 if (2 == sscanf(TimerId,
"%d@%m[^ \n]", &Id, &RemoteBuf) && Id != 0) {
3295 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3297 if (
cTimer *Timer = Timers->GetById(Id, Remote)) {
3298 cTimer OldTimer = *Timer;
3301 if (Timer->IsSingleEvent()) {
3325 if (
Interface->Confirm(
tr(
"Delete recording?"))) {
3332 FileName = Recording->FileName();
3334 if (!
Interface->Confirm(
tr(
"Recording is being edited - really delete?")))
3348 if (!Recording || Recording->
Delete()) {
3374 if (ri->IsDirectory())
3452 ri->SetRecording(riSub->Recording());
3480 virtual void Store(
void);
3515 virtual void Set(
void);
3606 bool ModifiedAppearance =
false;
3615 ModifiedAppearance =
true;
3618 if (
themes.NumThemes() &&
Skins.Current()->Theme()) {
3624 ModifiedAppearance =
true;
3626 ModifiedAppearance =
true;
3631 ModifiedAppearance =
true;
3633 ModifiedAppearance =
true;
3635 ModifiedAppearance =
true;
3636 if (
data.AlwaysSortFoldersFirst !=
Setup.AlwaysSortFoldersFirst ||
data.RecordingDirs !=
Setup.RecordingDirs ||
data.RecSortingDirection !=
Setup.RecSortingDirection) {
3638 Recordings->ClearSortNames();
3646 if (ModifiedAppearance)
3704 if (
data.SetSystemTime)
3722 if (
data.EPGLanguages[i] !=
::Setup.EPGLanguages[i]) {
3733 int oldSetSystemTime =
data.SetSystemTime;
3737 if (
numLanguages != oldnumLanguages ||
data.SetSystemTime != oldSetSystemTime) {
3739 data.EPGLanguages[i] = 0;
3742 for (k = 0; k < oldnumLanguages; k++) {
3743 if (
data.EPGLanguages[k] == l)
3746 if (k >= oldnumLanguages) {
3747 data.EPGLanguages[i] = l;
3803 SetHelp(NULL,
tr(
"Button$Audio"),
tr(
"Button$Subtitles"), NULL);
3816 if (
data.VideoFormat == 0)
3824 if (
data.DisplaySubtitles) {
3839 int oldVideoDisplayFormat =
::Setup.VideoDisplayFormat;
3840 bool oldVideoFormat =
::Setup.VideoFormat;
3841 bool newVideoFormat =
data.VideoFormat;
3842 bool oldDisplaySubtitles =
::Setup.DisplaySubtitles;
3843 bool newDisplaySubtitles =
data.DisplaySubtitles;
3857 bool DoSetup =
data.VideoFormat != newVideoFormat;
3858 DoSetup |=
data.DisplaySubtitles != newDisplaySubtitles;
3861 data.AudioLanguages[i] = 0;
3864 for (k = 0; k < oldnumAudioLanguages; k++) {
3865 if (
data.AudioLanguages[k] == l)
3868 if (k >= oldnumAudioLanguages) {
3869 data.AudioLanguages[i] = l;
3879 data.SubtitleLanguages[i] = 0;
3882 for (k = 0; k < oldnumSubtitleLanguages; k++) {
3883 if (
data.SubtitleLanguages[k] == l)
3886 if (k >= oldnumSubtitleLanguages) {
3887 data.SubtitleLanguages[i] = l;
3901 if (
::Setup.VideoDisplayFormat != oldVideoDisplayFormat)
3903 if (
::Setup.VideoFormat != oldVideoFormat)
3905 if (
::Setup.DisplaySubtitles != oldDisplaySubtitles)
3945 int NumSatDevices = 0;
3950 if (NumSatDevices > 1) {
3960 if (
data.UsePositioner) {
3973 int oldDiSEqC =
data.DiSEqC;
3974 int oldUsePositioner =
data.UsePositioner;
3975 bool DeviceBondingsChanged =
false;
3978 DeviceBondingsChanged = strcmp(
data.DeviceBondings, NewDeviceBondings) != 0;
3979 data.DeviceBondings = NewDeviceBondings;
3983 if (Key !=
kNone && (
data.DiSEqC != oldDiSEqC ||
data.UsePositioner != oldUsePositioner))
3985 else if (DeviceBondingsChanged)
4011 const char *Activating =
"";
4012 const char *CamName =
camSlot->GetCamName();
4014 switch (
camSlot->ModuleStatus()) {
4015 case msReset: CamName =
tr(
"CAM reset");
break;
4016 case msPresent: CamName =
tr(
"CAM present");
break;
4017 case msReady: CamName =
tr(
"CAM ready");
break;
4018 default: CamName =
"-";
break;
4021 else if (
camSlot->IsActivating())
4023 Activating =
tr(
" (activating)");
4027 CamSlot->Devices(DeviceNumbers);
4029 if (DeviceNumbers.
Size() > 0) {
4032 for (
int i = 0; i < DeviceNumbers.
Size(); i++)
4033 AssignedDevice =
cString::sprintf(
"%s %d", *AssignedDevice, DeviceNumbers[i]);
4037 if (strcmp(buffer,
Text()) != 0) {
4066 if (CamSlot->IsMasterSlot())
4077 const char *NewActivationHelp =
"";
4081 NewActivationHelp =
tr(
"Button$Cancel activation");
4083 NewActivationHelp =
tr(
"Button$Activate");
4097 time_t t0 = time(NULL);
4131 if (Device->ProvidesChannel(Channel)) {
4133 if (CamSlot->
Assign(Device,
true)) {
4136 if (CamSlot->
Assign(Device)) {
4137 if (Device->SwitchChannel(Channel,
true)) {
4237 virtual void Store(
void);
4254 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Initial duration for adaptive skipping (s)"), &
data.AdaptiveSkipInitial, 10, 600));
4255 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Reset timeout for adaptive skipping (s)"), &
data.AdaptiveSkipTimeout, 0, 10));
4259 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Skip distance with Green/Yellow keys in repeat (s)"), &
data.SkipSecondsRepeat, 5, 600));
4267 Recordings->ResetResume();
4306 if (
data.SVDRPPeering) {
4319 Add(
new cMenuEditIntItem(
tr(
"Setup.Miscellaneous$Initial volume"), &
data.InitialVolume, -1, 255,
tr(
"Setup.Miscellaneous$as before")));
4331 bool OldSVDRPPeering =
data.SVDRPPeering;
4332 bool ModifiedSVDRPSettings =
false;
4333 bool ModifiedShowChannelNamesWithSource =
false;
4335 ModifiedSVDRPSettings =
data.SVDRPPeering !=
Setup.SVDRPPeering || strcmp(
data.SVDRPHostName,
Setup.SVDRPHostName);
4336 ModifiedShowChannelNamesWithSource =
data.ShowChannelNamesWithSource !=
Setup.ShowChannelNamesWithSource;
4339 if (ModifiedShowChannelNamesWithSource) {
4341 for (
cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel))
4342 Channel->UpdateNameSource();
4344 if (
data.SVDRPPeering != OldSVDRPPeering)
4346 if (ModifiedSVDRPSettings) {
4350 Timers->SetExplicitModify();
4351 if (Timers->StoreRemoteTimers(NULL, NULL))
4352 Timers->SetModified();
4388 for (
int i = 0; ; i++) {
4412 Skins.Message(
mtInfo,
tr(
"This plugin has no setup parameters!"));
4430 virtual void Set(
void);
4448 snprintf(buffer,
sizeof(buffer),
"%s - VDR %s",
tr(
"Setup"),
VDRVERSION);
4518#define STOP_RECORDING trNOOP(" Stop recording ")
4568 for (
int i = 0; ; i++) {
4592 bool result =
false;
4594 bool NewReplaying =
false;
4599 if (Force || NewReplaying !=
replaying) {
4634 const char *s = NULL;
4693 default:
switch (Key) {
4695 case kRed:
if (!HadSubMenu)
4698 case kGreen:
if (!HadSubMenu) {
4703 case kYellow:
if (!HadSubMenu)
4706 case kBlue:
if (!HadSubMenu)
4712 bool DoDisplay =
Update();
4733 if (
const cChannel *Channel = Channels->GetByNumber(LiveChannel)) {
4735 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
4736 const cEvent *Present = Schedule->GetPresentEvent();
4745 Components = Recording->Info()->Components();
4750 int indexSubtitle = 0;
4754 case 2:
if (p->
type == 0x05)
4787 channel = Channels->GetByNumber(Number);
4840 const cEvent *Present = Schedule->GetPresentEvent();
4841 const cEvent *Following = Schedule->GetFollowingEvent();
4867 Channel = Direction > 0 ? Channels->
Next(Channel) : Channels->
Prev(Channel);
4868 if (!Channel &&
Setup.ChannelsWrap)
4869 Channel = Direction > 0 ? Channels->First() : Channels->Last();
4908 while (ch && (ch = Channels->
Next(ch)) != NULL) {
4910 if (n <= ch->Number() && ch->
Number() < n + m) {
4942 group = Channel->Index();
4945 int SaveGroup =
group;
5007 channel = Channels->Get(Channels->GetNextNormal(
group));
5045 Channels->SwitchTo(NewChannel->
Number());
5050 bool PositionerMoving = Positioner && Positioner->
IsMoving();
5052 if (!PositionerMoving) {
5069#define VOLUMETIMEOUT 1000
5070#define MUTETIMEOUT 5000
5136#define TRACKTIMEOUT 5000
5151 if (TrackId && TrackId->
id) {
5154 if (i == CurrentAudioTrack)
5203 int oldTrack =
track;
5220 static int ac[] = { 1, 0, 2 };
5247 if (
track != oldTrack) {
5272 if (TrackId && TrackId->
id) {
5275 if (i == CurrentSubtitleTrack)
5321 int oldTrack =
track;
5348 if (
track != oldTrack) {
5382 ChannelsStateKey.
Remove();
5384 timer->SetPending(
true);
5385 timer->SetRecording(
true);
5386 event =
timer->Event();
5397 timer->SetPending(
false);
5398 timer->SetRecording(
false);
5407 SchedulesStateKey.
Remove();
5419 if (!
Timer && !LastReplayed)
5421 SchedulesStateKey.
Remove();
5436 SchedulesStateKey.
Remove();
5445#define INSTANT_REC_EPG_LOOKAHEAD 300
5454 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
5455 event = Schedule->GetEventAround(Time);
5458 dsyslog(
"got EPG info after %d seconds", seconds);
5464 dsyslog(
"waiting for EPG info...");
5467 dsyslog(
"no EPG info available");
5477 isyslog(
"timer %s %s with %d error%s", *
timer->ToDescr(), Finished ?
"finished" :
"stopped", Errors, Errors != 1 ?
"s" :
"");
5478 if (
timer->HasFlags(
tfAvoid) && Errors == 0 && Finished) {
5484 timer->SetRecording(
false);
5488 if (ExecuteUserCommand && Finished)
5497 timer->SetPending(
false);
5510 static time_t LastNoDiskSpaceMessage = 0;
5519 isyslog(
"not enough disk space to start recording%s%s", Timer ?
" timer " :
"", Timer ? *Timer->
ToDescr() :
"");
5521 LastNoDiskSpaceMessage = time(NULL);
5525 LastNoDiskSpaceMessage = 0;
5532 int Priority = Timer ? Timer->
Priority() : Pause ?
Setup.PausePriority :
Setup.DefaultPriority;
5535 dsyslog(
"switching device %d to channel %d %s (%s)", device->
DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
5543 if (!Timer || Timer->
Matches()) {
5552 else if (!Timer || !Timer->
Pending()) {
5553 isyslog(
"no free DVB device to record channel %d (%s)!", ch, Channel->Name());
5558 esyslog(
"ERROR: channel %d not defined!", ch);
5567 return Start(Timers, NULL, Pause);
5577 if (
id && strcmp(
id, InstantId) == 0) {
5624 if (LastInstantId && LastInstantId ==
RecordControls[i]->InstantId())
5625 LastInstantId = NULL;
5653 bool Result =
false;
5672 isyslog(
"stopping recording due to modification of channel %d (%s)", Channel->
Number(), Channel->
Name());
5701 int NewState =
state;
5702 bool Result = State != NewState;
5734 if (
Setup.AdaptiveSkipAlternate)
5768 if (
Setup.ProgressDisplayTime)
5788 if (
Setup.DelTimeshiftRec == 2 ||
Interface->Confirm(
tr(
"Delete timeshift recording?"))) {
5791 Timers->SetExplicitModify();
5796 Timers->SetModified();
5804 Recordings->SetExplicitModify();
5806 if (Recording->Delete()) {
5809 Recordings->SetModified();
5829 marks.Lock(StateKey);
5849 if (!Recordings->GetByName(
fileName))
5902 bool NormalPlay = (
Play && Speed == -1);
5943 int NumErrors = Errors ? Errors->
Size() : 0;
5947 if (
Setup.ShowRemainingTime)
5948 Index = Current - Index;
5970 strcpy(buf,
tr(
"Jump: "));
5971 int len = strlen(buf);
5980 sprintf(buf + len,
"%c%c:%c%c", ch10, ch1, cm10, cm1);
5986#define STAY_SECONDS_OFF_END 10
6059 if (
GetIndex(Current, Total,
true)) {
6062 marks.Lock(StateKey);
6070 Goto(Current,
true);
6085 if (
marks.Count()) {
6087 if (!
Setup.PauseOnMarkJump) {
6091 Goto(m->Position());
6095 Goto(m->Position(),
true);
6122 if ((m2 =
marks.Next(m)) != NULL)
6130 if ((m2 =
marks.Prev(m)) != NULL)
6139 else if (!MarkRequired)
6147 int NumErrors = Errors ? Errors->
Size() : 0;
6148 if (NumErrors > 0) {
6153 for (
int i = 0; i < NumErrors; i++) {
6154 int Position = Errors->
At(i);
6155 if (Position > Current + Offset) {
6156 int NextIFrame =
SkipFrames(Position - Current) + Offset;
6157 if (NextIFrame > Position) {
6159 Offset = NextIFrame - Current;
6163 Goto(Position,
true);
6167 if (Current < Total)
6171 for (
int i = NumErrors - 1; i >= 0; i--) {
6172 if (Errors->
At(i) < Current) {
6173 int Position = Errors->
At(i);
6174 Goto(Position,
true);
6192 else if (!
marks.GetNumSequences())
6197 Skins.Message(
mtError,
tr(
"Not enough free disk space to start editing process!"));
6215 m =
marks.GetNext(Current);
6217 if ((m->
Index() & 0x01) != 0 && !
Setup.SkipEdited)
6273 bool DoShowMode =
true;
6282 if (
Setup.MultiSpeedMode)
break;
6287 if (
Setup.MultiSpeedMode)
break;
6306 case kPrev:
if (
Setup.AdaptiveSkipPrevNext) {
6314 case kNext:
if (
Setup.AdaptiveSkipPrevNext) {
cString ChannelString(const cChannel *Channel, int Number)
#define LOCK_CHANNELS_READ
#define LOCK_CHANNELS_WRITE
void Initialize(int *InitialValue, double FramesPerSecond)
int Priority(void)
Returns the priority of the device this slot is currently assigned to, or IDLEPRIORITY if it is not a...
virtual bool EnterMenu(void)
Requests the CAM in this slot to start its menu.
virtual bool HasUserIO(void)
Returns true if there is a pending user interaction, which shall be retrieved via GetMenu() or GetEnq...
virtual bool Assign(cDevice *Device, bool Query=false)
Assigns this CAM slot to the given Device, if this is possible.
cDevice * Device(void)
Returns the device this CAM slot is currently assigned to.
virtual bool Reset(void)
Resets the CAM in this slot.
virtual void StartActivation(void)
Puts the CAM in this slot into a mode where an inserted smart card can be activated.
virtual bool IsActivating(void)
Returns true if this CAM slot is currently activating a smart card.
virtual bool CanActivate(void)
Returns true if there is a CAM in this slot that can be put into activation mode.
cCamSlot * MtdSpawn(void)
If this CAM slot can do MTD ("Multi Transponder Decryption"), a call to this function returns a cMtdC...
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
virtual void CancelActivation(void)
Cancels a previously started activation (if any).
const char * Name(void) const
bool GroupSep(void) const
const char * Provider(void) const
static cChannels * GetChannelsWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for write access.
bool HasUniqueChannelID(const cChannel *NewChannel, const cChannel *OldChannel=NULL) const
static int MaxNumber(void)
int GetPrevNormal(int Idx) const
Get previous normal channel (not group)
static const cChannels * GetChannelsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for read access.
void ReNumber(void)
Recalculate 'number' based on channel type.
const cChannel * GetByNumber(int Number, int SkipGap=0) const
void SetModifiedByUser(void)
const cChannel * GetByChannelID(tChannelID ChannelID, bool TryWithoutRid=false, bool TryWithoutPolarization=false) const
bool SwitchTo(int Number) const
void Del(cChannel *Channel)
Delete the given Channel from the list.
int GetNextNormal(int Idx) const
Get next normal channel (not group)
tComponent * Component(int Index) const
int NumComponents(void) const
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
static cControl * Control(cMutexLock &MutexLock, bool Hidden=false)
Returns the current replay control (if any) in case it is currently visible.
double FramesPerSecond(void) const
static void Shutdown(void)
static void Launch(cControl *Control)
static cString EditedFileName(const char *FileName)
Returns the full path name of the edited version of the recording with the given FileName.
void SetKeepTracks(bool KeepTracks)
Controls whether the current audio and subtitle track settings shall be kept as they currently are,...
bool SetCurrentSubtitleTrack(eTrackType Type, bool Manual=false)
Sets the current subtitle track to the given Type.
virtual const cPositioner * Positioner(void) const
Returns a pointer to the positioner (if any) this device has used to move the satellite dish to the r...
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
static cDevice * PrimaryDevice(void)
Returns the primary device.
eTrackType GetCurrentSubtitleTrack(void) const
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
eTrackType GetCurrentAudioTrack(void) const
bool SwitchChannel(const cChannel *Channel, bool LiveView)
Switches the device to the given Channel, initiating transfer mode if necessary.
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
void StopReplay(void)
Stops the current replay session (if any).
int GetAudioChannel(void)
Gets the current audio channel, which is stereo (0), mono left (1) or mono right (2).
void EnsureAudioTrack(bool Force=false)
Makes sure an audio track is selected that is actually available.
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
static void SetCurrentChannel(int ChannelNumber)
Sets the number of the current channel on the primary device, without actually switching to it.
void SetAudioChannel(int AudioChannel)
Sets the audio channel to stereo (0), mono left (1) or mono right (2).
static int NumDevices(void)
Returns the total number of devices.
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder).
virtual void SetVideoFormat(bool VideoFormat16_9)
Sets the output video format to either 16:9 or 4:3 (only useful if this device has an MPEG decoder).
void ClrAvailableTracks(bool DescriptionsOnly=false, bool IdsOnly=false)
Clears the list of currently available tracks.
void EnsureSubtitleTrack(void)
Makes sure one of the preferred language subtitle tracks is selected.
static int CurrentVolume(void)
bool SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language=NULL, const char *Description=NULL)
Sets the track of the given Type and Index to the given values.
bool SetCurrentAudioTrack(eTrackType Type)
Sets the current audio track to the given Type.
const cEvent * lastPresent
void DisplayChannel(void)
virtual ~cDisplayChannel()
const cEvent * lastFollowing
cSkinDisplayChannel * displayChannel
const cPositioner * positioner
static cDisplayChannel * currentDisplayChannel
virtual eOSState ProcessKey(eKeys Key)
cDisplayChannel(int Number, bool Switched)
const cChannel * NextAvailableChannel(const cChannel *Channel, int Direction)
cSkinDisplayTracks * displayTracks
cDisplaySubtitleTracks(void)
static void Process(eKeys Key)
char * descriptions[ttMaxTrackTypes+1]
eTrackType types[ttMaxTrackTypes]
static cDisplaySubtitleTracks * currentDisplayTracks
virtual ~cDisplaySubtitleTracks()
static cDisplaySubtitleTracks * Create(void)
eOSState ProcessKey(eKeys Key)
char * descriptions[ttMaxTrackTypes+1]
static cDisplayTracks * Create(void)
virtual ~cDisplayTracks()
eOSState ProcessKey(eKeys Key)
static cDisplayTracks * currentDisplayTracks
cSkinDisplayTracks * displayTracks
static void Process(eKeys Key)
eTrackType types[ttMaxTrackTypes]
static cDisplayVolume * Create(void)
cSkinDisplayVolume * displayVolume
virtual ~cDisplayVolume()
eOSState ProcessKey(eKeys Key)
static void Process(eKeys Key)
static cDisplayVolume * currentDisplayVolume
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
void SetMarks(const cMarks *Marks)
bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
const cErrors * GetErrors(void)
void SkipSeconds(int Seconds)
cDvbPlayerControl(const char *FileName, bool PauseLive=false)
bool GetReplayMode(bool &Play, bool &Forward, int &Speed)
int SkipFrames(int Frames)
void Goto(int Index, bool Still=false)
bool GetFrameNumber(int &Current, int &Total)
static void SetupChanged(void)
const char * ShortText(void) const
const cComponents * Components(void) const
time_t StartTime(void) const
tChannelID ChannelID(void) const
const char * Title(void) const
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced=false)
Queries the font configuration for a list of available font names, which is returned in FontNames.
bool Contains(const cListObject *Object) const
If a pointer to an object contained in this list has been obtained while holding a lock,...
virtual void Move(int From, int To)
void SetExplicitModify(void)
If you have obtained a write lock on this list, and you don't want it to be automatically marked as m...
void SetModified(void)
Unconditionally marks this list as modified.
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
void Add(cListObject *Object, cListObject *After=NULL)
cListObject(const cListObject &ListObject)
cListObject * Prev(void) const
cListObject * Next(void) const
const cOsdItem * First(void) const
cList(const char *NeedsLocking=NULL)
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
const cOsdItem * Get(int Index) const
void SetPosition(int Position)
static bool DeleteMarksFile(const cRecording *Recording)
cList< cNestedItem > * commands
cMenuCommands(const char *Title, cList< cNestedItem > *Commands, const char *Parameters=NULL)
virtual eOSState ProcessKey(eKeys Key)
bool Parse(const char *s)
cOsdItem * cancelEditingItem
cOsdItem * stopRecordingItem
cOsdItem * stopReplayItem
bool Update(bool Force=false)
virtual eOSState ProcessKey(eKeys Key)
cMenuMain(eOSState State=osUnknown, bool OpenSubMenus=false)
static cOsdObject * pluginOsdObject
static cOsdObject * PluginOsdObject(void)
void SetSubItems(bool On)
cList< cNestedItem > * SubItems(void)
const char * Text(void) const
const char * Text(void) const
void SetSelectable(bool Selectable)
virtual eOSState ProcessKey(eKeys Key)
bool Selectable(void) const
void SetText(const char *Text, bool Copy=true)
cOsdItem(eOSState State=osUnknown)
void SetNeedsFastResponse(bool NeedsFastResponse)
cOsdObject(bool FastResponse=false)
static bool OsdSizeChanged(int &State)
Checks if the OSD size has changed and a currently displayed OSD needs to be redrawn.
static void UpdateOsdSize(bool Force=false)
Inquires the actual size of the video display and adjusts the OSD and font sizes accordingly.
static int IsOpen(void)
Returns true if there is currently a level 0 OSD open.
bool Open(const char *Command, const char *Mode)
static bool HasPlugins(void)
static cPlugin * GetPlugin(int Index)
virtual cMenuSetupPage * SetupMenu(void)
virtual const char * Version(void)=0
virtual const char * MainMenuEntry(void)
virtual cOsdObject * MainMenuAction(void)
virtual const char * Description(void)=0
A steerable satellite dish generally points to the south on the northern hemisphere,...
virtual bool IsMoving(void) const
Returns true if the dish is currently moving as a result of a call to GotoPosition() or GotoAngle().
virtual ~cRecordControl()
const char * InstantId(void)
void Stop(bool ExecuteUserCommand=true)
cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer=NULL, bool Pause=false)
static bool StateChanged(int &State)
static const char * GetInstantId(const char *LastInstantId)
static void ChannelDataModified(const cChannel *Channel)
static bool Process(cTimers *Timers, time_t t)
static bool PauseLiveVideo(void)
static void Shutdown(void)
static bool Start(cTimers *Timers, cTimer *Timer, bool Pause=false)
static cRecordControl * RecordControls[]
static void Stop(const char *InstantId)
static cRecordControl * GetRecordControl(const char *FileName)
static void ChangeState(void)
static void InvokeCommand(const char *State, const char *RecordingFileName, const char *SourceFileName=NULL)
bool ChangePriorityLifetime(int NewPriority, int NewLifetime)
Changes the priority and lifetime of this recording to the given values.
bool WriteInfo(const char *OtherFileName=NULL)
Writes in info file of this recording.
bool ChangeName(const char *NewName)
Changes the name of this recording to the given value.
bool Delete(void)
Changes the file name so that it will no longer be visible in the "Recordings" menu Returns false in ...
cString Folder(void) const
Returns the name of the folder this recording is stored in (without the video directory).
const char * Name(void) const
Returns the full name of the recording (without the video directory).
const char * FileName(void) const
Returns the full path name to the recording directory, including the video directory and the actual '...
double FramesPerSecond(void) const
bool IsPesRecording(void) const
static const cRecordings * GetRecordingsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of recordings for read access.
static cRecordings * GetRecordingsWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of recordings for write access.
static void TouchUpdate(void)
Touches the '.update' file in the video directory, so that other instances of VDR that access the sam...
void DelByName(const char *FileName)
const cRecording * GetByName(const char *FileName) const
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
static void TriggerLastActivity(void)
Simulates user activity, for instance to keep the current menu open even if no remote control key has...
static void SetRecording(const char *FileName)
static const char * LastReplayed(void)
void TimeSearchDisplay(void)
static void ClearLastReplayed(const char *FileName)
void MarkMove(int Frames, bool MarkRequired)
static cReplayControl * currentReplayControl
virtual eOSState ProcessKey(eKeys Key)
void TimeSearchProcess(eKeys Key)
void MarkJump(bool Forward)
cSkinDisplayReplay * displayReplay
void ShowTimed(int Seconds=0)
virtual const cRecording * GetRecording(void)
Returns the cRecording that is currently being replayed, or NULL if this player is not playing a cRec...
virtual void ClearEditingMarks(void)
Clears any editing marks this player might be showing.
bool ShowProgress(bool Initial)
cAdaptiveSkipper adaptiveSkipper
virtual cOsdObject * GetInfo(void)
Returns an OSD object that displays information about the currently played programme.
virtual ~cReplayControl()
void ErrorJump(bool Forward)
static const char * NowReplaying(void)
cReplayControl(bool PauseLive=false)
const cSchedule * GetSchedule(tChannelID ChannelID) const
static const cSchedules * GetSchedulesRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of schedules for read access.
static void ResetVersions(void)
static cString ToString(int Code)
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
static void MsgMarksModified(const cMarks *Marks)
static void MsgOsdChannel(const char *Text)
static void MsgSetAudioChannel(int AudioChannel)
static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle)
static void MsgReplaying(const cControl *Control, const char *Name, const char *FileName, bool On)
static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On)
static void MsgOsdClear(void)
static void MsgSetAudioTrack(int Index, const char *const *Tracks)
static void MsgOsdTextItem(const char *Text, bool Scroll=false)
static void MsgSetSubtitleTrack(int Index, const char *const *Tracks)
void Sort(bool IgnoreCase=false)
int Find(const char *s) const
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
static cString sprintf(const char *fmt,...) __attribute__((format(printf
cString PrintFirstDay(void) const
void SetPending(bool Pending)
time_t FirstDay(void) const
bool Recording(void) const
void SetRemote(const char *Remote)
const cEvent * Event(void) const
const cChannel * Channel(void) const
cString ToDescr(void) const
bool SetEventFromSchedule(const cSchedules *Schedules)
bool HasFlags(uint Flags) const
const char * Remote(void) const
bool Matches(time_t t=0, bool Directly=false, int Margin=0) const
cString ToText(bool UseChannelID=false) const
void Add(cTimer *Timer, cTimer *After=NULL)
static cTimers * GetTimersWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for write access.
void Del(cTimer *Timer, bool DeleteObject=true)
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
const cTimer * GetMatch(time_t t) const
void Sort(__compar_fn_t Compare)
virtual void Append(T Data)
static const char * Name(void)
static int VideoDiskSpace(int *FreeMB=NULL, int *UsedMB=NULL)
static void ForceCheck(void)
To avoid unnecessary load, the video disk usage is only actually checked every DISKSPACECHEK seconds.
cNestedItemList RecordingCommands
#define TIMERMACRO_BEFORE
#define TIMERMACRO_EPISODE
#define IS_AUDIO_TRACK(t)
#define IS_DOLBY_TRACK(t)
#define LOCK_SCHEDULES_READ
#define MAXEPGBUGFIXLEVEL
const char * DefaultFontOsd
const char * DefaultFontSml
const char * DefaultFontFix
const char * I18nLocale(int Language)
Returns the locale code of the given Language (which is an index as returned by I18nCurrentLanguage()...
const cStringList * I18nLanguages(void)
Returns the list of available languages.
int I18nNumLanguagesWithLocale(void)
Returns the number of entries in the list returned by I18nLanguages() that actually have a locale.
int I18nCurrentLanguage(void)
Returns the index of the current language.
void I18nSetLocale(const char *Locale)
Sets the current locale to Locale.
void I18nSetLanguage(int Language)
Sets the current language index to Language.
cString GetRecordingTimerId(const char *Directory)
cString IndexToHMSF(int Index, bool WithFrame, double FramesPerSecond)
void AssertFreeDiskSpace(int Priority, bool Force)
The special Priority value -1 means that we shall get rid of any deleted recordings faster than norma...
void GetRecordingsSortMode(const char *Directory)
int SecondsToFrames(int Seconds, double FramesPerSecond)
eRecordingsSortMode RecordingsSortMode
bool EnoughFreeDiskSpaceForEdit(const char *FileName)
char * ExchangeChars(char *s, bool ToFileSystem)
void IncRecordingsSortMode(const char *Directory)
cDoneRecordings DoneRecordingsPattern
cRecordingsHandler RecordingsHandler
void SetRecordingTimerId(const char *Directory, const char *TimerId)
#define RUC_BEFORERECORDING
#define RUC_AFTERRECORDING
#define LOCK_RECORDINGS_READ
#define MAXVIDEOFILESIZETS
#define LOCK_RECORDINGS_WRITE
cShutdownHandler ShutdownHandler
static const cCursesFont Font
cSourceParams SourceParams
char language[MAXLANGCODE2]
char language[MAXLANGCODE2]
void StopSVDRPHandler(void)
bool GetSVDRPServerNames(cStringList *ServerNames)
Gets a list of all available VDRs this VDR is connected to via SVDRP, and stores it in the given Serv...
bool ExecSVDRPCommand(const char *ServerName, const char *Command, cStringList *Response)
Sends the given SVDRP Command string to the remote VDR identified by ServerName and collects all of t...
void StartSVDRPHandler(void)
int SVDRPCode(const char *s)
Returns the value of the three digit reply code of the given SVDRP response string.
cStateKey StateKeySVDRPRemoteTimersPoll
Controls whether a change to the local list of timers needs to result in sending a POLL to the remote...
bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer, cString *Msg)
Performs any operations necessary to synchronize changes to a timer between peer VDR machines.
#define LOCK_TIMERS_WRITE