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)
override;
103 virtual void Set(
void)
override;
195 *
data.portalName = 0;
242 int oldSource =
data.source;
248 bool Modified =
false;
270 Skins.QueueMessage(
mtError,
tr(
"Channel settings are not unique!"));
299 virtual void Set(
void)
override;
352#define CHANNELNUMBERTIMEOUT 1000
359 void Set(
bool Force =
false);
368 virtual void Move(
int From,
int To)
override;
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)) {
507 Skins.QueueMessage(
mtError,
tr(
"Channel is being used by a timer!"));
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)
override;
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)
override;
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() ?
"}" :
""));
1345 for (
const cTimer *Timer = Timers->First(); Timer; Timer = Timers->
Next(Timer)) {
1349 if (CurrentTimer && Timer->
Id() == CurrentTimer->
Id() && (!Timer->Remote() && !CurrentTimer->
Remote() || Timer->Remote() && CurrentTimer->
Remote() && strcmp(Timer->Remote(), CurrentTimer->
Remote()) == 0))
1370 int NewHelpKeys = 0;
1409 StateKey.
Remove(Timer != NULL);
1425 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1436 bool TimerRecording = Timer->
Recording();
1438 if (
Interface->Confirm(
tr(
"Delete timer?")) && (!TimerRecording ||
Interface->Confirm(
tr(
"Timer still recording - really delete?")))) {
1468 if (Timer && Timer->
Event())
1496 Add(CurrentItem,
true);
1524 SetHelp(TimerMatch ==
tmFull ?
tr(
"Button$Timer") :
tr(
"Button$Record"), NULL, NULL, CanSwitch ?
tr(
"Button$Switch") : NULL);
1535 if (
event->Description())
1625 if (
event->Schedule() &&
event->Schedule()->HasTimer())
1633 char v =
event->Vps() && (
event->Vps() -
event->StartTime()) ?
'V' :
' ';
1634 char r =
event->SeenWithin(30) &&
event->IsRunning() ?
'*' :
' ';
1636 cString eds =
event->GetDateString();
1638 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());
1690 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1691 if (!Channel->GroupSep()) {
1693 if (
const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent())
1706 bool result =
false;
1721 int NewHelpKeys = 0;
1724 NewHelpKeys |= 0x02;
1726 NewHelpKeys |= 0x01;
1728 NewHelpKeys |= 0x04;
1730 NewHelpKeys |= 0x08;
1733 NewHelpKeys |= 0x10;
1739 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
1740 SetHelp(Red[NewHelpKeys & 0x03],
now ?
tr(
"Button$Next") :
tr(
"Button$Now"),
tr(
"Button$Schedule"),
canSwitch ?
tr(
"Button$Switch") : NULL);
1775 Timers->SetExplicitModify();
1776 if (item->timerMatch ==
tmFull) {
1777 if (
cTimer *Timer = Timers->GetMatch(item->event))
1781 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
1783 if (
cTimer *t = Timers->GetTimer(Timer)) {
1791 Timers->SetModified();
1796 else if (Timer->
Remote())
1859 if (HadSubMenu &&
Update())
1907 Set(Timers, Channels, NULL,
true);
1923 const cEvent *Event = NULL;
1926 Event = CurrentItem->
event;
1932 bool Refresh =
false;
1958 const cEvent *PresentEvent = Event ? Event : Schedule->GetPresentEvent();
1959 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1960 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1961 if (ev->EndTime() >
now || ev == PresentEvent)
1978 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
1979 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
1980 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
1997 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
1999 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
2000 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
2001 if ((ev->EndTime() >
now || ev == Event) && !strcmp(ev->Title(), Event->
Title()))
2017 for (
const cChannel *ch = Channels->First(); ch; ch = Channels->
Next(ch)) {
2019 time_t
now = time(NULL) -
Setup.EPGLinger * 60;
2020 for (
const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->
Next(ev)) {
2021 if (ev->EndTime() >
now || ev == Event)
2031 bool result =
false;
2046 int NewHelpKeys = 0;
2049 NewHelpKeys |= 0x02;
2051 NewHelpKeys |= 0x01;
2055 NewHelpKeys |= 0x10;
2061 const char *Red[] = { NULL,
tr(
"Button$Record"),
tr(
"Button$Timer") };
2062 SetHelp(Red[NewHelpKeys & 0x03],
tr(
"Button$Now"),
tr(
"Button$Next"),
canSwitch ?
tr(
"Button$Switch") : NULL);
2072 Set(Timers, Channels, NULL,
true);
2082 Timers->SetExplicitModify();
2083 if (item->timerMatch ==
tmFull) {
2084 if (
cTimer *Timer = Timers->GetMatch(item->event))
2088 if (
Setup.SVDRPPeering && *
Setup.SVDRPDefaultHost)
2090 if (
cTimer *t = Timers->GetTimer(Timer)) {
2098 Timers->SetModified();
2103 else if (Timer->
Remote())
2120 if ((Channel = Channels->GetByChannelID(item->
event->
ChannelID(),
true)) != NULL) {
2121 if (!Channels->SwitchTo(Channel->
Number()))
2136 Set(Timers, Channels);
2154 ChannelNr = Channel->Number();
2179 Set(Timers, Channels, Channel,
true);
2198 if (
const cChannel *Channel = Channels->GetByChannelID(ei->ChannelID(),
true)) {
2200 Set(Timers, Channels, Channel,
true);
2203 else if (HadSubMenu &&
Update())
2222 const char *s = Command->Text();
2223 if (Command->SubItems())
2237 const char *p = strchr(s,
':');
2244 if (l > 1 && t[l - 1] ==
'?') {
2272 const char *cmd = *cmdbuf ? *cmdbuf : *
command;
2273 dsyslog(
"executing command '%s'", cmd);
2275 if (p.
Open(cmd,
"r")) {
2278 while ((c = fgetc(p)) != EOF) {
2280 if (
char *NewBuffer = (
char *)realloc(
result, l + 21))
2283 esyslog(
"ERROR: out of memory");
2294 esyslog(
"ERROR: can't open pipe for command '%s'", cmd);
2396 dsyslog(
"CAM %d: Menu ------------------",
camSlot->SlotNumber());
2406 for (
int i = 0; i <
ciMenu->NumEntries(); i++) {
2418 int Length =
ciEnquiry->ExpectedLength();
2422 dsyslog(
"CAM %d: Enquiry ------------------",
camSlot->SlotNumber());
2435 const char *p = strchr(s,
'\n');
2436 int l = p ? p - s : strlen(s);
2439 item->
SetText(strndup(s, l),
false);
2448 if (
ciMenu->Selectable()) {
2458 snprintf(buffer,
sizeof(buffer),
tr(
"Please enter %d digits!"),
ciEnquiry->ExpectedLength());
2484 else if (state ==
osBack) {
2511 if (CamSlot->HasUserIO())
2524#define osUserRecRenamed osUser1
2525#define osUserRecMoved osUser2
2526#define osUserRecRemoved osUser3
2527#define osUserRecEmpty osUser4
2574 for (
const cRecording *Recording = Recordings->First(); Recording; Recording = Recordings->
Next(Recording)) {
2575 if (Recording->IsInPath(
path)) {
2576 int FileSizeMB = Recording->FileSizeMB();
2577 if (FileSizeMB > 0 )
2578 DirSize += FileSizeMB;
2619 if (strcmp(NewPath,
path)) {
2620 int NumRecordings = 0;
2623 NumRecordings = Recordings->GetNumRecordingsInPath(
path);
2625 if (NumRecordings > 1 && !
Interface->Confirm(
cString::sprintf(
tr(
"Move entire folder containing %d recordings?"), NumRecordings)))
2630 Recordings->SetExplicitModify();
2631 Error = !Recordings->MoveRecordings(
path, NewPath);
2633 Recordings->SetModified();
2657 else if (Key ==
kOk)
2739 Add(
new cOsdItem(
tr(
"This recording is currently in use - no changes are possible!"),
osUnknown,
false));
2803 Skins.QueueMessage(
mtError,
tr(
"Not enough free disk space to start editing process!"));
2805 Skins.QueueMessage(
mtError,
tr(
"Error while queueing recording for cutting!"));
2817 if (
Interface->Confirm(
tr(
"Rename recording to folder name?"))) {
2839 if (
const cRecording *Recording = Control->GetRecording()) {
2840 if (strcmp(
recording->FileName(), Recording->FileName()) == 0)
2841 Control->ClearEditingMarks();
2846 Skins.QueueMessage(
mtError,
tr(
"Error while deleting editing marks!"));
2861 bool Modified =
false;
2864 StateKey.
Remove(Modified);
2865 Skins.QueueMessage(
mtError,
tr(
"Error while changing priority/lifetime!"));
2873 StateKey.
Remove(Modified);
2874 Skins.QueueMessage(
mtError,
tr(
"Error while changing parental rating!"));
2886 if (strcmp(NewName, Recording->
Name())) {
2888 StateKey.
Remove(Modified);
2889 Skins.QueueMessage(
mtError,
tr(
"Error while changing folder/name!"));
2896 if (strcmp(Recording->
Folder(), OldFolder))
2899 StateKey.
Remove(Modified);
2902 StateKey.
Remove(Modified);
2939 virtual void Display(
void)
override;
2954 SetHelp(
tr(
"Button$Recordings"),
tr(
"Button$Restore"),
tr(
"Button$Permanently delete"));
2956 SetHelp(
tr(
"Button$Play"),
tr(
"Button$Rewind"), NULL,
tr(
"Button$Edit"));
2963 else if (t > 2 * 3600) buffer =
cString::sprintf(
tr(
"Deleted recording (%d hours left)"),
int(t / 3600));
2964 else if (t > 2 * 60) buffer =
cString::sprintf(
tr(
"Deleted recording (%d minutes left)"),
int(t / 60));
3077 if (*
Text() ==
'\t')
3119:
cOsdMenu(Base ? (DelRecMenu ? *
cString::sprintf(
"%s %s",
tr(
"Deleted in"), Base) : Base)
3120 : (DelRecMenu ?
tr(
"Deleted recordings") :
tr(
"Recordings")), 9, 6, 6)
3123 base = Base ? strdup(Base) : NULL;
3145 if (!ri->IsDirectory()) {
3158 int NewHelpKeys = 0;
3172 switch (NewHelpKeys) {
3176 case 3:
SetHelp(
tr(
"Button$Recordings"),
tr(
"Button$Restore"),
tr(
"Button$Permanently delete"),
tr(
"Button$Info"));
break;
3177 case 4:
SetHelp(
tr(
"Button$Deleted recordings"),
tr(
"Button$Rewind"),
tr(
"Button$Delete"),
tr(
"Button$Info"));
break;
3191 const char *CurrentRecording = NULL;
3193 CurrentRecording = ri->Recording()->FileName();
3194 if (!CurrentRecording) {
3197 else if (!
Setup.OpenRecMenuAtLastReplayed)
3209 time_t LastReplayTime = 0;
3210 for (
const cRecording *Recording = Recordings->
First(); Recording; Recording = Recordings->
Next(Recording)) {
3217 if (p->Name() && strcmp(p->Name(), Item->
Name()) == 0) {
3223 if (*Item->
Text() && !LastDir) {
3232 if (LastItem || LastDir) {
3233 if (CurrentRecording) {
3234 if (strcmp(CurrentRecording, Recording->FileName()) == 0)
3235 CurrentItem = LastDir ? LastDir : LastItem;
3238 time_t t = Recording->GetLastReplayTime();
3239 if (t > LastReplayTime) {
3241 CurrentItem = LastDir ? LastDir : LastItem;
3297 const char *t = ri->
Name();
3353 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3355 if (
cTimer *Timer = rc->Timer()) {
3357 if (Timer->IsSingleEvent()) {
3359 isyslog(
"deleted timer %s", *Timer->ToDescr());
3373 char *RemoteBuf = NULL;
3375 if (2 == sscanf(TimerId,
"%d@%m[^ \n]", &Id, &RemoteBuf) && Id != 0) {
3378 if (
Interface->Confirm(
tr(
"Timer still recording - really delete?"))) {
3380 if (
cTimer *Timer = Timers->GetById(Id, Remote)) {
3381 cTimer OldTimer = *Timer;
3383 if (Timer->IsSingleEvent()) {
3410 if (
Interface->Confirm(
tr(
"Delete recording?"))) {
3417 FileName = Recording->FileName();
3422 if (!
Interface->Confirm(
tr(
"Recording is being edited - really delete?")))
3433 if (!Recording || Recording->
Delete()) {
3435 Recordings->
Del(Recording,
false);
3436 DeletedRecordings->
Add(Recording);
3450 Skins.QueueMessage(
mtError,
tr(
"Error while deleting recording!"));
3464 if (
Interface->Confirm(
tr(
"Restore recording?"))) {
3469 if (Recording->Undelete()) {
3470 DeletedRecordings->
Del(Recording,
false);
3471 Recordings->
Add(Recording);
3485 Skins.QueueMessage(
mtError,
tr(
"Error while restoring recording!"));
3500 if (
Interface->Confirm(
tr(
"Permanently delete recording?")) &&
Interface->Confirm(
tr(
"Are you sure? This can't be undone!"))) {
3503 if (Recording->Remove()) {
3504 DeletedRecordings->
Del(Recording);
3516 Skins.QueueMessage(
mtError,
tr(
"Error while permanently deleting recording!"));
3529 if (ri->IsDirectory()) {
3622 ri->SetRecording(riSub->Recording());
3658 virtual void Store(
void)
override;
3693 virtual void Set(
void);
3784 bool ModifiedAppearance =
false;
3793 ModifiedAppearance =
true;
3796 if (
themes.NumThemes() &&
Skins.Current()->Theme()) {
3802 ModifiedAppearance =
true;
3804 ModifiedAppearance =
true;
3809 ModifiedAppearance =
true;
3811 ModifiedAppearance =
true;
3813 ModifiedAppearance =
true;
3814 if (
data.AlwaysSortFoldersFirst !=
Setup.AlwaysSortFoldersFirst ||
data.RecordingDirs !=
Setup.RecordingDirs ||
data.RecSortingDirection !=
Setup.RecSortingDirection) {
3816 Recordings->ClearSortNames();
3824 if (ModifiedAppearance)
3882 if (
data.SetSystemTime)
3900 if (
data.EPGLanguages[i] !=
::Setup.EPGLanguages[i]) {
3911 int oldSetSystemTime =
data.SetSystemTime;
3915 if (
numLanguages != oldnumLanguages ||
data.SetSystemTime != oldSetSystemTime) {
3917 data.EPGLanguages[i] = 0;
3920 for (k = 0; k < oldnumLanguages; k++) {
3921 if (
data.EPGLanguages[k] == l)
3924 if (k >= oldnumLanguages) {
3925 data.EPGLanguages[i] = l;
3985 SetHelp(NULL,
tr(
"Button$Audio"),
tr(
"Button$Subtitles"), NULL);
3998 if (
data.VideoFormat == 0)
4021 int oldVideoDisplayFormat =
::Setup.VideoDisplayFormat;
4022 bool oldVideoFormat =
::Setup.VideoFormat;
4023 bool newVideoFormat =
data.VideoFormat;
4024 int oldDisplaySubtitles =
::Setup.DisplaySubtitles;
4025 int newDisplaySubtitles =
data.DisplaySubtitles;
4039 bool DoSetup =
data.VideoFormat != newVideoFormat;
4040 DoSetup |=
data.DisplaySubtitles != newDisplaySubtitles;
4043 data.AudioLanguages[i] = 0;
4046 for (k = 0; k < oldnumAudioLanguages; k++) {
4047 if (
data.AudioLanguages[k] == l)
4050 if (k >= oldnumAudioLanguages) {
4051 data.AudioLanguages[i] = l;
4061 data.SubtitleLanguages[i] = 0;
4064 for (k = 0; k < oldnumSubtitleLanguages; k++) {
4065 if (
data.SubtitleLanguages[k] == l)
4068 if (k >= oldnumSubtitleLanguages) {
4069 data.SubtitleLanguages[i] = l;
4083 if (
::Setup.VideoDisplayFormat != oldVideoDisplayFormat)
4085 if (
::Setup.VideoFormat != oldVideoFormat)
4087 if (
::Setup.DisplaySubtitles != oldDisplaySubtitles)
4127 int NumSatDevices = 0;
4132 if (NumSatDevices > 1) {
4142 if (
data.UsePositioner) {
4155 int oldDiSEqC =
data.DiSEqC;
4156 int oldUsePositioner =
data.UsePositioner;
4157 bool DeviceBondingsChanged =
false;
4160 DeviceBondingsChanged = strcmp(
data.DeviceBondings, NewDeviceBondings) != 0;
4161 data.DeviceBondings = NewDeviceBondings;
4165 if (Key !=
kNone && (
data.DiSEqC != oldDiSEqC ||
data.UsePositioner != oldUsePositioner))
4167 else if (DeviceBondingsChanged)
4193 const char *Activating =
"";
4194 const char *CamName =
camSlot->GetCamName();
4196 switch (
camSlot->ModuleStatus()) {
4197 case msReset: CamName =
tr(
"CAM reset");
break;
4198 case msPresent: CamName =
tr(
"CAM present");
break;
4199 case msReady: CamName =
tr(
"CAM ready");
break;
4200 default: CamName =
"-";
break;
4203 else if (
camSlot->IsActivating())
4205 Activating =
tr(
" (activating)");
4209 CamSlot->Devices(DeviceNumbers);
4211 if (DeviceNumbers.
Size() > 0) {
4214 for (
int i = 0; i < DeviceNumbers.
Size(); i++)
4215 AssignedDevice =
cString::sprintf(
"%s %d", *AssignedDevice, DeviceNumbers[i]);
4219 if (strcmp(buffer,
Text()) != 0) {
4248 if (CamSlot->IsMasterSlot())
4259 const char *NewActivationHelp =
"";
4263 NewActivationHelp =
tr(
"Button$Cancel activation");
4265 NewActivationHelp =
tr(
"Button$Activate");
4279 time_t t0 = time(NULL);
4313 if (Device->ProvidesChannel(Channel)) {
4315 if (CamSlot->
Assign(Device,
true)) {
4318 if (CamSlot->
Assign(Device)) {
4319 if (Device->SwitchChannel(Channel,
true)) {
4419 virtual void Store(
void)
override;
4436 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Initial duration for adaptive skipping (s)"), &
data.AdaptiveSkipInitial, 10, 600));
4437 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Reset timeout for adaptive skipping (s)"), &
data.AdaptiveSkipTimeout, 0, 10));
4441 Add(
new cMenuEditIntItem(
tr(
"Setup.Replay$Skip distance with Green/Yellow keys in repeat (s)"), &
data.SkipSecondsRepeat, 5, 600));
4449 Recordings->ResetResume();
4488 if (
data.SVDRPPeering) {
4502 Add(
new cMenuEditIntItem(
tr(
"Setup.Miscellaneous$Initial volume"), &
data.InitialVolume, -1, 255,
tr(
"Setup.Miscellaneous$as before")));
4507 Add(
new cMenuEditBoolItem(
tr(
"Setup.Miscellaneous$Open Recordings menu at last replayed"), &
data.OpenRecMenuAtLastReplayed));
4515 bool OldSVDRPPeering =
data.SVDRPPeering;
4516 bool ModifiedSVDRPSettings =
false;
4517 bool ModifiedShowChannelNamesWithSource =
false;
4519 ModifiedSVDRPSettings =
data.SVDRPPeering !=
Setup.SVDRPPeering || strcmp(
data.SVDRPHostName,
Setup.SVDRPHostName);
4520 ModifiedShowChannelNamesWithSource =
data.ShowChannelNamesWithSource !=
Setup.ShowChannelNamesWithSource;
4523 if (ModifiedShowChannelNamesWithSource) {
4525 for (
cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel))
4526 Channel->UpdateNameSource();
4528 if (
data.SVDRPPeering != OldSVDRPPeering)
4530 if (ModifiedSVDRPSettings) {
4534 Timers->SetExplicitModify();
4535 if (Timers->StoreRemoteTimers(NULL, NULL))
4536 Timers->SetModified();
4572 for (
int i = 0; ; i++) {
4596 Skins.QueueMessage(
mtInfo,
tr(
"This plugin has no setup parameters!"));
4614 virtual void Set(
void);
4632 snprintf(buffer,
sizeof(buffer),
"%s - VDR %s",
tr(
"Setup"),
VDRVERSION);
4702#define STOP_RECORDING trNOOP(" Stop recording ")
4769 for (
int i = 0; ; i++) {
4793 bool result =
false;
4798 bool HasDeletedRecordings = DeletedRecordings->Count();
4812 bool NewReplaying =
false;
4817 if (Force || NewReplaying !=
replaying) {
4852 const char *s = NULL;
4934 default:
switch (Key) {
4936 case kRed:
if (!HadSubMenu)
4939 case kGreen:
if (!HadSubMenu) {
4944 case kYellow:
if (!HadSubMenu)
4947 case kBlue:
if (!HadSubMenu)
4959 bool DoDisplay =
Update();
4980 if (
const cChannel *Channel = Channels->GetByNumber(LiveChannel)) {
4982 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
4983 const cEvent *Present = Schedule->GetPresentEvent();
4992 Components = Recording->Info()->Components();
4997 int indexSubtitle = 0;
5001 case 2:
if (p->
type == 0x05)
5034 channel = Channels->GetByNumber(Number);
5087 const cEvent *Present = Schedule->GetPresentEvent();
5088 const cEvent *Following = Schedule->GetFollowingEvent();
5114 Channel = Direction > 0 ? Channels->
Next(Channel) : Channels->
Prev(Channel);
5115 if (!Channel &&
Setup.ChannelsWrap)
5116 Channel = Direction > 0 ? Channels->First() : Channels->Last();
5155 while (ch && (ch = Channels->
Next(ch)) != NULL) {
5157 if (n <= ch->Number() && ch->
Number() < n + m) {
5189 group = Channel->Index();
5192 int SaveGroup =
group;
5254 channel = Channels->Get(Channels->GetNextNormal(
group));
5292 Channels->SwitchTo(NewChannel->
Number());
5297 bool PositionerMoving = Positioner && Positioner->
IsMoving();
5299 if (!PositionerMoving) {
5316#define VOLUMETIMEOUT 1000
5317#define MUTETIMEOUT 5000
5383#define TRACKTIMEOUT 5000
5398 if (TrackId && TrackId->
id) {
5401 if (i == CurrentAudioTrack)
5450 int oldTrack =
track;
5467 static int ac[] = { 1, 0, 2 };
5494 if (
track != oldTrack) {
5519 if (TrackId && TrackId->
id) {
5522 if (i == CurrentSubtitleTrack)
5568 int oldTrack =
track;
5594 if (
track != oldTrack) {
5632 ChannelsStateKey.
Remove();
5634 timer->SetPending(
true);
5635 timer->SetRecording(
true);
5636 event =
timer->Event();
5647 timer->SetPending(
false);
5648 timer->SetRecording(
false);
5657 SchedulesStateKey.
Remove();
5669 if (!
Timer && !LastReplayed)
5671 SchedulesStateKey.
Remove();
5686 SchedulesStateKey.
Remove();
5695#define INSTANT_REC_EPG_LOOKAHEAD 300
5704 if (
const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
5705 event = Schedule->GetEventAround(Time);
5708 dsyslog(
"got EPG info after %d seconds", seconds);
5714 dsyslog(
"waiting for EPG info...");
5717 dsyslog(
"no EPG info available");
5728 isyslog(
"timer %s %s with %d error%s", *
timer->ToDescr(), Finished ?
"finished" :
"stopped", Errors, Errors != 1 ?
"s" :
"");
5729 if (
timer->HasFlags(
tfAvoid) && Errors == 0 && Finished) {
5735 timer->SetRecording(
false);
5739 if (ExecuteUserCommand && Finished)
5748 timer->SetPending(
false);
5761 static time_t LastNoDiskSpaceMessage = 0;
5770 isyslog(
"not enough disk space to start recording%s%s", Timer ?
" timer " :
"", Timer ? *Timer->
ToDescr() :
"");
5771 Skins.QueueMessage(
mtWarning,
tr(
"Not enough disk space to start recording!"));
5772 LastNoDiskSpaceMessage = time(NULL);
5776 LastNoDiskSpaceMessage = 0;
5783 int Priority = Timer ? Timer->
Priority() : Pause ?
Setup.PausePriority :
Setup.DefaultPriority;
5786 dsyslog(
"switching device %d to channel %d %s (%s)", device->
DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
5794 if (!Timer || Timer->
Matches()) {
5803 else if (!Timer || !Timer->
Pending()) {
5804 isyslog(
"no free DVB device to record channel %d (%s)!", ch, Channel->Name());
5805 Skins.QueueMessage(
mtError,
tr(
"No free DVB device to record!"));
5809 esyslog(
"ERROR: channel %d not defined!", ch);
5818 return Start(Timers, NULL, Pause);
5828 if (
id && strcmp(
id, InstantId) == 0) {
5876 if (LastInstantId && LastInstantId ==
RecordControls[i]->InstantId())
5877 LastInstantId = NULL;
5905 bool Result =
false;
5924 isyslog(
"stopping recording due to modification of channel %d (%s)", Channel->
Number(), Channel->
Name());
5953 int NewState =
state;
5954 bool Result = State != NewState;
5986 if (
Setup.AdaptiveSkipAlternate)
6021 if (
Setup.ProgressDisplayTime)
6037 Timers->SetExplicitModify();
6039 Timers->SetModified();
6053 if (
Setup.DelTimeshiftRec == 2 ||
Interface->Confirm(
tr(
"Delete timeshift recording?"))) {
6062 Recordings->SetExplicitModify();
6064 if (Recording->Delete()) {
6066 Recordings->Del(Recording,
false);
6067 DeletedRecordings->Add(Recording);
6069 Recordings->SetModified();
6076 Skins.QueueMessage(
mtError,
tr(
"Error while deleting recording!"));
6089 marks.Lock(StateKey);
6109 if (!Recordings->GetByName(
fileName))
6162 bool NormalPlay = (
Play && Speed == -1);
6203 int NumErrors = Errors ? Errors->
Size() : 0;
6207 if (
Setup.ShowRemainingTime)
6208 Index = Current - Index;
6230 strcpy(buf,
tr(
"Jump: "));
6231 int len = strlen(buf);
6240 sprintf(buf + len,
"%c%c:%c%c", ch10, ch1, cm10, cm1);
6246#define STAY_SECONDS_OFF_END 10
6319 if (
GetIndex(Current, Total,
true)) {
6322 marks.Lock(StateKey);
6330 Goto(Current,
true);
6345 if (
marks.Count()) {
6347 if (!
Setup.PauseOnMarkJump) {
6351 Goto(m->Position());
6355 Goto(m->Position(),
true);
6382 if ((m2 =
marks.Next(m)) != NULL)
6390 if ((m2 =
marks.Prev(m)) != NULL)
6399 else if (!MarkRequired)
6407 int NumErrors = Errors ? Errors->
Size() : 0;
6408 if (NumErrors > 0) {
6413 for (
int i = 0; i < NumErrors; i++) {
6414 int Position = Errors->
At(i);
6415 if (Offset && Position == Current + Offset) {
6416 Goto(Position,
true);
6419 if (Position > Current + Offset) {
6420 int NextIFrame =
SkipFrames(Position - Current) + Offset;
6421 if (NextIFrame > Position) {
6423 Offset = NextIFrame - Current;
6427 Goto(Position,
true);
6431 if (Current < Total)
6435 for (
int i = NumErrors - 1; i >= 0; i--) {
6436 if (Errors->
At(i) < Current) {
6437 int Position = Errors->
At(i);
6438 Goto(Position,
true);
6456 else if (!
marks.GetNumSequences())
6457 Skins.QueueMessage(
mtError,
tr(
"No editing sequences defined!"));
6461 Skins.QueueMessage(
mtError,
tr(
"Not enough free disk space to start editing process!"));
6468 Skins.QueueMessage(
mtError,
tr(
"Editing process already active!"));
6479 m =
marks.GetNext(Current);
6481 if ((m->
Index() & 0x01) != 0 && !
Setup.SkipEdited)
6537 bool DoShowMode =
true;
6546 if (
Setup.MultiSpeedMode)
break;
6551 if (
Setup.MultiSpeedMode)
break;
6570 case kPrev:
if (
Setup.AdaptiveSkipPrevNext) {
6578 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)
const cEvent * lastFollowing
cSkinDisplayChannel * displayChannel
virtual ~cDisplayChannel() override
virtual eOSState ProcessKey(eKeys Key) override
const cPositioner * positioner
static cDisplayChannel * currentDisplayChannel
cDisplayChannel(int Number, bool Switched)
const cChannel * NextAvailableChannel(const cChannel *Channel, int Direction)
virtual void Show(void) override
cSkinDisplayTracks * displayTracks
cDisplaySubtitleTracks(void)
static void Process(eKeys Key)
char * descriptions[ttMaxTrackTypes+1]
eTrackType types[ttMaxTrackTypes]
static cDisplaySubtitleTracks * currentDisplayTracks
static cDisplaySubtitleTracks * Create(void)
virtual ~cDisplaySubtitleTracks() override
virtual eOSState ProcessKey(eKeys Key) override
virtual eOSState ProcessKey(eKeys Key) override
char * descriptions[ttMaxTrackTypes+1]
static cDisplayTracks * Create(void)
static cDisplayTracks * currentDisplayTracks
virtual void Show(void) override
cSkinDisplayTracks * displayTracks
static void Process(eKeys Key)
virtual ~cDisplayTracks() override
eTrackType types[ttMaxTrackTypes]
static cDisplayVolume * Create(void)
cSkinDisplayVolume * displayVolume
virtual void Show(void) override
virtual eOSState ProcessKey(eKeys Key) override
static void Process(eKeys Key)
static cDisplayVolume * currentDisplayVolume
virtual ~cDisplayVolume() override
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,...
void Del(cListObject *Object, bool DeleteObject=true)
virtual void Move(int From, int To)
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)
virtual eOSState ProcessKey(eKeys Key) override
cList< cNestedItem > * commands
virtual ~cMenuCommands() override
cMenuCommands(const char *Title, cList< cNestedItem > *Commands, const char *Parameters=NULL)
bool Parse(const char *s)
cOsdItem * cancelEditingItem
cOsdItem * stopRecordingItem
cOsdItem * stopReplayItem
virtual eOSState ProcessKey(eKeys Key) override
cOsdItem * deletedRecordingsItem
bool Update(bool Force=false)
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 * CallFirstService(const char *Id, void *Data=NULL)
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)
void SetParentalRating(int ParentalRating)
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 the 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 (both internally and on disk) to make this a "deleted" recording.
cString Folder(void) const
Returns the name of the folder this recording is stored in (without the video directory).
void DeleteResume(void) const
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 '...
cRecordingInfo * Info(void) const
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 const cRecordings * GetDeletedRecordingsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of deleted recordings for read access.
static cRecordings * GetDeletedRecordingsWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of deleted recordings for write 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 Add(cRecording *Recording)
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)
virtual void Show(void) override
void TimeSearchDisplay(void)
static void ClearLastReplayed(const char *FileName)
virtual eOSState ProcessKey(eKeys Key) override
void MarkMove(int Frames, bool MarkRequired)
static cReplayControl * currentReplayControl
virtual const cRecording * GetRecording(void) override
Returns the cRecording that is currently being replayed, or NULL if this player is not playing a cRec...
void TimeSearchProcess(eKeys Key)
void MarkJump(bool Forward)
cSkinDisplayReplay * displayReplay
void ShowTimed(int Seconds=0)
static cTimer * timeshiftTimer
virtual cOsdObject * GetInfo(void) override
Returns an OSD object that displays information about the currently played programme.
virtual void Hide(void) override
bool ShowProgress(bool Initial)
static void DelTimeshiftTimer(void)
cAdaptiveSkipper adaptiveSkipper
virtual void ClearEditingMarks(void) override
Clears any editing marks this player might be showing.
virtual ~cReplayControl() override
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
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 MAXPARENTALRATING
#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_DELETEDRECORDINGS_WRITE
#define LOCK_DELETEDRECORDINGS_READ
#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