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);
351#define CHANNELNUMBERTIMEOUT 1000
358 void Set(
bool Force =
false);
367 virtual void Move(
int From,
int To);
396 for (
const cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel)) {
400 if (Channel == CurrentChannel)
410 SetHelp(
tr(
"Button$Edit"),
tr(
"Button$New"),
tr(
"Button$Delete"),
tr(
"Button$Mark"));
445 if (!ci->Channel()->GroupSep() && ci->Channel()->Number() ==
number) {
498 bool Deleted =
false;
501 int DeletedChannel = Channel->
Number();
503 if (Timers->UsesChannel(Channel)) {
509 if (CurrentChannel && Channel == CurrentChannel) {
513 CurrentChannel = Channels->
Get(n);
514 CurrentChannelNr = 0;
516 Channels->
Del(Channel);
519 isyslog(
"channel %d deleted", DeletedChannel);
521 if (CurrentChannel && CurrentChannel->
Number() != CurrentChannelNr) {
537 cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
540 if (FromChannel && ToChannel) {
541 int FromNumber = FromChannel->
Number();
542 int ToNumber = ToChannel->
Number();
543 if (Channels->MoveNeedsDecrement(FromChannel, ToChannel)) {
544 ToChannel = Channels->
Prev(ToChannel);
547 Channels->Move(FromChannel, ToChannel);
551 isyslog(
"channel %d moved to %d", FromNumber, ToNumber);
552 if (CurrentChannel && CurrentChannel->
Number() != CurrentChannelNr) {
554 Channels->SwitchTo(CurrentChannel->
Number());
572 if (
cChannel *Channel = MenuEditChannel->Channel()) {
599 if (!ci->Channel()->GroupSep() && ci->Channel()->Number() == CurrentChannelNr) {
632 text = Text ? strdup(Text) : NULL;
677 virtual void Set(
void);
712:
cOsdMenu(Folder ?
tr(
"Edit folder") :
tr(
"New folder"), 12)
741 if (strcmp(Folder->Text(),
name) == 0) {
746 char *p = strpbrk(
name,
"\\{}#~");
821#define FOLDERDELIMCHARSUBST 0x01
829 for (Folder =
List->First(); Folder; Folder =
List->Next(Folder)) {
830 if (strcmp(Path, Folder->
Text()) == 0)
842 for (
const cRecording *Recording = Recordings->
First(); Recording; Recording = Recordings->
Next(Recording)) {
843 cString Folder = Recording->Folder();
845 if (Dirs.
Find(Folder) < 0)
846 Dirs.
Append(strdup(Folder));
849 for (
int i = 0; i < Dirs.
Size(); i++) {
850 if (
char *s = Dirs[i])
862 RecordingsStateKey.
Remove();
875 Add(FolderItem, CurrentFolder ? strcmp(Folder->Text(), CurrentFolder) == 0 :
false);
887 if (strncmp(Folder->Folder()->Text(), Path, p - Path) == 0) {
924 if (Folder &&
Interface->Confirm(Folder->
Folder()->
SubItems() ?
tr(
"Delete folder and all sub folders?") :
tr(
"Delete folder?"))) {
951 Set(mef->GetFolder());
1069 SetHelp(
tr(
"Button$Folder"),
data.weekdays ?
tr(
"Button$Single") :
tr(
"Button$Repeating"), *
data.pattern ?
tr(
"Button$Regular") :
tr(
"Button$Pattern"));
1087 if (Initial && !*
data.pattern) {
1096 if (!*
data.pattern) {
1118 cString Folder = mf->GetFolder();
1122 else if (p !=
data.file)
1123 memmove(
data.file, p, strlen(p) + 1);
1164 data.channel = Channel;
1170 strcpy(
data.file,
data.Channel()->ShortName(
true));
1178 Timers->Del(
timer,
false);
1190 if (
data.Local() && !
timer->IsPatternTimer() &&
data.IsPatternTimer())
1191 data.SetEvent(NULL);
1194 timer->TriggerRespawn();
1196 timer->SetEventFromSchedule(Schedules);
1203 day->ToggleRepeating();
1231 virtual void Set(
void);
1250 if (
timer->WeekDays())
1251 day =
timer->PrintDay(0,
timer->WeekDays(),
false);
1258 time_t Day =
timer->Day();
1259 localtime_r(&Day, &tm_r);
1261 strftime(buffer,
sizeof(buffer),
"%Y%m%d", &tm_r);
1264 const char *File =
timer->Pattern();
1267 File =
timer->Event()->Title();
1273 File =
timer->File();
1278 timer->Channel()->Number(),
1280 *name && **name ?
" " :
"",
1282 timer->Start() / 100,
1283 timer->Start() % 100,
1284 timer->Stop() / 100,
1285 timer->Stop() % 100,
1287 timer->IsPatternTimer() ?
"{" :
"",
1289 timer->IsPatternTimer() ?
"}" :
""));
1337 for (
const cTimer *Timer = Timers->First(); Timer; Timer = Timers->
Next(Timer)) {
1340 if (CurrentTimer && Timer->
Id() == CurrentTimer->
Id() && (!Timer->Remote() && !CurrentTimer->
Remote() || Timer->Remote() && CurrentTimer->
Remote() && strcmp(Timer->Remote(), CurrentTimer->
Remote()) == 0))
1359 int NewHelpKeys = 0;
1398 StateKey.
Remove(Timer != NULL);
1414 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1425 bool TimerRecording = Timer->
Recording();
1427 if (
Interface->Confirm(
tr(
"Delete timer?")) && (!TimerRecording ||
Interface->Confirm(
tr(
"Timer still recording - really delete?")))) {
1458 if (Timer && Timer->
Event())
1484 Add(CurrentItem,
true);
1508 SetHelp(TimerMatch ==
tmFull ?
tr(
"Button$Timer") :
tr(
"Button$Record"), NULL, NULL, CanSwitch ?
tr(
"Button$Switch") : NULL);
1518 if (
event->Description())
1605 if (
event->EndTime() < time(NULL) && !
event->IsRunning() && (!Timer || !Timer->
Recording()))
1611 char v =
event->Vps() && (
event->Vps() -
event->StartTime()) ?
'V' :
' ';
1612 char r =
event->SeenWithin(30) &&
event->IsRunning() ?
'*' :
' ';
1614 cString eds =
event->GetDateString();
1616 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());
1665 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1666 if (!Channel->GroupSep()) {
1668 if (
const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent())
1680 bool result =
false;
1695 int NewHelpKeys = 0;
1698 NewHelpKeys |= 0x02;
1700 NewHelpKeys |= 0x01;
1702 NewHelpKeys |= 0x04;
1704 NewHelpKeys |= 0x08;
1707 NewHelpKeys |= 0x10;
1713 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
1714 SetHelp(Red[NewHelpKeys & 0x03],
now ?
tr(
"Button$Next") :
tr(
"Button$Now"),
tr(
"Button$Schedule"),
canSwitch ?
tr(
"Button$Switch") : NULL);
1749 Timers->SetExplicitModify();
1750 if (item->timerMatch ==
tmFull) {
1751 if (
cTimer *Timer = Timers->GetMatch(item->event))
1755 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1757 if (
cTimer *t = Timers->GetTimer(Timer)) {
1765 Timers->SetModified();
1770 else if (Timer->
Remote())
1835 if (HadSubMenu &&
Update()) {
1885 Set(Timers, Channels, NULL,
true);
1901 const cEvent *Event = NULL;
1904 Event = CurrentItem->
event;
1910 bool Refresh =
false;
1936 const cEvent *PresentEvent = Event ? Event : Schedule->GetPresentEvent();
1937 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1938 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1939 if (ev->EndTime() >
now || ev == PresentEvent)
1956 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1957 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1958 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
1975 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
1977 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1978 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1979 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
1995 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
1997 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1998 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1999 if (ev->EndTime() >
now || ev == Event)
2009 bool result =
false;
2024 int NewHelpKeys = 0;
2027 NewHelpKeys |= 0x02;
2029 NewHelpKeys |= 0x01;
2033 NewHelpKeys |= 0x10;
2039 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
2040 SetHelp(Red[NewHelpKeys & 0x03],
tr(
"Button$Now"),
tr(
"Button$Next"),
canSwitch ?
tr(
"Button$Switch") : NULL);
2050 Set(Timers, Channels, NULL,
true);
2060 Timers->SetExplicitModify();
2061 if (item->timerMatch ==
tmFull) {
2062 if (
cTimer *Timer = Timers->GetMatch(item->event))
2066 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
2068 if (
cTimer *t = Timers->GetTimer(Timer)) {
2076 Timers->SetModified();
2081 else if (Timer->
Remote())
2100 if ((Channel = Channels->GetByChannelID(item->
event->
ChannelID(),
true)) != NULL) {
2101 if (!Channels->SwitchTo(Channel->
Number()))
2116 Set(Timers, Channels);
2134 ChannelNr = Channel->Number();
2159 Set(Timers, Channels, Channel,
true);
2178 if (
const cChannel *Channel = Channels->GetByChannelID(ei->ChannelID(),
true)) {
2180 Set(Timers, Channels, Channel,
true);
2183 else if (HadSubMenu &&
Update()) {
2204 const char *s = Command->Text();
2205 if (Command->SubItems())
2219 const char *p = strchr(s,
':');
2226 if (l > 1 && t[l - 1] ==
'?') {
2254 const char *cmd = *cmdbuf ? *cmdbuf : *
command;
2255 dsyslog(
"executing command '%s'", cmd);
2257 if (p.
Open(cmd,
"r")) {
2260 while ((c = fgetc(p)) != EOF) {
2262 if (
char *NewBuffer = (
char *)realloc(
result, l + 21))
2265 esyslog(
"ERROR: out of memory");
2276 esyslog(
"ERROR: can't open pipe for command '%s'", cmd);
2378 dsyslog(
"CAM %d: Menu ------------------",
camSlot->SlotNumber());
2388 for (
int i = 0; i <
ciMenu->NumEntries(); i++) {
2400 int Length =
ciEnquiry->ExpectedLength();
2404 dsyslog(
"CAM %d: Enquiry ------------------",
camSlot->SlotNumber());
2417 const char *p = strchr(s,
'\n');
2418 int l = p ? p - s : strlen(s);
2421 item->
SetText(strndup(s, l),
false);
2430 if (
ciMenu->Selectable()) {
2440 snprintf(buffer,
sizeof(buffer),
tr(
"Please enter %d digits!"),
ciEnquiry->ExpectedLength());
2466 else if (state ==
osBack) {
2493 if (CamSlot->HasUserIO())
2506#define osUserRecRenamed osUser1
2507#define osUserRecMoved osUser2
2508#define osUserRecRemoved osUser3
2509#define osUserRecEmpty osUser4
2556 for (
const cRecording *Recording = Recordings->First(); Recording; Recording = Recordings->
Next(Recording)) {
2557 if (Recording->IsInPath(
path)) {
2558 int FileSizeMB = Recording->FileSizeMB();
2559 if (FileSizeMB > 0 )
2560 DirSize += FileSizeMB;
2601 if (strcmp(NewPath,
path)) {
2602 int NumRecordings = 0;
2605 NumRecordings = Recordings->GetNumRecordingsInPath(
path);
2607 if (NumRecordings > 1 && !
Interface->Confirm(
cString::sprintf(
tr(
"Move entire folder containing %d recordings?"), NumRecordings)))
2612 Recordings->SetExplicitModify();
2613 Error = !Recordings->MoveRecordings(
path, NewPath);
2615 Recordings->SetModified();
2639 else if (Key ==
kOk)
2721 Add(
new cOsdItem(
tr(
"This recording is currently in use - no changes are possible!"),
osUnknown,
false));
2791 Skins.Message(
mtError,
tr(
"Not enough free disk space to start editing process!"));
2793 Skins.Message(
mtError,
tr(
"Error while queueing recording for cutting!"));
2801 if (strcmp(NewName,
recording->Name())) {
2805 if (access(*FileName, F_OK) != 0 ||
Interface->Confirm(
tr(
"Edited version already exists - overwrite?"))) {
2807 Skins.Message(
mtError,
tr(
"Error while queueing recording for copying!"));
2810 Recordings->AddByName(FileName);
2824 if (
Interface->Confirm(
tr(
"Rename recording to folder name?"))) {
2854 if (
const cRecording *Recording = Control->GetRecording()) {
2855 if (strcmp(
recording->FileName(), Recording->FileName()) == 0)
2856 Control->ClearEditingMarks();
2861 Skins.Message(
mtError,
tr(
"Error while deleting editing marks!"));
2877 bool Modified =
false;
2880 StateKey.
Remove(Modified);
2881 Skins.Message(
mtError,
tr(
"Error while changing priority/lifetime!"));
2893 if (strcmp(NewName, Recording->
Name())) {
2895 StateKey.
Remove(Modified);
2903 if (strcmp(Recording->
Folder(), OldFolder))
2906 StateKey.
Remove(Modified);
2909 StateKey.
Remove(Modified);
2961 SetHelp(
tr(
"Button$Play"),
tr(
"Button$Rewind"), NULL,
tr(
"Button$Edit"));
3060 if (*
Text() ==
'\t')
3094:
cOsdMenu(Base ? Base :
tr(
"Recordings"), 9, 6, 6)
3097 base = Base ? strdup(Base) : NULL;
3117 if (!ri->IsDirectory())
3126 int NewHelpKeys = 0;
3134 switch (NewHelpKeys) {
3136 case 1:
SetHelp(
tr(
"Button$Open"), NULL, NULL,
tr(
"Button$Edit"));
break;
3149 const char *CurrentRecording = NULL;
3151 CurrentRecording = ri->Recording()->FileName();
3152 if (!CurrentRecording)
3160 for (
const cRecording *Recording = Recordings->
First(); Recording; Recording = Recordings->
Next(Recording)) {
3167 if (p->Name() && strcmp(p->Name(), Item->
Name()) == 0) {
3173 if (*Item->
Text() && !LastDir) {
3181 if (LastItem || LastDir) {
3183 if (strcmp(
path, Recording->Folder()) == 0)
3184 CurrentItem = LastDir ? LastDir : LastItem;
3186 else if (CurrentRecording && strcmp(CurrentRecording, Recording->FileName()) == 0)
3187 CurrentItem = LastDir ? LastDir : LastItem;
3223 const char *t = ri->
Name();
3267 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3269 if (
cTimer *Timer = rc->Timer()) {
3272 if (Timer->IsSingleEvent()) {
3274 isyslog(
"deleted timer %s", *Timer->ToDescr());
3286 char *RemoteBuf = NULL;
3288 if (2 == sscanf(TimerId,
"%d@%m[^ \n]", &Id, &RemoteBuf) && Id != 0) {
3291 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3293 if (
cTimer *Timer = Timers->GetById(Id, Remote)) {
3294 cTimer OldTimer = *Timer;
3297 if (Timer->IsSingleEvent()) {
3321 if (
Interface->Confirm(
tr(
"Delete recording?"))) {
3328 FileName = Recording->FileName();
3330 if (!
Interface->Confirm(
tr(
"Recording is being edited - really delete?")))
3344 if (!Recording || Recording->
Delete()) {
3370 if (ri->IsDirectory())
3448 ri->SetRecording(riSub->Recording());
3476 virtual void Store(
void);
3511 virtual void Set(
void);
3602 bool ModifiedAppearance =
false;
3611 ModifiedAppearance =
true;
3614 if (
themes.NumThemes() &&
Skins.Current()->Theme()) {
3620 ModifiedAppearance =
true;
3622 ModifiedAppearance =
true;
3627 ModifiedAppearance =
true;
3629 ModifiedAppearance =
true;
3631 ModifiedAppearance =
true;
3632 if (
data.AlwaysSortFoldersFirst !=
Setup.AlwaysSortFoldersFirst ||
data.RecordingDirs !=
Setup.RecordingDirs ||
data.RecSortingDirection !=
Setup.RecSortingDirection) {
3634 Recordings->ClearSortNames();
3642 if (ModifiedAppearance)
3700 if (
data.SetSystemTime)
3718 if (
data.EPGLanguages[i] !=
::Setup.EPGLanguages[i]) {
3729 int oldSetSystemTime =
data.SetSystemTime;
3733 if (
numLanguages != oldnumLanguages ||
data.SetSystemTime != oldSetSystemTime) {
3735 data.EPGLanguages[i] = 0;
3738 for (k = 0; k < oldnumLanguages; k++) {
3739 if (
data.EPGLanguages[k] == l)
3742 if (k >= oldnumLanguages) {
3743 data.EPGLanguages[i] = l;
3799 SetHelp(NULL,
tr(
"Button$Audio"),
tr(
"Button$Subtitles"), NULL);
3812 if (
data.VideoFormat == 0)
3820 if (
data.DisplaySubtitles) {
3835 int oldVideoDisplayFormat =
::Setup.VideoDisplayFormat;
3836 bool oldVideoFormat =
::Setup.VideoFormat;
3837 bool newVideoFormat =
data.VideoFormat;
3838 bool oldDisplaySubtitles =
::Setup.DisplaySubtitles;
3839 bool newDisplaySubtitles =
data.DisplaySubtitles;
3853 bool DoSetup =
data.VideoFormat != newVideoFormat;
3854 DoSetup |=
data.DisplaySubtitles != newDisplaySubtitles;
3857 data.AudioLanguages[i] = 0;
3860 for (k = 0; k < oldnumAudioLanguages; k++) {
3861 if (
data.AudioLanguages[k] == l)
3864 if (k >= oldnumAudioLanguages) {
3865 data.AudioLanguages[i] = l;
3875 data.SubtitleLanguages[i] = 0;
3878 for (k = 0; k < oldnumSubtitleLanguages; k++) {
3879 if (
data.SubtitleLanguages[k] == l)
3882 if (k >= oldnumSubtitleLanguages) {
3883 data.SubtitleLanguages[i] = l;
3897 if (
::Setup.VideoDisplayFormat != oldVideoDisplayFormat)
3899 if (
::Setup.VideoFormat != oldVideoFormat)
3901 if (
::Setup.DisplaySubtitles != oldDisplaySubtitles)
3941 int NumSatDevices = 0;
3946 if (NumSatDevices > 1) {
3956 if (
data.UsePositioner) {
3969 int oldDiSEqC =
data.DiSEqC;
3970 int oldUsePositioner =
data.UsePositioner;
3971 bool DeviceBondingsChanged =
false;
3974 DeviceBondingsChanged = strcmp(
data.DeviceBondings, NewDeviceBondings) != 0;
3975 data.DeviceBondings = NewDeviceBondings;
3979 if (Key !=
kNone && (
data.DiSEqC != oldDiSEqC ||
data.UsePositioner != oldUsePositioner))
3981 else if (DeviceBondingsChanged)
4007 const char *Activating =
"";
4008 const char *CamName =
camSlot->GetCamName();
4010 switch (
camSlot->ModuleStatus()) {
4011 case msReset: CamName =
tr(
"CAM reset");
break;
4012 case msPresent: CamName =
tr(
"CAM present");
break;
4013 case msReady: CamName =
tr(
"CAM ready");
break;
4014 default: CamName =
"-";
break;
4017 else if (
camSlot->IsActivating())
4019 Activating =
tr(
" (activating)");
4023 CamSlot->Devices(DeviceNumbers);
4025 if (DeviceNumbers.
Size() > 0) {
4028 for (
int i = 0; i < DeviceNumbers.
Size(); i++)
4029 AssignedDevice =
cString::sprintf(
"%s %d", *AssignedDevice, DeviceNumbers[i]);
4033 if (strcmp(buffer,
Text()) != 0) {
4062 if (CamSlot->IsMasterSlot())
4073 const char *NewActivationHelp =
"";
4077 NewActivationHelp =
tr(
"Button$Cancel activation");
4079 NewActivationHelp =
tr(
"Button$Activate");
4093 time_t t0 = time(NULL);
4127 if (Device->ProvidesChannel(Channel)) {
4129 if (CamSlot->
Assign(Device,
true)) {
4132 if (CamSlot->
Assign(Device)) {
4133 if (Device->SwitchChannel(Channel,
true)) {
4233 virtual void Store(
void);
4250 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Initial duration for adaptive skipping (s)"), &
data.AdaptiveSkipInitial, 10, 600));
4251 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Reset timeout for adaptive skipping (s)"), &
data.AdaptiveSkipTimeout, 0, 10));
4255 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Skip distance with Green/Yellow keys in repeat (s)"), &
data.SkipSecondsRepeat, 5, 600));
4263 Recordings->ResetResume();
4302 if (
data.SVDRPPeering) {
4315 Add(
new cMenuEditIntItem(
tr(
"Setup.Miscellaneous$Initial volume"), &
data.InitialVolume, -1, 255,
tr(
"Setup.Miscellaneous$as before")));
4327 bool OldSVDRPPeering =
data.SVDRPPeering;
4328 bool ModifiedSVDRPSettings =
false;
4329 bool ModifiedShowChannelNamesWithSource =
false;
4331 ModifiedSVDRPSettings =
data.SVDRPPeering !=
Setup.SVDRPPeering || strcmp(
data.SVDRPHostName,
Setup.SVDRPHostName);
4332 ModifiedShowChannelNamesWithSource =
data.ShowChannelNamesWithSource !=
Setup.ShowChannelNamesWithSource;
4335 if (ModifiedShowChannelNamesWithSource) {
4337 for (
cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel))
4338 Channel->UpdateNameSource();
4340 if (
data.SVDRPPeering != OldSVDRPPeering)
4342 if (ModifiedSVDRPSettings) {
4346 Timers->SetExplicitModify();
4347 if (Timers->StoreRemoteTimers(NULL, NULL))
4348 Timers->SetModified();
4384 for (
int i = 0; ; i++) {
4408 Skins.Message(
mtInfo,
tr(
"This plugin has no setup parameters!"));
4426 virtual void Set(
void);
4444 snprintf(buffer,
sizeof(buffer),
"%s - VDR %s",
tr(
"Setup"),
VDRVERSION);
4514#define STOP_RECORDING trNOOP(" Stop recording ")
4564 for (
int i = 0; ; i++) {
4588 bool result =
false;
4590 bool NewReplaying =
false;
4595 if (Force || NewReplaying !=
replaying) {
4630 const char *s = NULL;
4689 default:
switch (Key) {
4691 case kRed:
if (!HadSubMenu)
4694 case kGreen:
if (!HadSubMenu) {
4699 case kYellow:
if (!HadSubMenu)
4702 case kBlue:
if (!HadSubMenu)
4728 if (
const cChannel *Channel = Channels->GetByNumber(LiveChannel)) {
4730 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
4731 const cEvent *Present = Schedule->GetPresentEvent();
4740 Components = Recording->Info()->Components();
4745 int indexSubtitle = 0;
4749 case 2:
if (p->
type == 0x05)
4782 channel = Channels->GetByNumber(Number);
4835 const cEvent *Present = Schedule->GetPresentEvent();
4836 const cEvent *Following = Schedule->GetFollowingEvent();
4862 Channel = Direction > 0 ? Channels->
Next(Channel) : Channels->
Prev(Channel);
4863 if (!Channel &&
Setup.ChannelsWrap)
4864 Channel = Direction > 0 ? Channels->First() : Channels->Last();
4903 while (ch && (ch = Channels->
Next(ch)) != NULL) {
4905 if (n <= ch->Number() && ch->
Number() < n + m) {
4937 group = Channel->Index();
4940 int SaveGroup =
group;
5002 channel = Channels->Get(Channels->GetNextNormal(
group));
5040 Channels->SwitchTo(NewChannel->
Number());
5045 bool PositionerMoving = Positioner && Positioner->
IsMoving();
5047 if (!PositionerMoving) {
5064#define VOLUMETIMEOUT 1000
5065#define MUTETIMEOUT 5000
5131#define TRACKTIMEOUT 5000
5146 if (TrackId && TrackId->
id) {
5149 if (i == CurrentAudioTrack)
5198 int oldTrack =
track;
5215 static int ac[] = { 1, 0, 2 };
5242 if (
track != oldTrack) {
5267 if (TrackId && TrackId->
id) {
5270 if (i == CurrentSubtitleTrack)
5316 int oldTrack =
track;
5343 if (
track != oldTrack) {
5377 ChannelsStateKey.
Remove();
5379 timer->SetPending(
true);
5380 timer->SetRecording(
true);
5381 event =
timer->Event();
5392 timer->SetPending(
false);
5393 timer->SetRecording(
false);
5402 SchedulesStateKey.
Remove();
5414 if (!
Timer && !LastReplayed)
5416 SchedulesStateKey.
Remove();
5431 SchedulesStateKey.
Remove();
5440#define INSTANT_REC_EPG_LOOKAHEAD 300
5449 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
5450 event = Schedule->GetEventAround(Time);
5453 dsyslog(
"got EPG info after %d seconds", seconds);
5459 dsyslog(
"waiting for EPG info...");
5462 dsyslog(
"no EPG info available");
5472 isyslog(
"timer %s %s with %d error%s", *
timer->ToDescr(), Finished ?
"finished" :
"stopped", Errors, Errors != 1 ?
"s" :
"");
5473 if (
timer->HasFlags(
tfAvoid) && Errors == 0 && Finished) {
5479 timer->SetRecording(
false);
5483 if (ExecuteUserCommand && Finished)
5492 timer->SetPending(
false);
5505 static time_t LastNoDiskSpaceMessage = 0;
5514 isyslog(
"not enough disk space to start recording%s%s", Timer ?
" timer " :
"", Timer ? *Timer->
ToDescr() :
"");
5516 LastNoDiskSpaceMessage = time(NULL);
5520 LastNoDiskSpaceMessage = 0;
5527 int Priority = Timer ? Timer->
Priority() : Pause ?
Setup.PausePriority :
Setup.DefaultPriority;
5530 dsyslog(
"switching device %d to channel %d %s (%s)", device->
DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
5538 if (!Timer || Timer->
Matches()) {
5547 else if (!Timer || !Timer->
Pending()) {
5548 isyslog(
"no free DVB device to record channel %d (%s)!", ch, Channel->Name());
5553 esyslog(
"ERROR: channel %d not defined!", ch);
5562 return Start(Timers, NULL, Pause);
5572 if (
id && strcmp(
id, InstantId) == 0) {
5619 if (LastInstantId && LastInstantId ==
RecordControls[i]->InstantId())
5620 LastInstantId = NULL;
5648 bool Result =
false;
5667 isyslog(
"stopping recording due to modification of channel %d (%s)", Channel->
Number(), Channel->
Name());
5696 int NewState =
state;
5697 bool Result = State != NewState;
5729 if (
Setup.AdaptiveSkipAlternate)
5763 if (
Setup.ProgressDisplayTime)
5783 if (
Setup.DelTimeshiftRec == 2 ||
Interface->Confirm(
tr(
"Delete timeshift recording?"))) {
5786 Timers->SetExplicitModify();
5791 Timers->SetModified();
5799 Recordings->SetExplicitModify();
5801 if (Recording->Delete()) {
5804 Recordings->SetModified();
5824 marks.Lock(StateKey);
5844 if (!Recordings->GetByName(
fileName))
5897 bool NormalPlay = (
Play && Speed == -1);
5938 int NumErrors = Errors ? Errors->
Size() : 0;
5942 if (
Setup.ShowRemainingTime)
5943 Index = Current - Index;
5965 strcpy(buf,
tr(
"Jump: "));
5966 int len = strlen(buf);
5975 sprintf(buf + len,
"%c%c:%c%c", ch10, ch1, cm10, cm1);
5981#define STAY_SECONDS_OFF_END 10
6054 if (
GetIndex(Current, Total,
true)) {
6057 marks.Lock(StateKey);
6065 Goto(Current,
true);
6080 if (
marks.Count()) {
6082 if (!
Setup.PauseOnMarkJump) {
6086 Goto(m->Position());
6090 Goto(m->Position(),
true);
6117 if ((m2 =
marks.Next(m)) != NULL)
6125 if ((m2 =
marks.Prev(m)) != NULL)
6134 else if (!MarkRequired)
6142 int NumErrors = Errors ? Errors->
Size() : 0;
6143 if (NumErrors > 0) {
6148 for (
int i = 0; i < NumErrors; i++) {
6149 int Position = Errors->
At(i);
6150 if (Position > Current + Offset) {
6151 int NextIFrame =
SkipFrames(Position - Current) + Offset;
6152 if (NextIFrame > Position) {
6154 Offset = NextIFrame - Current;
6158 Goto(Position,
true);
6162 if (Current < Total)
6166 for (
int i = NumErrors - 1; i >= 0; i--) {
6167 if (Errors->
At(i) < Current) {
6168 int Position = Errors->
At(i);
6169 Goto(Position,
true);
6187 else if (!
marks.GetNumSequences())
6192 Skins.Message(
mtError,
tr(
"Not enough free disk space to start editing process!"));
6210 m =
marks.GetNext(Current);
6212 if ((m->
Index() & 0x01) != 0 && !
Setup.SkipEdited)
6268 bool DoShowMode =
true;
6277 if (
Setup.MultiSpeedMode)
break;
6282 if (
Setup.MultiSpeedMode)
break;
6301 case kPrev:
if (
Setup.AdaptiveSkipPrevNext) {
6309 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