diff -ruN vdr-1.7.31-ext/channels.c vdr-1.7.31/channels.c --- vdr-1.7.31-ext/channels.c 2012-07-14 14:34:47.000000000 +0200 +++ vdr-1.7.31/channels.c 2012-09-19 23:54:19.000000000 +0200 @@ -13,6 +13,9 @@ #include "epg.h" #include "libsi/si.h" #include "timers.h" +#ifdef USE_ALTERNATECHANNEL +#include "tools.h" +#endif /* ALTERNATECHANNEL */ // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' // format characters in order to allow any number of blanks after a numeric @@ -285,6 +288,14 @@ } } +#ifdef USE_ALTERNATECHANNEL +void cChannel::SetAlternativeChannelID(const char *AlternativeChannelID) +{ + if (!isempty(AlternativeChannelID)) + alternativeChannelID = tChannelID::FromString(AlternativeChannelID); +} +#endif /* ALTERNATECHANNEL */ + #define STRDIFF 0x01 #define VALDIFF 0x02 @@ -408,6 +419,28 @@ } } +#ifdef USE_TTXTSUBS +void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) +{ + int mod = CHANNELMOD_NONE; + if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages)) + mod |= CHANNELMOD_PIDS; + totalTtxtSubtitlePages = fixedTtxtSubtitlePages; + for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { + if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType || + strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) { + mod |= CHANNELMOD_PIDS; + teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i]; + } + totalTtxtSubtitlePages++; + } + modification |= mod; + Channels.SetModified(); +} +#endif // USE_TTXTSUBS + void cChannel::SetCaIds(const int *CaIds) { if (caids[0] && caids[0] <= CA_USER_MAX) @@ -536,10 +569,23 @@ q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); } *q = 0; +#ifdef USE_TTXTSUBS + const int TBufferSize = (MAXTXTPAGES * MAXSPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid +#else const int TBufferSize = MAXSPIDS * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid +#endif char tpidbuf[TBufferSize]; q = tpidbuf; q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid); +#ifdef USE_TTXTSUBS + if (Channel->fixedTtxtSubtitlePages > 0) { + *q++ = '+'; + for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) { + tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i]; + q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage); + } + } +#endif // USE_TTXTSUBS if (Channel->spids[0]) { *q++ = ';'; q += IntArrayToString(q, Channel->spids, 10, Channel->slangs); @@ -710,6 +756,34 @@ } spids[NumSpids] = 0; } +#ifdef USE_TTXTSUBS + fixedTtxtSubtitlePages = 0; + if ((p = strchr(tpidbuf, '+')) != NULL) { + *p++ = 0; + char *q; + char *strtok_next; + while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { + if (fixedTtxtSubtitlePages < MAXTXTPAGES) { + int page; + char *l = strchr(q, '='); + if (l) + *l++ = 0; + if (sscanf(q, "%d", &page) == 1) { + teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page); + if (l) + strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE2); + fixedTtxtSubtitlePages++; + } + else + esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false' + } + else + esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false' + p = NULL; + } + totalTtxtSubtitlePages = fixedTtxtSubtitlePages; + } +#endif // USE_TTXTSUBS if (sscanf(tpidbuf, "%d", &tpid) != 1) return false; if (caidbuf) { @@ -826,6 +900,50 @@ return false; } +#ifdef USE_ALTERNATECHANNEL +bool cChannels::LoadAlternativeChannels(const char *FileName) +{ + FILE *fp; + char *line; + cReadLine ReadLine; + cChannel *origChannel; + tChannelID channelID; + if ((fp = fopen(FileName,"r"))==NULL) + { + esyslog("Can't open Alternative Channels-File <%s>",FileName); + return false; + } + while ((line = ReadLine.Read(fp)) != NULL) + { + if (line[0] != '#') + { + line=strtok(line, ";"); + if (line != NULL) + { + channelID = tChannelID::FromString(line); + if (channelID == tChannelID::InvalidID) + dsyslog("Skipping invalid channel ID <%s>",line); + else { + origChannel = Channels.GetByChannelID(channelID); + if (!origChannel) + dsyslog("Skipping unknown channel ID <%s>",line); + else { + line=strtok(NULL, ";"); + channelID = tChannelID::FromString(line); + if (channelID == tChannelID::InvalidID || !Channels.GetByChannelID(channelID)) + dsyslog("Skipping invalid/unknown alternative channel ID <%s>",line); + else + origChannel->SetAlternativeChannelID(line); + } + } + } + } + } while (line != NULL); + fclose(fp); + return true; +} +#endif /* ALTERNATECHANNEL */ + void cChannels::HashChannel(cChannel *Channel) { channelsHashSid.Add(Channel, Channel->Sid()); diff -ruN vdr-1.7.31-ext/channels.h vdr-1.7.31/channels.h --- vdr-1.7.31-ext/channels.h 2012-06-17 13:21:33.000000000 +0200 +++ vdr-1.7.31/channels.h 2012-09-19 23:54:19.000000000 +0200 @@ -35,6 +35,9 @@ #define MAXDPIDS 16 // dolby (AC3 + DTS) #define MAXSPIDS 32 // subtitles #define MAXCAIDS 12 // conditional access +#ifdef USE_TTXTSUBS +#define MAXTXTPAGES 8 // teletext pages +#endif // USE_TTXTSUBS #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated @@ -71,6 +74,17 @@ static const tChannelID InvalidID; }; +#ifdef USE_TTXTSUBS +struct tTeletextSubtitlePage { + tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = 0; ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } + tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } + char ttxtLanguage[MAXLANGCODE1]; + uchar ttxtPage; + uchar ttxtMagazine; + uchar ttxtType; + int PageNumber(void) const { return BCDCHARTOINT(ttxtMagazine) * 100 + BCDCHARTOINT(ttxtPage); } + }; +#endif // USE_TTXTSUBS class cChannel; class cLinkChannel : public cListObject { @@ -96,6 +110,9 @@ char *shortName; char *provider; char *portalName; +#ifdef USE_ALTERNATECHANNEL + tChannelID alternativeChannelID; +#endif /* ALTERNATECHANNEL */ int __BeginData__; int frequency; // MHz int source; @@ -115,6 +132,11 @@ uint16_t compositionPageIds[MAXSPIDS]; uint16_t ancillaryPageIds[MAXSPIDS]; int tpid; +#ifdef USE_TTXTSUBS + int fixedTtxtSubtitlePages; + int totalTtxtSubtitlePages; + tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; +#endif // USE_TTXTSUBS int caids[MAXCAIDS + 1]; // list is zero-terminated int nid; int tid; @@ -143,6 +165,9 @@ const char *ShortName(bool OrName = false) const; const char *Provider(void) const { return provider; } const char *PortalName(void) const { return portalName; } +#ifdef USE_ALTERNATECHANNEL + const tChannelID AlternativeChannelID(void) const { return alternativeChannelID; } +#endif /* ALTERNATECHANNEL */ int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf' int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization @@ -166,6 +191,10 @@ uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } int Tpid(void) const { return tpid; } +#ifdef USE_TTXTSUBS + const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } + int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } +#endif // USE_TTXTSUBS const int *Caids(void) const { return caids; } int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } int Nid(void) const { return nid; } @@ -191,7 +220,13 @@ void SetId(int Nid, int Tid, int Sid, int Rid = 0); void SetName(const char *Name, const char *ShortName, const char *Provider); void SetPortalName(const char *PortalName); +#ifdef USE_ALTERNATECHANNEL + void SetAlternativeChannelID(const char *AlternativeChannelID); +#endif /* ALTERNATECHANNEL */ void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); +#ifdef USE_TTXTSUBS + void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); +#endif // USE_TTXTSUBS void SetCaIds(const int *CaIds); // list must be zero-terminated void SetCaDescriptors(int Level); void SetLinkChannels(cLinkChannels *LinkChannels); @@ -211,6 +246,9 @@ public: cChannels(void); bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false); +#ifdef USE_ALTERNATECHANNEL + bool LoadAlternativeChannels(const char *FileName); +#endif /* ALTERNATECHANNEL */ void HashChannel(cChannel *Channel); void UnhashChannel(cChannel *Channel); int GetNextGroup(int Idx); // Get next channel group diff -ruN vdr-1.7.31-ext/ci.c vdr-1.7.31/ci.c --- vdr-1.7.31-ext/ci.c 2012-05-29 13:13:40.000000000 +0200 +++ vdr-1.7.31/ci.c 2012-09-19 23:54:19.000000000 +0200 @@ -1914,6 +1914,10 @@ AddPid(Channel->Sid(), *Dpid, STREAM_TYPE_PRIVATE); for (const int *Spid = Channel->Spids(); *Spid; Spid++) AddPid(Channel->Sid(), *Spid, STREAM_TYPE_PRIVATE); +#ifdef USE_TTXTSUBS + if (Channel->Tpid() && Setup.SupportTeletext) + AddPid(Channel->Sid(), Channel->Tpid(), STREAM_TYPE_PRIVATE); +#endif // USE_TTXTSUBS } } @@ -1937,6 +1941,11 @@ CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); for (const int *Spid = Channel->Spids(); *Spid; Spid++) CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); +#ifdef USE_TTXTSUBS + if (Channel->Tpid() && Setup.SupportTeletext) { + CaPmt.AddPid(Channel->Tpid(), STREAM_TYPE_PRIVATE); + } +#endif // USE_TTXTSUBS cas->SendPMT(&CaPmt); cTimeMs Timeout(QUERY_REPLY_TIMEOUT); do { diff -ruN vdr-1.7.31-ext/config.c vdr-1.7.31/config.c --- vdr-1.7.31-ext/config.c 2012-09-15 13:52:03.000000000 +0200 +++ vdr-1.7.31/config.c 2012-09-19 23:54:19.000000000 +0200 @@ -375,6 +375,9 @@ strcpy(OSDLanguage, ""); // default is taken from environment strcpy(OSDSkin, "lcars"); strcpy(OSDTheme, "default"); +#ifdef USE_WAREAGLEICON + WarEagleIcons = 1; +#endif /* WAREAGLEICON */ PrimaryDVB = 1; ShowInfoOnChSwitch = 1; TimeoutRequChInfo = 1; @@ -396,11 +399,20 @@ MarginStop = 10; AudioLanguages[0] = -1; DisplaySubtitles = 0; +#ifdef USE_TTXTSUBS + SupportTeletext = 0; +#endif // USE_TTXTSUBS SubtitleLanguages[0] = -1; SubtitleOffset = 0; SubtitleFgTransparency = 0; SubtitleBgTransparency = 0; EPGLanguages[0] = -1; +#ifdef USE_DDEPGENTRY + DoubleEpgTimeDelta = 15; + DoubleEpgAction = 0; + MixEpgAction = 0; + DisableVPS = 0; +#endif /* DDEPGENTRY */ EPGScanTimeout = 5; EPGBugfixLevel = 3; EPGLinger = 0; @@ -425,6 +437,9 @@ VideoDisplayFormat = 1; VideoFormat = 0; UpdateChannels = 5; +#ifdef USE_CHANNELBIND + ChannelBindingByRid = 0; +#endif /* CHANNELBIND */ UseDolbyDigital = 1; ChannelInfoPos = 0; ChannelInfoTime = 5; @@ -450,8 +465,15 @@ FontSmlSize = 18; FontFixSize = 20; MaxVideoFileSize = MAXVIDEOFILESIZEDEFAULT; +#ifdef USE_HARDLINKCUTTER + MaxRecordingSize = DEFAULTRECORDINGSIZE; + HardLinkCutter = 0; +#endif /* HARDLINKCUTTER */ SplitEditedFiles = 0; DelTimeshiftRec = 0; +#ifdef USE_NALUDUMP + DumpNaluFill = 0; +#endif // USE_NALUDUMP MinEventTimeout = 30; MinUserInactivity = 300; NextWakeupTime = 0; @@ -459,15 +481,45 @@ ShowReplayMode = 0; ShowRemainingTime = 0; ResumeID = 0; +#ifdef USE_JUMPPLAY + JumpPlay = 0; + PlayJump = 0; + PauseLastMark = 0; +#endif /* JUMPPLAY */ CurrentChannel = -1; CurrentVolume = MAXVOLUME; CurrentDolby = 0; InitialChannel = ""; DeviceBondings = ""; InitialVolume = -1; +#ifdef USE_VOLCTRL + LRVolumeControl = 0; + LRChannelGroups = 1; + LRForwardRewind = 1; +#endif // USE_VOLCTRL ChannelsWrap = 0; ShowChannelNamesWithSource = 0; EmergencyExit = 1; +#ifdef USE_JUMPINGSECONDS + JumpSeconds = 60; + JumpSecondsSlow = 10; + JumpSecondsRepeat = 300; +#endif // USE_JUMPINGSECONDS +#ifdef USE_LIRCSETTINGS + LircRepeatDelay = 350; + LircRepeatFreq = 100; + LircRepeatTimeout = 500; +#endif /* LIRCSETTINGS */ +#ifdef USE_DVLVIDPREFER + UseVidPrefer = 0; // default = disabled + nVidPrefer = 1; + for (int zz = 1; zz < DVLVIDPREFER_MAX; zz++) { + VidPreferPrio[ zz ] = 50; + VidPreferSize[ zz ] = 100; + } + VidPreferSize[ 0 ] = 800; + VidPreferPrio[ 0 ] = 50; +#endif /* DVLVIDPREFER */ } cSetup& cSetup::operator= (const cSetup &s) @@ -575,6 +627,9 @@ if (!strcasecmp(Name, "OSDLanguage")) { strn0cpy(OSDLanguage, Value, sizeof(OSDLanguage)); I18nSetLocale(OSDLanguage); } else if (!strcasecmp(Name, "OSDSkin")) Utf8Strn0Cpy(OSDSkin, Value, MaxSkinName); else if (!strcasecmp(Name, "OSDTheme")) Utf8Strn0Cpy(OSDTheme, Value, MaxThemeName); +#ifdef USE_WAREAGLEICON + else if (!strcasecmp(Name, "WarEagleIcons")) WarEagleIcons = atoi(Value); +#endif /* WAREAGLEICON */ else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); else if (!strcasecmp(Name, "TimeoutRequChInfo")) TimeoutRequChInfo = atoi(Value); @@ -596,11 +651,20 @@ else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); else if (!strcasecmp(Name, "DisplaySubtitles")) DisplaySubtitles = atoi(Value); +#ifdef USE_TTXTSUBS + else if (!strcasecmp(Name, "SupportTeletext")) SupportTeletext = atoi(Value); +#endif // USE_TTXTSUBS else if (!strcasecmp(Name, "SubtitleLanguages")) return ParseLanguages(Value, SubtitleLanguages); else if (!strcasecmp(Name, "SubtitleOffset")) SubtitleOffset = atoi(Value); else if (!strcasecmp(Name, "SubtitleFgTransparency")) SubtitleFgTransparency = atoi(Value); else if (!strcasecmp(Name, "SubtitleBgTransparency")) SubtitleBgTransparency = atoi(Value); else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages); +#ifdef USE_DDEPGENTRY + else if (!strcasecmp(Name, "DoubleEpgTimeDelta")) DoubleEpgTimeDelta = atoi(Value); + else if (!strcasecmp(Name, "DoubleEpgAction")) DoubleEpgAction = atoi(Value); + else if (!strcasecmp(Name, "MixEpgAction")) MixEpgAction = atoi(Value); + else if (!strcasecmp(Name, "DisableVPS")) DisableVPS = atoi(Value); +#endif /* DDEPGENTRY */ else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value); else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value); else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value); @@ -625,6 +689,9 @@ else if (!strcasecmp(Name, "VideoDisplayFormat")) VideoDisplayFormat = atoi(Value); else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value); else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value); +#ifdef USE_CHANNELBIND + else if (!strcasecmp(Name, "ChannelBindingByRid")) ChannelBindingByRid= atoi(Value); +#endif /* CHANNELBIND */ else if (!strcasecmp(Name, "UseDolbyDigital")) UseDolbyDigital = atoi(Value); else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); else if (!strcasecmp(Name, "ChannelInfoTime")) ChannelInfoTime = atoi(Value); @@ -650,8 +717,15 @@ else if (!strcasecmp(Name, "FontSmlSize")) FontSmlSize = atoi(Value); else if (!strcasecmp(Name, "FontFixSize")) FontFixSize = atoi(Value); else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value); +#ifdef USE_HARDLINKCUTTER + else if (!strcasecmp(Name, "MaxRecordingSize")) MaxRecordingSize = atoi(Value); + else if (!strcasecmp(Name, "HardLinkCutter")) HardLinkCutter = atoi(Value); +#endif /* HARDLINKCUTTER */ else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value); else if (!strcasecmp(Name, "DelTimeshiftRec")) DelTimeshiftRec = atoi(Value); +#ifdef USE_NALUDUMP + else if (!strcasecmp(Name, "DumpNaluFill")) DumpNaluFill = atoi(Value); +#endif // USE_NALUDUMP else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); else if (!strcasecmp(Name, "NextWakeupTime")) NextWakeupTime = atoi(Value); @@ -659,15 +733,63 @@ else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); else if (!strcasecmp(Name, "ShowRemainingTime")) ShowRemainingTime = atoi(Value); else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value); +#ifdef USE_JUMPPLAY + else if (!strcasecmp(Name, "JumpPlay")) JumpPlay = atoi(Value); + else if (!strcasecmp(Name, "PlayJump")) PlayJump = atoi(Value); + else if (!strcasecmp(Name, "PauseLastMark")) PauseLastMark = atoi(Value); +#endif /* JUMPPLAY */ else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value); else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value); else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value); else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = Value; else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); +#ifdef USE_VOLCTRL + else if (!strcasecmp(Name, "LRVolumeControl")) LRVolumeControl = atoi(Value); + else if (!strcasecmp(Name, "LRChannelGroups")) LRChannelGroups = atoi(Value); + else if (!strcasecmp(Name, "LRForwardRewind")) LRForwardRewind = atoi(Value); +#endif // USE_VOLCTRL else if (!strcasecmp(Name, "DeviceBondings")) DeviceBondings = Value; else if (!strcasecmp(Name, "ChannelsWrap")) ChannelsWrap = atoi(Value); else if (!strcasecmp(Name, "ShowChannelNamesWithSource")) ShowChannelNamesWithSource = atoi(Value); else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value); +#ifdef USE_JUMPINGSECONDS + else if (!strcasecmp(Name, "JumpSeconds")) JumpSeconds = atoi(Value); + else if (!strcasecmp(Name, "JumpSecondsSlow")) JumpSecondsSlow = atoi(Value); + else if (!strcasecmp(Name, "JumpSecondsRepeat")) JumpSecondsRepeat = atoi(Value); +#endif // USE_JUMPINGSECONDS +#ifdef USE_LIRCSETTINGS + else if (!strcasecmp(Name, "LircRepeatDelay")) LircRepeatDelay = atoi(Value); + else if (!strcasecmp(Name, "LircRepeatFreq")) LircRepeatFreq = atoi(Value); + else if (!strcasecmp(Name, "LircRepeatTimeout")) LircRepeatTimeout = atoi(Value); +#endif /* LIRCSETTINGS */ +#ifdef USE_DVLVIDPREFER + else if (strcasecmp(Name, "UseVidPrefer") == 0) UseVidPrefer = atoi(Value); + else if (strcasecmp(Name, "nVidPrefer") == 0) nVidPrefer = atoi(Value); + else if (strstr(Name, "VidPrefer") == Name) { + char *x = (char *)&Name[ strlen(Name) - 1 ]; + int vN; + + if (isdigit(*x) != 0) { + while (isdigit(*x) != 0) + x--; + x++; + } + + vN = atoi(x); + if (vN < DVLVIDPREFER_MAX) { + if (strstr(Name, "VidPreferPrio") == Name) { + VidPreferPrio[ vN ] = atoi(Value); + if (VidPreferPrio[ vN ] > 99) + VidPreferPrio[ vN ] = 99; + } + else if (strstr(Name, "VidPreferSize") == Name) { + VidPreferSize[ vN ] = atoi(Value); + } + else + return false; + } + } +#endif /* DVLVIDPREFER */ else return false; return true; @@ -678,6 +800,9 @@ Store("OSDLanguage", OSDLanguage); Store("OSDSkin", OSDSkin); Store("OSDTheme", OSDTheme); +#ifdef USE_WAREAGLEICON + Store("WarEagleIcons", WarEagleIcons); +#endif /* WAREAGLEICON */ Store("PrimaryDVB", PrimaryDVB); Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch); Store("TimeoutRequChInfo", TimeoutRequChInfo); @@ -699,11 +824,20 @@ Store("MarginStop", MarginStop); StoreLanguages("AudioLanguages", AudioLanguages); Store("DisplaySubtitles", DisplaySubtitles); +#ifdef USE_TTXTSUBS + Store("SupportTeletext", SupportTeletext); +#endif // USE_TTXTSUBS StoreLanguages("SubtitleLanguages", SubtitleLanguages); Store("SubtitleOffset", SubtitleOffset); Store("SubtitleFgTransparency", SubtitleFgTransparency); Store("SubtitleBgTransparency", SubtitleBgTransparency); StoreLanguages("EPGLanguages", EPGLanguages); +#ifdef USE_DDEPGENTRY + Store("DoubleEpgTimeDelta", DoubleEpgTimeDelta); + Store("DoubleEpgAction", DoubleEpgAction); + Store("MixEpgAction", MixEpgAction); + Store("DisableVPS", DisableVPS); +#endif /* DDEPGENTRY */ Store("EPGScanTimeout", EPGScanTimeout); Store("EPGBugfixLevel", EPGBugfixLevel); Store("EPGLinger", EPGLinger); @@ -728,6 +862,9 @@ Store("VideoDisplayFormat", VideoDisplayFormat); Store("VideoFormat", VideoFormat); Store("UpdateChannels", UpdateChannels); +#ifdef USE_CHANNELBIND + Store("ChannelBindingByRid",ChannelBindingByRid); +#endif /* CHANNELBIND */ Store("UseDolbyDigital", UseDolbyDigital); Store("ChannelInfoPos", ChannelInfoPos); Store("ChannelInfoTime", ChannelInfoTime); @@ -755,6 +892,9 @@ Store("MaxVideoFileSize", MaxVideoFileSize); Store("SplitEditedFiles", SplitEditedFiles); Store("DelTimeshiftRec", DelTimeshiftRec); +#ifdef USE_NALUDUMP + Store("DumpNaluFill", DumpNaluFill); +#endif // USE_NALUDUMP Store("MinEventTimeout", MinEventTimeout); Store("MinUserInactivity", MinUserInactivity); Store("NextWakeupTime", NextWakeupTime); @@ -762,15 +902,51 @@ Store("ShowReplayMode", ShowReplayMode); Store("ShowRemainingTime", ShowRemainingTime); Store("ResumeID", ResumeID); +#ifdef USE_JUMPPLAY + Store("JumpPlay", JumpPlay); + Store("PlayJump", PlayJump); + Store("PauseLastMark", PauseLastMark); +#endif /* JUMPPLAY */ Store("CurrentChannel", CurrentChannel); Store("CurrentVolume", CurrentVolume); Store("CurrentDolby", CurrentDolby); +#ifdef USE_HARDLINKCUTTER + Store("MaxRecordingSize", MaxRecordingSize); + Store("HardLinkCutter", HardLinkCutter); +#endif /* HARDLINKCUTTER */ Store("InitialChannel", InitialChannel); Store("InitialVolume", InitialVolume); +#ifdef USE_VOLCTRL + Store("LRVolumeControl", LRVolumeControl); + Store("LRChannelGroups", LRChannelGroups); + Store("LRForwardRewind", LRForwardRewind); +#endif // USE_VOLCTRL Store("DeviceBondings", DeviceBondings); Store("ChannelsWrap", ChannelsWrap); Store("ShowChannelNamesWithSource", ShowChannelNamesWithSource); Store("EmergencyExit", EmergencyExit); +#ifdef USE_JUMPINGSECONDS + Store("JumpSeconds", JumpSeconds); + Store("JumpSecondsSlow", JumpSecondsSlow); + Store("JumpSecondsRepeat", JumpSecondsRepeat); +#endif // USE_JUMPINGSECONDS +#ifdef USE_LIRCSETTINGS + Store("LircRepeatDelay", LircRepeatDelay); + Store("LircRepeatFreq", LircRepeatFreq); + Store("LircRepeatTimeout", LircRepeatTimeout); +#endif /* LIRCSETTINGS */ +#ifdef USE_DVLVIDPREFER + Store ("UseVidPrefer", UseVidPrefer); + Store ("nVidPrefer", nVidPrefer); + + char vidBuf[32]; + for (int zz = 0; zz < nVidPrefer; zz++) { + sprintf(vidBuf, "VidPreferPrio%d", zz); + Store (vidBuf, VidPreferPrio[zz]); + sprintf(vidBuf, "VidPreferSize%d", zz); + Store (vidBuf, VidPreferSize[zz]); + } +#endif /* DVLVIDPREFER */ Sort(); diff -ruN vdr-1.7.31-ext/config.h vdr-1.7.31/config.h --- vdr-1.7.31-ext/config.h 2012-09-15 13:51:54.000000000 +0200 +++ vdr-1.7.31/config.h 2012-09-19 23:54:19.000000000 +0200 @@ -30,12 +30,34 @@ #define APIVERSION "1.7.31" #define APIVERSNUM 10731 // Version * 10000 + Major * 100 + Minor +#ifdef USE_YAEPG +#define YAEPGHDVERSNUM 1 +#endif /* YAEPG */ + // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to // VDR header files since the last APIVERSION. This allows compiled // plugins to work with newer versions of the core VDR as long as no // VDR header files have changed. +#ifdef USE_CHANNELBIND +#define CHANNELBINDINGVERSNUM 2 +#endif /* CHANNELBIND */ + +#ifdef USE_MAINMENUHOOKS +// The MainMenuHook Patch's version number: +#define MAINMENUHOOKSVERSION "1.0.1" +#define MAINMENUHOOKSVERSNUM 10001 // Version * 10000 + Major * 100 + Minor +#endif /* MAINMENUHOOKS */ + +#ifdef USE_JUMPPLAY +#define JUMPPLAYVERSNUM 100 +#endif /* JUMPPLAY */ + +#ifdef USE_LIEMIKUUTIO +#define LIEMIKUUTIO 134 +#endif /* LIEMIKUUTIO */ + #define MAXPRIORITY 99 #define MINPRIORITY (-MAXPRIORITY) #define LIVEPRIORITY 0 // priority used when selecting a device for live viewing @@ -44,6 +66,10 @@ #define MAXLIFETIME 99 #define DEFINSTRECTIME 180 // default instant recording time (minutes) +#ifdef USE_DVLVIDPREFER +#define DVLVIDPREFER_MAX 12 +#endif /* DVLVIDPREFER */ + #define MINOSDWIDTH 480 #define MAXOSDWIDTH 1920 #define MINOSDHEIGHT 324 @@ -250,6 +276,9 @@ char OSDLanguage[I18N_MAX_LOCALE_LEN]; char OSDSkin[MaxSkinName]; char OSDTheme[MaxThemeName]; +#ifdef USE_WAREAGLEICON + int WarEagleIcons; +#endif /* WAREAGLEICON */ int PrimaryDVB; int ShowInfoOnChSwitch; int TimeoutRequChInfo; @@ -270,10 +299,19 @@ int MarginStart, MarginStop; int AudioLanguages[I18N_MAX_LANGUAGES + 1]; int DisplaySubtitles; +#ifdef USE_TTXTSUBS + int SupportTeletext; +#endif // USE_TTXTSUBS int SubtitleLanguages[I18N_MAX_LANGUAGES + 1]; int SubtitleOffset; int SubtitleFgTransparency, SubtitleBgTransparency; int EPGLanguages[I18N_MAX_LANGUAGES + 1]; +#ifdef USE_DDEPGENTRY + int DoubleEpgTimeDelta; + int DoubleEpgAction; + int MixEpgAction; + int DisableVPS; +#endif /* DDEPPGENTRY */ int EPGScanTimeout; int EPGBugfixLevel; int EPGLinger; @@ -293,6 +331,9 @@ int VideoDisplayFormat; int VideoFormat; int UpdateChannels; +#ifdef USE_CHANNELBIND + int ChannelBindingByRid; +#endif /* CHANNELBIND */ int UseDolbyDigital; int ChannelInfoPos; int ChannelInfoTime; @@ -312,8 +353,15 @@ int FontSmlSize; int FontFixSize; int MaxVideoFileSize; +#ifdef USE_HARDLINKCUTTER + int MaxRecordingSize; + int HardLinkCutter; +#endif /* HARDLINKCUTTER */ int SplitEditedFiles; int DelTimeshiftRec; +#ifdef USE_NALUDUMP + int DumpNaluFill; +#endif // USE_NALUDUMP int MinEventTimeout, MinUserInactivity; time_t NextWakeupTime; int MultiSpeedMode; @@ -321,12 +369,38 @@ int ShowRemainingTime; int ResumeID; int CurrentChannel; +#ifdef USE_JUMPPLAY + int JumpPlay; + int PlayJump; + int PauseLastMark; +#endif /* JUMPPLAY */ int CurrentVolume; int CurrentDolby; int InitialVolume; +#ifdef USE_VOLCTRL + int LRVolumeControl; + int LRChannelGroups; + int LRForwardRewind; +#endif // USE_VOLCTRL int ChannelsWrap; int ShowChannelNamesWithSource; int EmergencyExit; +#ifdef USE_JUMPINGSECONDS + int JumpSeconds; + int JumpSecondsSlow; + int JumpSecondsRepeat; +#endif // USE_JUMPINGSECONDS +#ifdef USE_LIRCSETTINGS + int LircRepeatDelay; + int LircRepeatFreq; + int LircRepeatTimeout; +#endif /* LIRCSETTINGS */ +#ifdef USE_DVLVIDPREFER + int UseVidPrefer; // 0 = VDR's default, 1 = use + int nVidPrefer; + int VidPreferPrio[DVLVIDPREFER_MAX]; + int VidPreferSize[DVLVIDPREFER_MAX]; +#endif /* DVLVIDPREFER */ int __EndData__; cString InitialChannel; cString DeviceBondings; diff -ruN vdr-1.7.31-ext/cutter.c vdr-1.7.31/cutter.c --- vdr-1.7.31-ext/cutter.c 2012-09-20 11:12:47.000000000 +0200 +++ vdr-1.7.31/cutter.c 2012-09-19 23:54:19.000000000 +0200 @@ -8,6 +8,9 @@ */ #include "cutter.h" +#ifdef USE_LIEMIKUUTIO +#include "interface.h" +#endif /* LIEMIKUUTIO */ #include "menu.h" #include "recording.h" #include "remux.h" @@ -15,6 +18,19 @@ // --- cCuttingThread -------------------------------------------------------- +#ifdef USE_CUTTERLIMIT +#ifndef CUTTER_MAX_BANDWIDTH +#define CUTTER_MAX_BANDWIDTH MEGABYTE(10) // 10 MB/s +#endif +#ifndef CUTTER_REL_BANDWIDTH +#define CUTTER_REL_BANDWIDTH 75 // % +#endif +#ifndef CUTTER_PRIORITY +#define CUTTER_PRIORITY sched_get_priority_min(SCHED_OTHER) +#endif +#define CUTTER_TIMESLICE 100 // ms +#endif /* CUTTERLIMIT */ + class cCuttingThread : public cThread { private: const char *error; @@ -67,6 +83,22 @@ void cCuttingThread::Action(void) { +#ifdef USE_CUTTERLIMIT +#ifdef USE_HARDLINKCUTTER + if (!Setup.HardLinkCutter) +#endif /* HARDLINKCUTTER */ + { + sched_param tmp; + tmp.sched_priority = CUTTER_PRIORITY; + if(!pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp)) + printf("cCuttingThread::Action: cant set priority\n"); + } + + int bytes = 0; + int __attribute__((unused)) burst_size = CUTTER_MAX_BANDWIDTH * CUTTER_TIMESLICE / 1000; // max bytes/timeslice + cTimeMs __attribute__((unused)) t; +#endif /* CUTTERLIMIT */ + cMark *Mark = fromMarks.First(); if (Mark) { SetPriority(19); @@ -80,6 +112,9 @@ Mark = fromMarks.Next(Mark); off_t FileSize = 0; int CurrentFileNumber = 0; +#ifdef USE_HARDLINKCUTTER + bool SkipThisSourceFile = false; +#endif /* HARDLINKCUTTER */ int LastIFrame = 0; toMarks.Add(0); toMarks.Save(); @@ -116,6 +151,95 @@ // Read one frame: +#ifdef USE_HARDLINKCUTTER + if (!fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) { + // Error, unless we're past last cut-in and there's no cut-out + if (Mark || LastMark) + error = "index"; + break; + } + + if (FileNumber != CurrentFileNumber) { + fromFile = fromFileName->SetOffset(FileNumber, FileOffset); + if (fromFile) + fromFile->SetReadAhead(MEGABYTE(20)); + CurrentFileNumber = FileNumber; + if (SkipThisSourceFile) { + // At end of fast forward: Always skip to next file + toFile = toFileName->NextFile(); + if (!toFile) { + error = "toFile 4"; + break; + } + FileSize = 0; + SkipThisSourceFile = false; + } + + + if (Setup.HardLinkCutter && FileOffset == 0) { + // We are at the beginning of a new source file. + // Do we need to copy the whole file? + + // if !Mark && LastMark, then we're past the last cut-out and continue to next I-frame + // if !Mark && !LastMark, then there's just a cut-in, but no cut-out + // if Mark, then we're between a cut-in and a cut-out + + uint16_t MarkFileNumber; + off_t MarkFileOffset; + // Get file number of next cut mark + if (!Mark && !LastMark + || Mark + && fromIndex->Get(Mark->Position(), &MarkFileNumber, &MarkFileOffset) + && (MarkFileNumber != CurrentFileNumber)) { + // The current source file will be copied completely. + // Start new output file unless we did that already + if (FileSize != 0) { + toFile = toFileName->NextFile(); + if (!toFile) { + error = "toFile 3"; + break; + } + FileSize = 0; + } + + // Safety check that file has zero size + struct stat buf; + if (stat(toFileName->Name(), &buf) == 0) { + if (buf.st_size != 0) { + esyslog("cCuttingThread: File %s exists and has nonzero size", toFileName->Name()); + error = "nonzero file exist"; + break; + } + } + else if (errno != ENOENT) { + esyslog("cCuttingThread: stat failed on %s", toFileName->Name()); + error = "stat"; + break; + } + + // Clean the existing 0-byte file + toFileName->Close(); + cString ActualToFileName(ReadLink(toFileName->Name()), true); + unlink(ActualToFileName); + unlink(toFileName->Name()); + + // Try to create a hard link + if (HardLinkVideoFile(fromFileName->Name(), toFileName->Name())) { + // Success. Skip all data transfer for this file + SkipThisSourceFile = true; + cutIn = false; + toFile = NULL; // was deleted by toFileName->Close() + } + else { + // Fallback: Re-open the file if necessary + toFile = toFileName->Open(); + } + } + } + } + + if (!SkipThisSourceFile) { +#else if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) { if (FileNumber != CurrentFileNumber) { fromFile = fromFileName->SetOffset(FileNumber, FileOffset); @@ -123,6 +247,7 @@ fromFile->SetReadAhead(MEGABYTE(20)); CurrentFileNumber = FileNumber; } +#endif /* HARDLINKCUTTER */ if (fromFile) { int len = ReadFrame(fromFile, buffer, Length, sizeof(buffer)); if (len < 0) { @@ -139,19 +264,25 @@ break; } } +#ifndef USE_HARDLINKCUTTER else { // Error, unless we're past the last cut-in and there's no cut-out if (Mark || LastMark) error = "index"; break; } +#endif /* HARDLINKCUTTER */ // Write one frame: if (Independent) { // every file shall start with an independent frame if (LastMark) // edited version shall end before next I-frame break; +#ifdef USE_HARDLINKCUTTER + if (!SkipThisSourceFile && FileSize > toFileName->MaxFileSize()) { +#else if (FileSize > maxVideoFileSize) { +#endif /* HARDLINKCUTTER */ toFile = toFileName->NextFile(); if (!toFile) { error = "toFile 1"; @@ -160,6 +291,10 @@ FileSize = 0; } LastIFrame = 0; + +#ifdef USE_HARDLINKCUTTER + if (!SkipThisSourceFile && cutIn) { +#else // Compare the current frame with the previously stored one, to see if this is a seamlessly merged recording of the same stream: if (CheckForSeamlessStream) { if (Length == Length2) { @@ -176,6 +311,7 @@ CheckForSeamlessStream = false; } if (cutIn) { +#endif /* HARDLINKCUTTER */ if (isPesRecording) cRemux::SetBrokenLink(buffer, Length); else @@ -183,7 +319,11 @@ cutIn = false; } } +#ifdef USE_HARDLINKCUTTER + if (!SkipThisSourceFile && toFile->Write(buffer, Length) < 0) { +#else if (toFile->Write(buffer, Length) < 0) { +#endif /* HARDLINKCUTTER */ error = "safe_write"; break; } @@ -228,8 +368,45 @@ } } else +#ifdef USE_HARDLINKCUTTER + LastMark = true; // After last cut-out: Write on until next I-frame, then exit +#else LastMark = true; +#endif /* HARDLINKCUTTER */ + } + +#ifdef USE_CUTTERLIMIT +#ifdef USE_HARDLINKCUTTER + if (!Setup.HardLinkCutter) { +#endif /* HARDLINKCUTTER */ + bytes += Length; + if(bytes >= burst_size) { + int elapsed = t.Elapsed(); + int sleep = 0; + +#if CUTTER_REL_BANDWIDTH > 0 && CUTTER_REL_BANDWIDTH < 100 + // stay under max. relative bandwidth + + sleep = (elapsed * 100 / CUTTER_REL_BANDWIDTH) - elapsed; + //if(sleep<=0 && elapsed<=2) sleep = 1; + //if(sleep) esyslog("cutter: relative bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); +#endif + // stay under max. absolute bandwidth + if(elapsed < CUTTER_TIMESLICE) { + sleep = max(CUTTER_TIMESLICE - elapsed, sleep); + //if(sleep) esyslog("cutter: absolute bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); + } + + if(sleep>0) + cCondWait::SleepMs(sleep); + t.Set(); + bytes = 0; + } +#ifdef USE_HARDLINKCUTTER } +#endif /* HARDLINKCUTTER */ +#endif /* CUTTERLIMIT */ + } Recordings.TouchUpdate(); } @@ -246,7 +423,11 @@ bool cCutter::error = false; bool cCutter::ended = false; +#ifdef USE_LIEMIKUUTIO +bool cCutter::Start(const char *FileName, const char *TargetFileName, bool Overwrite) +#else bool cCutter::Start(const char *FileName) +#endif /* LIEMIKUUTIO */ { cMutexLock MutexLock(&mutex); if (!cuttingThread) { @@ -260,11 +441,25 @@ if (cMark *First = FromMarks.First()) Recording.SetStartTime(Recording.Start() + (int(First->Position() / Recording.FramesPerSecond() + 30) / 60) * 60); +#ifdef USE_LIEMIKUUTIO + cString evn = (TargetFileName && *TargetFileName) ? Recording.UpdateFileName(TargetFileName) : Recording.PrefixFileName('%'); + if (!Overwrite && *evn && (access(*evn, F_OK) == 0) && !Interface->Confirm(tr("File already exists - overwrite?"))) { + do { + evn = PrefixVideoFileName(*evn, '%'); + } while (*evn && (access(*evn, F_OK) == 0)); + } + if (*evn && RemoveVideoFile(*evn) && MakeDirs(*evn, true)) { +#else const char *evn = Recording.PrefixFileName('%'); if (evn && RemoveVideoFile(evn) && MakeDirs(evn, true)) { +#endif /* LIEMIKUUTIO */ // XXX this can be removed once RenameVideoFile() follows symlinks (see videodir.c) // remove a possible deleted recording with the same name to avoid symlink mixups: +#ifdef USE_LIEMIKUUTIO + char *s = strdup(*evn); +#else char *s = strdup(evn); +#endif /* LIEMIKUUTIO */ char *e = strrchr(s, '.'); if (e) { if (strcmp(e, ".rec") == 0) { @@ -317,6 +512,7 @@ editedVersionName = NULL; ended = true; } + return false; } diff -ruN vdr-1.7.31-ext/cutter.h vdr-1.7.31/cutter.h --- vdr-1.7.31-ext/cutter.h 2012-02-16 13:05:33.000000000 +0100 +++ vdr-1.7.31/cutter.h 2012-09-19 23:54:19.000000000 +0200 @@ -24,7 +24,11 @@ static bool error; static bool ended; public: +#ifdef USE_LIEMIKUUTIO + static bool Start(const char *FileName, const char *TargetFileName = NULL, bool Overwrite = true); +#else static bool Start(const char *FileName); +#endif /* LIEMIKUUTIO */ static void Stop(void); static bool Active(const char *FileName = NULL); ///< Returns true if the cutter is currently active. diff -ruN vdr-1.7.31-ext/device.c vdr-1.7.31/device.c --- vdr-1.7.31-ext/device.c 2012-09-20 11:32:26.000000000 +0200 +++ vdr-1.7.31/device.c 2012-09-19 23:54:19.000000000 +0200 @@ -18,6 +18,9 @@ #include "receiver.h" #include "status.h" #include "transfer.h" +#ifdef USE_TTXTSUBS +#include "vdrttxtsubshooks.h" +#endif // USE_TTXTSUBS // --- cLiveSubtitle --------------------------------------------------------- @@ -691,6 +694,11 @@ bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) { +#ifdef USE_PINPLUGIN + if (LiveView && cStatus::MsgChannelProtected(this, Channel) == true) + return scrNotAvailable; +#endif /* PINPLUGIN */ + if (LiveView) { isyslog("switching to channel %d", Channel->Number()); cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer @@ -721,6 +729,9 @@ cChannel *channel; while ((channel = Channels.GetByNumber(n, Direction)) != NULL) { // try only channels which are currently available +#ifdef USE_PINPLUGIN + if (cStatus::MsgChannelProtected(0, channel) == false) +#endif /* PINPLUGIN */ if (GetDevice(channel, LIVEPRIORITY, true, true)) break; n = channel->Number() + Direction; @@ -1306,6 +1317,14 @@ } break; case 0xBD: { // private stream 1 +#ifdef USE_TTXTSUBS + // EBU Teletext data, ETSI EN 300 472 + // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) + if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { + cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); + break; + } +#endif // USE_TTXTSUBS int PayloadOffset = Data[8] + 9; // Compatibility mode for old subtitles plugin: @@ -1465,6 +1484,9 @@ tsToPesVideo.Reset(); tsToPesAudio.Reset(); tsToPesSubtitle.Reset(); +#ifdef USE_TTXTSUBS + tsToPesTeletext.Reset(); +#endif // USE_TTXTSUBS } else if (Length < TS_SIZE) { esyslog("ERROR: skipped %d bytes of TS fragment", Length); @@ -1510,6 +1532,19 @@ if (!VideoOnly || HasIBPTrickSpeed()) PlayTsSubtitle(Data, TS_SIZE); } +#ifdef USE_TTXTSUBS + else if (Pid == patPmtParser.Tpid()) { + if (!VideoOnly || HasIBPTrickSpeed()) { + int l; + tsToPesTeletext.PutTs(Data, Length); + if (const uchar *p = tsToPesTeletext.GetPes(l)) { + if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) + cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages(), patPmtParser.TotalTeletextSubtitlePages()); + tsToPesTeletext.Reset(); + } + } + } +#endif // USE_TTXTSUBS } } else if (Pid == patPmtParser.Ppid()) { diff -ruN vdr-1.7.31-ext/device.h vdr-1.7.31/device.h --- vdr-1.7.31-ext/device.h 2012-08-26 15:25:44.000000000 +0200 +++ vdr-1.7.31/device.h 2012-09-19 23:54:19.000000000 +0200 @@ -24,6 +24,10 @@ #include "spu.h" #include "thread.h" #include "tools.h" +#ifdef USE_ROTOR +#include +#include +#endif /* ROTOR */ #define MAXDEVICES 16 // the maximum number of devices in the system #define MAXPIDHANDLES 64 // the maximum number of different PIDs per device @@ -304,12 +308,18 @@ ///< Direction (only the sign of Direction is evaluated, positive values ///< switch to higher channel numbers). private: +#ifndef USE_YAEPG eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); ///< Sets the device to the given channel (general setup). +#endif /* YAEPG */ protected: virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); ///< Sets the device to the given channel (actual physical setup). public: +#ifdef USE_YAEPG + eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); + ///< Sets the device to the given channel (general setup). +#endif /* YAEPG */ static int CurrentChannel(void) { return primaryDevice ? currentChannel : 0; } ///< Returns the number of the current channel on the primary device. static void SetCurrentChannel(const cChannel *Channel) { currentChannel = Channel ? Channel->Number() : 0; } @@ -337,6 +347,9 @@ virtual bool HasProgramme(void); ///< Returns true if the device is currently showing any programme to ///< the user, either through replaying or live. +#ifdef USE_ROTOR + virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) {return false;} +#endif /* ROTOR */ // PID handle facilities @@ -579,6 +592,7 @@ cTsToPes tsToPesVideo; cTsToPes tsToPesAudio; cTsToPes tsToPesSubtitle; + cTsToPes tsToPesTeletext; bool isPlayingVideo; protected: const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } diff -ruN vdr-1.7.31-ext/dvbdevice.c vdr-1.7.31/dvbdevice.c --- vdr-1.7.31-ext/dvbdevice.c 2012-09-20 12:07:54.000000000 +0200 +++ vdr-1.7.31/dvbdevice.c 2012-09-19 23:54:19.000000000 +0200 @@ -285,6 +285,9 @@ private: static cMutex bondMutex; enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; +#ifdef USE_ROTOR + bool SendDiseqc; +#endif /* ROTOR */ int frontendType; const cDvbDevice *device; int fd_frontend; @@ -301,6 +304,9 @@ cMutex mutex; cCondVar locked; cCondVar newSet; +#ifdef USE_ROTOR + dvb_diseqc_master_cmd diseqc_cmd; +#endif /* ROTOR */ cDvbTuner *bondedTuner; bool bondedMaster; bool SetFrontendType(const cChannel *Channel); @@ -323,6 +329,9 @@ uint32_t SubsystemId(void) const { return subsystemId; } bool IsTunedTo(const cChannel *Channel) const; void SetChannel(const cChannel *Channel); +#ifdef USE_ROTOR + bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); +#endif /* ROTOR */ bool Locked(int TimeoutMs = 0); int GetSignalStrength(void) const; int GetSignalQuality(void) const; @@ -335,6 +344,9 @@ frontendType = SYS_UNDEFINED; device = Device; fd_frontend = Fd_Frontend; +#ifdef USE_ROTOR + SendDiseqc=false; +#endif /* ROTOR */ adapter = Adapter; frontend = Frontend; subsystemId = cDvbDeviceProbe::GetSubsystemId(adapter, frontend); @@ -848,6 +860,12 @@ Status = NewStatus; cMutexLock MutexLock(&mutex); int WaitTime = 1000; +#ifdef USE_ROTOR + if (SendDiseqc) { + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd)); + SendDiseqc=false; + } +#endif /* ROTOR */ switch (tunerStatus) { case tsIdle: break; @@ -898,6 +916,19 @@ } } +#ifdef USE_ROTOR +bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) +{ + cMutexLock MutexLock(&mutex); + if (SendDiseqc) + return false; + diseqc_cmd=cmd; + SendDiseqc=true; + newSet.Broadcast(); + return true; +} +#endif /* ROTOR */ + // --- cDvbSourceParam ------------------------------------------------------- class cDvbSourceParam : public cSourceParam { @@ -1442,6 +1473,16 @@ bool needsDetachReceivers = false; needsDetachBondedReceivers = false; +#ifdef USE_CHANNELBIND + if (Setup.ChannelBindingByRid && Channel->Rid()) { + if (0 == ((unsigned) Channel->Rid() & (1<<(unsigned) CardIndex())) ) { + #if 0 + printf("device %d doesn't provide channel %s", CardIndex(), *Channel->ToText()); + #endif + return false; + } + } +#endif /* CHANNELBIND */ if (dvbTuner && ProvidesTransponder(Channel)) { result = hasPriority; if (Priority > IDLEPRIORITY) { @@ -1530,6 +1571,16 @@ return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false; } +#ifdef USE_ROTOR +bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) +{ + if (ProvidesDeliverySystem(SYS_DVBS) || ProvidesDeliverySystem(SYS_DVBS2)) + return dvbTuner->SendDiseqcCmd(cmd); + else + return false; +} +#endif /* ROTOR */ + void cDvbDevice::SetTransferModeForDolbyDigital(int Mode) { setTransferModeForDolbyDigital = Mode; diff -ruN vdr-1.7.31-ext/dvbdevice.h vdr-1.7.31/dvbdevice.h --- vdr-1.7.31-ext/dvbdevice.h 2012-03-31 13:13:31.000000000 +0200 +++ vdr-1.7.31/dvbdevice.h 2012-09-19 23:54:19.000000000 +0200 @@ -193,6 +193,9 @@ virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); public: virtual bool HasLock(int TimeoutMs = 0); +#ifdef USE_ROTOR + virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); +#endif /* ROTOR */ // PID handle facilities diff -ruN vdr-1.7.31-ext/dvbplayer.c vdr-1.7.31/dvbplayer.c --- vdr-1.7.31-ext/dvbplayer.c 2012-06-09 16:37:24.000000000 +0200 +++ vdr-1.7.31/dvbplayer.c 2012-09-19 23:54:19.000000000 +0200 @@ -204,6 +204,9 @@ cNonBlockingFileReader *nonBlockingFileReader; cRingBufferFrame *ringBuffer; cPtsIndex ptsIndex; +#ifdef USE_JUMPPLAY + cMarks marks; +#endif /* JUMPPLAY */ cFileName *fileName; cIndexFile *index; cUnbufferedFile *replayFile; @@ -286,6 +289,9 @@ } else if (PauseLive) framesPerSecond = cRecording(FileName).FramesPerSecond(); // the fps rate might have changed from the default +#ifdef USE_JUMPPLAY + marks.Load(FileName, framesPerSecond, isPesRecording); +#endif /* JUMPPLAY */ } cDvbPlayer::~cDvbPlayer() @@ -364,6 +370,12 @@ if (index) { int Index = ptsIndex.FindIndex(DeviceGetSTC()); if (Index >= 0) { +#ifdef USE_JUMPPLAY + // set resume position to 0 if replay stops at the first mark + if (Setup.PlayJump && marks.First() && + abs(Index - marks.First()->Position()) <= int(round(RESUMEBACKUP * framesPerSecond))) + Index = 0; +#endif /* JUMPPLAY */ Index -= int(round(RESUMEBACKUP * framesPerSecond)); if (Index > 0) Index = index->GetNextIFrame(Index, false); @@ -390,11 +402,30 @@ { uchar *p = NULL; int pc = 0; +#ifdef USE_JUMPPLAY + bool cutIn = false; + int total = -1; +#endif /* JUMPPLAY */ readIndex = Resume(); if (readIndex >= 0) isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true, framesPerSecond)); +#ifdef USE_JUMPPLAY + if (Setup.PlayJump && readIndex <= 0 && marks.First() && index) { + int Index = marks.First()->Position(); + uint16_t FileNumber; + off_t FileOffset; + if (index->Get(Index, &FileNumber, &FileOffset) && + NextFile(FileNumber, FileOffset)) { + isyslog("PlayJump: start replay at first mark %d (%s)", + Index, *IndexToHMSF(Index, true, framesPerSecond)); + readIndex = Index; + } + } + + bool LastMarkPause = false; +#endif /* JUMPPLAY */ nonBlockingFileReader = new cNonBlockingFileReader; int Length = 0; bool Sleep = false; @@ -421,7 +452,11 @@ // Read the next frame from the file: +#ifdef USE_JUMPPLAY + if (playMode != pmStill && playMode != pmPause && !LastMarkPause) { +#else if (playMode != pmStill && playMode != pmPause) { +#endif /* JUMPPLAY */ if (!readFrame && (replayFile || readIndex >= 0)) { if (!nonBlockingFileReader->Reading()) { if (!SwitchToPlayFrame && (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))) { @@ -458,6 +493,46 @@ else if (index) { uint16_t FileNumber; off_t FileOffset; +#ifdef USE_JUMPPLAY + if (Setup.PlayJump || Setup.PauseLastMark) { + // check for end mark - jump to next mark or pause + readIndex++; + marks.Update(); + cMark *m = marks.Get(readIndex); + if (m && (m->Index() & 0x01) != 0) { + m = marks.Next(m); + int Index; + if (m) + Index = m->Position(); + else if (Setup.PauseLastMark) { + // pause at last mark + isyslog("PauseLastMark: pause at position %d (%s)", + readIndex, *IndexToHMSF(readIndex, true, framesPerSecond)); + LastMarkPause = true; + Index = -1; + } + else if (total == index->Last()) + // at last mark jump to end of recording + Index = index->Last() - 1; + else + // jump but stay off end of live-recordings + Index = index->GetNextIFrame(index->Last() - int(round(MAXSTUCKATEOF * framesPerSecond)), true); + // don't jump in edited recordings + if (Setup.PlayJump && Index > readIndex && + Index > index->GetNextIFrame(readIndex, true)) { + isyslog("PlayJump: %d frames to %d (%s)", + Index - readIndex, Index, + *IndexToHMSF(Index, true, framesPerSecond)); + readIndex = Index; + cutIn = true; + } + } + readIndex--; + } + // for detecting growing length of live-recordings + if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent) && readIndependent) + total = index->Last(); +#endif /* JUMPPLAY */ if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length) && NextFile(FileNumber, FileOffset)) readIndex++; else @@ -502,6 +577,15 @@ // Store the frame in the buffer: if (readFrame) { +#ifdef USE_JUMPPLAY + if (cutIn) { + if (isPesRecording) + cRemux::SetBrokenLink(readFrame->Data(), readFrame->Count()); + else + TsSetTeiOnBrokenPackets(readFrame->Data(), readFrame->Count()); + cutIn = false; + } +#endif /* JUMPPLAY */ if (ringBuffer->Put(readFrame)) readFrame = NULL; else @@ -567,8 +651,19 @@ p = NULL; } } +#ifdef USE_JUMPPLAY + else { + if (LastMarkPause) { + LastMarkPause = false; + playMode = pmPause; + } +#else else +#endif /* JUMPPLAY */ Sleep = true; +#ifdef USE_JUMPPLAY + } +#endif /* JUMPPLAY */ // Handle hitting begin/end of recording: diff -ruN vdr-1.7.31-ext/eit.c vdr-1.7.31/eit.c --- vdr-1.7.31-ext/eit.c 2012-08-25 13:13:00.000000000 +0200 +++ vdr-1.7.31/eit.c 2012-09-19 23:54:19.000000000 +0200 @@ -99,7 +99,87 @@ // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers. else if (Tid == TableID && pEvent->Version() == getVersionNumber()) +#ifdef USE_DDEPGENTRY + { + if(Setup.MixEpgAction == 0) continue; + + //printf("in"); + //printf("%s", pEvent->GetTimeString()); + // to use the info of the original epg, update the extern one, + // if it has less info + SI::Descriptor *d; + SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL; + //SI::ExtendedEventDescriptor *eed = NULL; + SI::ShortEventDescriptor *ShortEventDescriptor = NULL; + //SI::ShortEventDescriptor *sed = NULL; + //SI::TimeShiftedEventDescriptor *tsed = NULL; + //cLinkChannels *LinkChannels = NULL; + for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2));) + { + if(d->getDescriptorTag() == SI::ShortEventDescriptorTag) + { + int LanguagePreferenceShort = -1; + SI::ShortEventDescriptor *sed = (SI::ShortEventDescriptor *)d; + if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort) || !ShortEventDescriptor) + { + delete ShortEventDescriptor; + ShortEventDescriptor = sed; + d = NULL; // so that it is not deleted + } + } + else if(d->getDescriptorTag() == SI::ExtendedEventDescriptorTag) + { + int LanguagePreferenceExt = -1; + bool UseExtendedEventDescriptor = false; + SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d; + if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt) || !ExtendedEventDescriptors) + { + delete ExtendedEventDescriptors; + ExtendedEventDescriptors = new SI::ExtendedEventDescriptors; + UseExtendedEventDescriptor = true; + } + if (UseExtendedEventDescriptor) + { + ExtendedEventDescriptors->Add(eed); + d = NULL; // so that it is not deleted + } + if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber()) + UseExtendedEventDescriptor = false; + } + delete d; + } + if(pEvent) + { + + if(ShortEventDescriptor) + { + char buffer[256]; + if(ShortEventDescriptor->text.getText(buffer, sizeof(buffer)) && pEvent->ShortText() && (strlen(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))) > strlen(pEvent->ShortText()))) + { + pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))); + pEvent->FixEpgBugs(); + } + } + if(ExtendedEventDescriptors) + { + char buffer[ExtendedEventDescriptors->getMaximumTextLength(": ") + 1]; + //pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); + + if(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ") && pEvent->Description() && (strlen(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")) > strlen(pEvent->Description()))) + { + pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); + pEvent->FixEpgBugs(); + } + } + } + delete ExtendedEventDescriptors; + delete ShortEventDescriptor; + continue; + } +#else + continue; +#endif /* DDEPGENTRY */ EpgHandlers.SetEventID(pEvent, SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-( EpgHandlers.SetStartTime(pEvent, StartTime); EpgHandlers.SetDuration(pEvent, Duration); @@ -107,7 +187,11 @@ if (pEvent->TableID() > 0x4E) // for backwards compatibility, table ids less than 0x4E are never overwritten pEvent->SetTableID(Tid); if (Tid == 0x4E) { // we trust only the present/following info on the actual TS +#ifdef USE_DDEPGENTRY + if (Setup.DisableVPS == 0 && SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) +#else if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) +#endif /* DDEPGENTRY */ pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), channel); } if (OnlyRunningStatus) { @@ -294,8 +378,85 @@ channel->SetLinkChannels(LinkChannels); Modified = true; EpgHandlers.HandleEvent(pEvent); + if (handledExternally) delete pEvent; + +#ifdef USE_DDEPGENTRY + //to avoid double epg-entrys from ext and int epg sources :EW + if (pEvent && pEvent->TableID() != 0x00) + { + cEvent *pPreviousEvent = (cEvent *)pSchedule->GetPreviousEvent(pEvent); + + if (pPreviousEvent) + { + if(Setup.DoubleEpgAction == 0) + { + pPreviousEvent->SetStartTime(pEvent->StartTime()); + pPreviousEvent->SetDuration(pEvent->Duration()); + + if(Setup.DisableVPS == 0) + { + if(channel) + pPreviousEvent->SetRunningStatus(pEvent->RunningStatus(), channel); + else + pPreviousEvent->SetRunningStatus(pEvent->RunningStatus()); + } + + // to use the info of the original epg, update the extern one, + // if it has less info + char buffer_short_intern[256]; + char buffer_short_extern[256]; + int len_short_intern = 0; + int len_short_extern = 0; + + if (pEvent->ShortText()) + len_short_intern = snprintf (buffer_short_intern, sizeof(buffer_short_intern), "%s", pEvent->ShortText()); + + if (pPreviousEvent->ShortText()) + len_short_extern = snprintf (buffer_short_extern, sizeof(buffer_short_extern), "%s",pPreviousEvent->ShortText()); + + if(len_short_intern > 0) + { + if(len_short_extern < 1) + pPreviousEvent->SetShortText(buffer_short_intern); + else if (len_short_intern > len_short_extern) + pPreviousEvent->SetShortText(buffer_short_intern); + } + + if(pEvent->Description()) + { + char buffer_title_intern[4096]; + char buffer_title_extern[4096]; + int len_title_intern = 0; + int len_title_extern = 0; + + if (pEvent->Description()) + len_title_intern = snprintf (buffer_title_intern, sizeof(buffer_title_intern), "%s", pEvent->Description()); + + if (pPreviousEvent->Description()) + len_title_extern = snprintf (buffer_title_extern, sizeof(buffer_title_extern), "%s", pPreviousEvent->Description()); + + if(len_title_intern > 0) + { + if(len_title_extern < 1) + pPreviousEvent->SetDescription(buffer_title_intern); + else if (len_title_intern > len_title_extern) + pPreviousEvent->SetDescription(buffer_title_intern); + } + } + + if(pPreviousEvent->Vps() == 0 && pEvent->Vps() != 0) + pPreviousEvent->SetVps(pEvent->Vps()); + + pSchedule->DelEvent(pEvent); + pPreviousEvent->FixEpgBugs(); + } + else + pSchedule->DelEvent(pPreviousEvent); + } + } +#endif /* DDEPGENTRY */ } if (Tid == 0x4E) { if (Empty && getSectionNumber() == 0) diff -ruN vdr-1.7.31-ext/epg.c vdr-1.7.31/epg.c --- vdr-1.7.31-ext/epg.c 2012-09-29 16:29:49.000000000 +0200 +++ vdr-1.7.31/epg.c 2012-09-19 23:54:19.000000000 +0200 @@ -972,6 +972,31 @@ return pe; } +#ifdef USE_DDEPGENTRY +const cEvent *cSchedule::GetPreviousEvent(cEvent *Event) const +{ + + if(!Event || Event->Duration() == 0 || Event->StartTime() == 0) + return NULL; + // Returns either the event info to the previous/following event to the given EventID or, if that one can't be found NULL :EW + cEvent *pt = NULL; + int epgTimeDelta = Setup.DoubleEpgTimeDelta * 60 + 1; + for (pt = events.First(); pt; pt = events.Next(pt)) + if(pt && pt->TableID() == 0x00) + if ((Event->StartTime() - pt->StartTime()) > - epgTimeDelta && (Event->StartTime() - pt->StartTime()) < epgTimeDelta) + { + if((pt->Duration() + (pt->Duration()/ 5) + 1) > Event->Duration() && (pt->Duration() - (pt->Duration()/ 5) - 1) < Event->Duration()) + return pt; + else if (pt->Title() && Event->Title() && (strcmp(pt->Title(), ".") != 0 && strcmp(Event->Title(), ".") != 0)) + { + if (strstr(pt->Title(), Event->Title()) != NULL || strstr(Event->Title(), pt->Title()) != NULL) + return pt; + } + } + return NULL; +} +#endif /* DDEPGENTRY */ + void cSchedule::SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel) { hasRunning = false; diff -ruN vdr-1.7.31-ext/epg.h vdr-1.7.31/epg.h --- vdr-1.7.31-ext/epg.h 2012-09-24 14:53:53.000000000 +0200 +++ vdr-1.7.31/epg.h 2012-09-19 23:54:19.000000000 +0200 @@ -164,6 +164,9 @@ void DropOutdated(time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); void Cleanup(time_t Time); void Cleanup(void); +#ifdef USE_DDEPGENTRY + const cEvent *GetPreviousEvent(cEvent *Event) const; //:EW +#endif /* DDEPGENTRY */ cEvent *AddEvent(cEvent *Event); void DelEvent(cEvent *Event); void HashEvent(cEvent *Event); diff -ruN vdr-1.7.31-ext/filetransfer.c vdr-1.7.31/filetransfer.c --- vdr-1.7.31-ext/filetransfer.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/filetransfer.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,280 @@ +#ifdef USE_LIEMIKUUTIO +/* + * filetransfer.c: The video file transfer facilities + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: $ + */ + +#include "videodir.h" +#include "filetransfer.h" + +static cString StripLastDirectory(const char *DirName) +{ + if (DirName && *DirName) { + cString s(DirName); + int l = strlen(*s); + const char *p = *s + l; + while (l > 0) { + if (*p-- == '/') + break; + l--; + } + if (l) + s = s.Truncate(l); + return s; + } + return NULL; +} + +// --- cCopyingThread -------------------------------------------------------- + +class cCopyingThread : public cThread { +private: + const char *error; + bool deleteSource; + cString source; + cString target; +protected: + virtual void Action(void); +public: + cCopyingThread(const char *SourceName, const char *ToFileName, bool DeleteSource = false); + virtual ~cCopyingThread(); + const char *Error(void) { return error; } + }; + +cCopyingThread::cCopyingThread(const char *SourceName, const char *TargetName, bool DeleteSource) +:cThread("copying"), + error(NULL), + deleteSource(DeleteSource), + source(SourceName), + target(TargetName) +{ + // add missing directory delimiters + const char *delim = "/"; + if (!endswith(*source, delim)) + source = cString::sprintf("%s%s", *source, delim); + if (!endswith(*target, delim)) + target = cString::sprintf("%s%s", *target, delim); + + Start(); +} + +cCopyingThread::~cCopyingThread() +{ + Cancel(3); +} + +void cCopyingThread::Action(void) +{ + SetPriority(19); + SetIOPriority(7); + + if (strcmp(*source, *target)) { + // validate target directory + if (strstr(*target, *source)) { + error = "invalid target"; + return; + } + + // recordings methods require the last directory delimiter to be stripped off + cString recname = target; + recname.Truncate(strlen(*recname) - 1); + Recordings.AddByName(*recname, false); + + RemoveFileOrDir(*target); + if (!MakeDirs(*target, true)) { + error = "MakeDirs"; + return; + } + + if (deleteSource && EntriesOnSameFileSystem(*source, *target)) { + if (rename(*source, *target) == -1) { + error = "rename"; + return; + } + // delete all empty source directories + recname = source; + recname.Truncate(strlen(*recname) - 1); + recname = StripLastDirectory(*recname); + do { + if (!RemoveEmptyDirectories(*recname, true)) + break; + recname = StripLastDirectory(*recname); + } + while (strcmp(*recname, VideoDirectory)); + } + else { + int required = DirSizeMB(*source); + int available = FreeDiskSpaceMB(*target); + + // validate free space + if (required < available) { + cReadDir d(*source); + struct dirent *e; + bool success = true; + + // allocate copying buffer + const int len = 1024 * 1024; + char *buffer = MALLOC(char, len); + if (!buffer) { + error = "MALLOC"; + return; + } + + // loop through all files, but skip all sub-directories + while (Running() && (e = d.Next()) != NULL) { + // skip generic entries + if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) { + cString sourceFile = cString::sprintf("%s%s", *source, e->d_name); + cString targetFile = cString::sprintf("%s%s", *target, e->d_name); + + // copy only regular files + struct stat sts; + if (!stat(*sourceFile, &sts) && S_ISREG(sts.st_mode)) { + int r = -1, w = -1; + cUnbufferedFile *inputFile = cUnbufferedFile::Create(*sourceFile, O_RDONLY | O_LARGEFILE); + cUnbufferedFile *outputFile = cUnbufferedFile::Create(*targetFile, O_RDWR | O_CREAT | O_LARGEFILE); + + // validate files + if (!inputFile || !outputFile) { + success = false; + break; + } + + // do actual copy + do { + r = inputFile->Read(buffer, len); + if (r > 0) + w = outputFile->Write(buffer, r); + else + w = 0; + } while (Running() && r > 0 && w > 0); + DELETENULL(inputFile); + DELETENULL(outputFile); + + // validate result + if (!Running() || r < 0 || w < 0) { + success = false; + break; + } + } + } + } + + // release allocated buffer + free(buffer); + + // delete all created target files and directories + if (!success) { + target = StripLastDirectory(*target); + RemoveFileOrDir(*target, true); + target = StripLastDirectory(*target); + RemoveEmptyDirectories(*target, true); + error = "copy failed"; + return; + } + } + else { + // delete all created empty target directories + recname = target; + recname.Truncate(strlen(*recname) - 1); + recname = StripLastDirectory(*recname); + do { + if (!RemoveEmptyDirectories(*recname, true)) + break; + recname = StripLastDirectory(*recname); + } + while (strcmp(*recname, VideoDirectory)); + error = "insufficient free space"; + return; + } + } + + if (deleteSource) { + // Recordings' methods require the last directory delimiter to be stripped off + source.Truncate(strlen(*source) - 1); + cRecording *recording = Recordings.GetByName(*source); + if (recording->Delete()) + Recordings.DelByName(*source, false); + } + else + Recordings.TouchUpdate(); + } +} + +// --- cFileTransfer ---------------------------------------------------------------- + +cMutex cFileTransfer::mutex; +char *cFileTransfer::copiedVersionName = NULL; +cCopyingThread *cFileTransfer::copyingThread = NULL; +bool cFileTransfer::error = false; +bool cFileTransfer::ended = false; + +bool cFileTransfer::Start(cRecording *Recording, const char *FileName, bool CopyOnly) +{ + cMutexLock MutexLock(&mutex); + if (!copyingThread) { + cString NewName = NewVideoFileName(Recording->FileName(), FileName); + error = false; + ended = false; + if (strlen(*NewName)) { + copiedVersionName = strdup(*NewName); + copyingThread = new cCopyingThread(Recording->FileName(), copiedVersionName, !CopyOnly); + return true; + } + } + return false; +} + +void cFileTransfer::Stop(void) +{ + cMutexLock MutexLock(&mutex); + bool Interrupted = copyingThread && copyingThread->Active(); + const char *Error = copyingThread ? copyingThread->Error() : NULL; + DELETENULL(copyingThread); + if ((Interrupted || Error)) { + if (Interrupted) + isyslog("file transfer has been interrupted"); + if (Error) + esyslog("ERROR: '%s' during file transfer", Error); + RemoveVideoFile(copiedVersionName); //XXX what if this file is currently being replayed? + Recordings.DelByName(copiedVersionName); + free(copiedVersionName); + copiedVersionName = NULL; + } +} + +bool cFileTransfer::Active(void) +{ + cMutexLock MutexLock(&mutex); + if (copyingThread) { + if (copyingThread->Active()) + return true; + error = copyingThread->Error(); + Stop(); + free(copiedVersionName); + copiedVersionName = NULL; + ended = true; + } + return false; +} + +bool cFileTransfer::Error(void) +{ + cMutexLock MutexLock(&mutex); + bool result = error; + error = false; + return result; +} + +bool cFileTransfer::Ended(void) +{ + cMutexLock MutexLock(&mutex); + bool result = ended; + ended = false; + return result; +} +#endif /* LIEMIKUUTIO */ diff -ruN vdr-1.7.31-ext/filetransfer.h vdr-1.7.31/filetransfer.h --- vdr-1.7.31-ext/filetransfer.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/filetransfer.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,35 @@ +#ifdef USE_LIEMIKUUTIO +/* + * filetransfer.h: The video file transfer facilities + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: $ + */ + +#ifndef __FILETRANSFER_H +#define __FILETRANSFER_H + +#include "recording.h" +#include "thread.h" + +class cCopyingThread; + +class cFileTransfer { +private: + static cMutex mutex; + static char *copiedVersionName; + static cCopyingThread *copyingThread; + static bool error; + static bool ended; +public: + static bool Start(cRecording *Recording, const char *NewName, bool CopyOnly = false); + static void Stop(void); + static bool Active(void); + static bool Error(void); + static bool Ended(void); + }; + +#endif //__FILETRANSFER_H +#endif /* LIEMIKUUTIO */ diff -ruN vdr-1.7.31-ext/HISTORY-liemikuutio vdr-1.7.31/HISTORY-liemikuutio --- vdr-1.7.31-ext/HISTORY-liemikuutio 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/HISTORY-liemikuutio 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,165 @@ +----------------------------------- +Liemikuutio for Video Disc Recorder + +Maintainer: Rolf Ahrenberg +----------------------------------- + +2006-01-08: Version 1.0 + +- Based on enAIO with these original patches: + Simple recordings sorting by Walter@VDRPortal + Alternate rename recordings by Ralf MÃŒller + Menu selection by Peter Dittmann + Recording length by Tobias Faust + +2006-01-15: Version 1.1 + +- Removed patches already found in vdr-1.3.39. + +2006-01-25: Version 1.2 + +- Added "Main menu command position" feature. + +2006-02-05: Version 1.3 + +- Improved menu selection response. + +2006-04-18: Version 1.4 + +- Added Estonian translation (Thanks to Arthur Konovalov). + +2006-04-30: Version 1.5 + +- Added progress bar view into "What's on now?" menu. + +2006-06-06: Version 1.6 + +- Added French translation (Thanks to ECLiPSE). + +2006-06-14: Version 1.7 + +- Fixed RENR crash. + +2006-07-14: Version 1.8 + +- Fixed RENR/OSD bug. + +2006-08-27: Version 1.9 + +- Some modifications to the recording length and rename recordings + patches (Thanks to Firefly). +- Added k1_k3_jumps_20s patch by Petri Hintukainen. + +2006-08-29: Version 1.10 + +- The cRecording:Title() method now defaults to original formatting. + +2006-09-04: Version 1.11 + +- Removed unused variable from cRecording::Title() method (Thanks to + C.Y.M.). +- Some modifications to the rename recordings patch (Thanks to Firefly). + +2006-09-13: Version 1.12 + +- More modifications to the rename recordings patch (Thanks to Firefly). + +2006-10-01: Version 1.13 + +- Removed unnecessary syslog printing (Thanks to Firefly). + +2007-08-14: Version 1.14 + +- Updated for vdr-1.5.7. + +2007-10-16: Version 1.15 + +- Added recmenu play patch (Thanks to Ville Skyttä). +- Updated French translation (Thanks to ECLiPSE). + +2007-11-04: Version 1.16 + +- Updated for vdr-1.5.11. + +2007-12-08: Version 1.17 + +- Added binary skip patch. +- Removed k1_k3_jumps_20s patch. + +2008-02-17: Version 1.18 + +- Updated for vdr-1.5.15. + +2008-03-02: Version 1.19 + +- Modified binary skip to use kPrev and kNext keys and the skip is now + always shortened after a direction change (Thanks to Timo Eskola). +- Readded k1_k3_jumps_20s patch. + +2008-04-04: Version 1.20 + +- Added bitrate information into rename menu. +- Readded the path editing support of rename recordings patch (Thanks + to Firefly). + +2008-05-08: Version 1.21 + +- Fixed rename recordings (Thanks to Firefly). +- Added a DVB subtitles hack for old recordings (Thanks to Anssi Hannula). + +2009-01-08: Version 1.22 + +- Updated for vdr-1.7.3. + +2009-01-25: Version 1.23 + +- Updated for vdr-1.7.4. + +2009-02-27: Version 1.24 + +- Fixed compilation under gcc-4.4. + +2009-04-05: Version 1.25 + +- Fixed the length detection of recordings (Thanks to Thomas Günther). + +2009-04-17: Version 1.26 + +- Fixed the length detection of audio recordings (Thanks to Thomas Günther). + +2009-04-26: Version 1.27 + +- Fixed the length detection of empty recordings (Thanks to Thomas Günther). + +2009-07-12: Version 1.28 + +- Fixed the TS/PES detection of recording marks. + +2009-11-23: Version 1.29 + +- Updated Estonian translation (Thanks to Arthur Konovalov). + +2010-02-01: Version 1.30 + +- Updated for vdr-1.7.12. + +2011-09-04: Version 1.31 + +- Updated for vdr-1.7.21. +- Removed progress bar view form "What's on now?" menu. +- Removed "Main menu command position" and recordings length/sorting features. +- Changed renaming functionality to support different filesystems and binded it to key '0'. + +2011-10-19: Version 1.32 + +- Refactored renaming functionality to support both background moving and copying. +- Removed main menu command position changes completely. + +2011-11-16: Version 1.33 + +- Updated the filetransfer patch. + +2012-03-03: Version 1.34 + +- Updated the filetransfer patch. +- Removed the DVB subtitles hack for old recordings. diff -ruN vdr-1.7.31-ext/iconpatch.c vdr-1.7.31/iconpatch.c --- vdr-1.7.31-ext/iconpatch.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/iconpatch.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,31 @@ +#ifdef USE_WAREAGLEICON + +#include "iconpatch.h" + +#include +#include +#include +#include +#include + +bool IsLangUtf8(void) +{ + char *CodeSet = NULL; + if (setlocale(LC_CTYPE, "")) + CodeSet = nl_langinfo(CODESET); + else { + char *LangEnv = getenv("LANG"); // last resort in case locale stuff isn't installed + if (LangEnv) { + CodeSet = strchr(LangEnv, '.'); + if (CodeSet) + CodeSet++; // skip the dot + } + } + + if (CodeSet && strcasestr(CodeSet, "UTF-8") != 0) + return true; + + return false; +} + +#endif /* WAREAGLEICON */ diff -ruN vdr-1.7.31-ext/iconpatch.h vdr-1.7.31/iconpatch.h --- vdr-1.7.31-ext/iconpatch.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/iconpatch.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,58 @@ +#ifdef USE_WAREAGLEICON + +#define ICON_NUMBERSIGN "\x23" +#define ICON_ASTERISK "\x2A" +#define ICON_GREATER "\x3E" +#define ICON_EXCLAM "\x21" +#define ICON_PLUSMINUS "\xB1" + +#define ICON_RESUME "\x80" +#define ICON_DVD "\x81" +#define ICON_FOLDER "\x82" +#define ICON_BLANK "\x83" +#define ICON_CUTTING "\x84" +#define ICON_MOVE_FILE "\x85" +#define ICON_MOVE_FOLDER "\x86" +#define ICON_BAR_START "\x87" +#define ICON_BAR_FILLED "\x88" +#define ICON_BAR_CLEAR "\x89" +#define ICON_BAR_END "\x8A" +#define ICON_REC "\x8B" +#define ICON_CLOCK "\x8C" +#define ICON_TV_CRYPTED "\x8D" +#define ICON_RADIO "\x8E" +#define ICON_TV "\x8F" +#define ICON_NEW "\x90" +#define ICON_ARROW "\x91" +#define ICON_RUNNING "\x92" +#define ICON_VPS "\x93" +#define ICON_CLOCK_UH "\x94" +#define ICON_CLOCK_LH "\x95" + +// UTF-8 Icons +#define ICON_RESUME_UTF8 "\uE000" +#define ICON_DVD_UTF8 "\uE001" +#define ICON_FOLDER_UTF8 "\uE002" +#define ICON_BLANK_UTF8 "\uE003" +#define ICON_CUTTING_UTF8 "\uE004" +#define ICON_MOVE_FILE_UTF8 "\uE005" +#define ICON_MOVE_FOLDER_UTF8 "\uE006" +#define ICON_BAR_START_UTF8 "\uE007" +#define ICON_BAR_FILLED_UTF8 "\uE008" +#define ICON_BAR_EMPTY_UTF8 "\uE009" +#define ICON_BAR_CLOSE_UTF8 "\uE00A" +#define ICON_REC_UTF8 "\uE00B" +#define ICON_CLOCK_UTF8 "\uE00C" +#define ICON_TV_CRYPTED_UTF8 "\uE00D" +#define ICON_RADIO_UTF8 "\uE00E" +#define ICON_TV_UTF8 "\uE00F" +#define ICON_NEW_UTF8 "\uE010" +#define ICON_ARROW_UTF8 "\uE011" +#define ICON_RUNNING_UTF8 "\uE012" +#define ICON_VPS_UTF8 "\uE013" +#define ICON_CLOCK_UH_UTF8 "\uE014" +#define ICON_CLOCK_LH_UTF8 "\uE015" + +bool IsLangUtf8(void); + +#endif /* WAREAGLEICON */ diff -ruN vdr-1.7.31-ext/lirc.c vdr-1.7.31/lirc.c --- vdr-1.7.31-ext/lirc.c 2011-03-08 16:35:13.000000000 +0100 +++ vdr-1.7.31/lirc.c 2012-09-19 23:54:19.000000000 +0200 @@ -12,6 +12,10 @@ #include "lirc.h" #include #include +#ifdef USE_LIRCSETTINGS +#include "config.h" +#endif /* LIRCSETTINGS */ + #define REPEATDELAY 350 // ms #define REPEATFREQ 100 // ms @@ -95,7 +99,11 @@ continue; } if (count == 0) { +#ifdef USE_LIRCSETTINGS + if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) +#else if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < REPEATDELAY) +#endif /* LIRCSETTINGS */ continue; // skip keys coming in too fast if (repeat) Put(LastKeyName, false, true); @@ -105,18 +113,34 @@ timeout = -1; } else { +#ifdef USE_LIRCSETTINGS + if (LastTime.Elapsed() < (unsigned int)Setup.LircRepeatFreq) +#else if (LastTime.Elapsed() < REPEATFREQ) +#endif /* LIRCSETTINGS */ continue; // repeat function kicks in after a short delay (after last key instead of first key) +#ifdef USE_LIRCSETTINGS + if (FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) +#else if (FirstTime.Elapsed() < REPEATDELAY) +#endif /* LIRCSETTINGS */ continue; // skip keys coming in too fast (for count != 0 as well) repeat = true; +#ifdef USE_LIRCSETTINGS + timeout = Setup.LircRepeatDelay; +#else timeout = REPEATDELAY; +#endif /* LIRCSETTINGS */ } LastTime.Set(); Put(KeyName, repeat); } else if (repeat) { // the last one was a repeat, so let's generate a release +#ifdef USE_LIRCSETTINGS + if (LastTime.Elapsed() >= (unsigned int)Setup.LircRepeatTimeout) { +#else if (LastTime.Elapsed() >= REPEATTIMEOUT) { +#endif /* LIRCSETTINGS */ Put(LastKeyName, false, true); repeat = false; *LastKeyName = 0; diff -ruN vdr-1.7.31-ext/mainmenuitemsprovider.h vdr-1.7.31/mainmenuitemsprovider.h --- vdr-1.7.31-ext/mainmenuitemsprovider.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/mainmenuitemsprovider.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,62 @@ +#ifdef USE_MENUORG +/* + * vdr-menuorg - A plugin for the Linux Video Disk Recorder + * Copyright (c) 2007 - 2008 Tobias Grimm + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $Id$ + * + */ + +#ifndef __MAINMENUITEMSPROVIDER_H +#define __MAINMENUITEMSPROVIDER_H + +#include + +class cOsdItem; +class cOsdMenu; + +class IMenuItemDefinition +{ + public: + virtual ~IMenuItemDefinition() {}; + virtual bool IsCustomOsdItem() = 0; + virtual bool IsPluginItem() = 0; + virtual bool IsSeparatorItem() = 0; + virtual cOsdItem* CustomOsdItem() = 0; + virtual const char* PluginMenuEntry() = 0; + virtual bool IsSelected() = 0; + virtual int PluginIndex() = 0; +}; + +typedef std::vector MenuItemDefinitions; + +#define MENU_ITEMS_PROVIDER_SERVICE_ID "MenuOrgPatch-v0.4.2::MainMenuItemsProvider" + +class IMainMenuItemsProvider +{ + public: + virtual ~IMainMenuItemsProvider() {}; + virtual bool IsCustomMenuAvailable() = 0; + virtual MenuItemDefinitions* MainMenuItems() = 0; + virtual void EnterRootMenu() = 0; + virtual void EnterSubMenu(cOsdItem* item) = 0; + virtual bool LeaveSubMenu() = 0; + virtual cOsdMenu* Execute(cOsdItem* item) = 0; +}; + +#endif //__MAINMENUITEMSPROVIDER_H +#endif /* MENUORG */ diff -ruN vdr-1.7.31-ext/Make.config.template vdr-1.7.31/Make.config.template --- vdr-1.7.31-ext/Make.config.template 2012-09-01 12:31:33.000000000 +0200 +++ vdr-1.7.31/Make.config.template 2012-09-19 23:54:19.000000000 +0200 @@ -52,8 +52,127 @@ ## Define if you want vdr to not run as root #VDR_USER = vdr +### VDR-Extensions: + +#ALTERNATECHANNEL = 1 +#CHANNELBIND = 1 +#CUTTERLIMIT = 1 +#DDEPGENTRY = 1 +#DVLVIDPREFER = 1 +#GRAPHTFT = 1 +#HARDLINKCUTTER = 1 +#JUMPINGSECONDS = 1 +#JUMPPLAY = 1 +#LIEMIKUUTIO = 1 +#LIRCSETTINGS = 1 +#MAINMENUHOOKS = 1 +#MENUORG = 1 +#NALUDUMP = 1 +#PINPLUGIN = 1 +#PLUGINMISSING = 1 +#ROTOR = 1 +#SETUP = 1 +#TIMERINFO = 1 +#TTXTSUBS = 1 +#VOLCTRL = 1 +#WAREAGLEICON = 1 +#YAEPG = 1 + ### You don't need to touch the following: ifdef DVBDIR INCLUDES += -I$(DVBDIR)/include endif + +ifdef ALTERNATECHANNEL +DEFINES += -DUSE_ALTERNATECHANNEL +endif + +ifdef CHANNELBIND +DEFINES += -DUSE_CHANNELBIND +endif + +ifdef CUTTERLIMIT +DEFINES += -DUSE_CUTTERLIMIT +endif + +ifdef DDEPGENTRY +DEFINES += -DUSE_DDEPGENTRY +endif + +ifdef DVLVIDPREFER +DEFINES += -DUSE_DVLVIDPREFER +endif + +ifdef GRAPHTFT +DEFINES += -DUSE_GRAPHTFT +endif + +ifdef HARDLINKCUTTER +DEFINES += -DUSE_HARDLINKCUTTER +endif + +ifdef JUMPINGSECONDS +DEFINES += -DUSE_JUMPINGSECONDS +endif + +ifdef JUMPPLAY +DEFINES += -DUSE_JUMPPLAY +endif + +ifdef LIRCSETTINGS +DEFINES += -DUSE_LIRCSETTINGS +endif + +ifdef LIEMIKUUTIO +DEFINES += -DUSE_LIEMIKUUTIO +endif + +ifdef MAINMENUHOOKS +DEFINES += -DUSE_MAINMENUHOOKS +endif + +ifdef MENUORG +DEFINES += -DUSE_MENUORG +endif + +ifdef NALUDUMP +DEFINES += -DUSE_NALUDUMP +endif + +ifdef PINPLUGIN +DEFINES += -DUSE_PINPLUGIN +endif + +ifdef PLUGINMISSING +DEFINES += -DUSE_PLUGINMISSING +endif + +ifdef ROTOR +DEFINES += -DUSE_ROTOR +endif + +ifdef SETUP +DEFINES += -DUSE_SETUP +endif + +ifdef TIMERINFO +DEFINES += -DUSE_TIMERINFO +endif + +ifdef TTXTSUBS +DEFINES += -DUSE_TTXTSUBS +endif + +ifdef VOLCTRL +DEFINES += -DUSE_VOLCTRL +endif + +ifdef WAREAGLEICON +DEFINES += -DUSE_WAREAGLEICON +endif + +ifdef YAEPG +DEFINES += -DUSE_YAEPG +endif + diff -ruN vdr-1.7.31-ext/Makefile vdr-1.7.31/Makefile --- vdr-1.7.31-ext/Makefile 2012-09-07 16:11:37.000000000 +0200 +++ vdr-1.7.31/Makefile 2012-09-19 23:54:19.000000000 +0200 @@ -48,6 +48,23 @@ skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ timers.o tools.o transfer.o vdr.o videodir.o +ifdef LIEMIKUUTIO +OBJS += filetransfer.o +endif + +ifdef SETUP +OBJS += tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o submenu.o + +endif + +ifdef WAREAGLEICON +OBJS += iconpatch.o +endif + +ifdef TTXTSUBS +OBJS += vdrttxtsubshooks.o +endif + ifndef NO_KBD DEFINES += -DREMOTE_KBD endif diff -ruN vdr-1.7.31-ext/MANUAL vdr-1.7.31/MANUAL --- vdr-1.7.31-ext/MANUAL 2012-09-15 15:50:06.000000000 +0200 +++ vdr-1.7.31/MANUAL 2012-09-19 23:54:19.000000000 +0200 @@ -751,6 +751,9 @@ background transparency. By default the values as broadcast are used. + Record Teletext Subtitles = no + If set to 'yes', teletext subtitles will be recorded. + LNB: Use DiSEqC = no Generally turns DiSEqC support on or off. diff -ruN vdr-1.7.31-ext/menu.c vdr-1.7.31/menu.c --- vdr-1.7.31-ext/menu.c 2012-09-15 13:45:28.000000000 +0200 +++ vdr-1.7.31/menu.c 2012-09-19 23:54:19.000000000 +0200 @@ -8,6 +8,9 @@ */ #include "menu.h" +#ifdef USE_WAREAGLEICON +#include "iconpatch.h" +#endif /* WAREAGLEICON */ #include #include #include @@ -18,6 +21,9 @@ #include "config.h" #include "cutter.h" #include "eitscan.h" +#ifdef USE_LIEMIKUUTIO +#include "filetransfer.h" +#endif /* LIEMIKUUTIO */ #include "i18n.h" #include "interface.h" #include "plugin.h" @@ -31,6 +37,9 @@ #include "timers.h" #include "transfer.h" #include "videodir.h" +#ifdef USE_MENUORG +#include "menuorgpatch.h" +#endif /* MENUORG */ #define MAXWAIT4EPGINFO 3 // seconds #define MODETIMEOUT 3 // seconds @@ -51,6 +60,8 @@ #define CHNUMWIDTH (numdigits(Channels.MaxNumber()) + 1) #define CHNAMWIDTH (min(MAXCHNAMWIDTH, Channels.MaxShortChannelNameLength() + 1)) +#define MB_PER_MINUTE 25.75 // this is just an estimate! + // --- cMenuEditCaItem ------------------------------------------------------- class cMenuEditCaItem : public cMenuEditIntItem { @@ -167,6 +178,9 @@ public: cMenuEditChannel(cChannel *Channel, bool New = false); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuEditChannel"; } +#endif /* GRAPHTFT */ }; cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New) @@ -215,6 +229,9 @@ Add(new cMenuEditIntItem( tr("Tid"), &data.tid, 0)); Add(new cMenuEditIntItem( tr("Rid"), &data.rid, 0)); XXX*/ +#ifdef USE_CHANNELBIND + Add(new cMenuEditIntItem( tr("Rid"), &data.rid, 0)); // channel binding patch +#endif /* CHANNELBIND */ // Parameters for specific types of sources: sourceParam = SourceParams.Get(**cSource::ToString(data.source)); if (sourceParam) { @@ -315,6 +332,16 @@ if (!channel->GroupSep()) { if (sortMode == csmProvider) buffer = cString::sprintf("%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name()); +#ifdef USE_WAREAGLEICON + else if (Setup.WarEagleIcons) { + if (channel->Vpid() == 1 || channel->Vpid() == 0) + buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_RADIO_UTF8 : ICON_RADIO, channel->Name()); + else if (channel->Ca() == 0) + buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_UTF8 : ICON_TV, channel->Name()); + else + buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_CRYPTED_UTF8 : ICON_TV_CRYPTED, channel->Name()); + } +#endif /* WAREAGLEICON */ else buffer = cString::sprintf("%d\t%s", channel->Number(), channel->Name()); } @@ -345,6 +372,9 @@ cMenuChannels(void); ~cMenuChannels(); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuChannels"; } +#endif /* GRAPHTFT */ }; cMenuChannels::cMenuChannels(void) @@ -889,6 +919,17 @@ Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME)); +#ifdef USE_PINPLUGIN + if (cOsd::pinValid || !data.fskProtection) Add(new cMenuEditBoolItem(tr("Childlock"),&data.fskProtection)); + else { + char* buf = 0; + if (asprintf(&buf, "%s\t%s", tr("Childlock"), data.fskProtection ? tr("yes") : tr("no")) > 0) { + Add(new cOsdItem(buf)); + free(buf); + } + } + +#endif /* PINPLUGIN */ Add(file = new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file))); SetFirstDayItem(); } @@ -996,8 +1037,14 @@ class cMenuTimerItem : public cOsdItem { private: cTimer *timer; +#ifdef USE_TIMERINFO + char diskStatus; +#endif /* TIMERINFO */ public: cMenuTimerItem(cTimer *Timer); +#ifdef USE_TIMERINFO + void SetDiskStatus(char DiskStatus); +#endif /* TIMERINFO */ virtual int Compare(const cListObject &ListObject) const; virtual void Set(void); cTimer *Timer(void) { return timer; } @@ -1006,6 +1053,9 @@ cMenuTimerItem::cMenuTimerItem(cTimer *Timer) { timer = Timer; +#ifdef USE_TIMERINFO + diskStatus = ' '; +#endif /* TIMERINFO */ Set(); } @@ -1036,8 +1086,30 @@ File++; else File = timer->File(); +#ifdef USE_TIMERINFO +#ifdef USE_WAREAGLEICON + cCharSetConv csc("ISO-8859-1", cCharSetConv::SystemCharacterTable()); + char diskStatusString[2] = { diskStatus, 0 }; + SetText(cString::sprintf("%s%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", + csc.Convert(diskStatusString), +#else + cCharSetConv csc("ISO-8859-1", cCharSetConv::SystemCharacterTable()); + char diskStatusString[2] = { diskStatus, 0 }; + SetText(cString::sprintf("%s%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", + csc.Convert(diskStatusString), +#endif /* WAREAGLEICON */ +#else +#ifdef USE_WAREAGLEICON + SetText(cString::sprintf("%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", +#else SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", +#endif /* WAREAGLEICON */ +#endif /* TIMERINFO */ +#ifdef USE_WAREAGLEICON + !(timer->HasFlags(tfActive)) ? " " : timer->FirstDay() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_ARROW_UTF8 : ICON_ARROW : "!" : timer->Recording() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_REC_UTF8 : ICON_REC : "#" : Setup.WarEagleIcons ? IsLangUtf8() ? ICON_CLOCK_UTF8 : ICON_CLOCK : ">", +#else !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>', +#endif /* WAREAGLEICON */ timer->Channel()->Number(), *name, *name && **name ? " " : "", @@ -1049,6 +1121,58 @@ File)); } +#ifdef USE_TIMERINFO +void cMenuTimerItem::SetDiskStatus(char DiskStatus) +{ + diskStatus = DiskStatus; + Set(); +} + +// --- cTimerEntry ----------------------------------------------------------- + +class cTimerEntry : public cListObject { +private: + cMenuTimerItem *item; + const cTimer *timer; + time_t start; +public: + cTimerEntry(cMenuTimerItem *item) : item(item), timer(item->Timer()), start(timer->StartTime()) {} + cTimerEntry(const cTimer *timer, time_t start) : item(NULL), timer(timer), start(start) {} + virtual int Compare(const cListObject &ListObject) const; + bool active(void) const { return timer->HasFlags(tfActive); } + time_t startTime(void) const { return start; } + int priority(void) const { return timer->Priority(); } + int duration(void) const; + bool repTimer(void) const { return !timer->IsSingleEvent(); } + bool isDummy(void) const { return item == NULL; } + const cTimer *Timer(void) const { return timer; } + void SetDiskStatus(char DiskStatus); + }; + +int cTimerEntry::Compare(const cListObject &ListObject) const +{ + cTimerEntry *entry = (cTimerEntry *)&ListObject; + int r = startTime() - entry->startTime(); + if (r == 0) + r = entry->priority() - priority(); + return r; +} + +int cTimerEntry::duration(void) const +{ + int dur = (timer->Stop() / 100 * 60 + timer->Stop() % 100) - + (timer->Start() / 100 * 60 + timer->Start() % 100); + if (dur < 0) + dur += 24 * 60; + return dur; +} + +void cTimerEntry::SetDiskStatus(char DiskStatus) +{ + if (item) + item->SetDiskStatus(DiskStatus); +} +#endif /* TIMERINFO */ // --- cMenuTimers ----------------------------------------------------------- class cMenuTimers : public cOsdMenu { @@ -1061,14 +1185,25 @@ eOSState Info(void); cTimer *CurrentTimer(void); void SetHelpKeys(void); +#ifdef USE_TIMERINFO + void ActualiseDiskStatus(void); + bool actualiseDiskStatus; +#endif /* TIMERINFO */ public: cMenuTimers(void); virtual ~cMenuTimers(); +#ifdef USE_TIMERINFO + virtual void Display(void); +#endif /* TIMERINFO */ virtual eOSState ProcessKey(eKeys Key); }; cMenuTimers::cMenuTimers(void) +#ifdef USE_TIMERINFO +:cOsdMenu(tr("Timers"), 3, CHNUMWIDTH, 10, 6, 6) +#else :cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6) +#endif /* TIMERINFO */ { SetMenuCategory(mcTimer); helpKeys = -1; @@ -1080,6 +1215,9 @@ SetCurrent(First()); SetHelpKeys(); Timers.IncBeingEdited(); +#ifdef USE_TIMERINFO + actualiseDiskStatus = true; +#endif /* TIMERINFO */ } cMenuTimers::~cMenuTimers() @@ -1118,7 +1256,11 @@ timer->OnOff(); timer->SetEventFromSchedule(); RefreshCurrent(); +#ifdef USE_TIMERINFO + Display(); +#else DisplayCurrent(true); +#endif /* TIMERINFO */ if (timer->FirstDay()) isyslog("timer %s first day set to %s", *timer->ToDescr(), *timer->PrintFirstDay()); else @@ -1177,6 +1319,68 @@ return osContinue; } +#ifdef USE_TIMERINFO +void cMenuTimers::ActualiseDiskStatus(void) +{ + if (!actualiseDiskStatus || !Count()) + return; + + // compute free disk space + int freeMB, freeMinutes, runshortMinutes; + VideoDiskSpace(&freeMB); + freeMinutes = int(double(freeMB) * 1.1 / MB_PER_MINUTE); // overestimate by 10 percent + runshortMinutes = freeMinutes / 5; // 20 Percent + + // fill entries list + cTimerEntry *entry; + cList entries; + for (cOsdItem *item = First(); item; item = Next(item)) + entries.Add(new cTimerEntry((cMenuTimerItem *)item)); + + // search last start time + time_t last = 0; + for (entry = entries.First(); entry; entry = entries.Next(entry)) + last = max(entry->startTime(), last); + + // add entries for repeating timers + for (entry = entries.First(); entry; entry = entries.Next(entry)) + if (entry->repTimer() && !entry->isDummy()) + for (time_t start = cTimer::IncDay(entry->startTime(), 1); + start <= last; + start = cTimer::IncDay(start, 1)) + if (entry->Timer()->DayMatches(start)) + entries.Add(new cTimerEntry(entry->Timer(), start)); + + // set the disk-status + entries.Sort(); + for (entry = entries.First(); entry; entry = entries.Next(entry)) { + char status = ' '; + if (entry->active()) { + freeMinutes -= entry->duration(); + status = freeMinutes > runshortMinutes ? '+' : freeMinutes > 0 ? 177 /* +/- */ : '-'; + } + entry->SetDiskStatus(status); +#ifdef DEBUG_TIMER_INFO + dsyslog("timer-info: %c | %d | %s | %s | %3d | %+5d -> %+5d", + status, + entry->startTime(), + entry->active() ? "aktiv " : "n.akt.", + entry->repTimer() ? entry->isDummy() ? " dummy " : "mehrmalig" : "einmalig ", + entry->duration(), + entry->active() ? freeMinutes + entry->duration() : freeMinutes, + freeMinutes); +#endif + } + + actualiseDiskStatus = false; +} + +void cMenuTimers::Display(void) +{ + ActualiseDiskStatus(); + cOsdMenu::Display(); +} +#endif /* TIMERINFO */ eOSState cMenuTimers::ProcessKey(eKeys Key) { int TimerNumber = HasSubMenu() ? Count() : -1; @@ -1185,18 +1389,36 @@ if (state == osUnknown) { switch (Key) { case kOk: return Edit(); +#ifdef USE_TIMERINFO + case kRed: actualiseDiskStatus = true; + state = OnOff(); break; // must go through SetHelpKeys()! +#else case kRed: state = OnOff(); break; // must go through SetHelpKeys()! +#endif /* TIMERINFO */ case kGreen: return New(); +#ifdef USE_TIMERINFO + case kYellow: actualiseDiskStatus = true; + state = Delete(); break; +#else case kYellow: state = Delete(); break; +#endif /* TIMERINFO */ case kInfo: case kBlue: return Info(); break; default: break; } } +#ifdef USE_TIMERINFO + if (TimerNumber >= 0 && !HasSubMenu()) { + if (Timers.Get(TimerNumber)) // a newly created timer was confirmed with Ok + Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); + Sort(); + actualiseDiskStatus = true; +#else if (TimerNumber >= 0 && !HasSubMenu() && Timers.Get(TimerNumber)) { // a newly created timer was confirmed with Ok Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); +#endif /* TIMERINFO */ Display(); } if (Key != kNone) @@ -1227,6 +1449,9 @@ { cOsdMenu::Display(); DisplayMenu()->SetEvent(event); +#ifdef USE_GRAPHTFT + cStatus::MsgOsdSetEvent(event); +#endif /* GRAPHTFT */ if (event->Description()) cStatus::MsgOsdTextItem(event->Description()); } @@ -1304,7 +1529,16 @@ return r; } +#ifdef USE_WAREAGLEICON +static const char *TimerMatchChars[9] = +{ + " ", "t", "T", + ICON_BLANK, ICON_CLOCK_UH, ICON_CLOCK, + ICON_BLANK_UTF8, ICON_CLOCK_UH_UTF8, ICON_CLOCK_UTF8 +}; +#else static const char *TimerMatchChars = " tT"; +#endif /* WAREAGLEICON */ bool cMenuScheduleItem::Update(bool Force) { @@ -1313,17 +1547,35 @@ Timers.GetMatch(event, &timerMatch); if (Force || timerMatch != OldTimerMatch) { cString buffer; +#ifdef USE_WAREAGLEICON + const char *t = Setup.WarEagleIcons ? IsLangUtf8() ? TimerMatchChars[timerMatch+6] : TimerMatchChars[timerMatch+3] : TimerMatchChars[timerMatch]; + const char *v = event->Vps() && (event->Vps() - event->StartTime()) ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_VPS_UTF8 : ICON_VPS : "V" : " "; + const char *r = event->SeenWithin(30) && event->IsRunning() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_RUNNING_UTF8 : ICON_RUNNING : "*" : " "; +#else char t = TimerMatchChars[timerMatch]; char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' '; +#endif /* WAREAGLEICON */ const char *csn = channel ? channel->ShortName(true) : NULL; cString eds = event->GetDateString(); if (channel && withDate) +#ifdef USE_WAREAGLEICON + buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 999), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); +#else 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()); +#endif /* WAREAGLEICON */ else if (channel) +#ifdef USE_WAREAGLEICON + buffer = cString::sprintf("%d\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 999), csn, *event->GetTimeString(), t, v, r, event->Title()); +#else buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 999), csn, *event->GetTimeString(), t, v, r, event->Title()); +#endif /* WAREAGLEICON */ else +#ifdef USE_WAREAGLEICON + buffer = cString::sprintf("%.*s\t%s\t%s%s%s\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); +#else buffer = cString::sprintf("%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); +#endif /* WAREAGLEICON */ SetText(buffer); result = true; } @@ -1349,6 +1601,10 @@ static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; } static const cEvent *ScheduleEvent(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return now ? "MenuWhatsOnNow" : "MenuWhatsOnNext"; } + virtual void Display(void); +#endif /* GRAPHTFT */ }; int cMenuWhatsOn::currentChannel = 0; @@ -1377,6 +1633,20 @@ SetHelpKeys(); } +#ifdef USE_GRAPHTFT +void cMenuWhatsOn::Display(void) +{ + cOsdMenu::Display(); + + if (Count() > 0) { + int ni = 0; + for (cOsdItem *item = First(); item; item = Next(item)) { + cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); + } + } +} +#endif /* GRAPHTFT */ + bool cMenuWhatsOn::Update(void) { bool result = false; @@ -1517,6 +1787,10 @@ cMenuSchedule(void); virtual ~cMenuSchedule(); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSchedule"; } + virtual void Display(void); +#endif /* GRAPHTFT */ }; cMenuSchedule::cMenuSchedule(void) @@ -1543,6 +1817,20 @@ cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared } +#ifdef USE_GRAPHTFT +void cMenuSchedule::Display(void) +{ + cOsdMenu::Display(); + + if (Count() > 0) { + int ni = 0; + for (cOsdItem *item = First(); item; item = Next(item)) { + cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); + } + } +} +#endif /* GRAPHTFT */ + void cMenuSchedule::PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel) { Clear(); @@ -1907,6 +2195,9 @@ cMenuCam(cCamSlot *CamSlot); virtual ~cMenuCam(); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuCam"; } +#endif /* GRAPHTFT */ }; cMenuCam::cMenuCam(cCamSlot *CamSlot) @@ -2094,6 +2385,9 @@ cMenuRecording(const cRecording *Recording, bool WithButtons = false); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuRecording"; } +#endif /* GRAPHTFT */ }; cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) @@ -2110,6 +2404,9 @@ { cOsdMenu::Display(); DisplayMenu()->SetRecording(recording); +#ifdef USE_GRAPHTFT + cStatus::MsgOsdSetRecording(recording); +#endif /* GRAPHTFT */ if (recording->Info()->Description()) cStatus::MsgOsdTextItem(recording->Info()->Description()); } @@ -2189,6 +2486,169 @@ SetText(cString::sprintf("%d\t\t%d\t%s", totalEntries, newEntries, name)); } +#ifdef USE_LIEMIKUUTIO +// --- cMenuEditRecording ---------------------------------------------------- + +class cMenuEditRecording : public cOsdMenu { +private: + char name[MaxFileName]; + cMenuEditStrItem *file; + cOsdItem *marksItem, *resumeItem; + bool isResume, isMarks; + cRecording *recording; + void SetHelpKeys(void); + eOSState SetFolder(void); +public: + cMenuEditRecording(cRecording *Recording); + virtual eOSState ProcessKey(eKeys Key); +}; + +cMenuEditRecording::cMenuEditRecording(cRecording *Recording) +:cOsdMenu(tr("Edit recording"), 14) +{ + cMarks marks; + + file = NULL; + recording = Recording; + + if (recording) { + Utf8Strn0Cpy(name, recording->Name(), sizeof(name)); + Add(file = new cMenuEditStrItem(tr("File"), name, sizeof(name))); + + Add(new cOsdItem("", osUnknown, false)); + + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Date"), *DayDateTime(recording->Start())), osUnknown, false)); + + cChannel *channel = Channels.GetByChannelID(((cRecordingInfo *)recording->Info())->ChannelID()); + if (channel) + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Channel"), *ChannelString(channel, 0)), osUnknown, false)); + + int recLen = recording->LengthInSeconds(); + if (recLen >= 0) + Add(new cOsdItem(cString::sprintf("%s:\t%d:%02d:%02d", tr("Length"), recLen / 3600, recLen / 60 % 60, recLen % 60), osUnknown, false)); + else + recLen = 0; + + int dirSize = DirSizeMB(recording->FileName()); + cString bitRate = recLen ? cString::sprintf(" (%.2f MBit/s)", 8.0 * dirSize / recLen) : cString(""); + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Format"), recording->IsPesRecording() ? tr("PES") : tr("TS")), osUnknown, false)); + Add(new cOsdItem((dirSize > 9999) ? cString::sprintf("%s:\t%.2f GB%s", tr("Size"), dirSize / 1024.0, *bitRate) : cString::sprintf("%s:\t%d MB%s", tr("Size"), dirSize, *bitRate), osUnknown, false)); + + Add(new cOsdItem("", osUnknown, false)); + + isMarks = marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording()) && marks.Count(); + marksItem = new cOsdItem(tr("Delete marks information?"), osUser1, isMarks); + Add(marksItem); + + cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording()); + isResume = (ResumeFile.Read() != -1); + resumeItem = new cOsdItem(tr("Delete resume information?"), osUser2, isResume); + Add(resumeItem); + } + + SetHelpKeys(); +} + +void cMenuEditRecording::SetHelpKeys(void) +{ + SetHelp(tr("Button$Folder"), tr("Button$Cut"), tr("Button$Copy"), tr("Button$Rename/Move")); +} + +eOSState cMenuEditRecording::SetFolder(void) +{ + cMenuFolder *mf = (cMenuFolder *)SubMenu(); + if (mf) { + cString Folder = mf->GetFolder(); + char *p = strrchr(name, FOLDERDELIMCHAR); + if (p) + p++; + else + p = name; + if (!isempty(*Folder)) + strn0cpy(name, cString::sprintf("%s%c%s", *Folder, FOLDERDELIMCHAR, p), sizeof(name)); + else if (p != name) + memmove(name, p, strlen(p) + 1); + SetCurrent(file); + Display(); + } + return CloseSubMenu(); +} + +eOSState cMenuEditRecording::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kRed: + return AddSubMenu(new cMenuFolder(tr("Select folder"), &Folders, name)); + break; + case kGreen: + if (!cCutter::Active()) { + if (!isMarks) + Skins.Message(mtError, tr("No editing marks defined!")); + else if (!cCutter::Start(recording->FileName(), strcmp(recording->Name(), name) ? *NewVideoFileName(recording->FileName(), name) : NULL, false)) + Skins.Message(mtError, tr("Can't start editing process!")); + else + Skins.Message(mtInfo, tr("Editing process started")); + } + else + Skins.Message(mtError, tr("Editing process already active!")); + return osContinue; + case kYellow: + case kBlue: + if (strcmp(recording->Name(), name)) { + if (!cFileTransfer::Active()) { + if (cFileTransfer::Start(recording, name, (Key == kYellow))) + Skins.Message(mtInfo, tr("File transfer started")); + else + Skins.Message(mtError, tr("Can't start file transfer!")); + } + else + Skins.Message(mtError, tr("File transfer already active!")); + } + return osRecordings; + default: + break; + } + return osContinue; + } + else if (state == osEnd && HasSubMenu()) + state = SetFolder(); + else if (state == osUser1) { + if (isMarks && Interface->Confirm(tr("Delete marks information?"))) { + cMarks marks; + marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording()); + cMark *mark = marks.First(); + while (mark) { + cMark *nextmark = marks.Next(mark); + marks.Del(mark); + mark = nextmark; + } + marks.Save(); + isMarks = false; + marksItem->SetSelectable(isMarks); + SetCurrent(First()); + Display(); + } + return osContinue; + } + else if (state == osUser2) { + if (isResume && Interface->Confirm(tr("Delete resume information?"))) { + cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording()); + ResumeFile.Delete(); + isResume = false; + resumeItem->SetSelectable(isResume); + SetCurrent(First()); + Display(); + } + return osContinue; + } + + return state; +} +#endif /* LIEMIKUUTIO */ + // --- cMenuRecordings ------------------------------------------------------- cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) @@ -2261,7 +2721,13 @@ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) { cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); +#ifdef USE_PINPLUGIN + if ((*Item->Text() && (!Item->IsDirectory() || (!LastItem || !LastItem->IsDirectory() || strcmp(Item->Text(), LastItemText) != 0))) + && (!cStatus::MsgReplayProtected(GetRecording(Item), Item->Name(), base, + Item->IsDirectory(), true))) { +#else if (*Item->Text() && (!Item->IsDirectory() || (!LastItem || !LastItem->IsDirectory() || strcmp(Item->Text(), LastItemText) != 0))) { +#endif /* PINPLUGIN */ Add(Item); LastItem = Item; free(LastItemText); @@ -2321,6 +2787,11 @@ { cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri) { +#ifdef USE_PINPLUGIN + if (cStatus::MsgReplayProtected(GetRecording(ri), ri->Name(), base, + ri->IsDirectory()) == true) + return osContinue; +#endif /* PINPLUGIN */ if (ri->IsDirectory()) Open(); else { @@ -2438,6 +2909,21 @@ return osContinue; } +#ifdef USE_LIEMIKUUTIO +eOSState cMenuRecordings::Edit(void) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + if (ri && !ri->IsDirectory()) { + cRecording *recording = GetRecording(ri); + if (recording) + return AddSubMenu(new cMenuEditRecording(recording)); + } + return osContinue; +} +#endif /* LIEMIKUUTIO */ + eOSState cMenuRecordings::Sort(void) { if (HasSubMenu()) @@ -2462,7 +2948,17 @@ case kInfo: case kBlue: return Info(); case k0: return Sort(); +#ifdef USE_LIEMIKUUTIO + case k1...k9: if (Key==k4) { + Edit(); + break; + } + else + return Commands(Key); + +#else case k1...k9: return Commands(Key); +#endif /* LIEMIKUUTIO */ case kNone: if (Recordings.StateChanged(recordingsState)) Set(true); break; @@ -2526,6 +3022,9 @@ cMenuSetupOSD(void); virtual ~cMenuSetupOSD(); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupOsd"; } +#endif /* GRAPHTFT */ }; cMenuSetupOSD::cMenuSetupOSD(void) @@ -2571,6 +3070,9 @@ Add(new cMenuEditStraItem(tr("Setup.OSD$Skin"), &skinIndex, numSkins, skinDescriptions)); if (themes.NumThemes()) Add(new cMenuEditStraItem(tr("Setup.OSD$Theme"), &themeIndex, themes.NumThemes(), themes.Descriptions())); +#ifdef USE_WAREAGLEICON + Add(new cMenuEditBoolItem(tr("Setup.OSD$WarEagle icons"), &data.WarEagleIcons)); +#endif /* WAREAGLEICON */ Add(new cMenuEditPrcItem( tr("Setup.OSD$Left (%)"), &data.OSDLeftP, 0.0, 0.5)); Add(new cMenuEditPrcItem( tr("Setup.OSD$Top (%)"), &data.OSDTopP, 0.0, 0.5)); Add(new cMenuEditPrcItem( tr("Setup.OSD$Width (%)"), &data.OSDWidthP, 0.5, 1.0)); @@ -2675,6 +3177,9 @@ public: cMenuSetupEPG(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupEpg"; } +#endif /* GRAPHTFT */ }; cMenuSetupEPG::cMenuSetupEPG(void) @@ -2704,6 +3209,12 @@ for (int i = 0; i < numLanguages; i++) // TRANSLATORS: note the singular! Add(new cMenuEditStraItem(tr("Setup.EPG$Preferred language"), &data.EPGLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); +#ifdef USE_DDEPGENTRY + Add(new cMenuEditIntItem(tr("Setup.EPG$Period for double EPG search(min)"), &data.DoubleEpgTimeDelta)); + Add(new cMenuEditBoolItem(tr("Setup.EPG$extern double Epg entry"), &data.DoubleEpgAction, "adjust", "delete")); + Add(new cMenuEditBoolItem(tr("Setup.EPG$Mix intern and extern EPG"), &data.MixEpgAction)); + Add(new cMenuEditBoolItem(tr("Setup.EPG$Disable running VPS event"), &data.DisableVPS)); +#endif /* DDEPGENTRY */ SetCurrent(Get(current)); Display(); @@ -2771,6 +3282,9 @@ public: cMenuSetupDVB(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupDvb"; } +#endif /* GRAPHTFT */ }; cMenuSetupDVB::cMenuSetupDVB(void) @@ -2811,6 +3325,9 @@ Add(new cMenuEditStraItem(tr("Setup.DVB$Video display format"), &data.VideoDisplayFormat, 3, videoDisplayFormatTexts)); Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Dolby Digital"), &data.UseDolbyDigital)); Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"), &data.UpdateChannels, 6, updateChannelsTexts)); +#ifdef USE_CHANNELBIND + Add(new cMenuEditBoolItem(tr("Setup.DVB$channel binding by Rid"),&data.ChannelBindingByRid)); +#endif /* CHANNELBIND */ Add(new cMenuEditIntItem( tr("Setup.DVB$Audio languages"), &numAudioLanguages, 0, I18nLanguages()->Size())); for (int i = 0; i < numAudioLanguages; i++) Add(new cMenuEditStraItem(tr("Setup.DVB$Audio language"), &data.AudioLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); @@ -2823,6 +3340,9 @@ Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); } +#ifdef USE_TTXTSUBS + Add(new cMenuEditBoolItem(tr("Setup.DVB$Enable teletext support"), &data.SupportTeletext)); +#endif // USE_TTXTSUBS SetCurrent(Get(current)); Display(); @@ -2915,6 +3435,9 @@ public: cMenuSetupLNB(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupLnb"; } +#endif /* GRAPHTFT */ }; cMenuSetupLNB::cMenuSetupLNB(void) @@ -3017,6 +3540,9 @@ public: cMenuSetupCAM(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupCam"; } +#endif /* GRAPHTFT */ }; cMenuSetupCAM::cMenuSetupCAM(void) @@ -3093,12 +3619,49 @@ private: const char *pauseKeyHandlingTexts[3]; const char *delTimeshiftRecTexts[3]; +#ifdef USE_DVLVIDPREFER + void Set(void); + int tmpNVidPrefer, + tmpUseVidPrefer; +#endif /* DVLVIDPREFER */ public: cMenuSetupRecord(void); +#ifdef USE_DVLVIDPREFER + eOSState ProcessKey(eKeys key); +#endif /* DVLVIDPREFER */ }; cMenuSetupRecord::cMenuSetupRecord(void) { +#ifdef USE_DVLVIDPREFER + Set(); +} + +eOSState cMenuSetupRecord::ProcessKey(eKeys key) +{ + eOSState s = cMenuSetupBase::ProcessKey(key);; + + if (key != kNone) { + if (tmpNVidPrefer != data.nVidPrefer || tmpUseVidPrefer != data.UseVidPrefer) { + int cur = Current(); + + tmpNVidPrefer = data.nVidPrefer; + tmpUseVidPrefer = data.UseVidPrefer; + + Clear(); + Set(); + SetCurrent(Get(cur)); + Display(); + cMenuSetupBase::ProcessKey(kNone); + return osContinue; + } + } + return s; +} + +void cMenuSetupRecord::Set(void) +{ +#endif /* DVLVIDPREFER */ pauseKeyHandlingTexts[0] = tr("do not pause live video"); pauseKeyHandlingTexts[1] = tr("confirm pause live video"); pauseKeyHandlingTexts[2] = tr("pause live video"); @@ -3113,6 +3676,22 @@ Add(new cMenuEditStraItem(tr("Setup.Recording$Pause key handling"), &data.PauseKeyHandling, 3, pauseKeyHandlingTexts)); Add(new cMenuEditIntItem( tr("Setup.Recording$Pause priority"), &data.PausePriority, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("Setup.Recording$Pause lifetime (d)"), &data.PauseLifetime, 0, MAXLIFETIME)); +#ifdef USE_DVLVIDPREFER + tmpNVidPrefer = data.nVidPrefer; + tmpUseVidPrefer = data.UseVidPrefer; + + Add(new cMenuEditBoolItem(tr("Setup.Recording$Video directory policy"), &data.UseVidPrefer)); + if (data.UseVidPrefer != 0) { + char tmp[ 64 ]; + Add(new cMenuEditIntItem(tr("Setup.Recording$Number of video directories"), &data.nVidPrefer, 1, DVLVIDPREFER_MAX)); + for (int zz = 0; zz < data.nVidPrefer; zz++) { + sprintf(tmp, tr("Setup.Recording$Video %d priority"), zz); + Add(new cMenuEditIntItem(tmp, &data.VidPreferPrio[ zz ], 0, 99)); + sprintf(tmp, tr("Setup.Recording$Video %d min. free MB"), zz); + Add(new cMenuEditIntItem(tmp, &data.VidPreferSize[ zz ], -1, 99999)); + } + } +#endif /* DVLVIDPREFER */ Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle)); Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps)); Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0)); @@ -3120,8 +3699,15 @@ Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord))); Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 0, MAXINSTANTRECTIME, tr("Setup.Recording$present event"))); Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZETS)); +#ifdef USE_HARDLINKCUTTER + Add(new cMenuEditIntItem( tr("Setup.Recording$Max. recording size (GB)"), &data.MaxRecordingSize, MINRECORDINGSIZE, MAXRECORDINGSIZE)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Hard Link Cutter"), &data.HardLinkCutter)); +#endif /* HARDLINKCUTTER */ Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles)); Add(new cMenuEditStraItem(tr("Setup.Recording$Delete timeshift recording"),&data.DelTimeshiftRec, 3, delTimeshiftRecTexts)); +#ifdef USE_NALUDUMP + Add(new cMenuEditBoolItem(tr("Setup.Recording$Dump NALU Fill data"), &data.DumpNaluFill)); +#endif // USE_NALUDUMP } // --- cMenuSetupReplay ------------------------------------------------------ @@ -3140,6 +3726,16 @@ Add(new cMenuEditBoolItem(tr("Setup.Replay$Show replay mode"), &data.ShowReplayMode)); Add(new cMenuEditBoolItem(tr("Setup.Replay$Show remaining time"), &data.ShowRemainingTime)); Add(new cMenuEditIntItem(tr("Setup.Replay$Resume ID"), &data.ResumeID, 0, 99)); +#ifdef USE_JUMPPLAY + Add(new cMenuEditBoolItem(tr("Setup.Replay$Jump&Play"), &data.JumpPlay)); + Add(new cMenuEditBoolItem(tr("Setup.Replay$Play&Jump"), &data.PlayJump)); + Add(new cMenuEditBoolItem(tr("Setup.Replay$Pause at last mark"), &data.PauseLastMark)); +#endif /* JUMPPLAY */ +#ifdef USE_JUMPINGSECONDS + Add(new cMenuEditIntItem(tr("Setup.Replay$Jump Seconds"), &data.JumpSeconds)); + Add(new cMenuEditIntItem(tr("Setup.Replay$Jump Seconds Slow"), &data.JumpSecondsSlow)); + Add(new cMenuEditIntItem(tr("Setup.Recording$Jump Seconds (Repeat)"), &data.JumpSecondsRepeat)); +#endif /* USE_JUMPINGSECONDS */ } void cMenuSetupReplay::Store(void) @@ -3152,13 +3748,50 @@ // --- cMenuSetupMisc -------------------------------------------------------- class cMenuSetupMisc : public cMenuSetupBase { +#ifdef USE_VOLCTRL +private: + const char *lrChannelGroupsTexts[3]; + const char *lrForwardRewindTexts[3]; + void Setup(void); +#endif // USE_VOLCTRL public: cMenuSetupMisc(void); +#ifdef USE_VOLCTRL + virtual eOSState ProcessKey(eKeys Key); +#endif // USE_VOLCTRL }; cMenuSetupMisc::cMenuSetupMisc(void) { +#ifdef USE_VOLCTRL + lrChannelGroupsTexts[0] = tr("no"); + lrChannelGroupsTexts[1] = tr("Setup.Miscellaneous$only in channelinfo"); + lrChannelGroupsTexts[2] = tr("yes"); + lrForwardRewindTexts[0] = tr("no"); + lrForwardRewindTexts[1] = tr("Setup.Miscellaneous$only in progress display"); + lrForwardRewindTexts[2] = tr("yes"); +#endif // USE_VOLCTRL SetSection(tr("Miscellaneous")); +#ifdef USE_VOLCTRL + Setup(); +} + +eOSState cMenuSetupMisc::ProcessKey(eKeys Key) +{ + int newLRVolumeControl = data.LRVolumeControl; + eOSState state = cMenuSetupBase::ProcessKey(Key); + + if (Key != kNone && data.LRVolumeControl != newLRVolumeControl) + Setup(); + return state; +} + +void cMenuSetupMisc::Setup(void) +{ + int current = Current(); + + Clear(); +#endif // USE_VOLCTRL Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout)); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity)); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); @@ -3166,9 +3799,25 @@ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0)); Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before"))); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Initial volume"), &data.InitialVolume, -1, 255, tr("Setup.Miscellaneous$as before"))); +#ifdef USE_VOLCTRL + Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Volume ctrl with left/right"), &data.LRVolumeControl)); + if (data.LRVolumeControl) { + Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Channelgroups with left/right"), &data.LRChannelGroups, 3, lrChannelGroupsTexts)); + Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Search fwd/back with left/right"), &data.LRForwardRewind, 3, lrForwardRewindTexts)); + } +#endif // USE_VOLCTRL Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Channels wrap"), &data.ChannelsWrap)); Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Show channel names with source"), &data.ShowChannelNamesWithSource)); Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit)); +#ifdef USE_LIRCSETTINGS + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat delay"), &data.LircRepeatDelay, 0, 1000)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat freq"), &data.LircRepeatFreq, 0, 1000)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat timeout"), &data.LircRepeatTimeout, 0, 5000)); +#endif /* LIRCSETTINGS */ +#ifdef USE_VOLCTRL + SetCurrent(Get(current)); + Display(); +#endif // USE_VOLCTRL } // --- cMenuSetupPluginItem -------------------------------------------------- @@ -3193,6 +3842,9 @@ public: cMenuSetupPlugins(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetupPlugins"; } +#endif /* GRAPHTFT */ }; cMenuSetupPlugins::cMenuSetupPlugins(void) @@ -3247,6 +3899,9 @@ public: cMenuSetup(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuSetup"; } +#endif /* GRAPHTFT */ }; cMenuSetup::cMenuSetup(void) @@ -3337,25 +3992,70 @@ cMenuMain::cMenuMain(eOSState State) :cOsdMenu("") { +#ifdef USE_SETUP + // Load Menu Configuration + cString menuXML = cString::sprintf("%s/setup/vdr-menu.%s.xml", cPlugin::ConfigDirectory(), Setup.OSDLanguage); + if (access(menuXML, 04) == -1) + menuXML = cString::sprintf("%s/setup/vdr-menu.xml", cPlugin::ConfigDirectory()); + subMenu.LoadXml(menuXML); + nrDynamicMenuEntries = 0; +#endif /* SETUP */ + SetMenuCategory(mcMain); replaying = false; stopReplayItem = NULL; cancelEditingItem = NULL; +#ifdef USE_LIEMIKUUTIO + cancelFileTransferItem = NULL; +#endif /* LIEMIKUUTIO */ stopRecordingItem = NULL; recordControlsState = 0; + +#ifdef USE_MENUORG + MenuOrgPatch::EnterRootMenu(); +#endif /* MENUORG */ Set(); // Initial submenus: +#ifdef USE_MAINMENUHOOKS + cOsdObject *menu = NULL; +#endif /* MAINMENUHOOKS */ switch (State) { +#ifdef USE_MAINMENUHOOKS + case osSchedule: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu)) + menu = new cMenuSchedule; + break; + case osChannels: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu)) + menu = new cMenuChannels; + break; + case osTimers: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu)) + menu = new cMenuTimers; + break; + case osRecordings: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu)) + menu = new cMenuRecordings(NULL, 0, true); + break; + case osSetup: menu = new cMenuSetup; break; + case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; +#else case osSchedule: AddSubMenu(new cMenuSchedule); break; case osChannels: AddSubMenu(new cMenuChannels); break; case osTimers: AddSubMenu(new cMenuTimers); break; case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; case osSetup: AddSubMenu(new cMenuSetup); break; case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break; +#endif /* MAINMENUHOOKS */ default: break; } +#ifdef USE_MAINMENUHOOKS + if (menu) + if (menu->IsMenu()) + AddSubMenu((cOsdMenu *) menu); +#endif /* MAINMENUHOOKS */ } cOsdObject *cMenuMain::PluginOsdObject(void) @@ -3365,37 +4065,156 @@ return o; } +#ifdef USE_SETUP +void cMenuMain::Set(int current) +#else void cMenuMain::Set(void) +#endif /* SETUP */ { Clear(); SetTitle("VDR"); SetHasHotkeys(); +#ifdef USE_MENUORG + if (MenuOrgPatch::IsCustomMenuAvailable()) { + MenuItemDefinitions* menuItems = MenuOrgPatch::MainMenuItems(); + for (MenuItemDefinitions::iterator i = menuItems->begin(); i != menuItems->end(); i++) { + cOsdItem* osdItem = NULL; + if ((*i)->IsCustomOsdItem()) { + osdItem = (*i)->CustomOsdItem(); + if (osdItem && !(*i)->IsSeparatorItem()) + osdItem->SetText(hk(osdItem->Text())); + } + else if ((*i)->IsPluginItem()) { + const char *item = (*i)->PluginMenuEntry(); + if (item) + osdItem = new cMenuPluginItem(hk(item), (*i)->PluginIndex()); + } + if (osdItem) { + Add(osdItem); + if ((*i)->IsSelected()) + SetCurrent(osdItem); + } + } + } + else { +#endif /* MENUORG */ +#ifdef USE_SETUP + stopReplayItem = NULL; + cancelEditingItem = NULL; + stopRecordingItem = NULL; + + // remember initial dynamic MenuEntries added + nrDynamicMenuEntries = Count(); + for (cSubMenuNode *node = subMenu.GetMenuTree()->First(); node; node = subMenu.GetMenuTree()->Next(node)) { + cSubMenuNode::Type type = node->GetType(); + if (type==cSubMenuNode::PLUGIN) { + const char *item = node->GetPluginMainMenuEntry(); +#ifdef USE_PINPLUGIN + if (item && !cStatus::MsgPluginProtected(cPluginManager::GetPlugin(node->GetPluginIndex()), true)) +#else + if (item) +#endif /* PINPLUGIN */ + Add(new cMenuPluginItem(hk(item), node->GetPluginIndex())); + } + else if (type==cSubMenuNode::MENU) { + cString item = cString::sprintf("%s%s", node->GetName(), *subMenu.GetMenuSuffix()); +#ifdef USE_PINPLUGIN + if (!cStatus::MsgMenuItemProtected(item, true)) + Add(new cOsdItem(hk(item), osUnknown, node)); +#else + Add(new cOsdItem(hk(item))); +#endif /* PINPLUGIN */ + } + else if ((type==cSubMenuNode::COMMAND) || (type==cSubMenuNode::THREAD)) { +#ifdef USE_PINPLUGIN + if (!cStatus::MsgMenuItemProtected(node->GetName(), true)) + Add(new cOsdItem(hk(node->GetName()), osUnknown, node)); +#else + Add(new cOsdItem(hk(node->GetName()))); +#endif /* PINPLUGIN */ + } + else if (type==cSubMenuNode::SYSTEM) { + const char *item = node->GetName(); +#ifdef USE_PINPLUGIN + if (cStatus::MsgMenuItemProtected(item, true)) + ; // nothing to do ;) + else +#endif /* PINPLUGIN */ + if (strcmp(item, "Schedule") == 0) + Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); + else if (strcmp(item, "Channels") == 0) + Add(new cOsdItem(hk(tr("Channels")), osChannels)); + else if (strcmp(item, "Timers") == 0) + Add(new cOsdItem(hk(tr("Timers")), osTimers)); + else if (strcmp(item, "Recordings") == 0) + Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); + else if (strcmp(item, "Setup") == 0) { + cString itemSetup = cString::sprintf("%s%s", tr("Setup"), *subMenu.GetMenuSuffix()); + Add(new cOsdItem(hk(itemSetup), osSetup)); + } + else if (strcmp(item, "Commands") == 0 && Commands.Count() > 0) { + cString itemCommands = cString::sprintf("%s%s", tr("Commands"), *subMenu.GetMenuSuffix()); + Add(new cOsdItem(hk(itemCommands), osCommands)); + } + } + } + if (current >=0 && currentMainMenuEntry(); if (item) Add(new cMenuPluginItem(hk(item), i)); } +#ifdef USE_PINPLUGIN + } +#endif /* PINPLUGIN */ else break; } // More basic menu items: +#ifdef USE_PINPLUGIN + if (!cStatus::MsgMenuItemProtected("Setup", true)) Add(new cOsdItem(hk(tr("Setup")), osSetup)); +#else Add(new cOsdItem(hk(tr("Setup")), osSetup)); +#endif /* PINPLUGIN */ if (Commands.Count()) +#ifdef USE_PINPLUGIN + if (!cStatus::MsgMenuItemProtected("Commands", true)) +#endif /* PINPLUGIN */ Add(new cOsdItem(hk(tr("Commands")), osCommands)); +#endif /* SETUP */ + +#ifdef USE_MENUORG + } +#endif /* MENUORG */ Update(true); @@ -3406,6 +4225,19 @@ { bool result = false; +#ifdef USE_SETUP + cOsdItem *fMenu = NULL; + if (Force && subMenu.isTopMenu()) { + fMenu = First(); + nrDynamicMenuEntries = 0; + } + + if (!subMenu.isTopMenu()) { + SetTitle(cString::sprintf("%s - %s", tr("VDR"), subMenu.GetParentMenuTitel())); + result = true; + } +#endif /* SETUP */ + bool NewReplaying = cControl::Control() != NULL; if (Force || NewReplaying != replaying) { replaying = NewReplaying; @@ -3435,6 +4267,21 @@ result = true; } +#ifdef USE_LIEMIKUUTIO + // File transfer control: + bool FileTransferActive = cFileTransfer::Active(); + if (FileTransferActive && !cancelFileTransferItem) { + // TRANSLATORS: note the leading blank! + Add(cancelFileTransferItem = new cOsdItem(tr(" Cancel file transfer"), osCancelTransfer)); + result = true; + } + else if (cancelFileTransferItem && !FileTransferActive) { + Del(cancelFileTransferItem->Index()); + cancelFileTransferItem = NULL; + result = true; + } +#endif /* LIEMIKUUTIO */ + // Record control: if (cRecordControls::StateChanged(recordControlsState)) { while (stopRecordingItem) { @@ -3453,6 +4300,12 @@ result = true; } +#ifdef USE_SETUP + // adjust nrDynamicMenuEntries + if (fMenu != NULL) + nrDynamicMenuEntries = fMenu->Index(); +#endif /* SETUP */ + return result; } @@ -3463,13 +4316,53 @@ eOSState state = cOsdMenu::ProcessKey(Key); HadSubMenu |= HasSubMenu(); +#ifdef USE_PINPLUGIN + cOsdItem* item = Get(Current()); + + if (item && item->Text() && state != osContinue && state != osUnknown && state != osBack) + if (cStatus::MsgMenuItemProtected(item->Text())) + return osContinue; +#endif /* PINPLUGIN */ + +#ifdef USE_MAINMENUHOOKS + cOsdObject *menu = NULL; +#endif /* MAINMENUHOOKS */ switch (state) { +#ifdef USE_MAINMENUHOOKS + case osSchedule: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu)) + menu = new cMenuSchedule; + else + state = osContinue; + break; + case osChannels: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu)) + menu = new cMenuChannels; + else + state = osContinue; + break; + case osTimers: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu)) + menu = new cMenuTimers; + else + state = osContinue; + break; + case osRecordings: + if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu)) + menu = new cMenuRecordings; + else + state = osContinue; + break; + case osSetup: menu = new cMenuSetup; break; + case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; +#else case osSchedule: return AddSubMenu(new cMenuSchedule); case osChannels: return AddSubMenu(new cMenuChannels); case osTimers: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); case osSetup: return AddSubMenu(new cMenuSetup); case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); +#endif /* MAINMENUHOOKS */ case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) { cOsdItem *item = Get(Current()); if (item) { @@ -3483,11 +4376,22 @@ return osEnd; } break; +#ifdef USE_LIEMIKUUTIO + case osCancelTransfer: + if (Interface->Confirm(tr("Cancel file transfer?"))) { + cFileTransfer::Stop(); + return osEnd; + } + break; +#endif case osPlugin: { cMenuPluginItem *item = (cMenuPluginItem *)Get(Current()); if (item) { cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex()); if (p) { +#ifdef USE_PINPLUGIN + if (!cStatus::MsgPluginProtected(p)) { +#endif /* PINPLUGIN */ cOsdObject *menu = p->MainMenuAction(); if (menu) { if (menu->IsMenu()) @@ -3497,11 +4401,63 @@ return osPlugin; } } +#ifdef USE_PINPLUGIN + } +#endif /* PINPLUGIN */ } } state = osEnd; } break; +#ifdef USE_MENUORG + case osBack: { + if (MenuOrgPatch::IsCustomMenuAvailable()) + { + bool leavingMenuSucceeded = MenuOrgPatch::LeaveSubMenu(); + Set(); + stopReplayItem = NULL; + cancelEditingItem = NULL; + stopRecordingItem = NULL; + recordControlsState = 0; + Update(true); + Display(); + if (leavingMenuSucceeded) + return osContinue; + else + return osEnd; + } + } + break; + case osUser1: { + if (MenuOrgPatch::IsCustomMenuAvailable()) { + MenuOrgPatch::EnterSubMenu(Get(Current())); + Set(); + return osContinue; + } + } + break; + case osUser2: { + if (MenuOrgPatch::IsCustomMenuAvailable()) { + cOsdMenu* osdMenu = MenuOrgPatch::Execute(Get(Current())); + if (osdMenu) + return AddSubMenu(osdMenu); + return osEnd; + } + } + break; +#endif /* MENUORG */ +#ifdef USE_SETUP + case osBack: { + int newCurrent = 0; + if (subMenu.Up(&newCurrent)) { + Set(newCurrent); + return osContinue; + } + else + return osEnd; + } + break; +#endif /* SETUP */ default: switch (Key) { case kRecord: case kRed: if (!HadSubMenu) @@ -3518,9 +4474,67 @@ case kBlue: if (!HadSubMenu) state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue; break; +#ifdef USE_SETUP + case kOk: if (state == osUnknown) { + cString buffer; + int index = Current()-nrDynamicMenuEntries; + cSubMenuNode *node = subMenu.GetNode(index); + + if (node != NULL) { + if (node->GetType() == cSubMenuNode::MENU) { +#ifdef USE_PINPLUGIN + subMenu.Down(node, Current()); +#else + subMenu.Down(index); +#endif /* PINPLUGIN */ + } + else if (node->GetType() == cSubMenuNode::COMMAND) { + bool confirmed = true; + if (node->CommandConfirm()) { + buffer = cString::sprintf("%s?", node->GetName()); + confirmed = Interface->Confirm(buffer); + } + if (confirmed) { + const char *Result = subMenu.ExecuteCommand(node->GetCommand()); + if (Result) + return AddSubMenu(new cMenuText(node->GetName(), Result, fontFix)); + return osEnd; + } + } + else if (node->GetType() == cSubMenuNode::THREAD) { + bool confirmed = true; + if (node->CommandConfirm()) { + buffer = cString::sprintf("%s?", node->GetName()); + confirmed = Interface->Confirm(buffer); + } + if (confirmed) { + buffer = cString::sprintf("%s", node->GetCommand()); + cExecCmdThread *execcmd = new cExecCmdThread(node->GetCommand()); + if (execcmd->Start()) + dsyslog("executing command '%s'", *buffer); + else + esyslog("ERROR: can't execute command '%s'", *buffer); + return osEnd; + } + } + } + + Set(); + return osContinue; + } + break; +#endif /* SETUP */ default: break; } } +#ifdef USE_MAINMENUHOOKS + if (menu) { + if (menu->IsMenu()) + return AddSubMenu((cOsdMenu *) menu); + pluginOsdObject = menu; + return osPlugin; + } +#endif /* MAINMENUHOOKS */ if (!HasSubMenu() && Update(HadSubMenu)) Display(); if (Key != kNone) { @@ -3667,6 +4681,9 @@ if (Direction) { while (Channel) { Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel); +#ifdef USE_PINPLUGIN + if (cStatus::MsgChannelProtected(0, Channel) == false) +#endif /* PINPLUGIN */ if (!Channel && Setup.ChannelsWrap) Channel = Direction > 0 ? Channels.First() : Channels.Last(); if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, LIVEPRIORITY, true, true)) @@ -3727,6 +4744,13 @@ case kLeft: case kRight|k_Repeat: case kRight: +#ifdef USE_VOLCTRL + if (Setup.LRVolumeControl && !Setup.LRChannelGroups) { + cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); + break; + } + // else fall through +#endif // USE_VOLCTRL case kNext|k_Repeat: case kNext: case kPrev|k_Repeat: @@ -3886,6 +4910,17 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key) { switch (int(Key)) { +#ifdef USE_VOLCTRL + case kLeft|k_Repeat: + case kLeft: + case kRight|k_Repeat: + case kRight: + if (Setup.LRVolumeControl) { + cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); + break; + } + // else fall through +#endif // USE_VOLCTRL case kVolUp|k_Repeat: case kVolUp: case kVolDn|k_Repeat: @@ -4133,7 +5168,11 @@ // --- cRecordControl -------------------------------------------------------- +#ifdef USE_ALTERNATECHANNEL +cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause, cChannel *Channel) +#else cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) +#endif /* ALTERNATECHANNEL */ { // Whatever happens here, the timers will be modified in some way... Timers.SetModified(); @@ -4182,9 +5221,16 @@ cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName); isyslog("record %s", fileName); if (MakeDirs(fileName, true)) { +#ifdef USE_ALTERNATECHANNEL + const cChannel *ch = Channel ? Channel : timer->Channel(); + if (ch) + recorder = new cRecorder(fileName, ch, timer->Priority()); + if (ch && device->AttachReceiver(recorder)) { +#else const cChannel *ch = timer->Channel(); recorder = new cRecorder(fileName, ch, timer->Priority()); if (device->AttachReceiver(recorder)) { +#endif /* ALTERNATECHANNEL */ Recording.WriteInfo(); cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() @@ -4207,7 +5253,12 @@ return; } else +#ifdef USE_ALTERNATECHANNEL + if (ch) DELETENULL(recorder); +#else + DELETENULL(recorder); +#endif /* ALTERNATECHANNEL */ } else timer->SetDeferred(DEFERTIMER); @@ -4308,6 +5359,17 @@ if (channel) { int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority; cDevice *device = cDevice::GetDevice(channel, Priority, false); + +#ifdef USE_ALTERNATECHANNEL + if (!device && channel->AlternativeChannelID().Valid()) {// check for alternatives + dsyslog("prepare to use alternative channel for channel %d", channel->Number()); + channel = Channels.GetByChannelID(channel->AlternativeChannelID()); + device = cDevice::GetDevice(channel, Priority, false); + if (device) + dsyslog("use of alternative channel %d successfully initiated", channel->Number()); + } +#endif /* ALTERNATECHANNEL */ + if (device) { dsyslog("switching device %d to channel %d", device->DeviceNumber() + 1, channel->Number()); if (!device->SwitchChannel(channel, false)) { @@ -4317,7 +5379,14 @@ if (!Timer || Timer->Matches()) { for (int i = 0; i < MAXRECORDCONTROLS; i++) { if (!RecordControls[i]) { +#ifdef USE_ALTERNATECHANNEL + RecordControls[i] = new cRecordControl(device, Timer, Pause, channel); +#else RecordControls[i] = new cRecordControl(device, Timer, Pause); +#endif /* ALTERNATECHANNEL */ +#ifdef USE_PINPLUGIN + cStatus::MsgRecordingFile(RecordControls[i]->FileName()); +#endif /* PINPLUGIN */ return RecordControls[i]->Process(time(NULL)); } } @@ -4456,6 +5525,12 @@ // --- cReplayControl -------------------------------------------------------- +#ifdef USE_LIEMIKUUTIO +#define REPLAYCONTROLSKIPLIMIT 9 // s +#define REPLAYCONTROLSKIPSECONDS 90 // s +#define REPLAYCONTROLSKIPTIMEOUT 5000 // ms +#endif /* LIEMIKUUTIO */ + cReplayControl *cReplayControl::currentReplayControl = NULL; cString cReplayControl::fileName; @@ -4469,6 +5544,11 @@ lastCurrent = lastTotal = -1; lastPlay = lastForward = false; lastSpeed = -2; // an invalid value +#ifdef USE_LIEMIKUUTIO + lastSkipKey = kNone; + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipTimeout.Set(0); +#endif /* LIEMIKUUTIO */ timeoutShow = 0; timeSearchActive = false; cRecording Recording(fileName); @@ -4739,8 +5819,16 @@ marks.Add(Current); bool Play, Forward; int Speed; +#ifdef USE_JUMPPLAY + if (GetReplayMode(Play, Forward, Speed) && !Play) { +#else if (GetReplayMode(Play, Forward, Speed) && !Play) +#endif /* JUMPPLAY */ Goto(Current, true); +#ifdef USE_JUMPPLAY + displayFrames = true; + } +#endif /* JUMPPLAY */ } ShowTimed(2); marksModified = true; @@ -4754,8 +5842,22 @@ if (GetIndex(Current, Total)) { cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current); if (m) { +#ifdef USE_JUMPPLAY + bool Play2, Forward2; + int Speed; + if (Setup.JumpPlay && GetReplayMode(Play2, Forward2, Speed) && + Play2 && Forward && m->Position() < Total - SecondsToFrames(3, FramesPerSecond())) { + Goto(m->Position()); + Play(); + } + else { + Goto(m->Position(), true); + displayFrames = true; + } +#else Goto(m->Position(), true); displayFrames = true; +#endif /* JUMPPLAY */ } } } @@ -4796,7 +5898,11 @@ if (!cCutter::Active()) { if (!marks.Count()) Skins.Message(mtError, tr("No editing marks defined!")); +#ifdef USE_LIEMIKUUTIO + else if (!cCutter::Start(fileName, NULL, false)) +#else else if (!cCutter::Start(fileName)) +#endif /* LIEMIKUUTIO */ Skins.Message(mtError, tr("Can't start editing process!")); else Skins.Message(mtInfo, tr("Editing process started")); @@ -4815,7 +5921,11 @@ if (!m) m = marks.GetNext(Current); if (m) { +#ifdef USE_JUMPPLAY + if ((m->Index() & 0x01) != 0 && !Setup.PlayJump) +#else if ((m->Index() & 0x01) != 0) +#endif /* JUMPPLAY */ m = marks.Next(m); if (m) { Goto(m->Position() - SecondsToFrames(3, FramesPerSecond())); @@ -4864,6 +5974,24 @@ return osContinue; } bool DoShowMode = true; +#ifdef USE_VOLCTRL + if (Setup.LRVolumeControl && + (!Setup.LRForwardRewind || + (Setup.LRForwardRewind == 1 && !visible))) { + switch (int(Key)) { + // Left/Right volume control + case kLeft|k_Repeat: + case kLeft: + case kRight|k_Repeat: + case kRight: + cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); + return osContinue; + break; + default: + break; + } + } +#endif // USE_VOLCTRL switch (int(Key)) { // Positioning: case kPlay: @@ -4881,10 +6009,53 @@ case kFastFwd: case kRight: Forward(); break; case kRed: TimeSearch(); break; +#ifdef USE_JUMPINGSECONDS + case kGreen|k_Repeat: + SkipSeconds(-(Setup.JumpSecondsRepeat)); break; + case kGreen: SkipSeconds(-(Setup.JumpSeconds)); break; + case k1|k_Repeat: + case k1: SkipSeconds(-Setup.JumpSecondsSlow); break; + case k3|k_Repeat: + case k3: SkipSeconds( Setup.JumpSecondsSlow); break; + case kYellow|k_Repeat: + SkipSeconds(Setup.JumpSecondsRepeat); break; + case kYellow: SkipSeconds(Setup.JumpSeconds); break; +#else case kGreen|k_Repeat: case kGreen: SkipSeconds(-60); break; case kYellow|k_Repeat: case kYellow: SkipSeconds( 60); break; +#endif /* JUMPINGSECONDS */ +#ifdef USE_LIEMIKUUTIO +#ifndef USE_JUMPINGSECONDS + case k1|k_Repeat: + case k1: SkipSeconds(-20); break; + case k3|k_Repeat: + case k3: SkipSeconds( 20); break; +#endif /* JUMPINGSECONDS */ + case kPrev|k_Repeat: + case kPrev: if (lastSkipTimeout.TimedOut()) { + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipKey = kPrev; + } + else if (RAWKEY(lastSkipKey) != kPrev && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { + lastSkipSeconds /= 2; + lastSkipKey = kNone; + } + lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); + SkipSeconds(-lastSkipSeconds); break; + case kNext|k_Repeat: + case kNext: if (lastSkipTimeout.TimedOut()) { + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipKey = kNext; + } + else if (RAWKEY(lastSkipKey) != kNext && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { + lastSkipSeconds /= 2; + lastSkipKey = kNone; + } + lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); + SkipSeconds(lastSkipSeconds); break; +#endif /* LIEMIKUUTIO */ case kStop: case kBlue: Hide(); Stop(); @@ -4894,12 +6065,16 @@ switch (int(Key)) { // Editing: case kMarkToggle: MarkToggle(); break; +#ifndef USE_LIEMIKUUTIO case kPrev|k_Repeat: case kPrev: +#endif /* LIEMIKUUTIO */ case kMarkJumpBack|k_Repeat: case kMarkJumpBack: MarkJump(false); break; +#ifndef USE_LIEMIKUUTIO case kNext|k_Repeat: case kNext: +#endif /* LIEMIKUUTIO */ case kMarkJumpForward|k_Repeat: case kMarkJumpForward: MarkJump(true); break; case kMarkMoveBack|k_Repeat: diff -ruN vdr-1.7.31-ext/menu.h vdr-1.7.31/menu.h --- vdr-1.7.31-ext/menu.h 2012-09-07 10:48:34.000000000 +0200 +++ vdr-1.7.31/menu.h 2012-09-19 23:54:19.000000000 +0200 @@ -18,6 +18,9 @@ #include "menuitems.h" #include "recorder.h" #include "skins.h" +#ifdef USE_SETUP +#include "submenu.h" +#endif /* SETUP */ class cMenuText : public cOsdMenu { private: @@ -51,6 +54,9 @@ cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path = NULL); cString GetFolder(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuText"; } +#endif /* GRAPHTFT */ }; class cMenuCommands : public cOsdMenu { @@ -85,6 +91,9 @@ cMenuEditTimer(cTimer *Timer, bool New = false); virtual ~cMenuEditTimer(); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuTimerEdit"; } +#endif /* GRAPHTFT */ }; class cMenuEvent : public cOsdMenu { @@ -94,22 +103,40 @@ cMenuEvent(const cEvent *Event, bool CanSwitch = false, bool Buttons = false); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuEvent"; } +#endif /* GRAPHTFT */ }; class cMenuMain : public cOsdMenu { private: +#ifdef USE_SETUP + int nrDynamicMenuEntries; +#endif /* SETUP */ bool replaying; cOsdItem *stopReplayItem; cOsdItem *cancelEditingItem; +#ifdef USE_LIEMIKUUTIO + cOsdItem *cancelFileTransferItem; +#endif /* LIEMIKUUTIO */ cOsdItem *stopRecordingItem; int recordControlsState; static cOsdObject *pluginOsdObject; +#ifdef USE_SETUP + void Set(int current=0); + bool Update(bool Force = false); + cSubMenu subMenu; +#else void Set(void); bool Update(bool Force = false); +#endif /* SETUP */ public: cMenuMain(eOSState State = osUnknown); virtual eOSState ProcessKey(eKeys Key); static cOsdObject *PluginOsdObject(void); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuMain"; } +#endif /* GRAPHTFT */ }; class cDisplayChannel : public cOsdObject { @@ -206,6 +233,9 @@ eOSState Info(void); eOSState Sort(void); eOSState Commands(eKeys Key = kNone); +#ifdef USE_LIEMIKUUTIO + eOSState Edit(void); +#endif /* LIEMIKUUTIO */ protected: cString DirectoryName(void); cRecording *GetRecording(cMenuRecordingItem *Item); @@ -225,7 +255,11 @@ char *fileName; bool GetEvent(void); public: +#ifdef USE_ALTERNATECHANNEL + cRecordControl(cDevice *Device, cTimer *Timer = NULL, bool Pause = false, cChannel *Channel = NULL); +#else cRecordControl(cDevice *Device, cTimer *Timer = NULL, bool Pause = false); +#endif /* ALTERNATECHANNEL */ virtual ~cRecordControl(); bool Process(time_t t); cDevice *Device(void) { return device; } @@ -265,6 +299,11 @@ int lastCurrent, lastTotal; bool lastPlay, lastForward; int lastSpeed; +#ifdef USE_LIEMIKUUTIO + int lastSkipSeconds; + eKeys lastSkipKey; + cTimeMs lastSkipTimeout; +#endif /* LIEMIKUUTIO */ time_t timeoutShow; bool timeSearchActive, timeSearchHide; int timeSearchTime, timeSearchPos; diff -ruN vdr-1.7.31-ext/menuitems.h vdr-1.7.31/menuitems.h --- vdr-1.7.31-ext/menuitems.h 2012-03-13 12:19:11.000000000 +0100 +++ vdr-1.7.31/menuitems.h 2012-09-19 23:54:19.000000000 +0200 @@ -209,6 +209,9 @@ cMenuSetupPage(void); virtual eOSState ProcessKey(eKeys Key); void SetPlugin(cPlugin *Plugin); +#ifdef USE_GRAPHTFT + const char* MenuKind() { return "MenuSetupPage"; } +#endif /* GRAPHTFT */ }; #endif //__MENUITEMS_H diff -ruN vdr-1.7.31-ext/menuorgpatch.h vdr-1.7.31/menuorgpatch.h --- vdr-1.7.31-ext/menuorgpatch.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/menuorgpatch.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,102 @@ +#ifdef USE_MENUORG +/* + * vdr-menuorg - A plugin for the Linux Video Disk Recorder + * Copyright (c) 2007 - 2008 Tobias Grimm + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $Id$ + * + */ + +#ifndef __MENUORGPATCH_H +#define __MENUORGPATCH_H + +#include "mainmenuitemsprovider.h" + +class MenuOrgPatch +{ + private: + static IMainMenuItemsProvider* _mainMenuItemsProvider; + + private: + static IMainMenuItemsProvider* MainMenuItemsProvider() + { + if (!_mainMenuItemsProvider) + { + IMainMenuItemsProvider* mainMenuItemsProvider; + + if (cPluginManager::CallFirstService(MENU_ITEMS_PROVIDER_SERVICE_ID, &mainMenuItemsProvider)) + { + _mainMenuItemsProvider = mainMenuItemsProvider; + } + } + return _mainMenuItemsProvider; + } + + public: + static bool IsCustomMenuAvailable() + { + return (MainMenuItemsProvider() != NULL) && (MainMenuItemsProvider()->IsCustomMenuAvailable()); + } + + static void EnterRootMenu() + { + if (MainMenuItemsProvider()) + { + MainMenuItemsProvider()->EnterRootMenu(); + } + } + + static bool LeaveSubMenu() + { + if (MainMenuItemsProvider()) + { + return MainMenuItemsProvider()->LeaveSubMenu(); + } + return false; + } + + static void EnterSubMenu(cOsdItem* item) + { + if (MainMenuItemsProvider()) + { + MainMenuItemsProvider()->EnterSubMenu(item); + } + } + + static MenuItemDefinitions* MainMenuItems() + { + if (MainMenuItemsProvider()) + { + return MainMenuItemsProvider()->MainMenuItems(); + } + return NULL; + } + + static cOsdMenu* Execute(cOsdItem* item) + { + if (MainMenuItemsProvider()) + { + return MainMenuItemsProvider()->Execute(item); + } + return NULL; + } +}; + +IMainMenuItemsProvider* MenuOrgPatch::_mainMenuItemsProvider = NULL; + +#endif //__MENUORGPATCH_H +#endif /* MENUORG */ diff -ruN vdr-1.7.31-ext/MLD vdr-1.7.31/MLD --- vdr-1.7.31-ext/MLD 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/MLD 2012-09-20 00:55:18.000000000 +0200 @@ -0,0 +1 @@ +this is the Extp-NG for VDR 1.7.31 diff -ruN vdr-1.7.31-ext/osdbase.c vdr-1.7.31/osdbase.c --- vdr-1.7.31-ext/osdbase.c 2012-04-23 11:41:22.000000000 +0200 +++ vdr-1.7.31/osdbase.c 2012-09-19 23:54:19.000000000 +0200 @@ -23,6 +23,9 @@ state = State; selectable = true; fresh = true; +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) + subMenu = 0; +#endif /* SETUP & PINPLUGIN */ } cOsdItem::cOsdItem(const char *Text, eOSState State, bool Selectable) @@ -32,8 +35,23 @@ selectable = Selectable; fresh = true; SetText(Text); +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) + subMenu = 0; +#endif /* SETUP & PINPLUGIN */ } +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) +cOsdItem::cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu) +{ + text = NULL; + state = State; + selectable = true; + fresh = true; + SetText(Text); + subMenu = SubMenu; +} +#endif /* SETUP & PINPLUGIN */ + cOsdItem::~cOsdItem() { free(text); @@ -77,6 +95,9 @@ { isMenu = true; digit = 0; +#ifdef USE_LIEMIKUUTIO + key_nr = -1; +#endif /* LIEMIKUUTIO */ hasHotkeys = false; displayMenuItems = 0; title = NULL; @@ -100,6 +121,9 @@ free(status); displayMenu->Clear(); cStatus::MsgOsdClear(); +#ifdef USE_GRAPHTFT + cStatus::MsgOsdMenuDestroy(); +#endif /* GRAPHTFT */ if (!--displayMenuCount) DELETENULL(displayMenu); } @@ -126,7 +150,11 @@ digit = -1; // prevents automatic hotkeys - input already has them if (digit >= 0) { digit++; +#ifdef USE_LIEMIKUUTIO + buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s); +#else buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s); +#endif /* LIEMIKUUTIO */ s = buffer; } } @@ -217,6 +245,9 @@ displayMenu->SetMessage(mtStatus, NULL); displayMenu->Clear(); cStatus::MsgOsdClear(); +#ifdef USE_GRAPHTFT + cStatus::MsgOsdMenuDisplay(MenuKind()); +#endif /* GRAPHTFT */ if (menuCategory != displayMenu->MenuCategory()) displayMenu->SetMenuCategory(menuCategory); displayMenuItems = displayMenu->MaxItems(); @@ -472,20 +503,77 @@ } } +#ifdef USE_LIEMIKUUTIO +#define MENUKEY_TIMEOUT 1500 +#endif /* LIEMIKUUTIO */ + eOSState cOsdMenu::HotKey(eKeys Key) { +#ifdef USE_LIEMIKUUTIO + bool match = false; + bool highlight = false; + int item_nr; + int i; + + if (Key == kNone) { + if (lastActivity.TimedOut()) + Key = kOk; + else + return osContinue; + } + else + lastActivity.Set(MENUKEY_TIMEOUT); + for (cOsdItem *item = Last(); item; item = Prev(item)) { +#else for (cOsdItem *item = First(); item; item = Next(item)) { +#endif /* LIEMIKUUTIO */ const char *s = item->Text(); +#ifdef USE_LIEMIKUUTIO + i = 0; + item_nr = 0; + if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') { + do { + item_nr = item_nr * 10 + (s[i] - '0'); + } + while ( !((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9')); + if ((Key == kOk) && (item_nr == key_nr)) { +#else if (s && (s = skipspace(s)) != NULL) { if (*s == Key - k1 + '1') { +#endif /* LIEMIKUUTIO */ current = item->Index(); RefreshCurrent(); Display(); cRemote::Put(kOk, true); +#ifdef USE_LIEMIKUUTIO + key_nr = -1; +#endif /* LIEMIKUUTIO */ break; } +#ifdef USE_LIEMIKUUTIO + else if (Key != kOk) { + if (!highlight && (item_nr == (Key - k0))) { + highlight = true; + current = item->Index(); + } + if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) { + match = true; + key_nr = (Key - k0); + } + else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) { + current = item->Index(); + cRemote::Put(kOk, true); + key_nr = -1; + break; + } + } +#endif /* LIEMIKUUTIO */ } } +#ifdef USE_LIEMIKUUTIO + if ((!match) && (Key != kNone)) + key_nr = -1; +#endif /* LIEMIKUUTIO */ return osContinue; } @@ -524,8 +612,13 @@ } } switch (int(Key)) { +#ifdef USE_LIEMIKUUTIO + case kNone: + case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown; +#else case k0: return osUnknown; case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; +#endif /* LIEMIKUUTIO */ case kUp|k_Repeat: case kUp: CursorUp(); break; case kDown|k_Repeat: diff -ruN vdr-1.7.31-ext/osdbase.h vdr-1.7.31/osdbase.h --- vdr-1.7.31-ext/osdbase.h 2012-04-23 11:40:07.000000000 +0200 +++ vdr-1.7.31/osdbase.h 2012-09-19 23:54:19.000000000 +0200 @@ -15,6 +15,10 @@ #include "skins.h" #include "tools.h" +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) +#include "submenu.h" +#endif /* SETUP & PINPLUGIN */ + enum eOSState { osUnknown, osContinue, osSchedule, @@ -30,6 +34,9 @@ osStopRecord, osStopReplay, osCancelEdit, +#ifdef USE_LIEMIKUUTIO + osCancelTransfer, +#endif /* LIEMIKUUTIO */ osSwitchDvb, osBack, osEnd, @@ -51,16 +58,26 @@ char *text; eOSState state; bool selectable; +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) + cSubMenuNode* subMenu; +#endif /* SETUP & PINPLUGIN */ protected: bool fresh; public: cOsdItem(eOSState State = osUnknown); cOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true); +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) + cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu); +#endif /* SETUP & PINPLUGIN */ virtual ~cOsdItem(); bool Selectable(void) const { return selectable; } void SetText(const char *Text, bool Copy = true); void SetSelectable(bool Selectable); void SetFresh(bool Fresh); +#if defined (USE_SETUP) && defined (USE_PINPLUGIN) + void SetSubMenu(cSubMenuNode* SubMenu) { subMenu = SubMenu; } + cSubMenuNode* SubMenu() { return subMenu; } +#endif /* SETUP & PINPLUGIN */ const char *Text(void) const { return text; } virtual void Set(void) {} virtual eOSState ProcessKey(eKeys Key); @@ -98,6 +115,10 @@ int digit; bool hasHotkeys; void DisplayHelp(bool Force = false); +#ifdef USE_LIEMIKUUTIO + int key_nr; + cTimeMs lastActivity; +#endif /* LIEMIKUUTIO */ protected: void SetDisplayMenu(void); cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; } @@ -135,6 +156,9 @@ void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); +#ifdef USE_GRAPHTFT + virtual const char* MenuKind() { return "MenuUnknown"; } +#endif /* GRAPHTFT */ }; #endif //__OSDBASE_H diff -ruN vdr-1.7.31-ext/osd.c vdr-1.7.31/osd.c --- vdr-1.7.31-ext/osd.c 2012-06-09 16:37:24.000000000 +0200 +++ vdr-1.7.31/osd.c 2012-09-19 23:54:19.000000000 +0200 @@ -1623,6 +1623,10 @@ int cOsd::osdHeight = 0; cVector cOsd::Osds; cMutex cOsd::mutex; +#ifdef USE_PINPLUGIN +bool cOsd::pinValid = false; +#endif /* PINPLUGIN */ + cOsd::cOsd(int Left, int Top, uint Level) { @@ -1637,6 +1641,9 @@ width = height = 0; level = Level; active = false; +#ifdef USE_YAEPG + vidWin.bpp = 0; +#endif /* YAEPG */ for (int i = 0; i < Osds.Size(); i++) { if (Osds[i]->level > level) { Osds.Insert(this, i); diff -ruN vdr-1.7.31-ext/osd.h vdr-1.7.31/osd.h --- vdr-1.7.31-ext/osd.h 2012-06-02 12:32:38.000000000 +0200 +++ vdr-1.7.31/osd.h 2012-09-19 23:54:19.000000000 +0200 @@ -730,6 +730,10 @@ int left, top, width, height; uint level; bool active; +#ifdef USE_YAEPG +public: + tArea vidWin; +#endif /* YAEPG */ protected: cOsd(int Left, int Top, uint Level); ///< Initializes the OSD with the given coordinates. @@ -931,6 +935,9 @@ ///< MyOsdDrawPixmap(Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y(), pm->Data(), w, h, h * d); ///< delete pm; ///< } +#ifdef USE_PINPLUGIN + static bool pinValid; +#endif /* PINPLUGIN */ }; #define MAXOSDIMAGES 64 diff -ruN vdr-1.7.31-ext/pat.c vdr-1.7.31/pat.c --- vdr-1.7.31-ext/pat.c 2012-04-15 11:54:53.000000000 +0200 +++ vdr-1.7.31/pat.c 2012-09-19 23:54:19.000000000 +0200 @@ -13,6 +13,9 @@ #include "libsi/section.h" #include "libsi/descriptor.h" #include "thread.h" +#ifdef USE_TTXTSUBS +#include "vdrttxtsubshooks.h" +#endif // USE_TTXTSUBS #define PMT_SCAN_TIMEOUT 10 // seconds @@ -343,6 +346,10 @@ char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; int Tpid = 0; +#ifdef USE_TTXTSUBS + tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES]; + int NumTPages = 0; +#endif // USE_TTXTSUBS int NumApids = 0; int NumDpids = 0; int NumSpids = 0; @@ -436,6 +443,22 @@ break; case SI::TeletextDescriptorTag: Tpid = esPid; +#ifdef USE_TTXTSUBS + { + SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; + SI::TeletextDescriptor::Teletext ttxt; + for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { + bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); + if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) { + strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); + TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber(); + TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); + TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType(); + NumTPages++; + } + } + } +#endif // USE_TTXTSUBS break; case SI::ISO639LanguageDescriptorTag: { SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; @@ -547,6 +570,14 @@ } if (Setup.UpdateChannels >= 2) { Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); +#ifdef USE_TTXTSUBS + if (NumTPages < MAXTXTPAGES) { + int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); + if (manualPageNumber) + TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber); + } + Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); +#endif // USE_TTXTSUBS Channel->SetCaIds(CaDescriptors->CaIds()); Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); } diff -ruN vdr-1.7.31-ext/plugin.c vdr-1.7.31/plugin.c --- vdr-1.7.31-ext/plugin.c 2012-09-01 15:10:27.000000000 +0200 +++ vdr-1.7.31/plugin.c 2012-09-19 23:54:19.000000000 +0200 @@ -341,6 +341,14 @@ char *p = strchr(s, ' '); if (p) *p = 0; +#ifdef USE_PLUGINMISSING + struct stat st; + if (stat (cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), &st) && errno == ENOENT) { + esyslog("WARN: missing plugin '%s'", s); + fprintf(stderr, "vdr: missing plugin '%s'\n", s); + } + else +#endif /* PLUGINMISSING */ dlls.Add(new cDll(cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), Args)); free(s); } @@ -349,7 +357,11 @@ { for (cDll *dll = dlls.First(); dll; dll = dlls.Next(dll)) { if (!dll->Load(Log)) +#ifdef USE_PLUGINMISSING + ; +#else return false; +#endif /* PLUGINMISSING */ } return true; } diff -ruN vdr-1.7.31-ext/po/ar.po vdr-1.7.31/po/ar.po --- vdr-1.7.31-ext/po/ar.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/ar.po 2012-09-19 23:54:19.000000000 +0200 @@ -568,6 +568,9 @@ msgid "Sid" msgstr "" +msgid "Rid" +msgstr "" + msgid "Channel settings are not unique!" msgstr "اعدادات القناة غبر موحد" @@ -647,6 +650,15 @@ msgid "Lifetime" msgstr "معدل البقاء" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "نعم" + +msgid "no" +msgstr "ï»»" + msgid "File" msgstr "ملÙ" @@ -741,6 +753,33 @@ msgid "Button$Rewind" msgstr "اعادة" +msgid "Date" +msgstr "التاريخ" + +msgid "Length" +msgstr "الطول" + +msgid "Format" +msgstr "" + +msgid "PES" +msgstr "" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "الحجم" + +msgid "Delete marks information?" +msgstr "حذ٠معلومات العلامة" + +msgid "Delete resume information?" +msgstr "حذ٠معلومات المواصلة" + +msgid "Error while accessing recording!" +msgstr "حدث خطاء عند محاولة الوصول لتسجيلات" + msgid "Recordings" msgstr "التسجيلات" @@ -750,9 +789,6 @@ msgid "Commands" msgstr "الاوامر" -msgid "Error while accessing recording!" -msgstr "حدث خطاء عند محاولة الوصول لتسجيلات" - msgid "Delete recording?" msgstr "حذ٠التسجيل" @@ -787,6 +823,10 @@ msgstr " الثيمة" #, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "الخط صغير" + +#, fuzzy msgid "Setup.OSD$Left (%)" msgstr "يسار" @@ -911,6 +951,18 @@ msgid "Setup.EPG$Preferred language" msgstr "اللغة المقضلة" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "بحث Ø®ÙÙŠÙ" @@ -920,9 +972,6 @@ msgid "center cut out" msgstr "قص من الوسط" -msgid "no" -msgstr "ï»»" - msgid "names only" msgstr "الاسماء Ùقط" @@ -965,6 +1014,10 @@ msgid "Setup.DVB$Update channels" msgstr "تحديث القنوات" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr " موضع معلومات القناة" + msgid "Setup.DVB$Audio languages" msgstr "لغات الصوت" @@ -989,6 +1042,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Ø´ÙØ§Ùية الخلÙية" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "الاقط" @@ -1056,9 +1112,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "نعم" - msgid "Recording" msgstr "تسجيل" @@ -1084,6 +1137,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "معدل الايقا٠باليوم" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "مجلد التسجيلات" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "مجلد التسجيلات" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "تعطيل الاولويات" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "اقصى حجم لمل٠الÙيديو ب Ù… ب" + msgid "Setup.Recording$Use episode name" msgstr "استخدم اسم المرحلة" @@ -1108,6 +1177,12 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "اقصى حجم لمل٠الÙيديو ب Ù… ب" +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "اقصى حجم للتسجيل Ù… ب" + +msgid "Setup.Recording$Hard Link Cutter" +msgstr "قاطع وصلات الاختصرات" + msgid "Setup.Recording$Split edited files" msgstr "اقسم المل٠المعدل" @@ -1115,6 +1190,9 @@ msgid "Setup.Recording$Delete timeshift recording" msgstr "اسم التسجيل الÙورى" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "اعادة عرض" @@ -1130,6 +1208,38 @@ msgid "Setup.Replay$Resume ID" msgstr "رقم المواصلة" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "رقم المواصلة" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "رقم المواصلة" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "موءقت النوم" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "رقم المواصلة" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "رقم المواصلة" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "رقم المواصلة" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "القناة الاساسية" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "خروج طارىء" + msgid "Miscellaneous" msgstr "Ù…ØªÙØ±Ù‚ات" @@ -1158,6 +1268,18 @@ msgstr "ÙØ¹Ù„ الصوت" #, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "خروج طارىء" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "كسابق" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "كسابق" + +#, fuzzy msgid "Setup.Miscellaneous$Channels wrap" msgstr "كسابق" @@ -1167,6 +1289,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "خروج طارىء" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "خروج طارىء" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "كسابق" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "مدة انتهاء الحدث بالدقيقة" + msgid "Plugins" msgstr "الملحقات" @@ -1202,7 +1336,6 @@ msgid "Button$Resume" msgstr "مواصلة" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " تعديل القناة" diff -ruN vdr-1.7.31-ext/po/ca_ES.po vdr-1.7.31/po/ca_ES.po --- vdr-1.7.31-ext/po/ca_ES.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/ca_ES.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Propietats del canal duplicades!" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "Durada" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "sí" + +msgid "no" +msgstr "no" + msgid "File" msgstr "Arxiu" @@ -732,6 +745,36 @@ msgid "Button$Rewind" msgstr "Enrera" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Esborrar gravació?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Esborrar gravació?" + +msgid "Error while accessing recording!" +msgstr "Error a l'accedir a la gravació!" + msgid "Recordings" msgstr "Veure programes gravats" @@ -741,9 +784,6 @@ msgid "Commands" msgstr "Ordres" -msgid "Error while accessing recording!" -msgstr "Error a l'accedir a la gravació!" - msgid "Delete recording?" msgstr "Esborrar gravació?" @@ -777,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Font petita" + msgid "Setup.OSD$Left (%)" msgstr "Esquerra (%)" @@ -893,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Idioma preferit" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -902,9 +958,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "no" - msgid "names only" msgstr "només noms" @@ -947,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "Actualitza canals" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Posició de la informació del canal" + msgid "Setup.DVB$Audio languages" msgstr "Idiomes d'àudio" @@ -971,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparència fons subtítols" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Configuració de l'LNB" @@ -1035,9 +1095,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "sí" - msgid "Recording" msgstr "Opcions de Gravació" @@ -1062,6 +1119,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Durada de la pausa (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Gravacions en subcarpetes" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Gravacions en subcarpetes" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioritat de la pausa" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Mida màxima de l'arxiu (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Utilitzar el nom de l'episodi" @@ -1086,12 +1159,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Mida màxima de l'arxiu (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Mida màxima de l'arxiu (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Marcar gravació instantània" + msgid "Setup.Recording$Split edited files" msgstr "Separar arxius" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Opcions de Reproducció" @@ -1107,6 +1191,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID de Continuar" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID de Continuar" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID de Continuar" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Mode de multivelocitat" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID de Continuar" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID de Continuar" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID de Continuar" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Canal inicial" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Sortida d'emergència" + msgid "Miscellaneous" msgstr "Miscel·lània" @@ -1134,6 +1250,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volum inicial" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Sortida d'emergència" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Temps d'introducció canal (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "anterior" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1143,6 +1271,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Sortida d'emergència" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Sortida d'emergència" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "anterior" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Temps mínim en pausa (min)" + msgid "Plugins" msgstr "Plugins" @@ -1178,7 +1318,6 @@ msgid "Button$Resume" msgstr "Continuar" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Cancel·lar l'edició " diff -ruN vdr-1.7.31-ext/po/cs_CZ.po vdr-1.7.31/po/cs_CZ.po --- vdr-1.7.31-ext/po/cs_CZ.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/cs_CZ.po 2012-09-19 23:54:19.000000000 +0200 @@ -562,6 +562,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Nastavení kanálu není jedineÄné!" @@ -638,6 +642,15 @@ msgid "Lifetime" msgstr "Životnost" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ano" + +msgid "no" +msgstr "ne" + msgid "File" msgstr "Soubor" @@ -731,6 +744,36 @@ msgid "Button$Rewind" msgstr "Na zaÄátek" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Smazat nahrávku?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Smazat nahrávku?" + +msgid "Error while accessing recording!" +msgstr "Chyba pÅ™i přístupu k nahrávkám!" + msgid "Recordings" msgstr "Nahrávky" @@ -740,9 +783,6 @@ msgid "Commands" msgstr "Příkazy" -msgid "Error while accessing recording!" -msgstr "Chyba pÅ™i přístupu k nahrávkám!" - msgid "Delete recording?" msgstr "Smazat nahrávku?" @@ -776,6 +816,10 @@ msgid "Setup.OSD$Theme" msgstr "Téma" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Malé písmo" + msgid "Setup.OSD$Left (%)" msgstr "Vlevo (%)" @@ -892,6 +936,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Preferovaný jazyk" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -901,9 +957,6 @@ msgid "center cut out" msgstr "dostÅ™edu oříznout" -msgid "no" -msgstr "ne" - msgid "names only" msgstr "jen názvy" @@ -946,6 +999,10 @@ msgid "Setup.DVB$Update channels" msgstr "Aktualizace kanálů" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozice informace o kanálu" + msgid "Setup.DVB$Audio languages" msgstr "Jazyky zvuku" @@ -970,6 +1027,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Průhlednost pozadí titulků" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1034,9 +1094,6 @@ msgid "confirm" msgstr "potvrdit" -msgid "yes" -msgstr "ano" - msgid "Recording" msgstr "Nahrávání" @@ -1061,6 +1118,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Životnost pÅ™eruÅ¡ení (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Seznam nahrávek" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Seznam nahrávek" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Priorita pÅ™eruÅ¡ení" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maximální velikost nahrávky (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Používat název epizody" @@ -1085,12 +1158,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maximální velikost nahrávky (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maximální velikost nahrávky (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "OznaÄit okamžité nahrávky" + msgid "Setup.Recording$Split edited files" msgstr "DÄ›lit editované soubory" msgid "Setup.Recording$Delete timeshift recording" msgstr "Mazat nahrávky Timeshift" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "PÅ™ehrávání" @@ -1106,6 +1190,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID obnovení" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID obnovení" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID obnovení" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Vícerychlostní mód" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID obnovení" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID obnovení" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID obnovení" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanál po spuÅ¡tÄ›ní" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Nouzové ukonÄení" + msgid "Miscellaneous" msgstr "Různé" @@ -1133,6 +1249,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Hlasitost po spuÅ¡tÄ›ní" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Nouzové ukonÄení" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Prodleva pÅ™i volbÄ› kanálu (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "jako naposledy" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1142,6 +1270,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Nouzové ukonÄení" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Nouzové ukonÄení" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "jako naposledy" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. pauza mezi událostmi (min)" + msgid "Plugins" msgstr "Moduly" @@ -1177,7 +1317,6 @@ msgid "Button$Resume" msgstr "PokraÄovat" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " ZruÅ¡it editaci" diff -ruN vdr-1.7.31-ext/po/da_DK.po vdr-1.7.31/po/da_DK.po --- vdr-1.7.31-ext/po/da_DK.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/da_DK.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Kanalindstillinger er ikke entydige!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "Levetid" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nej" + msgid "File" msgstr "Fil" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "Forfra" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Slet optagelse?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Slet optagelse?" + +msgid "Error while accessing recording!" +msgstr "Fejl ved læsning af optagelse!" + msgid "Recordings" msgstr "Optagelser" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "Kommandoer" -msgid "Error while accessing recording!" -msgstr "Fejl ved læsning af optagelse!" - msgid "Delete recording?" msgstr "Slet optagelse?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Lille skrift" + msgid "Setup.OSD$Left (%)" msgstr "Venstre (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Foretrukket sprog" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nej" - msgid "names only" msgstr "kun navne" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Opdatér kanaler" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Placering af kanalinfo" + msgid "Setup.DVB$Audio languages" msgstr "Audio sprog (ant.)" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Undertekst baggrundsgennemsigtighed" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "ja" - msgid "Recording" msgstr "Optagelse" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Pause levetid (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Optagelser i foldere" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Optagelser i foldere" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Pause prioritet" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Max. video filstørrelse (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Anvend udsendelsesnavn" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Max. video filstørrelse (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Max. video filstørrelse (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Markér direkte optagelse" + msgid "Setup.Recording$Split edited files" msgstr "Opdel redigerede filer" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Afspilning" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Genoptagelses ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Genoptagelses ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Genoptagelses ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Multi hastighedsmodus" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Genoptagelses ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Genoptagelses ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Genoptagelses ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanal ved opstart" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Nødudgang" + msgid "Miscellaneous" msgstr "Diverse" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Lydstyrke ved opstart" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Nødudgang" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanal adgang timeout (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "som før" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Nødudgang" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Nødudgang" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "som før" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Mindste hændelsespause (min)" + msgid "Plugins" msgstr "Plugins" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "Fortsæt" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Afbryd redigering" diff -ruN vdr-1.7.31-ext/po/de_DE.po vdr-1.7.31/po/de_DE.po --- vdr-1.7.31-ext/po/de_DE.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/de_DE.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Kanaleinstellungen sind nicht eindeutig!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "Lebensdauer" +msgid "Childlock" +msgstr "Kindersicherung" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nein" + msgid "File" msgstr "Datei" @@ -729,6 +742,33 @@ msgid "Button$Rewind" msgstr "Anfang" +msgid "Date" +msgstr "Datum" + +msgid "Length" +msgstr "Länge" + +msgid "Format" +msgstr "Format" + +msgid "PES" +msgstr "PES" + +msgid "TS" +msgstr "TS" + +msgid "Size" +msgstr "Größe" + +msgid "Delete marks information?" +msgstr "Schnittmarken löschen?" + +msgid "Delete resume information?" +msgstr "Gespeicherten Zeitpunkt der letzten Wiedergabe löschen?" + +msgid "Error while accessing recording!" +msgstr "Fehler beim Ansprechen der Aufzeichnung!" + msgid "Recordings" msgstr "Aufzeichnungen" @@ -738,9 +778,6 @@ msgid "Commands" msgstr "Befehle" -msgid "Error while accessing recording!" -msgstr "Fehler beim Ansprechen der Aufzeichnung!" - msgid "Delete recording?" msgstr "Aufzeichnung löschen?" @@ -774,6 +811,10 @@ msgid "Setup.OSD$Theme" msgstr "Thema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Kleine Schriftart" + msgid "Setup.OSD$Left (%)" msgstr "Links (%)" @@ -890,6 +931,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Bevorzugte Sprache" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "Zeitspanne für dop. EPG-Suche(min)" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "Doppelten externen EPG-Eintrag" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "Internen und externen EPG mischen" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "Erk. des lauf. VPS-Events abschalten" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +952,6 @@ msgid "center cut out" msgstr "Center-cut-out" -msgid "no" -msgstr "nein" - msgid "names only" msgstr "nur Namen" @@ -944,6 +994,9 @@ msgid "Setup.DVB$Update channels" msgstr "Kanäle aktualisieren" +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanal per Rid zuordnen" + msgid "Setup.DVB$Audio languages" msgstr "Audio-Sprachen" @@ -968,6 +1021,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Untertitel-Transparenz Hintergrund" +msgid "Setup.DVB$Enable teletext support" +msgstr "Videotext-Unterstützung aktivieren" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1088,6 @@ msgid "confirm" msgstr "bestätigen" -msgid "yes" -msgstr "ja" - msgid "Recording" msgstr "Aufnahme" @@ -1059,6 +1112,21 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Pause-Lebensdauer (d)" +# DVLVIDPREFER +msgid "Setup.Recording$Video directory policy" +msgstr "Videoverzeichnispolitik" + +msgid "Setup.Recording$Number of video directories" +msgstr "Anzahl der Videoverzeichnisse" + +#, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Video %d Priorität" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Video %d min. MB frei" + msgid "Setup.Recording$Use episode name" msgstr "Episodenname verwenden" @@ -1083,12 +1151,25 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Max. Videodateigröße (MB)" +# HARDLINKCUTTER +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Max. Videodateigröße (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Direktaufzeichnung markieren" +# HARDLINKCUTTER END + msgid "Setup.Recording$Split edited files" msgstr "Editierte Dateien aufteilen" msgid "Setup.Recording$Delete timeshift recording" msgstr "Zeitversetzte Aufnahme löschen" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Wiedergabe" @@ -1104,6 +1185,35 @@ msgid "Setup.Replay$Resume ID" msgstr "Wiedergabe-ID" +msgid "Setup.Replay$Jump&Play" +msgstr "Wiedergabe nach Sprung" + +msgid "Setup.Replay$Play&Jump" +msgstr "Sprung bei Schnittmarke" + +msgid "Setup.Replay$Pause at last mark" +msgstr "Pause bei letzter Marke" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Sprungweite in Sekunden" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Sprungweite in Sekunden" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Sprungweite in Sek. (wiederh.)" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanal beim Einschalten" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Notausstieg" + msgid "Miscellaneous" msgstr "Sonstiges" @@ -1131,6 +1241,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Lautstärke beim Einschalten" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Notausstieg" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Rundum zappen" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "wie vorher" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Rundum zappen" @@ -1140,6 +1262,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Notausstieg" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Notausstieg" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "wie vorher" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Brückenzeit zwischen Timern (min)" + msgid "Plugins" msgstr "Plugins" @@ -1175,7 +1309,6 @@ msgid "Button$Resume" msgstr "Weiter" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Schneiden abbrechen" @@ -1380,3 +1513,48 @@ msgid "free" msgstr "frei" + +#. USE_LIEMIKUUTIO +msgid "Edit recording" +msgstr "Aufnahme bearbeiten" + +msgid "Button$Cut" +msgstr "Schneiden" + +msgid "Button$Copy" +msgstr "Kopieren" + +msgid "Button$Rename/Move" +msgstr "Umbenennen/Bewegen" + +msgid "File transfer started" +msgstr "Dateiübertragung gestartet" + +msgid "Can't start file transfer!" +msgstr "Dateiübertragung kann nicht gestartet werden!" + +msgid "File transfer already active!" +msgstr "Dateiübertragung bereits aktiv!" + +#. TRANSLATORS: note the leading blank! +msgid " Cancel file transfer" +msgstr " Dateiübertragung beenden" + +msgid "Cancel file transfer?" +msgstr "Dateiübertragung beenden?" + +msgid "Transfering file - shut down anyway?" +msgstr "Übertrage Datei - trotzdem ausschalten?" + +msgid "Transfering file - restart anyway?" +msgstr "Übertrage Datei - trotzdem neustarten?" + +msgid "File transfer failed!" +msgstr "Dateiübertragung fehlgeschlagen!" + +msgid "File transfer finished" +msgstr "Dateiübertragung fertiggestellt" + +msgid "File already exists - overwrite?" +msgstr "Datei besteht bereits - überschreiben?" +#. LIEMIKUUTIO diff -ruN vdr-1.7.31-ext/po/el_GR.po vdr-1.7.31/po/el_GR.po --- vdr-1.7.31-ext/po/el_GR.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/el_GR.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Ïé ñéèìýóåéò ôïí êáíáëéþí áëëõëïóõìðßðôïõí!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "ÄéÝñêåéá ÐáñáìïíÞò" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "íáß" + +msgid "no" +msgstr "ü÷é" + msgid "File" msgstr "Áñ÷åßï" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "ÌåôáöïñÜ óôçí Áñ÷Þ" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "ÄéáãñáöÞ åããñáöÞò?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "ÄéáãñáöÞ åããñáöÞò?" + +msgid "Error while accessing recording!" +msgstr "Ðñüâëçìá óôÞí ðñïóðÝëáóç åããñáöÞò!" + msgid "Recordings" msgstr "ÅããñáöÝò" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "ÅíôïëÝò" -msgid "Error while accessing recording!" -msgstr "Ðñüâëçìá óôÞí ðñïóðÝëáóç åããñáöÞò!" - msgid "Delete recording?" msgstr "ÄéáãñáöÞ åããñáöÞò?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "ÈÝìá" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Ãëþóóá" + msgid "Setup.OSD$Left (%)" msgstr "ÁñéóôåñÜ (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Ðñïôåéíüìåíç ãëþóóá" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "ü÷é" - msgid "names only" msgstr "ìüíï ïíüìáôá" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "ÅíçìÝñùóç êáíáëéþí" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "ÈÝóç ðëçñïöïñßáò êáíáëéþí" + msgid "Setup.DVB$Audio languages" msgstr "Ãëþóóåò Þ÷ïõ" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "íáß" - msgid "Recording" msgstr "ÅããñáöÞ" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "ÄéÜñêåéá äéáëåßìáôïò" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "ÖÜêåëïé åããñáöþí" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "ÖÜêåëïé åããñáöþí" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Ðñïôåñáéüôçôá äéáëåßììáôïò" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "ÌÝãéóôï ìÝãåèïò áñ÷åßïõ (MB)" + msgid "Setup.Recording$Use episode name" msgstr "×ñÞóç ïíüìáôïò åðåéóïäßïõ" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "ÌÝãéóôï ìÝãåèïò áñ÷åßïõ (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "ÌÝãéóôï ìÝãåèïò áñ÷åßïõ (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "ÅðéëïãÞ ôñÝ÷ïõóáò åããñáöÞò" + msgid "Setup.Recording$Split edited files" msgstr "ÄéáìÝëéóìüò åðåîåñãáóìÝíùí áñ÷åßùí" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "ÁíáðáñáãùãÞ" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID áíáìåôÜäïóçò" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID áíáìåôÜäïóçò" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID áíáìåôÜäïóçò" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Ìåèïäïò ðïëëáðëÞò ôá÷ýôçôáò" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID áíáìåôÜäïóçò" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID áíáìåôÜäïóçò" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID áíáìåôÜäïóçò" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + msgid "Miscellaneous" msgstr "ÄéÜöïñá" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "ÆÜðéíãê äéáêïðÞ (ä)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "ÆÜðéíãê äéáêïðÞ (ä)" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)" + msgid "Plugins" msgstr "ÅðåêôÜóåéò" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "ÅðáíáöïñÜ" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Áêýñùóç åðåîåñãáóßáò" diff -ruN vdr-1.7.31-ext/po/es_ES.po vdr-1.7.31/po/es_ES.po --- vdr-1.7.31-ext/po/es_ES.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/es_ES.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "!Propiedades de canal duplicadas!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Duración" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "sí" + +msgid "no" +msgstr "no" + msgid "File" msgstr "Fichero" @@ -730,6 +743,36 @@ msgid "Button$Rewind" msgstr "Rebobinar" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "¿Eliminar grabacion?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "¿Eliminar grabacion?" + +msgid "Error while accessing recording!" +msgstr "¡Error al acceder a la grabación!" + msgid "Recordings" msgstr "Grabaciones" @@ -739,9 +782,6 @@ msgid "Commands" msgstr "Órdenes" -msgid "Error while accessing recording!" -msgstr "¡Error al acceder a la grabación!" - msgid "Delete recording?" msgstr "¿Eliminar grabacion?" @@ -775,6 +815,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Fuente pequeña" + msgid "Setup.OSD$Left (%)" msgstr "Izquierda (%)" @@ -891,6 +935,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Idioma preferido" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -900,9 +956,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "no" - msgid "names only" msgstr "sólo nombres" @@ -945,6 +998,10 @@ msgid "Setup.DVB$Update channels" msgstr "Actualizar canales" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Posición para información de canal" + msgid "Setup.DVB$Audio languages" msgstr "Idiomas de audio" @@ -969,6 +1026,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparencia fondo subtítulos" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1093,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "sí" - msgid "Recording" msgstr "Opciones de grabación" @@ -1060,6 +1117,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Duración en modo pausa (días)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Mostrar directorios de grabaciones" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Mostrar directorios de grabaciones" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioridad en modo pausa" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Tamaño máximo de fichero (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Utilizar nombre de episodo" @@ -1084,12 +1157,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Tamaño máximo de fichero (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Tamaño máximo de fichero (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Marcar grabaciones inmediatas" + msgid "Setup.Recording$Split edited files" msgstr "Partir ficheros editados" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Opciones de reproducción" @@ -1105,6 +1189,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID de continuación" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID de continuación" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID de continuación" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Modo multi-velocidad" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID de continuación" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID de continuación" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID de continuación" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Canal inicial" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Salida de emergencia" + msgid "Miscellaneous" msgstr "Varios" @@ -1132,6 +1248,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volumen inicial" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Salida de emergencia" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Tiempo introducción canal (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "anterior" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1141,6 +1269,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Salida de emergencia" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Salida de emergencia" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "anterior" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Tiempo mín. antes de un evento (m)" + msgid "Plugins" msgstr "Plugins" @@ -1176,7 +1316,6 @@ msgid "Button$Resume" msgstr "Continuar" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Anular edición" diff -ruN vdr-1.7.31-ext/po/et_EE.po vdr-1.7.31/po/et_EE.po --- vdr-1.7.31-ext/po/et_EE.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/et_EE.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,9 @@ msgid "Sid" msgstr "Sid" +msgid "Rid" +msgstr "" + msgid "Channel settings are not unique!" msgstr "Kanaliseaded ei ole unikaalsed!" @@ -636,6 +639,15 @@ msgid "Lifetime" msgstr "Eluiga" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "jah" + +msgid "no" +msgstr "ei" + msgid "File" msgstr "Fail" @@ -729,6 +741,33 @@ msgid "Button$Rewind" msgstr "Algusesse" +msgid "Date" +msgstr "Kuupäev" + +msgid "Length" +msgstr "Kestus" + +msgid "Format" +msgstr "Formaat" + +msgid "PES" +msgstr "PES" + +msgid "TS" +msgstr "TS" + +msgid "Size" +msgstr "Suurus" + +msgid "Delete marks information?" +msgstr "Kustutada märkide info?" + +msgid "Delete resume information?" +msgstr "Kustutada jätkamise info?" + +msgid "Error while accessing recording!" +msgstr "Salvestuse taasesitus nurjus!" + msgid "Recordings" msgstr "Salvestused" @@ -738,9 +777,6 @@ msgid "Commands" msgstr "Käsud" -msgid "Error while accessing recording!" -msgstr "Salvestuse taasesitus nurjus!" - msgid "Delete recording?" msgstr "Kustutada salvestus?" @@ -774,6 +810,10 @@ msgid "Setup.OSD$Theme" msgstr "Teema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Väike font" + msgid "Setup.OSD$Left (%)" msgstr "Nihe paremale (%)" @@ -890,6 +930,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Eelistatud keel" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +951,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "ei" - msgid "names only" msgstr "nimed" @@ -944,6 +993,10 @@ msgid "Setup.DVB$Update channels" msgstr "Kanalite uuendamine" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanaliinfo asukoht" + msgid "Setup.DVB$Audio languages" msgstr "Audio keeli" @@ -968,6 +1021,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Subtiitri tausta läbipaistvus" +msgid "Setup.DVB$Enable teletext support" +msgstr "Teleteksti tugi" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1088,6 @@ msgid "confirm" msgstr "kinnitada" -msgid "yes" -msgstr "jah" - msgid "Recording" msgstr "Salvestamine" @@ -1059,6 +1112,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Pausi eluiga (päevi)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Kausta nime salvestamine" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Kausta nime salvestamine" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Pausi prioriteet" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maks. failisuurus (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Episoodinime kasutamine" @@ -1083,12 +1152,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maks. failisuurus (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maks. failisuurus (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Kiirsalvestuse märgistamine" + msgid "Setup.Recording$Split edited files" msgstr "Failide jupitamine" msgid "Setup.Recording$Delete timeshift recording" msgstr "Kustutada ajanihke salvestus" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Taasesitus" @@ -1104,6 +1184,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Jätkamise ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Jätkamise ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Jätkamise ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Mitmekiiruse moodus" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Jätkamise ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Jätkamise ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Jätkamise ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanal käivitamisel" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Hädaväljumine" + msgid "Miscellaneous" msgstr "Muud sätted" @@ -1131,6 +1243,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Helitugevus käivitamisel" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Hädaväljumine" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanalite ringkerimine" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "endine" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Kanalite ringkerimine" @@ -1140,6 +1264,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Hädaväljumine" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Hädaväljumine" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "endine" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. saate taimaut (min)" + msgid "Plugins" msgstr "Laiendusmoodulid" @@ -1175,7 +1311,6 @@ msgid "Button$Resume" msgstr "Jätkata" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Katkestada redigeerimine" diff -ruN vdr-1.7.31-ext/po/fi_FI.po vdr-1.7.31/po/fi_FI.po --- vdr-1.7.31-ext/po/fi_FI.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/fi_FI.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Palvelu-ID" +#, fuzzy +msgid "Rid" +msgstr "Palvelu-ID" + msgid "Channel settings are not unique!" msgstr "Kanava-asetukset eivät ole yksilölliset!" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "Elinikä" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "kyllä" + +msgid "no" +msgstr "ei" + msgid "File" msgstr "Tiedosto" @@ -732,6 +745,33 @@ msgid "Button$Rewind" msgstr "Alkuun" +msgid "Date" +msgstr "Päiväys" + +msgid "Length" +msgstr "Pituus" + +msgid "Format" +msgstr "Tiedostomuoto" + +msgid "PES" +msgstr "PES" + +msgid "TS" +msgstr "TS" + +msgid "Size" +msgstr "Koko" + +msgid "Delete marks information?" +msgstr "Poista tallenteen merkinnät?" + +msgid "Delete resume information?" +msgstr "Poista tallenteen paluutiedot?" + +msgid "Error while accessing recording!" +msgstr "Tallenteen toistaminen epäonnistui!" + msgid "Recordings" msgstr "Tallenteet" @@ -741,9 +781,6 @@ msgid "Commands" msgstr "Komennot" -msgid "Error while accessing recording!" -msgstr "Tallenteen toistaminen epäonnistui!" - msgid "Delete recording?" msgstr "Poistetaanko tallenne?" @@ -777,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Teema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Pieni kirjasintyyppi" + msgid "Setup.OSD$Left (%)" msgstr "Vaakakeskitys (%)" @@ -893,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Suosikkikieli" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -902,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "ei" - msgid "names only" msgstr "vain nimet" @@ -947,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Päivitä kanavat" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanavatiedon sijainti" + msgid "Setup.DVB$Audio languages" msgstr "Äänen kielet" @@ -971,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Tekstityksen taustan läpinäkyvyys" +msgid "Setup.DVB$Enable teletext support" +msgstr "Salli teksti-TV-tuki" + msgid "LNB" msgstr "LNB" @@ -1035,9 +1092,6 @@ msgid "confirm" msgstr "varmista" -msgid "yes" -msgstr "kyllä" - msgid "Recording" msgstr "Tallennus" @@ -1062,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Taukotallenteen elinikä (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Näytä tallennehakemistot" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Näytä tallennehakemistot" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Taukotallenteen prioriteetti" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Suurin tiedostokoko (Mt)" + msgid "Setup.Recording$Use episode name" msgstr "Käytä jakson nimeä" @@ -1086,12 +1156,25 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Suurin tiedostokoko (Mt)" +# HARDLINKCUTTER +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Suurin tiedostokoko (Mt)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Merkitse pikatallenne" +# HARDLINKCUTTER END + msgid "Setup.Recording$Split edited files" msgstr "Jaottele muokatut tallenteet" msgid "Setup.Recording$Delete timeshift recording" msgstr "Poista ajansiirtotallenne" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Toisto" @@ -1107,6 +1190,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Tallenteen paluutunniste" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Tallenteen paluutunniste" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Tallenteen paluutunniste" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Käytä toiston moninopeustilaa" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Tallenteen paluutunniste" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Tallenteen paluutunniste" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Tallenteen paluutunniste" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanava käynnistettäessä" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Käytä hätäsammutusta" + msgid "Miscellaneous" msgstr "Sekalaiset" @@ -1134,6 +1249,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Äänenvoimakkuus käynnistettäessä" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Käytä hätäsammutusta" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanavien rullaus" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "edellinen" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Kanavien rullaus" @@ -1143,6 +1270,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Käytä hätäsammutusta" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Käytä hätäsammutusta" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "edellinen" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Tapahtuman odotusaika (min)" + msgid "Plugins" msgstr "Laajennokset" @@ -1178,7 +1317,6 @@ msgid "Button$Resume" msgstr "Jatka" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Peru muokkaus" @@ -1383,3 +1521,48 @@ msgid "free" msgstr "vapaana" + +#. USE_LIEMIKUUTIO +msgid "Edit recording" +msgstr "Muokkaa tallennetta" + +msgid "Button$Cut" +msgstr "Leikkaa" + +msgid "Button$Copy" +msgstr "Kopioi" + +msgid "Button$Rename/Move" +msgstr "Nimeä/Siirrä" + +msgid "File transfer started" +msgstr "Tiedoston siirto aloitettu" + +msgid "Can't start file transfer!" +msgstr "Tiedoston siirron aloitus epäonnistui!" + +msgid "File transfer already active!" +msgstr "Tiedoston siirto on jo käynnissä!" + +#. TRANSLATORS: note the leading blank! +msgid " Cancel file transfer" +msgstr " Peru tiedoston siirto" + +msgid "Cancel file transfer?" +msgstr "Perutaanko tiedoston siirto?" + +msgid "Transfering file - shut down anyway?" +msgstr "Tiedoston siirto kesken - sammutetaanko?" + +msgid "Transfering file - restart anyway?" +msgstr "Tiedoston siirto kesken - käynnistetäänkö uudelleen?" + +msgid "File transfer failed!" +msgstr "Tiedoston siirto epäonnistui!" + +msgid "File transfer finished" +msgstr "Tiedoston siirto valmis" + +msgid "File already exists - overwrite?" +msgstr "Tiedosto on jo olemassa - ylikirjoitetaanko?" +#. LIEMIKUUTIO diff -ruN vdr-1.7.31-ext/po/fr_FR.po vdr-1.7.31/po/fr_FR.po --- vdr-1.7.31-ext/po/fr_FR.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/fr_FR.po 2012-09-19 23:54:19.000000000 +0200 @@ -566,6 +566,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Caractéristiques des chaînes non uniques" @@ -642,6 +646,15 @@ msgid "Lifetime" msgstr "Durée de vie" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "oui" + +msgid "no" +msgstr "non" + msgid "File" msgstr "Fichier" @@ -735,6 +748,33 @@ msgid "Button$Rewind" msgstr "Retour" +msgid "Date" +msgstr "Date" + +msgid "Length" +msgstr "Longueur" + +msgid "Format" +msgstr "Format" + +msgid "PES" +msgstr "PES" + +msgid "TS" +msgstr "TS" + +msgid "Size" +msgstr "Taille" + +msgid "Delete marks information?" +msgstr "Effacer les informations de marquage" + +msgid "Delete resume information?" +msgstr "Effacer les informations de reprise" + +msgid "Error while accessing recording!" +msgstr "Impossible d'accéder à l'enregistrement" + msgid "Recordings" msgstr "Enregistrements" @@ -744,9 +784,6 @@ msgid "Commands" msgstr "Commandes" -msgid "Error while accessing recording!" -msgstr "Impossible d'accéder à l'enregistrement" - msgid "Delete recording?" msgstr "Supprimer l'enregistrement ?" @@ -780,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "Thème" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Petite police" + msgid "Setup.OSD$Left (%)" msgstr "Gauche (%)" @@ -896,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Langue préférée" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "Intervalle de recherche du double EPG(min)" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "Entrée EPG externe en double" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "Mixer EPG interne et externe" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "Désactiver événement VPS" + msgid "pan&scan" msgstr "pan&scan" @@ -905,9 +958,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "non" - msgid "names only" msgstr "noms uniquement" @@ -950,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "Mettre à jour les chaînes" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Position infos chaînes" + msgid "Setup.DVB$Audio languages" msgstr "Langues audio" @@ -974,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparence du fond" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1038,9 +1095,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "oui" - msgid "Recording" msgstr "Enregistrement" @@ -1065,6 +1119,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Durée de vie des pauses (j)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Dossiers d'enregistrements" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Dossiers d'enregistrements" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Priorité des pauses" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Taille maxi des fichiers (Mo)" + msgid "Setup.Recording$Use episode name" msgstr "Utiliser le nom de l'épisode" @@ -1089,12 +1159,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Taille maxi des fichiers (Mo)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Taille maxi des fichiers (Mo)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Marquage enregistr. immédiats" + msgid "Setup.Recording$Split edited files" msgstr "Séparer les séquences éditées" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Lecture" @@ -1110,6 +1191,35 @@ msgid "Setup.Replay$Resume ID" msgstr "ID de reprise" +msgid "Setup.Replay$Jump&Play" +msgstr "Lecture après saut" + +msgid "Setup.Replay$Play&Jump" +msgstr "Saut sur les marques de découpes" + +msgid "Setup.Replay$Pause at last mark" +msgstr "Pause après la dernière marque" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Lecture après saut" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Lecture après saut" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Lecture après saut" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Chaîne initiale" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Arrêt d'urgence" + msgid "Miscellaneous" msgstr "Divers" @@ -1137,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volume initial" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Arrêt d'urgence" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Entrée chaîne timeout (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "comme avant" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1146,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Arrêt d'urgence" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Arrêt d'urgence" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "comme avant" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "MinEventTimeout (min)" + msgid "Plugins" msgstr "Greffons" @@ -1181,7 +1315,6 @@ msgid "Button$Resume" msgstr "Reprendre" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Annuler le montage" diff -ruN vdr-1.7.31-ext/po/hr_HR.po vdr-1.7.31/po/hr_HR.po --- vdr-1.7.31-ext/po/hr_HR.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/hr_HR.po 2012-09-19 23:54:19.000000000 +0200 @@ -562,6 +562,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Postavke programa nisu jedinstvene!" @@ -638,6 +642,15 @@ msgid "Lifetime" msgstr "Trajanje" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "da" + +msgid "no" +msgstr "ne" + msgid "File" msgstr "Datoteka" @@ -731,6 +744,36 @@ msgid "Button$Rewind" msgstr "Na poèetak" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Obrisati snimku?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Obrisati snimku?" + +msgid "Error while accessing recording!" +msgstr "Gre¹ka pri pristupanju snimke!" + msgid "Recordings" msgstr "Snimke" @@ -740,9 +783,6 @@ msgid "Commands" msgstr "Naredbe" -msgid "Error while accessing recording!" -msgstr "Gre¹ka pri pristupanju snimke!" - msgid "Delete recording?" msgstr "Obrisati snimku?" @@ -776,6 +816,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Maleni font" + msgid "Setup.OSD$Left (%)" msgstr "Lijevo (%)" @@ -892,6 +936,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Preferirani jezik" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pro¹iri I ispitaj" @@ -901,9 +957,6 @@ msgid "center cut out" msgstr "izre¾i sredinu" -msgid "no" -msgstr "ne" - msgid "names only" msgstr "samo imena" @@ -946,6 +999,10 @@ msgid "Setup.DVB$Update channels" msgstr "Aktualiziraj programe" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozicija informacija o programu" + msgid "Setup.DVB$Audio languages" msgstr "Audio jezici" @@ -970,6 +1027,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparentnost pozadine titla" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1034,9 +1094,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "da" - msgid "Recording" msgstr "Snimanje" @@ -1061,6 +1118,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Trajanje pauze (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Imenik za snimke" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Imenik za snimke" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioritet pauze" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maksimalna velièina datoteke (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Koristi ime epizode" @@ -1085,12 +1158,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maksimalna velièina datoteke (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maksimalna velièina datoteke (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Oznaèi direktno snimanje" + msgid "Setup.Recording$Split edited files" msgstr "Podijeli ureðene datoteke" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Reprodukcija" @@ -1106,6 +1190,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID nastavka" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Vi¹estruke brzine prikaza" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Poèetni kanal" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Izlaz u sluèaju nu¾de" + msgid "Miscellaneous" msgstr "Raznovrsno" @@ -1133,6 +1249,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Poèetna jaèina zvuka" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Izlaz u sluèaju nu¾de" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Upis kanala istjeèe (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "kao prethodno" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1142,6 +1270,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Izlaz u sluèaju nu¾de" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Izlaz u sluèaju nu¾de" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "kao prethodno" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minimalno vrijeme pauze" + msgid "Plugins" msgstr "Dodaci" @@ -1177,7 +1317,6 @@ msgid "Button$Resume" msgstr "Nastavi" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Prekini ureðivanje" diff -ruN vdr-1.7.31-ext/po/hu_HU.po vdr-1.7.31/po/hu_HU.po --- vdr-1.7.31-ext/po/hu_HU.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/hu_HU.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Az adóbeállítások nem egyértelmûek" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "Élettartam" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "igen" + +msgid "no" +msgstr "nem" + msgid "File" msgstr "File" @@ -732,6 +745,36 @@ msgid "Button$Rewind" msgstr "Vissza az elejére" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Felvétel törlése?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Felvétel törlése?" + +msgid "Error while accessing recording!" +msgstr "Hiba a felvétel hozzáférésénél" + msgid "Recordings" msgstr "Felvételek" @@ -741,9 +784,6 @@ msgid "Commands" msgstr "Parancsok" -msgid "Error while accessing recording!" -msgstr "Hiba a felvétel hozzáférésénél" - msgid "Delete recording?" msgstr "Felvétel törlése?" @@ -777,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "Téma" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Kis betûtipus" + msgid "Setup.OSD$Left (%)" msgstr "Balra (%)" @@ -893,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Kedvenc nyelv" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -902,9 +958,6 @@ msgid "center cut out" msgstr "képközép kivágás" -msgid "no" -msgstr "nem" - msgid "names only" msgstr "kizárólag nevek" @@ -947,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "Adók aktualizálása" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Adásinformáció poziciója" + msgid "Setup.DVB$Audio languages" msgstr "Hangsáv nyelvek" @@ -971,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Felirat hátterének transzparenciája" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1036,9 +1096,6 @@ msgid "confirm" msgstr "megerõsítés" -msgid "yes" -msgstr "igen" - msgid "Recording" msgstr "Felvétel" @@ -1063,6 +1120,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Idõeltolás élettartama" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Felvételek listája" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Felvételek listája" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Szünet prioritás" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Max. video File-terjedelem (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Epizódnév" @@ -1087,12 +1160,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Max. video file méret (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Max. video File-terjedelem (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Direktfelvétel megjelölése" + msgid "Setup.Recording$Split edited files" msgstr "Feldolgozott file-ok felosztása" msgid "Setup.Recording$Delete timeshift recording" msgstr "Idõeltolásos felvétel törlése" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Lejátszás" @@ -1108,6 +1192,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Lejátszás ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Lejátszás ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Lejátszás ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "MultiSpeed funkció" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Lejátszás ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Lejátszás ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Lejátszás ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Adás a bekapcsolásnál" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "ahogy az elõbb" + msgid "Miscellaneous" msgstr "Egyéb" @@ -1135,6 +1251,15 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Hangerõ indulásnál" +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "" + +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "" + +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Csatornalista görgetése" @@ -1144,6 +1269,15 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Vészleállítás" +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "" + +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "" + +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "" + msgid "Plugins" msgstr "Plugins" @@ -1179,7 +1313,6 @@ msgid "Button$Resume" msgstr "Tovább" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Vágást megszakítani" diff -ruN vdr-1.7.31-ext/po/it_IT.po vdr-1.7.31/po/it_IT.po --- vdr-1.7.31-ext/po/it_IT.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/it_IT.po 2012-09-19 23:54:19.000000000 +0200 @@ -567,6 +567,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Parametri canale non univoci!" @@ -643,6 +647,15 @@ msgid "Lifetime" msgstr "Scadenza" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "sì" + +msgid "no" +msgstr "no" + msgid "File" msgstr "Nome" @@ -736,6 +749,36 @@ msgid "Button$Rewind" msgstr "Riavvolgi" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Eliminare la registrazione?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Eliminare la registrazione?" + +msgid "Error while accessing recording!" +msgstr "Errore accesso alla registrazione!" + msgid "Recordings" msgstr "Registrazioni" @@ -745,9 +788,6 @@ msgid "Commands" msgstr "Comandi" -msgid "Error while accessing recording!" -msgstr "Errore accesso alla registrazione!" - msgid "Delete recording?" msgstr "Eliminare la registrazione?" @@ -781,6 +821,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema colori" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Caratteri piccoli" + msgid "Setup.OSD$Left (%)" msgstr "Sinistra (%)" @@ -897,6 +941,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Lingua preferita" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -906,9 +962,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "no" - msgid "names only" msgstr "solo nomi" @@ -951,6 +1004,10 @@ msgid "Setup.DVB$Update channels" msgstr "Aggiornamento canali" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Posizione info canale" + msgid "Setup.DVB$Audio languages" msgstr "Lingue audio" @@ -975,6 +1032,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Trasparenza sfondo sottotitoli" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1039,9 +1099,6 @@ msgid "confirm" msgstr "conferma" -msgid "yes" -msgstr "sì" - msgid "Recording" msgstr "Registrazione" @@ -1066,6 +1123,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Scadenza pausa (gg)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Directory di registrazione" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Directory di registrazione" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Priorità di pausa" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Dim. massima file video (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Utilizza nome episodio" @@ -1090,12 +1163,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Dim. massima file video (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Dim. massima file video (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Segna reg. immediata" + msgid "Setup.Recording$Split edited files" msgstr "Dividi i file modificati" msgid "Setup.Recording$Delete timeshift recording" msgstr "Elimina registrazione timeshift" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Riproduzione" @@ -1111,6 +1195,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID di ripristino" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID di ripristino" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID di ripristino" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Modalità multispeed" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID di ripristino" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID di ripristino" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID di ripristino" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Canale iniziale" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Uscita di emergenza" + msgid "Miscellaneous" msgstr "Generici" @@ -1138,6 +1254,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volume iniziale" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Uscita di emergenza" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Riavvolgimento canali" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "come prima" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Riavvolgimento canali" @@ -1147,6 +1275,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Uscita di emergenza" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Uscita di emergenza" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "come prima" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Scadenza min. evento (min)" + msgid "Plugins" msgstr "Plugins" @@ -1182,7 +1322,6 @@ msgid "Button$Resume" msgstr "Riprendi" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Annulla modifiche" diff -ruN vdr-1.7.31-ext/po/lt_LT.po vdr-1.7.31/po/lt_LT.po --- vdr-1.7.31-ext/po/lt_LT.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/lt_LT.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Serviso id" +#, fuzzy +msgid "Rid" +msgstr "Serviso id" + msgid "Channel settings are not unique!" msgstr "Kanalų nustatymai neunikalÅ«s!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "Galiojimas" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "taip" + +msgid "no" +msgstr "ne" + msgid "File" msgstr "Failas" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "Atsukti" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "IÅ¡trinti įrašą?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "IÅ¡trinti įrašą?" + +msgid "Error while accessing recording!" +msgstr "Klaida atidarant įrašą!" + msgid "Recordings" msgstr "Ä®raÅ¡ai" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "Komandos" -msgid "Error while accessing recording!" -msgstr "Klaida atidarant įrašą!" - msgid "Delete recording?" msgstr "IÅ¡trinti įrašą?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Mažas Å¡riftas" + msgid "Setup.OSD$Left (%)" msgstr "Atitraukimas nuo kairÄ—s (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Pageidaujama kalba" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "panŲscan" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "ne" - msgid "names only" msgstr "tik pavadinimai" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Atnaujinti kanalus" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanalo informacijos lango pozicija" + msgid "Setup.DVB$Audio languages" msgstr "Garso takeliai" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Subtitrų fono permatomumas" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Konverteris (LNB)" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "patvirtinti" -msgid "yes" -msgstr "taip" - msgid "Recording" msgstr "Ä®raÅ¡ymas" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "AtidÄ—tos peržiÅ«roso saugojimas (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Ä®rašų katalogai" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Ä®rašų katalogai" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "AtidÄ—tos peržiÅ«ros prioritetas" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maks. video failo dydis (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Grupuoti pagal epizodus" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maks. video failo dydis (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maks. video failo dydis (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "PažymÄ—ti rankiniu bÅ«du vykdomus įraÅ¡us" + msgid "Setup.Recording$Split edited files" msgstr "Suskaidyti koreguotus failus" msgid "Setup.Recording$Delete timeshift recording" msgstr "Trinti atidÄ—to grojimo įrašą" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Pakartojimai" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "KÅ«rinio ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "KÅ«rinio ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "KÅ«rinio ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Prasukimo ręžimas" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "KÅ«rinio ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "KÅ«rinio ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "KÅ«rinio ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanalas įjungimo metu" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Avarinis išėjimas" + msgid "Miscellaneous" msgstr "Kiti" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Garsas įjungimo metu" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Avarinis išėjimas" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanalų pridengimas" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "kaip anksÄiau" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Kanalų pridengimas" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Avarinis išėjimas" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Avarinis išėjimas" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "kaip anksÄiau" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. įvykio laukimo laikas (min)" + msgid "Plugins" msgstr "Ä®skiepai" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "PradÄ—ti" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Sustabdyti koregavimÄ…" diff -ruN vdr-1.7.31-ext/po/mk_MK.po vdr-1.7.31/po/mk_MK.po --- vdr-1.7.31-ext/po/mk_MK.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/mk_MK.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Уредбите на каналот не Ñе уникатни!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Траење" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "да" + +msgid "no" +msgstr "не" + msgid "File" msgstr "Датотека" @@ -730,6 +743,36 @@ msgid "Button$Rewind" msgstr "Премотај" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Избриши Ñнимка?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Избриши Ñнимка?" + +msgid "Error while accessing recording!" +msgstr "Грешка при приÑтап до Ñнимката!" + msgid "Recordings" msgstr "Снимки" @@ -739,9 +782,6 @@ msgid "Commands" msgstr "Ðаредби" -msgid "Error while accessing recording!" -msgstr "Грешка при приÑтап до Ñнимката!" - msgid "Delete recording?" msgstr "Избриши Ñнимка?" @@ -775,6 +815,10 @@ msgid "Setup.OSD$Theme" msgstr "Тема" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Мал фонт" + msgid "Setup.OSD$Left (%)" msgstr "Лево (%)" @@ -891,6 +935,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Омилен јазик" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "прошири и барај" @@ -900,9 +956,6 @@ msgid "center cut out" msgstr "иÑечи Ñредина" -msgid "no" -msgstr "не" - msgid "names only" msgstr "Ñамо имиња" @@ -945,6 +998,10 @@ msgid "Setup.DVB$Update channels" msgstr "Ðжурирај канали" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Позиција на информациите за каналот" + msgid "Setup.DVB$Audio languages" msgstr "Ðудио јазици" @@ -969,6 +1026,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "ПровидноÑÑ‚ на позадината на титлот" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1093,6 @@ msgid "confirm" msgstr "потврди" -msgid "yes" -msgstr "да" - msgid "Recording" msgstr "Снимање" @@ -1060,6 +1117,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Траење на пауза (денови)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Директориум за Ñнимки" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Директориум за Ñнимки" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Приоритет на пауза" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "МакÑимална големина на датотека (MB)" + msgid "Setup.Recording$Use episode name" msgstr "КориÑти име на епизода" @@ -1084,12 +1157,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "МакÑимална големина на датотека (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "МакÑимална големина на датотека (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Означи директно Ñнимање" + msgid "Setup.Recording$Split edited files" msgstr "Раздвои уредени датотеки" msgid "Setup.Recording$Delete timeshift recording" msgstr "Избриши временÑки помеÑтена Ñнимка" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Репродукција" @@ -1105,6 +1189,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID на продолжеток" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID на продолжеток" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID на продолжеток" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "ПовеќебрзинÑки режим" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID на продолжеток" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID на продолжеток" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID на продолжеток" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Почетен канал" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Итен излез" + msgid "Miscellaneous" msgstr "Разно" @@ -1132,6 +1248,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Почетна јачина на звук" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Итен излез" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Премотување канали" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "како претходно" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Премотување канали" @@ -1141,6 +1269,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Итен излез" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Итен излез" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "како претходно" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Минимално време на тајмаут (мин)" + msgid "Plugins" msgstr "Додатоци" @@ -1176,7 +1316,6 @@ msgid "Button$Resume" msgstr "Продолжи" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Откажи уредување" diff -ruN vdr-1.7.31-ext/po/nl_NL.po vdr-1.7.31/po/nl_NL.po --- vdr-1.7.31-ext/po/nl_NL.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/nl_NL.po 2012-09-19 23:54:19.000000000 +0200 @@ -564,6 +564,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Kanaalinstellingen zijn niet uniek!" @@ -640,6 +644,15 @@ msgid "Lifetime" msgstr "Bewaarduur" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nee" + msgid "File" msgstr "Bestandnaam" @@ -733,6 +746,36 @@ msgid "Button$Rewind" msgstr "Naar begin" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Opname verwijderen?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Opname verwijderen?" + +msgid "Error while accessing recording!" +msgstr "Fout bij lezen opname!" + msgid "Recordings" msgstr "Opnames" @@ -742,9 +785,6 @@ msgid "Commands" msgstr "Commando's" -msgid "Error while accessing recording!" -msgstr "Fout bij lezen opname!" - msgid "Delete recording?" msgstr "Opname verwijderen?" @@ -778,6 +818,10 @@ msgid "Setup.OSD$Theme" msgstr "Thema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Kleine lettertype" + msgid "Setup.OSD$Left (%)" msgstr "Links (%)" @@ -894,6 +938,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Voorkeurstaal" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -903,9 +959,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nee" - msgid "names only" msgstr "alleen namen" @@ -948,6 +1001,10 @@ msgid "Setup.DVB$Update channels" msgstr "Kanalen actualiseren" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanaal info positie" + msgid "Setup.DVB$Audio languages" msgstr "Audio talen" @@ -972,6 +1029,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparantie achtergrond ondertiteling" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1036,9 +1096,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "ja" - msgid "Recording" msgstr "Opname" @@ -1063,6 +1120,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Pauze levensduur (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Opname mappen" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Opname mappen" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Pauze prioriteit" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maximale omvang video file (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Gebruik episode naam" @@ -1087,12 +1160,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maximale omvang video file (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maximale omvang video file (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Direkte opnamen markeren" + msgid "Setup.Recording$Split edited files" msgstr "Bewerkte files opdelen" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Afspelen" @@ -1108,6 +1192,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Hervattings ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Hervattings ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Hervattings ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Multi-speed mode" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Hervattings ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Hervattings ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Hervattings ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Opstartkanaal" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Nooduitgang" + msgid "Miscellaneous" msgstr "Overig" @@ -1135,6 +1251,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Opstartvolume" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Nooduitgang" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Tijdsduur kanaalinvoer (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "zoals eerder" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1144,6 +1272,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Nooduitgang" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Nooduitgang" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "zoals eerder" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minimale event time-out (min)" + msgid "Plugins" msgstr "Plugins" @@ -1179,7 +1319,6 @@ msgid "Button$Resume" msgstr "Hervat" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Bewerken afbreken" diff -ruN vdr-1.7.31-ext/po/nn_NO.po vdr-1.7.31/po/nn_NO.po --- vdr-1.7.31-ext/po/nn_NO.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/nn_NO.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Levetid" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nei" + msgid "File" msgstr "Filnavn" @@ -730,6 +743,35 @@ msgid "Button$Rewind" msgstr "Spol tilbake" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +msgid "PES" +msgstr "" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Slette opptak?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Slette opptak?" + +msgid "Error while accessing recording!" +msgstr "Feil under lesing av opptak!" + msgid "Recordings" msgstr "Opptak" @@ -739,9 +781,6 @@ msgid "Commands" msgstr "Kommandoer" -msgid "Error while accessing recording!" -msgstr "Feil under lesing av opptak!" - msgid "Delete recording?" msgstr "Slette opptak?" @@ -775,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Språk" + msgid "Setup.OSD$Left (%)" msgstr "" @@ -891,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -900,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nei" - msgid "names only" msgstr "" @@ -945,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Posisjon på kanalinformasjon" + msgid "Setup.DVB$Audio languages" msgstr "" @@ -969,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1092,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "ja" - msgid "Recording" msgstr "Opptak" @@ -1060,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Kataloger til opptak" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Kataloger til opptak" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Normal prioritet (Timer)" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maksimal størrelse på videofiler (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Bruk episodenavn" @@ -1084,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maksimal størrelse på videofiler (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maksimal størrelse på videofiler (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Markere direkteopptak" + msgid "Setup.Recording$Split edited files" msgstr "Splitt redigerte filer" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Spill av" @@ -1105,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Resume ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Resume ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Resume ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Multispeed modus" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Resume ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Resume ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Resume ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Minste hendelsespause (min)" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Minste hendelsespause (min)" + msgid "Miscellaneous" msgstr "Forskjellig" @@ -1132,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Minste hendelsespause (min)" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Minste hendelsespause (min)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "Minste hendelsespause (min)" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1141,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Minste hendelsespause (min)" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "Minste hendelsespause (min)" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minste hendelsespause (min)" + msgid "Plugins" msgstr "Plugins" @@ -1176,7 +1315,6 @@ msgid "Button$Resume" msgstr "Fortsett" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Avbryt redigering" diff -ruN vdr-1.7.31-ext/po/pl_PL.po vdr-1.7.31/po/pl_PL.po --- vdr-1.7.31-ext/po/pl_PL.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/pl_PL.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Ustawienia kana³u nie s± unikalne!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Czas ¿ycia" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "tak" + +msgid "no" +msgstr "nie" + msgid "File" msgstr "Plik" @@ -730,6 +743,36 @@ msgid "Button$Rewind" msgstr "Pocz±tek" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Usun±æ nagranie?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Usun±æ nagranie?" + +msgid "Error while accessing recording!" +msgstr "Bl±d podczas dostêpu do nagrania!" + msgid "Recordings" msgstr "Nagrania" @@ -739,9 +782,6 @@ msgid "Commands" msgstr "Polecenia" -msgid "Error while accessing recording!" -msgstr "Bl±d podczas dostêpu do nagrania!" - msgid "Delete recording?" msgstr "Usun±æ nagranie?" @@ -775,6 +815,10 @@ msgid "Setup.OSD$Theme" msgstr "Motyw" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Ma³a czcionka" + msgid "Setup.OSD$Left (%)" msgstr "Od lewej (%)" @@ -891,6 +935,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Preferowany jêzyk" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -900,9 +956,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nie" - msgid "names only" msgstr "tylko nazwy" @@ -945,6 +998,10 @@ msgid "Setup.DVB$Update channels" msgstr "Aktualizuj kana³y" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozycja informacji o kanale" + msgid "Setup.DVB$Audio languages" msgstr "Jêzyków d¼wiêku" @@ -969,6 +1026,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Prze¼rocze podtytu³ów: T³o" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1093,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "tak" - msgid "Recording" msgstr "Nagranie" @@ -1060,6 +1117,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Czas ¿ycia pauzy (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Katalogi nagrañ" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Katalogi nagrañ" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Priorytet pauzy" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maksymalny rozmiar pliku (MB)" + msgid "Setup.Recording$Use episode name" msgstr "U¿ywaj nazwy epizodu" @@ -1084,12 +1157,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maksymalny rozmiar pliku (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maksymalny rozmiar pliku (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Zaznaczaj natychm. nagrywanie" + msgid "Setup.Recording$Split edited files" msgstr "Dziel edytowane pliki" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Odtwarzanie" @@ -1105,6 +1189,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID wznowienia" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID wznowienia" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID wznowienia" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Tryb wieloprêdko¶ciowy" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID wznowienia" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID wznowienia" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID wznowienia" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Pocz±tkowy kana³" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Wyj¶cie awaryjne" + msgid "Miscellaneous" msgstr "Ró¿ne" @@ -1132,6 +1248,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Pocz±tkowa g³o¶no¶æ" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Wyj¶cie awaryjne" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Min±³ czas wej¶cia do kana³u" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "jak ostatnio" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1141,6 +1269,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Wyj¶cie awaryjne" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Wyj¶cie awaryjne" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "jak ostatnio" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minimalny czas audycji (min)" + msgid "Plugins" msgstr "Wtyczki" @@ -1176,7 +1316,6 @@ msgid "Button$Resume" msgstr "Wznów" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Anuluj edycjê" diff -ruN vdr-1.7.31-ext/po/pt_PT.po vdr-1.7.31/po/pt_PT.po --- vdr-1.7.31-ext/po/pt_PT.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/pt_PT.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Parâmetros do canal não são únicos!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Validade" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "sim" + +msgid "no" +msgstr "não" + msgid "File" msgstr "Ficheiro" @@ -730,6 +743,36 @@ msgid "Button$Rewind" msgstr "Retroceder" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Eliminar gravação?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Eliminar gravação?" + +msgid "Error while accessing recording!" +msgstr "Erro a aceder às gravações!" + msgid "Recordings" msgstr "Gravações" @@ -739,9 +782,6 @@ msgid "Commands" msgstr "Comandos" -msgid "Error while accessing recording!" -msgstr "Erro a aceder às gravações!" - msgid "Delete recording?" msgstr "Eliminar gravação?" @@ -775,6 +815,10 @@ msgid "Setup.OSD$Theme" msgstr "Cor do tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Fonte pequena" + msgid "Setup.OSD$Left (%)" msgstr "Esquerda (%)" @@ -891,6 +935,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Língua preferida" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -900,9 +956,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "não" - msgid "names only" msgstr "apenas nomes" @@ -945,6 +998,10 @@ msgid "Setup.DVB$Update channels" msgstr "Actualizar canais" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Posição da informação de canal" + msgid "Setup.DVB$Audio languages" msgstr "Idiomas do áudio" @@ -969,6 +1026,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparência de fundo das legendas" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1093,6 @@ msgid "confirm" msgstr "confirmar" -msgid "yes" -msgstr "sim" - msgid "Recording" msgstr "Gravação" @@ -1060,6 +1117,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Validade da pausa (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Pasta de gravações" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Pasta de gravações" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioridade da pausa" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Tamanho máximo do ficheiro de vídeo (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Usar nome do episódio" @@ -1084,12 +1157,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Tamanho máximo do ficheiro de vídeo (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Tamanho máximo do ficheiro de vídeo (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Marcar gravação instantânea" + msgid "Setup.Recording$Split edited files" msgstr "Dividir ficheiros editados" msgid "Setup.Recording$Delete timeshift recording" msgstr "Eliminar gravações timeshift" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Reproduzir" @@ -1105,6 +1189,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID de resumo" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID de resumo" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID de resumo" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Modo multi velocidade" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID de resumo" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID de resumo" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID de resumo" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Canal inicial" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Saída de emergência" + msgid "Miscellaneous" msgstr "Outros" @@ -1132,6 +1248,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volume inicial" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Saída de emergência" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Retroceder canais" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "como estava" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Retroceder canais" @@ -1141,6 +1269,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Saída de emergência" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Saída de emergência" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "como estava" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Tempo de espera mínimo antes de evento (min)" + msgid "Plugins" msgstr "Plugins" @@ -1176,7 +1316,6 @@ msgid "Button$Resume" msgstr "Continuar" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Cancelar edição" diff -ruN vdr-1.7.31-ext/po/ro_RO.po vdr-1.7.31/po/ro_RO.po --- vdr-1.7.31-ext/po/ro_RO.po 2012-09-15 15:57:37.000000000 +0200 +++ vdr-1.7.31/po/ro_RO.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Parametrii canalului nu sunt univoci!" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "Timp de pãstrare" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "da" + +msgid "no" +msgstr "nu" + msgid "File" msgstr "Fiºier" @@ -732,6 +745,36 @@ msgid "Button$Rewind" msgstr "Înapoi" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "ªterg înregistrarea?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "ªterg înregistrarea?" + +msgid "Error while accessing recording!" +msgstr "Eroare la accesarea înregistrãrii" + msgid "Recordings" msgstr "Înregistrãri" @@ -741,9 +784,6 @@ msgid "Commands" msgstr "Comenzi" -msgid "Error while accessing recording!" -msgstr "Eroare la accesarea înregistrãrii" - msgid "Delete recording?" msgstr "ªterg înregistrarea?" @@ -777,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "Temã" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Font mic" + msgid "Setup.OSD$Left (%)" msgstr "Stânga (%)" @@ -893,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Limba preferatã" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -902,9 +958,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nu" - msgid "names only" msgstr "doar numele" @@ -947,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "Actualizare canale" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Poziþia informaþiilor despre canal" + msgid "Setup.DVB$Audio languages" msgstr "Limbi sunet" @@ -971,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparenþa fundalului subtitrãrii" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1035,9 +1095,6 @@ msgid "confirm" msgstr "confirmare" -msgid "yes" -msgstr "da" - msgid "Recording" msgstr "Înregistrare" @@ -1062,6 +1119,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Pãstrarea emisiunilor 'pauzate' (zile)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Directoare înregistrãri" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Directoare înregistrãri" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioritate pauzã" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Dimensiune maximã a fiºierului video (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Utilizeazã numele episodului" @@ -1086,12 +1159,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Dimensiune maximã a fiºierului video (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Dimensiune maximã a fiºierului video (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Marcheazã înregistrare imediatã" + msgid "Setup.Recording$Split edited files" msgstr "Separare fiºiere montate" msgid "Setup.Recording$Delete timeshift recording" msgstr "ªterge înregistrarea pentru vizionare decalatã" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Redare" @@ -1107,6 +1191,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Identificator continuare" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Identificator continuare" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Identificator continuare" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Mod multi-vitezã" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Identificator continuare" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Identificator continuare" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Identificator continuare" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Canalul de pornire" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Oprire de urgenþã" + msgid "Miscellaneous" msgstr "Diverse" @@ -1134,6 +1250,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Volumul la pornire" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Oprire de urgenþã" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Lista de canale în buclã" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "ca mai înainte" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Lista de canale în buclã" @@ -1143,6 +1271,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Oprire de urgenþã" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Oprire de urgenþã" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "ca mai înainte" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Duratã minimã emisiuni (min)" + msgid "Plugins" msgstr "Plugin-uri" @@ -1178,7 +1318,6 @@ msgid "Button$Resume" msgstr "Continuare" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Opreºte montajul înregistrãrii" diff -ruN vdr-1.7.31-ext/po/ru_RU.po vdr-1.7.31/po/ru_RU.po --- vdr-1.7.31-ext/po/ru_RU.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/ru_RU.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "½ÐáâàÞÙÚØ ÚÐÝÐÛÐ ÝÕ ãÝØÚÐÛìÝë!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "ÁàÞÚ åàÐÝÕÝØï" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ÔÐ" + +msgid "no" +msgstr "ÝÕâ" + msgid "File" msgstr "ÄÐÙÛ" @@ -730,6 +743,33 @@ msgid "Button$Rewind" msgstr "½Ð×ÐÔ" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +msgid "PES" +msgstr "" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Delete marks information?" +msgstr "" + +msgid "Delete resume information?" +msgstr "" + +msgid "Error while accessing recording!" +msgstr "¾èØÑÚÐ ÔÞáâãßÐ Ú ×ÐߨáØ!" + msgid "Recordings" msgstr "·ÐߨáØ" @@ -739,9 +779,6 @@ msgid "Commands" msgstr "ºÞÜÐÝÔë" -msgid "Error while accessing recording!" -msgstr "¾èØÑÚÐ ÔÞáâãßÐ Ú ×ÐߨáØ!" - msgid "Delete recording?" msgstr "ÁâÕàÕâì ×Ðߨáì?" @@ -775,6 +812,10 @@ msgid "Setup.OSD$Theme" msgstr "ÂÕÜÐ" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "¼ÕÛÚØÙ äÞÝâ" + msgid "Setup.OSD$Left (%)" msgstr "¾âáâãß áÛÕÒÐ (%)" @@ -891,6 +932,18 @@ msgid "Setup.EPG$Preferred language" msgstr "²ëÑàÐÝ" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "ßÐÝÞàÐÜØàÞÒÐâì" @@ -900,9 +953,6 @@ msgid "center cut out" msgstr "ÞÑàÕ×Ðâì áÑÞÚã" -msgid "no" -msgstr "ÝÕâ" - msgid "names only" msgstr "âÞÛìÚÞ ÝÐ×ÒÐÝØï" @@ -945,6 +995,10 @@ msgid "Setup.DVB$Update channels" msgstr "¾ÑÝÞÒÛïâì ÝÐáâàÞÙÚØ ÚÐÝÐÛÞÒ" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "¿ÞÛÞÖÕÝØÕ ÞÚÝÐ ØÝäÞàÜÐæØØ Þ ÚÐÝÐÛÕ" + msgid "Setup.DVB$Audio languages" msgstr "¿àÕÔßÞçØâÐÕÜëÕ ï×ëÚØ (×ÒãÚ)" @@ -969,6 +1023,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "¿àÞ×àÐçÝÞáâì äÞÝÐ áãÑâØâàÞÒ" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "ºÞÝÒÕàâÕà" @@ -1033,9 +1090,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "ÔÐ" - msgid "Recording" msgstr "·Ðߨáì" @@ -1060,6 +1114,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "ÅàÐÝÕÝØÕ ÞâÛÞÖÕÝÝÞÓÞ ßàÞáÜÞâàÐ (Ô)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "ºÐâÐÛÞÓØ åàÐÝÕÝØï ×ÐߨáÕÙ" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "ºÐâÐÛÞÓØ åàÐÝÕÝØï ×ÐߨáÕÙ" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "¿àØÞàØâÕâ ÞâÛÞÖÕÝÝÞÓÞ ßàÞáÜÞâàÐ" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "¼ÐÚá. àÐ×ÜÕà ÒØÔÕÞäÐÙÛÐ (¼Ñ)" + msgid "Setup.Recording$Use episode name" msgstr "³àãßߨàÞÒÐâì äÐÙÛë ßÞ íߨ×ÞÔÐÜ" @@ -1084,12 +1154,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "¼ÐÚá. àÐ×ÜÕà ÒØÔÕÞäÐÙÛÐ (¼Ñ)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "¼ÐÚá. àÐ×ÜÕà ÒØÔÕÞäÐÙÛÐ (¼Ñ)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "¾âÜÕçÐâì áÔÕÛÐÝÝëÕ ÒàãçÝãî ×ÐߨáØ" + msgid "Setup.Recording$Split edited files" msgstr "´ÕÛØâì ÞâàÕÔÐÚâØàÞÒÐÝÝëÕ äÐÙÛë" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "²ÞáßàÞØ×ÒÕÔÕÝØÕ" @@ -1105,6 +1186,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "¼ÝÞÓÞáÚÞàÞáâÝÞÙ àÕÖØÜ" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID ÒÞáßàÞØ×ÒÕÔÕÝØï" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "ºÐÝÐÛ ßàØ ÒÚÛîçÕÝØØ" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "°ÒÐàØÙÝëÙ ÒëåÞÔ" + msgid "Miscellaneous" msgstr "¿àÞçÕÕ" @@ -1132,6 +1245,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "³àÞÜÚÞáâì ßàØ ÒÚÛîçÕÝØØ" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "°ÒÐàØÙÝëÙ ÒëåÞÔ" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "¿àÕÔÕÛ ÒàÕÜÕÝØ ÔÛï ÒÒÞÔÐ ÚÐÝÐÛÐ (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "ÚÐÚ àÐÝìèÕ" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1141,6 +1266,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "°ÒÐàØÙÝëÙ ÒëåÞÔ" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "°ÒÐàØÙÝëÙ ÒëåÞÔ" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "ÚÐÚ àÐÝìèÕ" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "¼ØÝ. ÒàÕÜï ÞÖØÔÐÝØï áÞÑëâØï (ÜØÝ)" + msgid "Plugins" msgstr "¼ÞÔãÛØ àÐáèØàÕÝØï" @@ -1176,7 +1313,6 @@ msgid "Button$Resume" msgstr "¿àÞÔÞÛÖØâì" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " ¿àÕàÒÐâì ÜÞÝâÐÖ ×ÐߨáØ" diff -ruN vdr-1.7.31-ext/po/sk_SK.po vdr-1.7.31/po/sk_SK.po --- vdr-1.7.31-ext/po/sk_SK.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/sk_SK.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Nastavenia kanálu nie sú obyèajné!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "®ivotnos»" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "áno" + +msgid "no" +msgstr "nie" + msgid "File" msgstr "Súbor" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "Na zaèiatok" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Zmaza» nahrávku?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Zmaza» nahrávku?" + +msgid "Error while accessing recording!" +msgstr "Chyba pri prístupe k nahrávkam!" + msgid "Recordings" msgstr "Nahrávky" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "Príkazy" -msgid "Error while accessing recording!" -msgstr "Chyba pri prístupe k nahrávkam!" - msgid "Delete recording?" msgstr "Zmaza» nahrávku?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Téma" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Malé písmo" + msgid "Setup.OSD$Left (%)" msgstr "Vµavo (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Uprednostni» jazyk" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "oreza» do stredu" -msgid "no" -msgstr "nie" - msgid "names only" msgstr "iba názvy" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Aktualizácia kanálov" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozícia informácií o kanále" + msgid "Setup.DVB$Audio languages" msgstr "Jazyky zvuku" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Priehµadnos» pozadia titulkov" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "overi»" -msgid "yes" -msgstr "áno" - msgid "Recording" msgstr "Nahrávanie" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "®ivotnos» preru¹enia (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Zoznam nahrávok" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Zoznam nahrávok" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Priorita preru¹enia" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maximálna veµkos» nahrávky (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Pou¾íva» názov epizódy" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maximálna veµkos» nahrávky (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maximálna veµkos» nahrávky (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Oznaèi» okam¾ité nahrávky" + msgid "Setup.Recording$Split edited files" msgstr "Deli» upravované súbory" msgid "Setup.Recording$Delete timeshift recording" msgstr "Vymaza» timeshift záznamy" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Prehrávanie" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID obnovenie" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID obnovenie" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID obnovenie" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Viac rýchlostný re¾im" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID obnovenie" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID obnovenie" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID obnovenie" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanál po spustení" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Núdzové ukonèenie" + msgid "Miscellaneous" msgstr "Rôzne" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Hlasitos» po spustení" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Núdzové ukonèenie" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Prepína» z prvého na posledný a opaène" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "ako naposledy" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Prepína» z prvého na posledný a opaène" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Núdzové ukonèenie" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Núdzové ukonèenie" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "ako naposledy" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. pauza medzi udalos»ami (min)" + msgid "Plugins" msgstr "Moduly" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "Pokraèova»" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Zru¹i» úpravu" diff -ruN vdr-1.7.31-ext/po/sl_SI.po vdr-1.7.31/po/sl_SI.po --- vdr-1.7.31-ext/po/sl_SI.po 2012-09-15 15:57:39.000000000 +0200 +++ vdr-1.7.31/po/sl_SI.po 2012-09-19 23:54:19.000000000 +0200 @@ -561,6 +561,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Nastavitve kanala niso edinstvene!" @@ -637,6 +641,15 @@ msgid "Lifetime" msgstr "Veljavnost" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "da" + +msgid "no" +msgstr "ne" + msgid "File" msgstr "Datoteka" @@ -730,6 +743,36 @@ msgid "Button$Rewind" msgstr "Na zaèetek" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Izbri¹i posnetek?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Izbri¹i posnetek?" + +msgid "Error while accessing recording!" +msgstr "Napaka pri dostopu do posnetka!" + msgid "Recordings" msgstr "Posnetki" @@ -739,9 +782,6 @@ msgid "Commands" msgstr "Ukazi" -msgid "Error while accessing recording!" -msgstr "Napaka pri dostopu do posnetka!" - msgid "Delete recording?" msgstr "Izbri¹i posnetek?" @@ -775,6 +815,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Mala pisava" + msgid "Setup.OSD$Left (%)" msgstr "Levo (%)" @@ -891,6 +935,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Prednostni jezik" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -900,9 +956,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "ne" - msgid "names only" msgstr "samo imena" @@ -945,6 +998,10 @@ msgid "Setup.DVB$Update channels" msgstr "Posodobi kanale" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozicija informacije o kanalu" + msgid "Setup.DVB$Audio languages" msgstr "Jeziki za zvok" @@ -969,6 +1026,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparentnost ozadja podnapisov" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1033,9 +1093,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "da" - msgid "Recording" msgstr "Snemanje" @@ -1060,6 +1117,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Èas pavze (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Direktoriji za posnetke" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Direktoriji za posnetke" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioriteta pavze" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Najveèja velikost datoteke (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Uporabi ime epizode" @@ -1084,12 +1157,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Najveèja velikost datoteke (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Najveèja velikost datoteke (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Oznaèi direktno snemanje" + msgid "Setup.Recording$Split edited files" msgstr "Razdeli urejene datoteke" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Predvajanje" @@ -1105,6 +1189,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID za predvajanje" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID za predvajanje" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID za predvajanje" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Re¾im z veè hitrostmi" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID za predvajanje" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID za predvajanje" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID za predvajanje" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Privzeti kanal" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Izhod v sili" + msgid "Miscellaneous" msgstr "Ostalo" @@ -1132,6 +1248,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Privzeta glasnost" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Izhod v sili" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Timeout za vnos kanala (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "kot prej" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1141,6 +1269,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Izhod v sili" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Izhod v sili" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "kot prej" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Najmanj¹i èas dogodka (min)" + msgid "Plugins" msgstr "Vstavki" @@ -1176,7 +1316,6 @@ msgid "Button$Resume" msgstr "Nadaljuj" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Prekini urejanje" diff -ruN vdr-1.7.31-ext/po/sr_SR.po vdr-1.7.31/po/sr_SR.po --- vdr-1.7.31-ext/po/sr_SR.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/sr_SR.po 2012-09-19 23:54:19.000000000 +0200 @@ -562,6 +562,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Postavke programa nisu jedinstvene!" @@ -641,6 +645,16 @@ msgid "Lifetime" msgstr "Trajanje" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "" + +#, fuzzy +msgid "no" +msgstr "ni¹ta" + msgid "File" msgstr "Datoteka" @@ -735,6 +749,36 @@ msgid "Button$Rewind" msgstr "Poèetak" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Obri¹i snimku?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Obri¹i snimku?" + +msgid "Error while accessing recording!" +msgstr "Gre¹ka prilikom pristupa snimanju!" + #, fuzzy msgid "Recordings" msgstr "Snimanje" @@ -747,9 +791,6 @@ msgid "Commands" msgstr "Naredbe" -msgid "Error while accessing recording!" -msgstr "Gre¹ka prilikom pristupa snimanju!" - msgid "Delete recording?" msgstr "Obri¹i snimku?" @@ -784,6 +825,10 @@ msgstr "Tema" #, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Mali font" + +#, fuzzy msgid "Setup.OSD$Left (%)" msgstr "Levo(%)" @@ -908,6 +953,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Odaberi jezik" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pro¹iri i ispitaj" @@ -917,10 +974,6 @@ msgid "center cut out" msgstr "izre¾i sredinu" -#, fuzzy -msgid "no" -msgstr "ni¹ta" - msgid "names only" msgstr "samo imena" @@ -963,6 +1016,10 @@ msgid "Setup.DVB$Update channels" msgstr "A¾uriranje kanala" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Pozicija informacija o programu" + msgid "Setup.DVB$Audio languages" msgstr "Audio jezici" @@ -987,6 +1044,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Providnost pozadine titla" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1054,9 +1114,6 @@ msgid "confirm" msgstr "potvrdi" -msgid "yes" -msgstr "" - msgid "Recording" msgstr "Snimanje" @@ -1082,6 +1139,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Trajanje pauze (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Direktorij za snimke" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Direktorij za snimke" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioritet pauze" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maks. velièina datoteke (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Koristi naziv epizode" @@ -1106,12 +1179,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maks. velièina datoteke (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maks. velièina datoteke (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Oznaèi trenutno snimanje" + msgid "Setup.Recording$Split edited files" msgstr "Podeli ureðene datoteke" msgid "Setup.Recording$Delete timeshift recording" msgstr "Bri¹i vremenski pomak snimke" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Reprodukcija" @@ -1127,6 +1211,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID nastavka" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Vi¹estruke brzine reprodukcije" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID nastavka" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Poèetni kanal" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Izlaz u sluèaju nu¾de" + msgid "Miscellaneous" msgstr "Razno" @@ -1155,6 +1271,18 @@ msgstr "Poèetna jaèina tona" #, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Izlaz u sluèaju nu¾de" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanal spakovan" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "kao prethodno" + +#, fuzzy msgid "Setup.Miscellaneous$Channels wrap" msgstr "Kanal spakovan" @@ -1164,6 +1292,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Izlaz u sluèaju nu¾de" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Izlaz u sluèaju nu¾de" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "kao prethodno" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. vreme pauze (min)" + msgid "Plugins" msgstr "Dodaci" @@ -1199,7 +1339,6 @@ msgid "Button$Resume" msgstr "Nastavi" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr "Zaustavi ispravke" diff -ruN vdr-1.7.31-ext/po/sv_SE.po vdr-1.7.31/po/sv_SE.po --- vdr-1.7.31-ext/po/sv_SE.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/sv_SE.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Kanalinställningarna är ej unika!" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "Livstid" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nej" + msgid "File" msgstr "Filnamn" @@ -732,6 +745,36 @@ msgid "Button$Rewind" msgstr "Återspolning" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Ta bort inspelningen?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Ta bort inspelningen?" + +msgid "Error while accessing recording!" +msgstr "Inspelningen går inte att läsa!" + msgid "Recordings" msgstr "Inspelningar" @@ -741,9 +784,6 @@ msgid "Commands" msgstr "Kommandon" -msgid "Error while accessing recording!" -msgstr "Inspelningen går inte att läsa!" - msgid "Delete recording?" msgstr "Ta bort inspelningen?" @@ -777,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Små typsnitt" + msgid "Setup.OSD$Left (%)" msgstr "Vänster (%)" @@ -893,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Önskat språk" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -902,9 +958,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "nej" - msgid "names only" msgstr "bara namn" @@ -947,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "Uppdatera kanaler" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Placering av kanalinformation" + msgid "Setup.DVB$Audio languages" msgstr "Antal ljudspråk" @@ -971,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparent bakgrund textremsa" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1035,9 +1095,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "ja" - msgid "Recording" msgstr "Inspelning" @@ -1062,6 +1119,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Livstid för direktinspelning (dagar)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Kataloger för inspelningar" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Kataloger för inspelningar" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Prioritet för direktinspelning" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maximal filstorlek för inspelning (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Använd episodnamn" @@ -1086,12 +1159,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maximal filstorlek för inspelning (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maximal filstorlek för inspelning (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Märk direktinspelning" + msgid "Setup.Recording$Split edited files" msgstr "Dela upp redigerade filer" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Uppspelning" @@ -1107,6 +1191,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Återuppta ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Återuppta ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Återuppta ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Multispeed mode" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Återuppta ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Återuppta ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Återuppta ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Kanal vid uppstart" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Oförutsedd avslutning" + msgid "Miscellaneous" msgstr "Diverse" @@ -1134,6 +1250,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Ljudstyrka vid uppstart" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Oförutsedd avslutning" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Timeout kanal (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "som förut" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1143,6 +1271,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Oförutsedd avslutning" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Oförutsedd avslutning" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "som förut" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minsta händelse-pause (min)" + msgid "Plugins" msgstr "Moduler" @@ -1178,7 +1318,6 @@ msgid "Button$Resume" msgstr "Fortsätt" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Avbryt redigering" diff -ruN vdr-1.7.31-ext/po/tr_TR.po vdr-1.7.31/po/tr_TR.po --- vdr-1.7.31-ext/po/tr_TR.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/tr_TR.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "Kanal ayarlarý belli deðýl!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "Ömrü" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "evet" + +msgid "no" +msgstr "hayýr" + msgid "File" msgstr "Kütük" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "Baslangýç" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Kayýtý sil?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Kayýtý sil?" + +msgid "Error while accessing recording!" +msgstr "Kayýt okuma hatasý!" + msgid "Recordings" msgstr "Kayýtlar" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "Komutlar" -msgid "Error while accessing recording!" -msgstr "Kayýt okuma hatasý!" - msgid "Delete recording?" msgstr "Kayýtý sil?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Tema" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Küçük font" + msgid "Setup.OSD$Left (%)" msgstr "Sol (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Dil tercihi" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "center cut out" -msgid "no" -msgstr "hayýr" - msgid "names only" msgstr "sýrf isimler" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Kanallarý yenile" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "Kanal bilgi pozisyonu" + msgid "Setup.DVB$Audio languages" msgstr "Audio dilleri" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Altyazý arka þeffaflýk" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "evet" - msgid "Recording" msgstr "Kayýt" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Duraklama ömrü (gün)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Kayýt dizinleri" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Kayýt dizinleri" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Duraklama prioritesi" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "Maksimum Video kütük büyüklügü (MB)" + msgid "Setup.Recording$Use episode name" msgstr "Episod ismini kullan" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "Maksimum Video kütük büyüklügü (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "Maksimum Video kütük büyüklügü (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Derhal çekimi iþaretle" + msgid "Setup.Recording$Split edited files" msgstr "Düzenlenmiþ kütükleri ayýr" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "Tekrar" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "Gösteriþ ID'si" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "Gösteriþ ID'si" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "Gösteriþ ID'si" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "Katlý hýz sarma" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "Gösteriþ ID'si" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "Gösteriþ ID'si" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "Gösteriþ ID'si" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Açýlýþdaki kanal" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Acil cýkýþ" + msgid "Miscellaneous" msgstr "Diðerler" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "Açýlýþdaki ses" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Acil cýkýþ" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Kanal giriþ zaman aþýmý (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "önceki gibi" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Acil cýkýþ" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Acil cýkýþ" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "önceki gibi" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Minimum olay zaman aþýmý (dak)" + msgid "Plugins" msgstr "Eklentiler" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "Sürdür" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Kesimi iptal et" diff -ruN vdr-1.7.31-ext/po/uk_UA.po vdr-1.7.31/po/uk_UA.po --- vdr-1.7.31-ext/po/uk_UA.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/uk_UA.po 2012-09-19 23:54:19.000000000 +0200 @@ -560,6 +560,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "ÐаÑтройки каналу не єдині!" @@ -636,6 +640,15 @@ msgid "Lifetime" msgstr "Строк зберіганнÑ" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "так" + +msgid "no" +msgstr "ні" + msgid "File" msgstr "Файл" @@ -729,6 +742,36 @@ msgid "Button$Rewind" msgstr "Ðазад" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS поправка" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "Витерти запиÑ?" + +#, fuzzy +msgid "Delete resume information?" +msgstr "Витерти запиÑ?" + +msgid "Error while accessing recording!" +msgstr "Помилка доÑтупу до запиÑу!" + msgid "Recordings" msgstr "ЗапиÑи" @@ -738,9 +781,6 @@ msgid "Commands" msgstr "Команди" -msgid "Error while accessing recording!" -msgstr "Помилка доÑтупу до запиÑу!" - msgid "Delete recording?" msgstr "Витерти запиÑ?" @@ -774,6 +814,10 @@ msgid "Setup.OSD$Theme" msgstr "Тема" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "Малий фонт" + msgid "Setup.OSD$Left (%)" msgstr "ВідÑтуп зліва (%)" @@ -890,6 +934,18 @@ msgid "Setup.EPG$Preferred language" msgstr "Бажана мова (телегід)" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "панорамувати" @@ -899,9 +955,6 @@ msgid "center cut out" msgstr "обрізати по боках" -msgid "no" -msgstr "ні" - msgid "names only" msgstr "тільки назви" @@ -944,6 +997,10 @@ msgid "Setup.DVB$Update channels" msgstr "Оновлювати канали" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "ÐŸÐ¾Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про канал" + msgid "Setup.DVB$Audio languages" msgstr "Бажані мови (звук)" @@ -968,6 +1025,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "ПрозоріÑть заднього плану Ñубтитрів" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Конвертер" @@ -1032,9 +1092,6 @@ msgid "confirm" msgstr "підтвердити" -msgid "yes" -msgstr "так" - msgid "Recording" msgstr "ЗапиÑ" @@ -1059,6 +1116,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "Ð—Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ÐºÐ»Ð°Ð´ÐµÐ½Ð¾Ð³Ð¾ переглÑду (дні)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "Каталоги Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñів" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "Каталоги Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñів" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "Пріоритет відкладеного переглÑду" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "МакÑ. размір відеофайлу (Мб)" + msgid "Setup.Recording$Use episode name" msgstr "Викор. назву епізоду" @@ -1083,12 +1156,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "МакÑ. размір відеофайлу (Мб)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "МакÑ. размір відеофайлу (Мб)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "Помітити зроблені вручну запиÑи" + msgid "Setup.Recording$Split edited files" msgstr "Поділити відредаговані файли" msgid "Setup.Recording$Delete timeshift recording" msgstr "Видалити запиÑи з зÑувом по чаÑу" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "ПереглÑд" @@ -1104,6 +1188,38 @@ msgid "Setup.Replay$Resume ID" msgstr "ID продовженнÑ" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "ID продовженнÑ" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "ID продовженнÑ" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "БагатошвидкіÑний режим" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "ID продовженнÑ" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "ID продовженнÑ" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "ID продовженнÑ" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "Канал при включенні" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "Ðварійний вихід" + msgid "Miscellaneous" msgstr "Різне" @@ -1131,6 +1247,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "ГучніÑть при включенні" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "Ðварійний вихід" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "Кінець каналів" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "Ñк раніше" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "Кінець каналів" @@ -1140,6 +1268,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "Ðварійний вихід" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "Ðварійний вихід" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "Ñк раніше" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Мін. Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð´Ñ–Ñ— (хв)" + msgid "Plugins" msgstr "Модулі розширеннÑ" @@ -1175,7 +1315,6 @@ msgid "Button$Resume" msgstr "Продовжити" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr " Перервати монтаж" diff -ruN vdr-1.7.31-ext/po/zh_CN.po vdr-1.7.31/po/zh_CN.po --- vdr-1.7.31-ext/po/zh_CN.po 2012-09-15 15:57:38.000000000 +0200 +++ vdr-1.7.31/po/zh_CN.po 2012-09-19 23:54:19.000000000 +0200 @@ -563,6 +563,10 @@ msgid "Sid" msgstr "Sid" +#, fuzzy +msgid "Rid" +msgstr "Sid" + msgid "Channel settings are not unique!" msgstr "频é“è®¾ç½®ä¸æ˜¯å”¯ä¸€çš„ï¼" @@ -639,6 +643,15 @@ msgid "Lifetime" msgstr "终生" +msgid "Childlock" +msgstr "" + +msgid "yes" +msgstr "是" + +msgid "no" +msgstr "ä¸" + msgid "File" msgstr "文件" @@ -732,6 +745,36 @@ msgid "Button$Rewind" msgstr "釿”¾" +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Format" +msgstr "" + +#, fuzzy +msgid "PES" +msgstr "VPS" + +msgid "TS" +msgstr "" + +msgid "Size" +msgstr "" + +#, fuzzy +msgid "Delete marks information?" +msgstr "是å¦åˆ é™¤å½•åƒï¼Ÿ" + +#, fuzzy +msgid "Delete resume information?" +msgstr "是å¦åˆ é™¤å½•åƒï¼Ÿ" + +msgid "Error while accessing recording!" +msgstr "å­˜å–录åƒé”™è¯¯ï¼" + msgid "Recordings" msgstr "录åƒå›žæ”¾åˆ—表" @@ -741,9 +784,6 @@ msgid "Commands" msgstr "常用æ“作命令" -msgid "Error while accessing recording!" -msgstr "å­˜å–录åƒé”™è¯¯ï¼" - msgid "Delete recording?" msgstr "是å¦åˆ é™¤å½•åƒï¼Ÿ" @@ -777,6 +817,10 @@ msgid "Setup.OSD$Theme" msgstr "主题选择" +#, fuzzy +msgid "Setup.OSD$WarEagle icons" +msgstr "å°å­—体选择" + msgid "Setup.OSD$Left (%)" msgstr "左边è·ç¦»è®¾ç½® (%)" @@ -893,6 +937,18 @@ msgid "Setup.EPG$Preferred language" msgstr "首选语言" +msgid "Setup.EPG$Period for double EPG search(min)" +msgstr "" + +msgid "Setup.EPG$extern double Epg entry" +msgstr "" + +msgid "Setup.EPG$Mix intern and extern EPG" +msgstr "" + +msgid "Setup.EPG$Disable running VPS event" +msgstr "" + msgid "pan&scan" msgstr "pan&scan模å¼" @@ -902,9 +958,6 @@ msgid "center cut out" msgstr "Center-cut-out模å¼" -msgid "no" -msgstr "ä¸" - msgid "names only" msgstr "仅是åå­—" @@ -947,6 +1000,10 @@ msgid "Setup.DVB$Update channels" msgstr "更新频é“" +#, fuzzy +msgid "Setup.DVB$channel binding by Rid" +msgstr "频é“ä¿¡æ¯ä½ç½®" + msgid "Setup.DVB$Audio languages" msgstr "声é“语言" @@ -971,6 +1028,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "å­—å¹•èƒŒæ™¯é€æ˜Žåº¦" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "切æ¢å™¨è®¾ç½®" @@ -1035,9 +1095,6 @@ msgid "confirm" msgstr "" -msgid "yes" -msgstr "是" - msgid "Recording" msgstr "录åƒè®¾ç½®" @@ -1062,6 +1119,22 @@ msgid "Setup.Recording$Pause lifetime (d)" msgstr "æš‚åœç»ˆèº« (d)" +#, fuzzy +msgid "Setup.Recording$Video directory policy" +msgstr "录åƒç›®å½•" + +#, fuzzy +msgid "Setup.Recording$Number of video directories" +msgstr "录åƒç›®å½•" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d priority" +msgstr "æš‚åœä¼˜å…ˆ" + +#, fuzzy, c-format +msgid "Setup.Recording$Video %d min. free MB" +msgstr "æœ€å¤§çš„è§†é¢‘æ–‡ä»¶å®¹é‡ (MB)" + msgid "Setup.Recording$Use episode name" msgstr "æ’入使用åå­—" @@ -1086,12 +1159,23 @@ msgid "Setup.Recording$Max. video file size (MB)" msgstr "æœ€å¤§çš„è§†é¢‘æ–‡ä»¶å®¹é‡ (MB)" +#, fuzzy +msgid "Setup.Recording$Max. recording size (GB)" +msgstr "æœ€å¤§çš„è§†é¢‘æ–‡ä»¶å®¹é‡ (MB)" + +#, fuzzy +msgid "Setup.Recording$Hard Link Cutter" +msgstr "标记直接记录" + msgid "Setup.Recording$Split edited files" msgstr "分离编辑文件" msgid "Setup.Recording$Delete timeshift recording" msgstr "" +msgid "Setup.Recording$Dump NALU Fill data" +msgstr "" + msgid "Replay" msgstr "回放设置" @@ -1107,6 +1191,38 @@ msgid "Setup.Replay$Resume ID" msgstr "æ¢å¤ ID" +#, fuzzy +msgid "Setup.Replay$Jump&Play" +msgstr "æ¢å¤ ID" + +#, fuzzy +msgid "Setup.Replay$Play&Jump" +msgstr "æ¢å¤ ID" + +#, fuzzy +msgid "Setup.Replay$Pause at last mark" +msgstr "媒体速度模å¼" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds" +msgstr "æ¢å¤ ID" + +#, fuzzy +msgid "Setup.Replay$Jump Seconds Slow" +msgstr "æ¢å¤ ID" + +#, fuzzy +msgid "Setup.Recording$Jump Seconds (Repeat)" +msgstr "æ¢å¤ ID" + +#, fuzzy +msgid "Setup.Miscellaneous$only in channelinfo" +msgstr "åˆå§‹é¢‘é“" + +#, fuzzy +msgid "Setup.Miscellaneous$only in progress display" +msgstr "çªå‘事件退出" + msgid "Miscellaneous" msgstr "其它设置" @@ -1134,6 +1250,18 @@ msgid "Setup.Miscellaneous$Initial volume" msgstr "åˆå§‹åŒ–声音" +#, fuzzy +msgid "Setup.Miscellaneous$Volume ctrl with left/right" +msgstr "çªå‘事件退出" + +#, fuzzy +msgid "Setup.Miscellaneous$Channelgroups with left/right" +msgstr "频é“进入超时 (ms)" + +#, fuzzy +msgid "Setup.Miscellaneous$Search fwd/back with left/right" +msgstr "之å‰" + msgid "Setup.Miscellaneous$Channels wrap" msgstr "" @@ -1143,6 +1271,18 @@ msgid "Setup.Miscellaneous$Emergency exit" msgstr "çªå‘事件退出" +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat delay" +msgstr "çªå‘事件退出" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat freq" +msgstr "之å‰" + +#, fuzzy +msgid "Setup.Miscellaneous$Lirc repeat timeout" +msgstr "Min. 结果超时 (min)" + msgid "Plugins" msgstr "æ’件设置" @@ -1178,7 +1318,6 @@ msgid "Button$Resume" msgstr "é‡ç½®" -#. TRANSLATORS: note the leading blank! msgid " Cancel editing" msgstr "å–æ¶ˆç¼–辑" diff -ruN vdr-1.7.31-ext/README-HLCUTTER vdr-1.7.31/README-HLCUTTER --- vdr-1.7.31-ext/README-HLCUTTER 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/README-HLCUTTER 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,127 @@ + VDR-HLCUTTER README + + +Written by: Udo Richter +Available at: http://www.udo-richter.de/vdr/patches.html#hlcutter + http://www.udo-richter.de/vdr/patches.en.html#hlcutter +Contact: udo_richter@gmx.de + + + +About +----- + +The hard link cutter patch changes the recording editing algorithms of VDR to +use filesystem hard links to 'copy' recording files whenever possible to speed +up editing recordings noticeably. + +The patch has matured to be quite stable, at least I'm using it without issues. +Nevertheless the patch is still in development and should be used with caution. +The patch is EXPERIMENTAL for multiple /videoxx folders. The safety checks +should prevent data loss, but you should always carefully check the results. + +While editing a recording, the patch searches for any 00x.vdr files that don't +contain editing marks and would normally be copied 1:1 unmodified to the edited +recording. In this case the current target 00x.vdr file will be aborted, and +the cutter process attempts to duplicate the source file as a hard link, so +that both files share the same disk space. If this succeeds, the editing +process fast-forwards through the duplicated file and continues normally +beginning with the next source file. If hard linking fails, the cutter process +continues with plain old copying. (but does not take up the aborted last file.) + +After editing, the un-edited recording can be deleted as usual, the hard linked +copies will continue to exist as the only remaining copy. + +To be effective, the default 'Max. video file size (MB)' should be lowered. +The patch lowers the smallest possible file size to 1mb. Since VDR only +supports up to 255 files, this would limit the recording size to 255Mb or +10 minutes, in other words: This setting is insane! + +To make sure that the 255 file limit will not be reached, the patch also +introduces "Max. recording size (GB)" with a default of 100Gb (66 hours), and +increases the file size to 2000Mb early enough, so that 100Gb-recordings will +fit into the 255 files. + +Picking the right parameters can be tricky. The smaller the file size, the +faster the editing process works. However, with a small file size, long +recordings will fall back to 2000Mb files soon, that are slow on editing again. + +Here are some examples: + +Max file size: 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb +Max recording size: 1Mb 10Mb 20Mb 30Mb 40Mb 50Mb 100Mb + +Small files: 1-203 1-204 1-205 1-206 1-207 1-209 1-214 + GBytes: 0.2 2.0 4.0 6.0 8.1 10.2 20.9 + Hours: 0.13 1.3 2.65 4 5.4 6.8 13.9 + +Big (2000mb) files: 204-255 204-255 206-255 207-255 208-255 210-255 215-255 + GBytes: 101.5 99.6 97.7 95.7 93.8 89.8 80.1 + Hours: 67 66 65 63 62 60 53 + +A recording limit of 100Gb keeps plenty of reserve without blocking too much +file numbers. And with a file size of 30-40Mb, recordings of 4-5 hours fit into +small files completely. (depends on bit rate of course) + + + +The patch must be enabled in Setup-> Recordings-> Hard Link Cutter. When +disabled, the cutter process behaves identical to VDR's default cutter. + +There's a //#define HARDLINK_TEST_ONLY in the videodir.c file that enables a +test-mode that hard-links 00x.vdr_ files only, and continues the classic +editing. The resulting 00x.vdr and 00x.vdr_ files should be identical. If you +delete the un-edited recording, don't forget to delete the *.vdr_ files too, +they will now eat real disk space. + +Note: 'du' displays the disk space of hard links only on first appearance, and +usually you will see a noticeably smaller size on the edited recording. + + +History +------- + +Version 0.2.3 + Fix: Compatible to VDR-1.7.27+ thx to Ville Skyttä + New: Add German translation + New: Add Finnish translation, thx to Ville Skyttä + +Version 0.2.2 + Fix: Adapt to GCC-4.4, thx to Ville Skyttä + +Version 0.2.1 + New: Support for TS recordings with up to 65535 files and up to 1TB per file + +Version 0.2.0 + New: Support for multiple /videoXX recording folders, using advanced searching + for matching file systems where a hard link can be created. + Also supports deep mounted file systems. + Fix: Do not fail if last mark is a cut-in. (Again.) + +Version 0.1.4 + New: Dynamic increase of file size before running out of xxx.vdr files + Fix: Last edit mark is not a cut-out + Fix: Write error if link-copied file is smaller than allowed file size + Fix: Broken index/marks if cut-in is at the start of a new file + Fix: Clear dangling pointer to free'd cUnbufferedFile, + thx to Matthias Schwarzott + +Version 0.1.0 + Initial release + + + + +Future plans +------------ + +Since original and edited copy share disk space, free space is wrong if one of +them is moved to *.del. Free space should only count files with hard link +count = 1. This still goes wrong if all copies get deleted. + + +For more safety, the hard-linked files may be made read-only, as modifications +to one copy will affect the other copy too. (except deleting, of course) + + +SetBrokenLink may get lost on rare cases, this needs some more thoughts. diff -ruN vdr-1.7.31-ext/README.patches vdr-1.7.31/README.patches --- vdr-1.7.31-ext/README.patches 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/README.patches 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1 @@ +liemikuutio - http://www.saunalahti.fi/~rahrenbe/vdr/patches/index.php diff -ruN vdr-1.7.31-ext/receiver.c vdr-1.7.31/receiver.c --- vdr-1.7.31-ext/receiver.c 2012-06-02 15:20:38.000000000 +0200 +++ vdr-1.7.31/receiver.c 2012-09-19 23:54:19.000000000 +0200 @@ -67,7 +67,12 @@ (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) && AddPids(Channel->Apids()) && AddPids(Channel->Dpids()) && +#ifdef USE_TTXTSUBS + AddPids(Channel->Spids()) && + (!Setup.SupportTeletext || AddPid(Channel->Tpid())); +#else AddPids(Channel->Spids()); +#endif // USE_TTXTSUBS } return true; } diff -ruN vdr-1.7.31-ext/recorder.c vdr-1.7.31/recorder.c --- vdr-1.7.31-ext/recorder.c 2012-09-22 13:53:57.000000000 +0200 +++ vdr-1.7.31/recorder.c 2012-09-19 23:54:19.000000000 +0200 @@ -46,6 +46,16 @@ Type = 0x06; } frameDetector = new cFrameDetector(Pid, Type); +#ifdef USE_NALUDUMP + if ( Type == 0x1B // MPEG4 video + && (Setup.DumpNaluFill ? (strstr(FileName, "NALUKEEP") == NULL) : (strstr(FileName, "NALUDUMP") != NULL))) { // MPEG4 + isyslog("Starting NALU fill dumper"); + naluStreamProcessor = new cNaluStreamProcessor(); + naluStreamProcessor->SetPid(Pid); + } + else + naluStreamProcessor = NULL; +#endif // USE_NALUDUMP index = NULL; fileSize = 0; lastDiskSpaceCheck = time(NULL); @@ -67,6 +77,14 @@ cRecorder::~cRecorder() { Detach(); +#ifdef USE_NALUDUMP + if (naluStreamProcessor) { + long long int TotalPackets = naluStreamProcessor->GetTotalPackets(); + long long int DroppedPackets = naluStreamProcessor->GetDroppedPackets(); + isyslog("NALU fill dumper: %lld of %lld packets dropped, %lli%%", DroppedPackets, TotalPackets, TotalPackets ? DroppedPackets*100/TotalPackets : 0); + delete naluStreamProcessor; + } +#endif // USE_NALUDUMP delete index; delete fileName; delete frameDetector; @@ -90,7 +108,11 @@ bool cRecorder::NextFile(void) { if (recordFile && frameDetector->IndependentFrame()) { // every file shall start with an independent frame +#ifdef USE_HARDLINKCUTTER + if (fileSize > fileName->MaxFileSize() || RunningLowOnDiskSpace()) { +#else if (fileSize > MEGABYTE(off_t(Setup.MaxVideoFileSize)) || RunningLowOnDiskSpace()) { +#endif /* HARDLINKCUTTER */ recordFile = fileName->NextFile(); fileSize = 0; } @@ -155,11 +177,39 @@ fileSize += TS_SIZE; } } +#ifndef USE_NALUDUMP + if (recordFile->Write(b, Count) < 0) { + LOG_ERROR_STR(fileName->Name()); + break; + } + fileSize += Count; +#else + if (naluStreamProcessor) { + naluStreamProcessor->PutBuffer(b, Count); + bool Fail = false; + while (true) { + int OutLength = 0; + uchar *OutData = naluStreamProcessor->GetBuffer(OutLength); + if (!OutData || OutLength <= 0) + break; + if (recordFile->Write(OutData, OutLength) < 0) { + LOG_ERROR_STR(fileName->Name()); + Fail = true; + break; + } + fileSize += OutLength; + } + if (Fail) + break; + } + else { if (recordFile->Write(b, Count) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize += Count; + } +#endif // USE_NALUDUMP t = time(NULL); } } diff -ruN vdr-1.7.31-ext/recorder.h vdr-1.7.31/recorder.h --- vdr-1.7.31-ext/recorder.h 2010-12-27 12:17:04.000000000 +0100 +++ vdr-1.7.31/recorder.h 2012-09-19 23:54:19.000000000 +0200 @@ -21,6 +21,9 @@ cRingBufferLinear *ringBuffer; cFrameDetector *frameDetector; cPatPmtGenerator patPmtGenerator; +#ifdef USE_NALUDUMP + cNaluStreamProcessor *naluStreamProcessor; +#endif // USE_NALUDUMP cFileName *fileName; cIndexFile *index; cUnbufferedFile *recordFile; diff -ruN vdr-1.7.31-ext/recording.c vdr-1.7.31/recording.c --- vdr-1.7.31-ext/recording.c 2012-09-30 15:05:14.000000000 +0200 +++ vdr-1.7.31/recording.c 2012-09-19 23:54:19.000000000 +0200 @@ -8,6 +8,9 @@ */ #include "recording.h" +#ifdef USE_WAREAGLEICON +#include "iconpatch.h" +#endif /* WAREAGLEICON */ #include #include #include @@ -880,7 +883,11 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) const { +#ifdef USE_WAREAGLEICON + const char *New = NewIndicator && IsNew() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_NEW_UTF8 : ICON_NEW : "*" : " "; +#else char New = NewIndicator && IsNew() ? '*' : ' '; +#endif /* WAREAGLEICON */ free(titleBuffer); titleBuffer = NULL; if (Level < 0 || Level == HierarchyLevels()) { @@ -900,7 +907,11 @@ Minutes % 60 ); } +#ifdef USE_WAREAGLEICON + titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%s%s%c%s", +#else titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%s%c%c%s", +#endif /* WAREAGLEICON */ t->tm_mday, t->tm_mon + 1, t->tm_year % 100, @@ -950,6 +961,18 @@ return NULL; } +#ifdef USE_LIEMIKUUTIO +const char *cRecording::UpdateFileName(const char *FileName) +{ + if (FileName && *FileName) { + free(fileName); + fileName = strdup(FileName); + return fileName; + } + return NULL; +} +#endif /* LIEMIKUUTIO */ + int cRecording::HierarchyLevels(void) const { const char *s = name; @@ -1242,7 +1265,11 @@ } } +#ifdef USE_LIEMIKUUTIO +void cRecordings::DelByName(const char *FileName, bool RemoveRecording) +#else void cRecordings::DelByName(const char *FileName) +#endif /* LIEMIKUUTIO */ { LOCK_THREAD; cRecording *recording = GetByName(FileName); @@ -1250,7 +1277,11 @@ cThreadLock DeletedRecordingsLock(&DeletedRecordings); Del(recording, false); char *ext = strrchr(recording->fileName, '.'); +#ifdef USE_LIEMIKUUTIO + if (ext && RemoveRecording) { +#else if (ext) { +#endif /* LIEMIKUUTIO */ strncpy(ext, DELEXT, strlen(ext)); if (access(recording->FileName(), F_OK) == 0) { recording->deleted = time(NULL); @@ -2140,6 +2171,22 @@ return NULL; } +#ifdef USE_HARDLINKCUTTER +off_t cFileName::MaxFileSize() { + const int maxVideoFileSize = isPesRecording ? MAXVIDEOFILESIZEPES : MAXVIDEOFILESIZETS; + const int setupMaxVideoFileSize = min(maxVideoFileSize, Setup.MaxVideoFileSize); + const int maxFileNumber = isPesRecording ? 255 : 65535; + + const off_t smallFiles = (maxFileNumber * off_t(maxVideoFileSize) - 1024 * Setup.MaxRecordingSize) + / max(maxVideoFileSize - setupMaxVideoFileSize, 1); + + if (fileNumber <= smallFiles) + return MEGABYTE(off_t(setupMaxVideoFileSize)); + + return MEGABYTE(off_t(maxVideoFileSize)); +} +#endif /* HARDLINKCUTTER */ + cUnbufferedFile *cFileName::NextFile(void) { return SetOffset(fileNumber + 1); diff -ruN vdr-1.7.31-ext/recording.h vdr-1.7.31/recording.h --- vdr-1.7.31-ext/recording.h 2012-09-17 10:53:23.000000000 +0200 +++ vdr-1.7.31/recording.h 2012-09-19 23:54:19.000000000 +0200 @@ -68,6 +68,9 @@ const cEvent *GetEvent(void) const { return event; } const char *Title(void) const { return event->Title(); } const char *ShortText(void) const { return event->ShortText(); } +#ifdef USE_GRAPHTFT + tEventID EventID(void) const { return event->EventID(); } +#endif /* GRAPHTFT */ const char *Description(void) const { return event->Description(); } const cComponents *Components(void) const { return event->Components(); } const char *Aux(void) const { return aux; } @@ -118,6 +121,9 @@ const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const; const cRecordingInfo *Info(void) const { return info; } const char *PrefixFileName(char Prefix); +#ifdef USE_LIEMIKUUTIO + const char *UpdateFileName(const char *FileName); +#endif /* LIEMIKUUTIO */ int HierarchyLevels(void) const; void ResetResume(void) const; double FramesPerSecond(void) const { return framesPerSecond; } @@ -189,7 +195,11 @@ void ResetResume(const char *ResumeFileName = NULL); cRecording *GetByName(const char *FileName); void AddByName(const char *FileName, bool TriggerUpdate = true); +#ifdef USE_LIEMIKUUTIO + void DelByName(const char *FileName, bool RemoveRecording = true); +#else void DelByName(const char *FileName); +#endif /* LIEMIKUUTIO */ void UpdateByName(const char *FileName); int TotalFileSizeMB(void); double MBperMinute(void); @@ -260,9 +270,23 @@ // before the next independent frame, to have a complete Group Of Pictures): #define MAXVIDEOFILESIZETS 1048570 // MB #define MAXVIDEOFILESIZEPES 2000 // MB +#ifdef USE_HARDLINKCUTTER +#define MINVIDEOFILESIZE 1 // MB +#else #define MINVIDEOFILESIZE 100 // MB +#endif /* HARDLINKCUTTER */ #define MAXVIDEOFILESIZEDEFAULT MAXVIDEOFILESIZEPES +#ifdef USE_HARDLINKCUTTER +#define MINRECORDINGSIZE 25 // GB +#define MAXRECORDINGSIZE 500 // GB +#define DEFAULTRECORDINGSIZE 100 // GB +// Dynamic recording size: +// Keep recording file size at Setup.MaxVideoFileSize for as long as possible, +// but switch to MAXVIDEOFILESIZE early enough, so that Setup.MaxRecordingSize +// will be reached, before recording to file 65535.vdr +#endif /* HARDLINKCUTTER */ + struct tIndexTs; class cIndexFileGenerator; @@ -320,6 +344,10 @@ cUnbufferedFile *Open(void); void Close(void); cUnbufferedFile *SetOffset(int Number, off_t Offset = 0); // yes, Number is int for easier internal calculating +#ifdef USE_HARDLINKCUTTER + off_t MaxFileSize(); + // Dynamic file size for this file +#endif /* HARDLINKCUTTER */ cUnbufferedFile *NextFile(void); }; diff -ruN vdr-1.7.31-ext/remux.c vdr-1.7.31/remux.c --- vdr-1.7.31-ext/remux.c 2012-09-19 12:28:42.000000000 +0200 +++ vdr-1.7.31/remux.c 2012-09-19 23:54:19.000000000 +0200 @@ -146,6 +146,44 @@ } } +#ifdef USE_NALUDUMP +void TsExtendAdaptionField(unsigned char *Packet, int ToLength) +{ + // Hint: ExtenAdaptionField(p, TsPayloadOffset(p) - 4) is a null operation + + int Offset = TsPayloadOffset(Packet); // First byte after existing adaption field + + if (ToLength <= 0) + { + // Remove adaption field + Packet[3] = Packet[3] & ~TS_ADAPT_FIELD_EXISTS; + return; + } + + // Set adaption field present + Packet[3] = Packet[3] | TS_ADAPT_FIELD_EXISTS; + + // Set new length of adaption field: + Packet[4] = ToLength <= TS_SIZE-4 ? ToLength-1 : TS_SIZE-4-1; + + if (Packet[4] == TS_SIZE-4-1) + { + // No more payload, remove payload flag + Packet[3] = Packet[3] & ~TS_PAYLOAD_EXISTS; + } + + int NewPayload = TsPayloadOffset(Packet); // First byte after new adaption field + + // Fill new adaption field + if (Offset == 4 && Offset < NewPayload) + Offset++; // skip adaptation_field_length + if (Offset == 5 && Offset < NewPayload) + Packet[Offset++] = 0; // various flags set to 0 + while (Offset < NewPayload) + Packet[Offset++] = 0xff; // stuffing byte +} + +#endif // USE_NALUDUMP // --- cPatPmtGenerator ------------------------------------------------------ cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel) @@ -219,6 +257,31 @@ return i; } +#ifdef USE_TTXTSUBS +int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount) +{ + int i = 0, j = 0; + Target[i++] = SI::TeletextDescriptorTag; + int l = i; + Target[i++] = 0x00; // length + for (int n = 0; n < pageCount; n++) { + const char* Language = pages[n].ttxtLanguage; + Target[i++] = *Language++; + Target[i++] = *Language++; + Target[i++] = *Language++; + Target[i++] = (pages[n].ttxtType << 3) + pages[n].ttxtMagazine; + Target[i++] = pages[n].ttxtPage; + j++; + } + if (j > 0) { + Target[l] = j * 5; // update length + IncEsInfoLength(i); + return i; + } + return 0; +} +#endif // USE_TTXTSUBS + int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) { int i = 0; @@ -306,6 +369,9 @@ if (Channel) { int Vpid = Channel->Vpid(); int Ppid = Channel->Ppid(); +#ifdef USE_TTXTSUBS + int Tpid = Channel->Tpid(); +#endif // USE_TTXTSUBS uchar *p = buf; int i = 0; p[i++] = 0x02; // table id @@ -338,6 +404,12 @@ i += MakeStream(buf + i, 0x06, Channel->Spid(n)); i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); } +#ifdef USE_TTXTSUBS + if (Tpid) { + i += MakeStream(buf + i, 0x06, Tpid); + i += MakeTeletextDescriptor(buf + i, Channel->TeletextSubtitlePages(), Channel->TotalTeletextSubtitlePages()); + } +#endif // USE_TTXTSUBS int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC buf[SectionLength] |= (sl >> 8) & 0x0F; @@ -411,6 +483,9 @@ pmtPid = -1; vpid = vtype = 0; ppid = 0; +#ifdef USE_TTXTSUBS + tpid = 0; +#endif // USE_TTXTSUBS } void cPatPmtParser::ParsePat(const uchar *Data, int Length) @@ -496,11 +571,17 @@ int NumSpids = 0; vpid = vtype = 0; ppid = 0; +#ifdef USE_TTXTSUBS + tpid = 0; +#endif // USE_TTXTSUBS apids[0] = 0; dpids[0] = 0; spids[0] = 0; atypes[0] = 0; dtypes[0] = 0; +#ifdef USE_TTXTSUBS + totalTtxtSubtitlePages = 0; +#endif // USE_TTXTSUBS SI::PMT::Stream stream; for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); @@ -599,6 +680,30 @@ spids[NumSpids]= 0; } break; +#ifdef USE_TTXTSUBS + case SI::TeletextDescriptorTag: { + dbgpatpmt(" teletext"); + tpid = stream.getPid(); + SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; + SI::TeletextDescriptor::Teletext ttxt; + if (totalTtxtSubtitlePages < MAXTXTPAGES) { + for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { + bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); + if (isSubtitlePage && ttxt.languageCode[0]) { + dbgpatpmt(" '%s:%x.%x'", ttxt.languageCode, ttxt.getTeletextMagazineNumber(), ttxt.getTeletextPageNumber()); + strn0cpy(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage = ttxt.getTeletextPageNumber(); + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType = ttxt.getTeletextType(); + totalTtxtSubtitlePages++; + if (totalTtxtSubtitlePages >= MAXTXTPAGES) + break; + } + } + } + } + break; +#endif // USE_TTXTSUBS case SI::ISO639LanguageDescriptorTag: { SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; dbgpatpmt(" '%s'", ld->languageCode); @@ -1066,3 +1171,346 @@ } return Processed; } +#ifdef USE_NALUDUMP + +// --- cNaluDumper --------------------------------------------------------- + +cNaluDumper::cNaluDumper() +{ + LastContinuityOutput = -1; + reset(); +} + +void cNaluDumper::reset() +{ + LastContinuityInput = -1; + ContinuityOffset = 0; + PesId = -1; + PesOffset = 0; + NaluFillState = NALU_NONE; + NaluOffset = 0; + History = 0xffffffff; + DropAllPayload = false; +} + +void cNaluDumper::ProcessPayload(unsigned char *Payload, int size, bool PayloadStart, sPayloadInfo &Info) +{ + Info.DropPayloadStartBytes = 0; + Info.DropPayloadEndBytes = 0; + int LastKeepByte = -1; + + if (PayloadStart) + { + History = 0xffffffff; + PesId = -1; + NaluFillState = NALU_NONE; + } + + for (int i=0; i= 0x00000180 && History <= 0x000001FF) + { + // Start of PES packet + PesId = History & 0xff; + PesOffset = 0; + NaluFillState = NALU_NONE; + } + else if (PesId >= 0xe0 && PesId <= 0xef // video stream + && History >= 0x00000100 && History <= 0x0000017F) // NALU start code + { + int NaluId = History & 0xff; + NaluOffset = 0; + NaluFillState = ((NaluId & 0x1f) == 0x0c) ? NALU_FILL : NALU_NONE; + } + + if (PesId >= 0xe0 && PesId <= 0xef // video stream + && PesOffset >= 1 && PesOffset <= 2) + { + Payload[i] = 0; // Zero out PES length field + } + + if (NaluFillState == NALU_FILL && NaluOffset > 0) // Within NALU fill data + { + // We expect a series of 0xff bytes terminated by a single 0x80 byte. + + if (Payload[i] == 0xFF) + { + DropByte = true; + } + else if (Payload[i] == 0x80) + { + NaluFillState = NALU_TERM; // Last byte of NALU fill, next byte sets NaluFillEnd=true + DropByte = true; + } + else // Invalid NALU fill + { + dsyslog("cNaluDumper: Unexpected NALU fill data: %02x", Payload[i]); + NaluFillState = NALU_END; + if (LastKeepByte == -1) + { + // Nalu fill from beginning of packet until last byte + // packet start needs to be dropped + Info.DropPayloadStartBytes = i; + } + } + } + else if (NaluFillState == NALU_TERM) // Within NALU fill data + { + // We are after the terminating 0x80 byte + NaluFillState = NALU_END; + if (LastKeepByte == -1) + { + // Nalu fill from beginning of packet until last byte + // packet start needs to be dropped + Info.DropPayloadStartBytes = i; + } + } + + if (!DropByte) + LastKeepByte = i; // Last useful byte + } + + Info.DropAllPayloadBytes = (LastKeepByte == -1); + Info.DropPayloadEndBytes = size-1-LastKeepByte; +} + +bool cNaluDumper::ProcessTSPacket(unsigned char *Packet) +{ + bool HasAdaption = TsHasAdaptationField(Packet); + bool HasPayload = TsHasPayload(Packet); + + // Check continuity: + int ContinuityInput = TsContinuityCounter(Packet); + if (LastContinuityInput >= 0) + { + int NewContinuityInput = HasPayload ? (LastContinuityInput + 1) & TS_CONT_CNT_MASK : LastContinuityInput; + int Offset = (NewContinuityInput - ContinuityInput) & TS_CONT_CNT_MASK; + if (Offset > 0) + dsyslog("cNaluDumper: TS continuity offset %i", Offset); + if (Offset > ContinuityOffset) + ContinuityOffset = Offset; // max if packets get dropped, otherwise always the current one. + } + LastContinuityInput = ContinuityInput; + + if (HasPayload) { + sPayloadInfo Info; + int Offset = TsPayloadOffset(Packet); + ProcessPayload(Packet + Offset, TS_SIZE - Offset, TsPayloadStart(Packet), Info); + + if (DropAllPayload && !Info.DropAllPayloadBytes) + { + // Return from drop packet mode to normal mode + DropAllPayload = false; + + // Does the packet start with some remaining NALU fill data? + if (Info.DropPayloadStartBytes > 0) + { + // Add these bytes as stuffing to the adaption field. + + // Sample payload layout: + // FF FF FF FF FF 80 00 00 01 xx xx xx xx + // ^DropPayloadStartBytes + + TsExtendAdaptionField(Packet, Offset - 4 + Info.DropPayloadStartBytes); + } + } + + bool DropThisPayload = DropAllPayload; + + if (!DropAllPayload && Info.DropPayloadEndBytes > 0) // Payload ends with 0xff NALU Fill + { + // Last packet of useful data + // Do early termination of NALU fill data + Packet[TS_SIZE-1] = 0x80; + DropAllPayload = true; + // Drop all packets AFTER this one + + // Since we already wrote the 0x80, we have to make sure that + // as soon as we stop dropping packets, any beginning NALU fill of next + // packet gets dumped. (see DropPayloadStartBytes above) + } + + if (DropThisPayload && HasAdaption) + { + // Drop payload data, but keep adaption field data + TsExtendAdaptionField(Packet, TS_SIZE-4); + DropThisPayload = false; + } + + if (DropThisPayload) + { + return true; // Drop packet + } + } + + // Fix Continuity Counter and reproduce incoming offsets: + int NewContinuityOutput = TsHasPayload(Packet) ? (LastContinuityOutput + 1) & TS_CONT_CNT_MASK : LastContinuityOutput; + NewContinuityOutput = (NewContinuityOutput + ContinuityOffset) & TS_CONT_CNT_MASK; + TsSetContinuityCounter(Packet, NewContinuityOutput); + LastContinuityOutput = NewContinuityOutput; + ContinuityOffset = 0; + + return false; // Keep packet +} + +// --- cNaluStreamProcessor --------------------------------------------------------- + +cNaluStreamProcessor::cNaluStreamProcessor() +{ + pPatPmtParser = NULL; + vpid = -1; + data = NULL; + length = 0; + tempLength = 0; + tempLengthAtEnd = false; + TotalPackets = 0; + DroppedPackets = 0; +} + +void cNaluStreamProcessor::PutBuffer(uchar *Data, int Length) +{ + if (length > 0) + esyslog("cNaluStreamProcessor::PutBuffer: New data before old data was processed!"); + + data = Data; + length = Length; +} + +uchar* cNaluStreamProcessor::GetBuffer(int &OutLength) +{ + if (length <= 0) + { + // Need more data - quick exit + OutLength = 0; + return NULL; + } + if (tempLength > 0) // Data in temp buffer? + { + if (tempLengthAtEnd) // Data is at end, copy to beginning + { + // Overlapping src and dst! + for (int i=0; i 0) + { + int Size = min(TS_SIZE-tempLength, length); + memcpy(tempBuffer+tempLength, data, Size); + data += Size; + length -= Size; + tempLength += Size; + } + if (tempLength < TS_SIZE) + { + // All incoming data buffered, but need more data + tempLengthAtEnd = false; + OutLength = 0; + return NULL; + } + // Now: TempLength==TS_SIZE + if (tempBuffer[0] != TS_SYNC_BYTE) + { + // Need to sync on TS within temp buffer + int Skipped = 1; + while (Skipped < TS_SIZE && (tempBuffer[Skipped] != TS_SYNC_BYTE || (Skipped < length && data[Skipped] != TS_SYNC_BYTE))) + Skipped++; + esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped); + // Pass through skipped bytes + tempLengthAtEnd = true; + tempLength = TS_SIZE - Skipped; // may be 0, thats ok + OutLength = Skipped; + return tempBuffer; + } + // Now: TempBuffer is a TS packet + int Pid = TsPid(tempBuffer); + if (pPatPmtParser) + { + if (Pid == 0) + pPatPmtParser->ParsePat(tempBuffer, TS_SIZE); + else if (Pid == pPatPmtParser->PmtPid()) + pPatPmtParser->ParsePmt(tempBuffer, TS_SIZE); + } + + TotalPackets++; + bool Drop = false; + if (Pid == vpid || (pPatPmtParser && Pid == pPatPmtParser->Vpid() && pPatPmtParser->Vtype() == 0x1B)) + Drop = NaluDumper.ProcessTSPacket(tempBuffer); + if (!Drop) + { + // Keep this packet, then continue with new data + tempLength = 0; + OutLength = TS_SIZE; + return tempBuffer; + } + // Drop TempBuffer + DroppedPackets++; + tempLength = 0; + } + // Now: TempLength==0, just process data/length + + // Pointer to processed data / length: + uchar *Out = data; + uchar *OutEnd = Out; + + while (length >= TS_SIZE) + { + if (data[0] != TS_SYNC_BYTE) { + int Skipped = 1; + while (Skipped < length && (data[Skipped] != TS_SYNC_BYTE || (length - Skipped > TS_SIZE && data[Skipped + TS_SIZE] != TS_SYNC_BYTE))) + Skipped++; + esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped); + + // Pass through skipped bytes + if (OutEnd != data) + memcpy(OutEnd, data, Skipped); + OutEnd += Skipped; + continue; + } + // Now: Data starts with complete TS packet + + int Pid = TsPid(data); + if (pPatPmtParser) + { + if (Pid == 0) + pPatPmtParser->ParsePat(data, TS_SIZE); + else if (Pid == pPatPmtParser->PmtPid()) + pPatPmtParser->ParsePmt(data, TS_SIZE); + } + + TotalPackets++; + bool Drop = false; + if (Pid == vpid || (pPatPmtParser && Pid == pPatPmtParser->Vpid() && pPatPmtParser->Vtype() == 0x1B)) + Drop = NaluDumper.ProcessTSPacket(data); + if (!Drop) + { + if (OutEnd != data) + memcpy(OutEnd, data, TS_SIZE); + OutEnd += TS_SIZE; + } + else + { + DroppedPackets++; + } + data += TS_SIZE; + length -= TS_SIZE; + } + // Now: Less than a packet remains. + if (length > 0) + { + // copy remains into temp buffer + memcpy(tempBuffer, data, length); + tempLength = length; + tempLengthAtEnd = false; + length = 0; + } + OutLength = (OutEnd - Out); + return OutLength > 0 ? Out : NULL; +} +#endif // USE_NALUDUMP diff -ruN vdr-1.7.31-ext/remux.h vdr-1.7.31/remux.h --- vdr-1.7.31-ext/remux.h 2011-09-04 14:48:26.000000000 +0200 +++ vdr-1.7.31/remux.h 2012-09-19 23:54:19.000000000 +0200 @@ -57,6 +57,13 @@ return p[3] & TS_PAYLOAD_EXISTS; } +#ifdef USE_NALUDUMP +inline bool TsSetPayload(const uchar *p) +{ + return p[3] & TS_PAYLOAD_EXISTS; +} + +#endif // USE_NALUDUMP inline bool TsHasAdaptationField(const uchar *p) { return p[3] & TS_ADAPT_FIELD_EXISTS; @@ -103,6 +110,13 @@ return p[3] & TS_CONT_CNT_MASK; } +#ifdef USE_NALUDUMP +inline void TsSetContinuityCounter(uchar *p, int Counter) +{ + p[3] = (p[3] & ~TS_CONT_CNT_MASK) | (Counter & TS_CONT_CNT_MASK); +} + +#endif // USE_NALUDUMP inline int TsGetAdaptationField(const uchar *p) { return TsHasAdaptationField(p) ? p[5] : 0x00; @@ -112,6 +126,9 @@ int64_t TsGetPts(const uchar *p, int l); void TsSetTeiOnBrokenPackets(uchar *p, int l); +#ifdef USE_NALUDUMP +void TsExtendAdaptionField(unsigned char *Packet, int ToLength); +#endif // USE_NALUDUMP // Some PES handling tools: // The following functions that take a pointer to PES data all assume that @@ -174,6 +191,9 @@ int MakeStream(uchar *Target, uchar Type, int Pid); int MakeAC3Descriptor(uchar *Target, uchar Type); int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); +#ifdef USE_TTXTSUBS + int MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount); +#endif // USE_TTXTSUBS int MakeLanguageDescriptor(uchar *Target, const char *Language); int MakeCRC(uchar *Target, const uchar *Data, int Length); void GeneratePmtPid(const cChannel *Channel); @@ -219,6 +239,9 @@ int vpid; int ppid; int vtype; +#ifdef USE_TTXTSUBS + int tpid; +#endif // USE_TTXTSUBS int apids[MAXAPIDS + 1]; // list is zero-terminated int atypes[MAXAPIDS + 1]; // list is zero-terminated char alangs[MAXAPIDS][MAXLANGCODE2]; @@ -231,6 +254,10 @@ uint16_t compositionPageIds[MAXSPIDS]; uint16_t ancillaryPageIds[MAXSPIDS]; bool updatePrimaryDevice; +#ifdef USE_TTXTSUBS + int totalTtxtSubtitlePages; + tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; +#endif // USE_TTXTSUBS protected: int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } public: @@ -263,6 +290,11 @@ int Vtype(void) const { return vtype; } ///< Returns the video stream type as defined by the current PMT, or 0 if no video ///< stream type has been detected, yet. +#ifdef USE_TTXTSUBS + int Tpid(void) { return tpid; } + ///< Returns the teletext pid as defined by the current PMT, or 0 if no teletext + ///< pid has been detected, yet. +#endif // USE_TTXTSUBS const int *Apids(void) const { return apids; } const int *Dpids(void) const { return dpids; } const int *Spids(void) const { return spids; } @@ -277,6 +309,10 @@ uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } +#ifdef USE_TTXTSUBS + const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } + int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } +#endif // USE_TTXTSUBS }; // TS to PES converter: @@ -390,4 +426,80 @@ ///< available. }; +#ifdef USE_NALUDUMP + +#define PATCH_NALUDUMP 100 + +class cNaluDumper { + unsigned int History; + + int LastContinuityInput; + int LastContinuityOutput; + int ContinuityOffset; + + bool DropAllPayload; + + int PesId; + int PesOffset; + + int NaluOffset; + + enum eNaluFillState { + NALU_NONE=0, // currently not NALU fill stream + NALU_FILL, // Within NALU fill stream, 0xff bytes and NALU start code in byte 0 + NALU_TERM, // Within NALU fill stream, read 0x80 terminating byte + NALU_END // Beyond end of NALU fill stream, expecting 0x00 0x00 0x01 now + }; + + eNaluFillState NaluFillState; + + struct sPayloadInfo { + int DropPayloadStartBytes; + int DropPayloadEndBytes; + bool DropAllPayloadBytes; + }; + +public: + cNaluDumper(); + + void reset(); + + // Single packet interface: + bool ProcessTSPacket(unsigned char *Packet); + +private: + void ProcessPayload(unsigned char *Payload, int size, bool PayloadStart, sPayloadInfo &Info); +}; + +class cNaluStreamProcessor { + //Buffer stream interface: + int vpid; + uchar *data; + int length; + uchar tempBuffer[TS_SIZE]; + int tempLength; + bool tempLengthAtEnd; + cPatPmtParser *pPatPmtParser; + cNaluDumper NaluDumper; + + long long int TotalPackets; + long long int DroppedPackets; +public: + cNaluStreamProcessor(); + + void SetPid(int VPid) { vpid = VPid; } + void SetPatPmtParser(cPatPmtParser *_pPatPmtParser) { pPatPmtParser = _pPatPmtParser; } + // Set either a PID or set a pointer to an PatPmtParser that will detect _one_ PID + + void PutBuffer(uchar *Data, int Length); + // Add new data to be processed. Data must be valid until Get() returns NULL. + uchar* GetBuffer(int &OutLength); + // Returns filtered data, or NULL/0 to indicate that all data from Put() was processed + // or buffered. + + long long int GetTotalPackets() { return TotalPackets; } + long long int GetDroppedPackets() { return DroppedPackets; } +}; + +#endif // USE_NALUDUMP #endif // __REMUX_H diff -ruN vdr-1.7.31-ext/shutdown.c vdr-1.7.31/shutdown.c --- vdr-1.7.31-ext/shutdown.c 2008-02-24 11:29:00.000000000 +0100 +++ vdr-1.7.31/shutdown.c 2012-09-19 23:54:19.000000000 +0200 @@ -17,6 +17,9 @@ #include "channels.h" #include "config.h" #include "cutter.h" +#ifdef USE_LIEMIKUUTIO +#include "filetransfer.h" +#endif /* LIEMIKUUTIO */ #include "i18n.h" #include "interface.h" #include "menu.h" @@ -166,6 +169,12 @@ if (!Interactive || !Interface->Confirm(tr("Editing - shut down anyway?"))) return false; } +#ifdef USE_LIEMIKUUTIO + if (cFileTransfer::Active()) { + if (!Interactive || !Interface->Confirm(tr("Transfering file - shut down anyway?"))) + return false; + } +#endif /* LIEMIKUUTIO */ cTimer *timer = Timers.GetNextActiveTimer(); time_t Next = timer ? timer->StartTime() : 0; @@ -209,6 +218,12 @@ if (!Interactive || !Interface->Confirm(tr("Editing - restart anyway?"))) return false; } +#ifdef USE_LIEMIKUUTIO + if (cFileTransfer::Active()) { + if (!Interactive || !Interface->Confirm(tr("Transfering file - restart anyway?"))) + return false; + } +#endif /* LIEMIKUUTIO */ cTimer *timer = Timers.GetNextActiveTimer(); time_t Next = timer ? timer->StartTime() : 0; diff -ruN vdr-1.7.31-ext/status.c vdr-1.7.31/status.c --- vdr-1.7.31-ext/status.c 2012-03-07 15:17:24.000000000 +0100 +++ vdr-1.7.31/status.c 2012-09-19 23:54:19.000000000 +0200 @@ -124,3 +124,88 @@ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, FollowingTime, FollowingTitle, FollowingSubtitle); } +#ifdef USE_GRAPHTFT + +void cStatus::MsgOsdSetEvent(const cEvent* event) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->OsdSetEvent(event); +} + +void cStatus::MsgOsdSetRecording(const cRecording* recording) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->OsdSetRecording(recording); +} + +void cStatus::MsgOsdMenuDisplay(const char* kind) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->OsdMenuDisplay(kind); +} + +void cStatus::MsgOsdMenuDestroy() +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->OsdMenuDestroy(); +} +void cStatus::MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->OsdEventItem(Event, Text, Index, Count); +} +#endif /* GRAPHTFT */ +#ifdef USE_PINPLUGIN + +bool cStatus::MsgChannelProtected(const cDevice* Device, const cChannel* Channel) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + if (sm->ChannelProtected(Device, Channel) == true) + return true; + + return false; +} + +bool cStatus::MsgReplayProtected(const cRecording* Recording, const char* Name, + const char* Base, bool isDirectory, int menuView) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + if (sm->ReplayProtected(Recording, Name, Base, isDirectory, menuView) == true) + return true; + return false; +} + +void cStatus::MsgRecordingFile(const char* FileName) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->RecordingFile(FileName); +} + +void cStatus::MsgTimerCreation(cTimer* Timer, const cEvent *Event) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->TimerCreation(Timer, Event); +} + +bool cStatus::MsgPluginProtected(cPlugin* Plugin, int menuView) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + if (sm->PluginProtected(Plugin, menuView) == true) + return true; + return false; +} + +void cStatus::MsgUserAction(const eKeys key, const cOsdObject* Interact) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + sm->UserAction(key, Interact); +} + +bool cStatus::MsgMenuItemProtected(const char* Name, int menuView) +{ + for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) + if (sm->MenuItemProtected(Name, menuView) == true) + return true; + return false; +} +#endif /* PINPLUGIN */ diff -ruN vdr-1.7.31-ext/status.h vdr-1.7.31/status.h --- vdr-1.7.31-ext/status.h 2012-03-07 15:16:57.000000000 +0100 +++ vdr-1.7.31/status.h 2012-09-19 23:54:19.000000000 +0200 @@ -14,6 +14,9 @@ #include "device.h" #include "player.h" #include "tools.h" +#ifdef USE_PINPLUGIN +#include "plugin.h" +#endif enum eTimerChange { tcMod, tcAdd, tcDel }; @@ -81,6 +84,38 @@ // The OSD displays the single line Text with the current channel information. virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) {} // The OSD displays the given programme information. +#ifdef USE_GRAPHTFT + virtual void OsdSetRecording(const cRecording* recording) {} + // The OSD displays the recording information. + virtual void OsdSetEvent(const cEvent* event) {} + // The OSD displays the event information. + virtual void OsdMenuDisplay(const char* kind) {} + // report menu creation + virtual void OsdMenuDestroy() {} + // report menu destruvtion + virtual void OsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) {} + // The OSD displays the given single line Event as menu item at Index. +#endif /* GRAPHTFT */ +#ifdef USE_PINPLUGIN + virtual bool ChannelProtected(const cDevice *Device, const cChannel* Channel) { return false; } + // Checks if a channel is protected. + virtual bool ReplayProtected(const cRecording* Recording, const char* Name, + const char* Base, bool isDirectory, int menuView = false) { return false; } + // Checks if a recording is protected. + virtual void RecordingFile(const char* FileName) {} + // The given DVB device has started recording to FileName. FileName is the name of the + // recording directory + virtual void TimerCreation(cTimer* Timer, const cEvent *Event) {} + // The given timer is created + virtual bool PluginProtected(cPlugin* Plugin, int menuView = false) { return false; } + // Checks if a plugin is protected. + virtual void UserAction(const eKeys key, const cOsdObject* Interact) {} + // report user action + virtual bool MenuItemProtected(const char* Name, int menuView = false) { return false; } + // Checks if a menu entry is protected. +#endif /* PINPLUGIn */ + + public: cStatus(void); virtual ~cStatus(); @@ -102,6 +137,23 @@ static void MsgOsdTextItem(const char *Text, bool Scroll = false); static void MsgOsdChannel(const char *Text); static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); +#ifdef USE_GRAPHTFT + static void MsgOsdSetEvent(const cEvent* event); + static void MsgOsdSetRecording(const cRecording* recording); + static void MsgOsdMenuDisplay(const char* kind); + static void MsgOsdMenuDestroy(); + static void MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count); +#endif /* GRAPHTFT */ +#ifdef USE_PINPLUGIN + static bool MsgChannelProtected(const cDevice* Device, const cChannel* Channel); + static bool MsgReplayProtected(const cRecording* Recording, const char* Name, + const char* Base, bool isDirectory, int menuView = false); + static void MsgRecordingFile(const char* FileName); + static void MsgTimerCreation(cTimer* Timer, const cEvent *Event); + static bool MsgPluginProtected(cPlugin* Plugin, int menuView = false); + static void MsgUserAction(const eKeys key, const cOsdObject* Interact); + static bool MsgMenuItemProtected(const char* Name, int menuView = false); +#endif /* PINPLUGIN */ }; #endif //__STATUS_H diff -ruN vdr-1.7.31-ext/submenu.c vdr-1.7.31/submenu.c --- vdr-1.7.31-ext/submenu.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/submenu.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,947 @@ +/**************************************************************************** + * DESCRIPTION: + * Submenu + * + * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ + * + * Contact: ranga@teddycats.de + * + * Copyright (C) 2004, 2005 by Ralf Dotzert + * + * modified for the VDR Extensions Patch by zulu @vdr-portal + ****************************************************************************/ + +#ifndef SUBMENU_H +#include "submenu.h" +#include "plugin.h" +#ifdef USE_WAREAGLEICON +#include "iconpatch.h" +#endif /* WAREAGLEICON */ + +static const char* TAG_SYSTEM = "system"; +static const char* TAG_PLUGIN = "plugin"; +static const char* TAG_COMMAND = "command"; +static const char* TAG_THREAD = "thread"; +static const char* TAG_MENU = "menu"; +static const char* TAG_UNDEFINED = "undefined"; +static const char* TRUE_STR = "yes"; + + +//################################################################################ +//# SubMenuNode +//################################################################################ + +cSubMenuNode::cSubMenuNode(TiXmlElement *xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) +{ + init(); + _parentMenu = parentMenu; + _currentMenu = currentMenu; + _level = level; + + if (xml != NULL && xml->Type() == TiXmlNode::ELEMENT) { + const char *tag = xml->Value(); + + if (cSubMenuNode::IsType(tag) != cSubMenuNode::UNDEFINED) { + SetType(tag); + SetName(xml->Attribute("name")); + if ((_type == COMMAND) || (_type == THREAD)) { + SetCommand(xml->Attribute("execute")); + const char *confirmStr = xml->Attribute("confirm"); + if (confirmStr != NULL && strcmp(confirmStr, TRUE_STR) == 0) + _commandConfirm = true; + } + else if (_type == PLUGIN) { // Add Plugin Index + SetCustomTitle(xml->Attribute("title")); + SetPlugin(); + } + else if (_type == MENU && xml->NoChildren() == false) { + xml = xml->FirstChildElement(); + do { + cSubMenuNode *node = new cSubMenuNode(xml, level+1, &_subMenus, currentMenu); + _subMenus.Add(node); + } while ((xml=xml->NextSiblingElement()) != NULL); + } + } + } + else + throw "Invalid XML Node"; +} + +/** + * Construct new Node empty Node + * + * + */ +cSubMenuNode::cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) +{ + init(); + _parentMenu = parentMenu; + _currentMenu = currentMenu; + +} + + +/** + * + */ +void cSubMenuNode::init() +{ + _name = NULL; + _command = NULL; + _title = NULL; + _pluginMainMenuEntry = NULL; + _type = UNDEFINED; + _level = 0; + _parentMenu = NULL; + _currentMenu = NULL; + _pluginIndex = 0; + _commandConfirm = false; +} + + +cSubMenuNode::~ cSubMenuNode() +{ + if (_name != NULL) + free((void*)_name); + if (_command != NULL) + free((void*)_command); + if (_title != NULL) + free((void*)_title); + if (_pluginMainMenuEntry != NULL) + free((void*)_pluginMainMenuEntry); +} + +/** + * + */ +void cSubMenuNode::SetPlugin() +{ + bool found = false; + for (int i = 0; ; i++) { + cPlugin *p = cPluginManager::GetPlugin(i); + if (p) { + if (strcmp(_name, p->Name()) == 0 && p->MainMenuEntry() != NULL) { + SetPluginMainMenuEntry(p->MainMenuEntry()); + _pluginIndex = i; + found = true; + break; + } + } + else + break; + } + + if (!found) + _type = UNDEFINED; +} + + +bool cSubMenuNode::SaveXml(TiXmlElement *root) +{ + bool ok = true; + + if (root!=NULL) { + TiXmlElement *e = NULL; + switch(_type) { + case SYSTEM: + e = new TiXmlElement(TAG_SYSTEM); + e->SetAttribute("name", GetName()); + break; + case COMMAND: + e = new TiXmlElement(TAG_COMMAND); + e->SetAttribute("name", GetName()); + e->SetAttribute("execute", GetCommand()); + if (_commandConfirm) + e->SetAttribute("confirm", TRUE_STR); + break; + case THREAD: + e = new TiXmlElement(TAG_THREAD); + e->SetAttribute("name", GetName()); + e->SetAttribute("execute", GetCommand()); + if (_commandConfirm) + e->SetAttribute("confirm", TRUE_STR); + break; + case PLUGIN: + e = new TiXmlElement(TAG_PLUGIN); + e->SetAttribute("name", GetName()); + if (GetCustomTitle() != NULL && strcmp(GetCustomTitle(), "") != 0) + e->SetAttribute("title", GetCustomTitle()); + break; + case MENU: + e = new TiXmlElement(TAG_MENU); + e->SetAttribute("name", GetName()); + break; + case UNDEFINED: + default: + ok = false; + break; + } + if (ok) { + root->LinkEndChild(e); + if (HasSubMenus()) + for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) + node->SaveXml(e); + } + } + + return(ok); +} + + +cSubMenuNode::Type cSubMenuNode::IsType(const char *name) +{ + Type type = UNDEFINED; + + if (strcmp(name ,TAG_SYSTEM) == 0) + type = cSubMenuNode::SYSTEM; + else if (strcmp(name ,TAG_PLUGIN) == 0) + type = cSubMenuNode::PLUGIN; + else if (strcmp(name ,TAG_COMMAND) == 0) + type = cSubMenuNode::COMMAND; + else if (strcmp(name ,TAG_THREAD) == 0) + type = cSubMenuNode::THREAD; + else if (strcmp(name ,TAG_MENU) == 0) + type = cSubMenuNode::MENU; + + return(type); +} + +void cSubMenuNode::SetType(const char *name) +{ + _type = IsType(name); +} + +void cSubMenuNode::SetType(enum Type type) +{ + _type = type; +} + + +cSubMenuNode::Type cSubMenuNode::GetType() +{ + return(_type); +} + +const char *cSubMenuNode::GetTypeAsString() +{ + const char *str=NULL; + switch(_type) { + case SYSTEM: + str = TAG_SYSTEM; + break; + case COMMAND: + str = TAG_COMMAND; + break; + case THREAD: + str = TAG_THREAD; + break; + case PLUGIN: + str = TAG_PLUGIN; + break; + case MENU: + str = TAG_MENU; + break; + case UNDEFINED: + str = TAG_UNDEFINED; + default: + break; + } + + return(str); +} + +void cSubMenuNode::SetCommand(const char *command) +{ + if (_command != NULL) + free((void*)_command); + + if (command != NULL) + _command = strdup(command); + else + _command = NULL; +} + +const char *cSubMenuNode::GetCommand() +{ + return(_command); +} + +bool cSubMenuNode::CommandConfirm() +{ + return(_commandConfirm); +} + +void cSubMenuNode::SetCommandConfirm(int val) +{ + if (val == 1) + _commandConfirm = true; + else + _commandConfirm = false; +} + +void cSubMenuNode::SetCustomTitle(const char *title) +{ + if (_title != NULL) + free((void*)_title); + + if (title != NULL) + _title = strdup(title); + else + _title = NULL; +} + +const char *cSubMenuNode::GetCustomTitle() +{ + return(_title); +} + +void cSubMenuNode::SetName(const char *name) +{ + if (_name) + free ((void*)_name); + + if (name != NULL) + _name = strdup(name); + else + _name = NULL; +} + +const char *cSubMenuNode::GetName() +{ + return(_name); +} + +int cSubMenuNode::GetLevel() +{ + return(_level); +} + +void cSubMenuNode::SetLevel(int level) +{ + _level = level; + if (HasSubMenus()) { //Adjust Levels of Subnodes + for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) + node->SetLevel(level+1); + } +} + +int cSubMenuNode::GetPluginIndex() +{ + return(_pluginIndex); +} + +void cSubMenuNode::SetPluginIndex(int index) +{ + _pluginIndex = index; +} + +void cSubMenuNode::SetPluginMainMenuEntry(const char *mainMenuEntry) +{ + if (_pluginMainMenuEntry != NULL) + free((void*)_pluginMainMenuEntry); + + if (_title != NULL && strcmp(_title, "") != 0) + _pluginMainMenuEntry = strdup(_title); + else if (mainMenuEntry != NULL) + _pluginMainMenuEntry = strdup(mainMenuEntry); + else + _pluginMainMenuEntry = NULL; +} + +const char *cSubMenuNode::GetPluginMainMenuEntry() +{ + return(_pluginMainMenuEntry); +} + + +cSubMenuNodes *cSubMenuNode::GetParentMenu() +{ + return(_parentMenu); +} + +void cSubMenuNode::SetParentMenu(cSubMenuNodes *parent) +{ + _parentMenu = parent; +} + +cSubMenuNodes *cSubMenuNode::GetCurrentMenu() +{ + return(_currentMenu); +} + +void cSubMenuNode::SetCurrentMenu(cSubMenuNodes *current) +{ + _currentMenu = current; +} + + +cSubMenuNodes *cSubMenuNode::GetSubMenus() +{ + return(&_subMenus); +} + +bool cSubMenuNode::HasSubMenus() +{ + if (_subMenus.Count() > 0) + return(true); + else + return(false); +} + + +void cSubMenuNode::Print(int index) +{ + for (int i = 0; i < index; i++) + printf(" "); + + printf("Name=%s Type=%s Level=%d", _name, GetTypeAsString(), _level); + if (_type == COMMAND || _type == THREAD) + printf(" Command=%s", _command); + else if (_type == PLUGIN && _title != NULL) + printf(" Title=%s", _title); + printf("\n"); + + for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) + node->Print(index+4); +} + + +//################################################################################ +//# +//################################################################################ +cSubMenu::cSubMenu() +{ + _commandResult = NULL; + _currentMenuTree = &_menuTree; + _currentParentMenuTree = NULL; +#ifdef USE_PINPLUGIN + _currentParentIndex = -1; +#endif /* PINPLUGIN */ + _nodeArray = NULL; + _nrNodes = 0; +} + + +cSubMenu::~cSubMenu() +{ + if (_commandResult) + free(_commandResult); + if (_nodeArray) + free(_nodeArray); + _nrNodes = 0; +} + + +bool cSubMenu::LoadXml(cString fname) +{ + TiXmlDocument xmlDoc = TiXmlDocument(fname); + TiXmlElement *root = NULL; + cSubMenuNode *node = NULL; + + bool ok = true; + // Clear previously loaded Menu + _menuTree.Clear(); + _fname = fname; + + if ((ok = xmlDoc.LoadFile())) { + if ((root = xmlDoc.FirstChildElement("menus")) != NULL) { + cString tmp = root->Attribute("suffix"); +#ifdef USE_WAREAGLEICON + if (strcmp(tmp, "ICON_FOLDER") == 0) tmp = cString::sprintf(" %s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER); + else if (strcmp(tmp, "ICON_MOVE_FOLDER") == 0) tmp = cString::sprintf(" %s", IsLangUtf8() ? ICON_MOVE_FOLDER_UTF8 : ICON_MOVE_FOLDER); +#endif /* WAREAGLEICON */ + if (*tmp) + _menuSuffix = tmp; + else + _menuSuffix = cString::sprintf(" "); + + if ((root = root->FirstChildElement()) != NULL) { + do { + try { + node = new cSubMenuNode(root, 0, &_menuTree, NULL); + _menuTree.Add(node); + } + catch (char *message) { + esyslog("ERROR: while decoding XML Node"); + ok = false; + } + } while (ok == true && (root = root->NextSiblingElement()) != NULL); + addMissingPlugins(); + removeUndefinedNodes(); + } + } + else { + esyslog("ERROR: in %s, missing Tag \n", *fname); + ok = false; + } + } + else { + esyslog("ERROR: in %s : %s Col=%d Row=%d\n", + *fname, + xmlDoc.ErrorDesc(), + xmlDoc.ErrorCol(), + xmlDoc.ErrorRow()); + ok = false; + } + + return(ok); +} + + +bool cSubMenu::SaveXml() +{ + return(SaveXml(_fname)); +} + + +bool cSubMenu::SaveXml(cString fname) +{ + bool ok = true; + + if (*_fname) { + TiXmlDocument xml = TiXmlDocument(fname); + TiXmlComment comment; + comment.SetValue("\n\ +- VDR Menu-Configuration File\n\ +-\n\ +-\n\ +- Example:\n\ +-\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + ...\n\ + \n\ + \n\ + \n\ + \n\ + ...\n\ + \n\ + \n\ +"); + + TiXmlElement root("menus"); + root.SetAttribute("suffix", _menuSuffix); + for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) + node->SaveXml(&root); + + if (xml.InsertEndChild(comment) != NULL && xml.InsertEndChild(root) != NULL) + ok = xml.SaveFile(fname); + } + else + ok = false; + + return(ok); +} + + +cSubMenuNodes *cSubMenu::GetMenuTree() +{ + return(_currentMenuTree); +} + + +void cSubMenu::PrintMenuTree() +{ + for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) + node->Print(); +} + + +int cSubMenu::GetNrOfNodes() +{ + if (_nrNodes == 0) { + if ((_nrNodes = countNodes(&_menuTree)) > 0) { + _nodeArray = (cSubMenuNode**) malloc(sizeof(cSubMenuNode*)*_nrNodes); + int index = 0; + tree2Array(&_menuTree, index); + } + } + + return(_nrNodes); +} + + +/** + * returns the specified node within the current menu + * @param index position in the current menu + * @return node or null if not found + */ +cSubMenuNode *cSubMenu::GetNode(int index) +{ + cSubMenuNode *node = NULL; + if (_currentMenuTree == NULL || (node=_currentMenuTree->Get(index)) == NULL) + esyslog("ERROR: illegal call of cSubMenu::GetNode(%d)", index); + + return(node); +} + + +/** + * Get the specified Node + * @param index specfies the absolut indes in the list of all nodes + * @return node or NULL if not found + */ +cSubMenuNode *cSubMenu::GetAbsNode(int index) +{ + cSubMenuNode *node = NULL; + GetNrOfNodes(); + if (_nrNodes > 0 && index >= 0 && index < _nrNodes) + node = _nodeArray[index]; + + return(node); +} + + +#ifdef USE_PINPLUGIN +bool cSubMenu::Down(cSubMenuNode *node, int currentIndex) +#else +bool cSubMenu::Down(int index) +#endif /* PINPLUGIN */ +{ + bool ok = true; +#ifdef USE_PINPLUGIN + if (_currentMenuTree != NULL && node && node->GetType() == cSubMenuNode::MENU) { +#else + cSubMenuNode *node = NULL; + + if (_currentMenuTree != NULL && (node=_currentMenuTree->Get(index)) != NULL && node->GetType() == cSubMenuNode::MENU) { +#endif /* PINPLUGIN */ + _currentParentMenuTree = _currentMenuTree; +#ifdef USE_PINPLUGIN + _currentParentIndex = currentIndex; +#endif /* PINPLUGIN */ + _currentMenuTree = node->GetSubMenus(); + } + else { + ok = false; +#ifdef USE_PINPLUGIN + esyslog("ERROR: illegal call of cSubMenu::Down"); +#else + esyslog("ERROR: illegal call of cSubMenu::Down(%d)", index); +#endif /* PINPLUGIN */ + } + + return(ok); +} + +bool cSubMenu::Up(int *parentIndex) +{ + bool ok = true; + + if (_currentMenuTree != NULL && parentIndex != NULL) { +#ifndef USE_PINPLUGIN + cSubMenuNode *node = NULL; +#endif /* PINPLUGIN */ + *parentIndex = 0; +#ifdef USE_PINPLUGIN + if (_currentParentIndex >= 0) + *parentIndex = _currentParentIndex; +#else + if (_currentParentMenuTree != NULL) + for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { + if (_currentMenuTree == node->GetSubMenus()) { + *parentIndex = i; + break; + } + } +#endif /* PINPLUGIN */ + + _currentMenuTree = _currentParentMenuTree; + if (_currentMenuTree != NULL) + _currentParentMenuTree = _currentMenuTree->Get(0)->GetParentMenu(); + else + ok = false; + } + else { + ok = false; + esyslog("ERROR: illegal call of cSubMenu::Up()"); + } + + return(ok); +} + +const char *cSubMenu::ExecuteCommand(const char *cmd) +{ + free(_commandResult); + _commandResult = NULL; + + dsyslog("executing command '%s'", cmd); + FILE *p = popen(cmd, "r"); + if (p) { + int l = 0; + int c; + while ((c = fgetc(p)) != EOF) { + if (l % 20 == 0) + _commandResult = (char *)realloc(_commandResult, l + 21); + _commandResult[l++] = c; + } + if (_commandResult) + _commandResult[l] = 0; + pclose(p); + } + else + esyslog("ERROR: can't open pipe for command '%s'", cmd); + + return _commandResult; +} + +/** + * Move Menu Entry to new Position + * @param index index of menu entry to move + * @param toIndex index of destination + * @param where After ore before the destination index + */ +void cSubMenu::MoveMenu(int index, int toIndex, enum Where where) +{ + if (index < 0 || index > _nrNodes || // invalid index is ignored + toIndex < 0 || toIndex > _nrNodes || index == toIndex) + return; + + cSubMenuNode *srcNode = GetAbsNode(index); + cSubMenuNode *destNode = GetAbsNode(toIndex); + + if (where == cSubMenu::INTO && destNode->GetType() != cSubMenuNode::MENU) + return; + + if (where == cSubMenu::INTO) { + if (destNode->GetType() == cSubMenuNode::MENU) { + srcNode->GetCurrentMenu()->Del(srcNode, false); + srcNode->SetLevel(destNode->GetLevel()+1); + srcNode->SetParentMenu(destNode->GetCurrentMenu()); + srcNode->SetCurrentMenu(destNode->GetSubMenus()); + + destNode->GetSubMenus()->Add(srcNode); + reloadNodeArray(); + } + } + else { + srcNode->GetCurrentMenu()->Del(srcNode, false); + srcNode->SetLevel(destNode->GetLevel()); + srcNode->SetParentMenu(destNode->GetParentMenu()); + srcNode->SetCurrentMenu(destNode->GetCurrentMenu()); + + if (where == cSubMenu::BEHIND) { + destNode->GetCurrentMenu()->Add(srcNode, GetAbsNode(toIndex)); + reloadNodeArray(); + } + else { + destNode->GetCurrentMenu()->Ins(srcNode, GetAbsNode(toIndex)); + reloadNodeArray(); + } + } +} + +/** + * Create a new Menu Entry + * @param index index of destination + * @param menuTitle Titel of new Menu entry + */ +void cSubMenu::CreateMenu(int index, const char *menuTitle) +{ + if (index >= 0 && index < _nrNodes) { + cSubMenuNode *srcNode = GetAbsNode(index); + if (srcNode != NULL) { + cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); + newNode->SetLevel(srcNode->GetLevel()); + newNode->SetName(menuTitle); + newNode->SetType(cSubMenuNode::MENU); + newNode->SetParentMenu(srcNode->GetParentMenu()); + newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); + + srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); + reloadNodeArray(); + } + } +} + +/** + * delete the specified entry, or subtree if the specified entry is a menu + * @param index destion index + */ +void cSubMenu::DeleteMenu(int index) +{ + if (index >= 0 && index < _nrNodes) { + cSubMenuNode *srcNode = GetAbsNode(index); + srcNode->GetCurrentMenu()->Del(srcNode, true); + reloadNodeArray(); + } +} + + +// Private Methods + +int cSubMenu::countNodes(cSubMenuNodes *tree) +{ + int count = 0; + if (tree != NULL) { + for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { + count++; + if (node->HasSubMenus()) + count += countNodes(node->GetSubMenus()); + } + } + return(count); +} + + +void cSubMenu::tree2Array(cSubMenuNodes *tree, int &index) +{ + if (tree != NULL) { + for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { + _nodeArray[index++]=node; + if (node->HasSubMenus()) + tree2Array(node->GetSubMenus(), index); + } + } + +} + +bool cSubMenu::IsPluginInMenu(const char *name) +{ + bool found = false; + for (int i = 0; i < _nrNodes && found == false; i++) { + cSubMenuNode *node = GetAbsNode(i); + if (node != NULL && node->GetType() == cSubMenuNode::PLUGIN && strcmp(name, node->GetName()) == 0) + found = true; + } + return(found); +} + +/** + * Adds the given plugin to the Menu-Tree if not allready in List + * @param name specifies the name of the plugin + */ +void cSubMenu::AddPlugin(const char *name) +{ + if (! IsPluginInMenu(name)) { + cSubMenuNode *node = new cSubMenuNode(&_menuTree, NULL); + node->SetName(name); + node->SetType("plugin"); + node->SetPlugin(); + _menuTree.Add(node); + } +} + +void cSubMenu::addMissingPlugins() +{ + _nrNodes = GetNrOfNodes(); + for (int i = 0; ; i++) { + cPlugin *p = cPluginManager::GetPlugin(i); + if (p) + AddPlugin(p->Name()); + else + break; + } + reloadNodeArray(); +} + +/** + * Adds the given command to the Menu-Tree + * @param name specifies the name of the command + */ +void cSubMenu::CreateCommand(int index, const char *name, const char *execute, int confirm) +{ + if (index >= 0 && index < _nrNodes) { + cSubMenuNode *srcNode = GetAbsNode(index); + if (srcNode != NULL) { + cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); + newNode->SetLevel(srcNode->GetLevel()); + newNode->SetName(name); + newNode->SetType("command"); + newNode->SetCommand(execute); + newNode->SetCommandConfirm(confirm); + newNode->SetParentMenu(srcNode->GetParentMenu()); + newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); + + srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); + reloadNodeArray(); + } + } +} + +void cSubMenu::CreateThread(int index, const char *name, const char *execute, int confirm) +{ + if (index >= 0 && index < _nrNodes) { + cSubMenuNode *srcNode = GetAbsNode(index); + if (srcNode != NULL) { + cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); + newNode->SetLevel(srcNode->GetLevel()); + newNode->SetName(name); + newNode->SetType("thread"); + newNode->SetCommand(execute); + newNode->SetCommandConfirm(confirm); + newNode->SetParentMenu(srcNode->GetParentMenu()); + newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); + + srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); + reloadNodeArray(); + } + } +} + +/** + * reloads the internal Array of Nodes + */ +void cSubMenu::reloadNodeArray() +{ + if (_nrNodes > 0) + free(_nodeArray); + _nodeArray = NULL; + _nrNodes = 0; + _nrNodes = GetNrOfNodes(); +} + +/** + * remove Undefined Nodes + */ +void cSubMenu::removeUndefinedNodes() +{ + bool remove = false; + + reloadNodeArray(); + for (int i = 0; i < _nrNodes; i++) { + cSubMenuNode *node = GetAbsNode(i); + if (node != NULL && node->GetType() == cSubMenuNode::UNDEFINED) { + cSubMenuNodes *pMenu = node->GetCurrentMenu(); + pMenu->Del(node, true); + remove = true; + } + } + if (remove) + reloadNodeArray(); +} + + +/** +* Retrieves the Menutitel of the parent Menu +*/ +const char *cSubMenu::GetParentMenuTitel() +{ + const char *result = ""; + + if (_currentMenuTree != NULL && _currentParentMenuTree != NULL) { + cSubMenuNode *node = NULL; + for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { + if (_currentMenuTree == node->GetSubMenus()) { + result = node->GetName(); + break; + } + } + } + + return(result); +} + +#endif diff -ruN vdr-1.7.31-ext/submenu.h vdr-1.7.31/submenu.h --- vdr-1.7.31-ext/submenu.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/submenu.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,157 @@ +/**************************************************************************** + * DESCRIPTION: + * Submenu + * + * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ + * + * Contact: ranga@teddycats.de + * + * Copyright (C) 2004, 2005 by Ralf Dotzert + * + * modified for the VDR Extensions Patch by zulu @vdr-portal + ****************************************************************************/ + +#ifndef SUBMENU_H +#define SUBMENU_H + +#include "thread.h" +#include "tools.h" +#include "tinystr.h" + +class cSubMenuNode; +class cSubMenuNodes; +class cSubMenu; + + +class cSubMenuNodes : public cList {}; + +// execute cmd thread +class cExecCmdThread : public cThread { +private: + cString ExecCmd; +protected: + virtual void Action(void) { + if (system(ExecCmd) == 0) + esyslog("%s - finished", *ExecCmd); + delete(this); + }; +public: + cExecCmdThread(char *cmd) { + ExecCmd = cString::sprintf("%s", cmd); + } + cExecCmdThread(const char *cmd) { + ExecCmd = cString::sprintf("%s", cmd); + } + ~cExecCmdThread() { + }; + }; + +//################################################################################ +//# SubMenuNode +//################################################################################ +class cSubMenuNode : public cListObject { +public: + enum Type { UNDEFINED, SYSTEM, COMMAND, THREAD, PLUGIN, MENU }; + cSubMenuNode(TiXmlElement *xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); + cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); + ~cSubMenuNode(); + bool SaveXml(TiXmlElement *root); + static cSubMenuNode::Type IsType(const char *name); + void SetType(const char *name); + void SetType(enum Type type); + void SetPlugin(); + cSubMenuNode::Type GetType(); + const char *GetTypeAsString(); + void SetCommand(const char *command); + bool CommandConfirm(); + void SetCommandConfirm(int val); + const char *GetCommand(); + void SetCustomTitle(const char *title); + const char *GetCustomTitle(); + void SetName(const char *name); + const char*GetName(); + int GetLevel(); + void SetLevel(int level); + int GetPluginIndex(); + void SetPluginIndex(int index); + void SetPluginMainMenuEntry(const char *mainMenuEntry); + const char *GetPluginMainMenuEntry(); + cSubMenuNodes *GetParentMenu(); + void SetParentMenu(cSubMenuNodes *parent); + cSubMenuNodes *GetCurrentMenu(); + void SetCurrentMenu(cSubMenuNodes *current); + cSubMenuNodes *GetSubMenus(); + bool HasSubMenus(); + void Print(int index = 0); +private: + Type _type; + int _level; + // Plugin Variables + int _pluginIndex; + const char *_pluginMainMenuEntry; + // common + const char *_name; + const char *_command; + bool _commandConfirm; + const char *_title; + cSubMenuNodes _subMenus; + cSubMenuNodes *_parentMenu; + cSubMenuNodes *_currentMenu; + void init(); + }; + + +//################################################################################ +//# SubMenu Class +//################################################################################ +class cSubMenu { +public: + cSubMenu(); + ~cSubMenu(); + enum Where { BEFORE, BEHIND, INTO}; + bool LoadXml(cString fname); + bool SaveXml(cString fname); + bool SaveXml(); + cSubMenuNodes *GetMenuTree(); + bool Up(int *ParentIndex); +#ifdef USE_PINPLUGIN + bool Down(cSubMenuNode* node, int currentIndex); +#else + bool Down(int index); +#endif /* PINPLUGIN */ + int GetNrOfNodes(); + cSubMenuNode* GetAbsNode(int index); + cSubMenuNode* GetNode(int index); + void PrintMenuTree(); + bool IsPluginInMenu(const char *name); + void AddPlugin(const char *name); + void CreateCommand(int index, const char *name, const char *execute, int confirm); + void CreateThread(int index, const char *name, const char *execute, int confirm); + const char *ExecuteCommand(const char *command); + void MoveMenu(int index, int toindex, enum Where); + void CreateMenu(int index, const char *menuTitle); + void DeleteMenu(int index); + cString GetMenuSuffix() { return _menuSuffix; } + void SetMenuSuffix(char *suffix) { _menuSuffix = suffix; } + bool isTopMenu() { return (_currentParentMenuTree == NULL); } + const char *GetParentMenuTitel(); +private: + cSubMenuNodes _menuTree; + cSubMenuNodes *_currentMenuTree; + cSubMenuNodes *_currentParentMenuTree; +#ifdef USE_PINPLUGIN + int _currentParentIndex; +#endif /* PINPLUGIN */ + cString _fname; + char *_commandResult; + int _nrNodes; + cSubMenuNode **_nodeArray; + cString _menuSuffix; + int countNodes(cSubMenuNodes *tree); + void tree2Array(cSubMenuNodes *tree, int &index); + void addMissingPlugins(); + void reloadNodeArray(); + void removeUndefinedNodes(); + }; + +#endif //__SUBMENU_H diff -ruN vdr-1.7.31-ext/svdrp.c vdr-1.7.31/svdrp.c --- vdr-1.7.31-ext/svdrp.c 2012-05-12 13:55:18.000000000 +0200 +++ vdr-1.7.31/svdrp.c 2012-09-19 23:54:19.000000000 +0200 @@ -31,6 +31,9 @@ #include "cutter.h" #include "device.h" #include "eitscan.h" +#ifdef USE_LIEMIKUUTIO +#include "filetransfer.h" +#endif /* LIEMIKUUTIO */ #include "keys.h" #include "menu.h" #include "plugin.h" @@ -193,6 +196,13 @@ " After a CLRE command, no further EPG processing is done for 10\n" " seconds, so that data sent with subsequent PUTE commands doesn't\n" " interfere with data from the broadcasters.", +#ifdef USE_LIEMIKUUTIO + "CPYR \n" + " Copy the recording with the given number. Before a recording can be\n" + " copied, an LSTR command must have been executed in order to retrieve\n" + " the recording numbers. The numbers don't change during subsequent CPYR\n" + " commands.", +#endif /* LIEMIKUUTIO */ "DELC \n" " Delete channel.", "DELR \n" @@ -256,6 +266,13 @@ " used to easily activate or deactivate a timer.", "MOVC \n" " Move a channel to a new position.", +#ifdef USE_LIEMIKUUTIO + "MOVR \n" + " Move the recording with the given number. Before a recording can be\n" + " moved, an LSTR command must have been executed in order to retrieve\n" + " the recording numbers. The numbers don't change during subsequent MOVR\n" + " commands.", +#endif /* LIEMIKUUTIO */ "NEWC \n" " Create a new channel. Settings must be in the same format as returned\n" " by the LSTC command.", @@ -611,6 +628,34 @@ } } +#ifdef USE_LIEMIKUUTIO +void cSVDRP::CmdCPYR(const char *Option) +{ + if (*Option) { + char *tail; + int n = strtol(Option, &tail, 10); + cRecording *recording = Recordings.Get(n - 1); + if (recording && tail && tail != Option) { + char *oldName = strdup(recording->Name()); + tail = skipspace(tail); + if (!cFileTransfer::Active()) { + if (cFileTransfer::Start(recording, tail, true)) + Reply(250, "Copying recording \"%s\" to \"%s\"", oldName, tail); + else + Reply(554, "Can't start file transfer"); + } + else + Reply(554, "File transfer already active"); + free(oldName); + } + else + Reply(550, "Recording \"%d\" not found%s", n, Recordings.Count() ? "" : " (use LSTR before copying)"); + } + else + Reply(501, "Invalid Option \"%s\"", Option); +} +#endif /* LIEMIKUUTIO */ + void cSVDRP::CmdDELC(const char *Option) { if (*Option) { @@ -1289,6 +1334,34 @@ Reply(501, "Missing channel number"); } +#ifdef USE_LIEMIKUUTIO +void cSVDRP::CmdMOVR(const char *Option) +{ + if (*Option) { + char *tail; + int n = strtol(Option, &tail, 10); + cRecording *recording = Recordings.Get(n - 1); + if (recording && tail && tail != Option) { + char *oldName = strdup(recording->Name()); + tail = skipspace(tail); + if (!cFileTransfer::Active()) { + if (cFileTransfer::Start(recording, tail)) + Reply(250, "Moving recording \"%s\" to \"%s\"", oldName, tail); + else + Reply(554, "Can't start file transfer"); + } + else + Reply(554, "File transfer already active"); + free(oldName); + } + else + Reply(550, "Recording \"%d\" not found%s", n, Recordings.Count() ? "" : " (use LSTR before moving)"); + } + else + Reply(501, "Invalid Option \"%s\"", Option); +} +#endif /* LIEMIKUUTIO */ + void cSVDRP::CmdNEWC(const char *Option) { if (*Option) { @@ -1618,6 +1691,9 @@ s = skipspace(s); if (CMD("CHAN")) CmdCHAN(s); else if (CMD("CLRE")) CmdCLRE(s); +#ifdef USE_LIEMIKUUTIO + else if (CMD("CPYR")) CmdCPYR(s); +#endif /* LIEMIKUUTIO */ else if (CMD("DELC")) CmdDELC(s); else if (CMD("DELR")) CmdDELR(s); else if (CMD("DELT")) CmdDELT(s); @@ -1633,6 +1709,9 @@ else if (CMD("MODC")) CmdMODC(s); else if (CMD("MODT")) CmdMODT(s); else if (CMD("MOVC")) CmdMOVC(s); +#ifdef USE_LIEMIKUUTIO + else if (CMD("MOVR")) CmdMOVR(s); +#endif /* LIEMIKUUTIO */ else if (CMD("NEWC")) CmdNEWC(s); else if (CMD("NEWT")) CmdNEWT(s); else if (CMD("NEXT")) CmdNEXT(s); diff -ruN vdr-1.7.31-ext/svdrp.h vdr-1.7.31/svdrp.h --- vdr-1.7.31-ext/svdrp.h 2012-04-26 12:30:06.000000000 +0200 +++ vdr-1.7.31/svdrp.h 2012-09-19 23:54:19.000000000 +0200 @@ -56,6 +56,9 @@ void PrintHelpTopics(const char **hp); void CmdCHAN(const char *Option); void CmdCLRE(const char *Option); +#ifdef USE_LIEMIKUUTIO + void CmdCPYR(const char *Option); +#endif /* LIEMIKUUTIO */ void CmdDELC(const char *Option); void CmdDELR(const char *Option); void CmdDELT(const char *Option); @@ -71,6 +74,9 @@ void CmdMODC(const char *Option); void CmdMODT(const char *Option); void CmdMOVC(const char *Option); +#ifdef USE_LIEMIKUUTIO + void CmdMOVR(const char *Option); +#endif /* LIEMIKUUTIO */ void CmdNEWC(const char *Option); void CmdNEWT(const char *Option); void CmdNEXT(const char *Option); diff -ruN vdr-1.7.31-ext/timers.c vdr-1.7.31/timers.c --- vdr-1.7.31-ext/timers.c 2012-09-15 15:34:03.000000000 +0200 +++ vdr-1.7.31/timers.c 2012-10-02 05:10:55.000000000 +0200 @@ -78,6 +78,9 @@ stop -= 2400; priority = Pause ? Setup.PausePriority : Setup.DefaultPriority; lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime; +#ifdef USE_PINPLUGIN + fskProtection = 0; +#endif /* PINPLUGIN */ if (Instant && channel) snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name()); if (VfatFileSystem && (Utf8StrLen(file) > VFAT_MAX_FILENAME)) { @@ -117,6 +120,9 @@ stop -= 2400; priority = Setup.DefaultPriority; lifetime = Setup.DefaultLifetime; +#ifdef USE_PINPLUGIN + fskProtection = 0; +#endif /* PINPLUGIN */ const char *Title = Event->Title(); if (!isempty(Title)) Utf8Strn0Cpy(file, Event->Title(), sizeof(file)); @@ -126,6 +132,9 @@ dsyslog("timer file name truncated to '%s'", file); } SetEvent(Event); +#ifdef USE_PINPLUGIN + cStatus::MsgTimerCreation(this, Event); +#endif /* PINPLUGIN */ } cTimer::cTimer(const cTimer &Timer) @@ -161,6 +170,9 @@ stop = Timer.stop; priority = Timer.priority; lifetime = Timer.lifetime; +#ifdef USE_PINPLUGIN + fskProtection = Timer.fskProtection; +#endif /* PINPLUGIN */ strncpy(file, Timer.file, sizeof(file)); free(aux); aux = Timer.aux ? strdup(Timer.aux) : NULL; @@ -355,6 +367,9 @@ result = false; } } +#ifdef USE_PINPLUGIN + fskProtection = aux && strstr(aux, "yes"); +#endif /* PINPLUGIN */ free(channelbuffer); free(daybuffer); free(filebuffer); @@ -710,6 +725,37 @@ Matches(); // refresh start and end time } +#ifdef USE_PINPLUGIN +void cTimer::SetFskProtection(int aFlag) +{ + char* p; + char* tmp = 0; + + fskProtection = aFlag; + + if (fskProtection && (!aux || !strstr(aux, "yes"))) + { + // add protection info to aux + + if (aux) { tmp = strdup(aux); free(aux); } + if (asprintf(&aux,"%syes", tmp ? tmp : "") < 0 ) + aux = NULL; + } + else if (!fskProtection && aux && (p = strstr(aux, "yes"))) + { + // remove protection info to aux + + if (asprintf(&tmp, "%.*s%s", p-aux, aux, p+strlen("yes")) >= 0 ) { + free(aux); + aux = strdup(tmp); + } + } + + if (tmp) + free(tmp); +} +#endif /* PINPLUGIN */ + // --- cTimers --------------------------------------------------------------- cTimers Timers; diff -ruN vdr-1.7.31-ext/timers.h vdr-1.7.31/timers.h --- vdr-1.7.31-ext/timers.h 2012-04-15 15:21:31.000000000 +0200 +++ vdr-1.7.31/timers.h 2012-09-19 23:54:19.000000000 +0200 @@ -38,6 +38,9 @@ int start; int stop; int priority; +#ifdef USE_PINPLUGIN + int fskProtection; +#endif /* PINPLUGIN */ int lifetime; mutable char file[MaxFileName]; char *aux; @@ -59,6 +62,9 @@ int Start(void) const { return start; } int Stop(void) const { return stop; } int Priority(void) const { return priority; } +#ifdef USE_PINPLUGIN + int FskProtection(void) const { return fskProtection; } +#endif /* PINPLUGIN */ int Lifetime(void) const { return lifetime; } const char *File(void) const { return file; } time_t FirstDay(void) const { return weekdays ? day : 0; } @@ -95,6 +101,9 @@ void SetAux(const char *Aux); void SetDeferred(int Seconds); void SetFlags(uint Flags); +#ifdef USE_PINPLUGIN + void SetFskProtection(int aFlag); +#endif /* PINPLUGIN */ void ClrFlags(uint Flags); void InvFlags(uint Flags); bool HasFlags(uint Flags) const; diff -ruN vdr-1.7.31-ext/tinystr.c vdr-1.7.31/tinystr.c --- vdr-1.7.31-ext/tinystr.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinystr.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,299 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" + +#ifndef TIXML_USE_STL + + +#include +#include +#include + +#include "tinystr.h" + +// TiXmlString constructor, based on a C string +TiXmlString::TiXmlString (const char* instring) +{ + unsigned newlen; + char * newstring; + + if (!instring) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = strlen (instring) + 1; + newstring = new char [newlen]; + memcpy (newstring, instring, newlen); + // strcpy (newstring, instring); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlString copy constructor +TiXmlString::TiXmlString (const TiXmlString& copy) +{ + unsigned newlen; + char * newstring; + + // Prevent copy to self! + if ( © == this ) + return; + + if (! copy . allocated) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = copy . length () + 1; + newstring = new char [newlen]; + // strcpy (newstring, copy . cstring); + memcpy (newstring, copy . cstring, newlen); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlString = operator. Safe when assign own content +void TiXmlString ::operator = (const char * content) +{ + unsigned newlen; + char * newstring; + + if (! content) + { + empty_it (); + return; + } + newlen = strlen (content) + 1; + newstring = new char [newlen]; + // strcpy (newstring, content); + memcpy (newstring, content, newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// = operator. Safe when assign own content +void TiXmlString ::operator = (const TiXmlString & copy) +{ + unsigned newlen; + char * newstring; + + if (! copy . length ()) + { + empty_it (); + return; + } + newlen = copy . length () + 1; + newstring = new char [newlen]; + // strcpy (newstring, copy . c_str ()); + memcpy (newstring, copy . c_str (), newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + + +// append a const char * to an existing TiXmlString +void TiXmlString::append( const char* str, int len ) +{ + char * new_string; + unsigned new_alloc, new_size, size_suffix; + + // don't use strlen - it can overrun the len passed in! + const char* p = str; + size_suffix = 0; + + while ( *p && size_suffix < (unsigned)len ) + { + ++p; + ++size_suffix; + } + if ( !size_suffix) + return; + + new_size = length () + size_suffix + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new char [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + // strcpy (new_string, cstring); + memcpy (new_string, cstring, length ()); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // strncat (new_string, str, len); + memcpy (new_string + length (), + str, + size_suffix); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new string + // strncat (cstring, str, len); + memcpy (cstring + length (), + str, + size_suffix); + } + current_length = new_size - 1; + cstring [current_length] = 0; +} + + +// append a const char * to an existing TiXmlString +void TiXmlString::append( const char * suffix ) +{ + char * new_string; + unsigned new_alloc, new_size; + + new_size = length () + strlen (suffix) + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new char [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + memcpy (new_string, cstring, 1 + length ()); + // strcpy (new_string, cstring); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // strcat (new_string, suffix); + memcpy (new_string + length (), + suffix, + strlen (suffix) + 1); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new string + // strcat (cstring, suffix); + memcpy (cstring + length (), + suffix, + strlen (suffix) + 1); + } + current_length = new_size - 1; +} + +// Check for TiXmlString equuivalence +//bool TiXmlString::operator == (const TiXmlString & compare) const +//{ +// return (! strcmp (c_str (), compare . c_str ())); +//} + +//unsigned TiXmlString::length () const +//{ +// if (allocated) +// // return strlen (cstring); +// return current_length; +// return 0; +//} + + +unsigned TiXmlString::find (char tofind, unsigned offset) const +{ + char * lookup; + + if (offset >= length ()) + return (unsigned) notfound; + for (lookup = cstring + offset; * lookup; lookup++) + if (* lookup == tofind) + return lookup - cstring; + return (unsigned) notfound; +} + + +bool TiXmlString::operator == (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) == 0 ); + } + return false; +} + + +bool TiXmlString::operator < (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) > 0 ); + } + return false; +} + + +bool TiXmlString::operator > (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) < 0 ); + } + return false; +} + + +#endif // TIXML_USE_STL diff -ruN vdr-1.7.31-ext/tinystr.h vdr-1.7.31/tinystr.h --- vdr-1.7.31-ext/tinystr.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinystr.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,242 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" + + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#ifdef _MSC_VER +#pragma warning( disable : 4786 ) // Debugger truncating names. +#endif + +#include + +/* + TiXmlString is an emulation of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // TiXmlString constructor, based on a string + TiXmlString (const char * instring); + + // TiXmlString empty constructor + TiXmlString () + { + allocated = 0; + cstring = NULL; + current_length = 0; + } + + // TiXmlString copy constructor + TiXmlString (const TiXmlString& copy); + + // TiXmlString destructor + ~ TiXmlString () + { + empty_it (); + } + + // Convert a TiXmlString into a classical char * + const char * c_str () const + { + if (allocated) + return cstring; + return ""; + } + + // Return the length of a TiXmlString + unsigned length () const + { + return ( allocated ) ? current_length : 0; + } + + // TiXmlString = operator + void operator = (const char * content); + + // = operator + void operator = (const TiXmlString & copy); + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + append (suffix); + return *this; + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + append (single); + return *this; + } + + // += operator. Maps to append + TiXmlString& operator += (TiXmlString & suffix) + { + append (suffix); + return *this; + } + bool operator == (const TiXmlString & compare) const; + bool operator < (const TiXmlString & compare) const; + bool operator > (const TiXmlString & compare) const; + + // Checks if a TiXmlString is empty + bool empty () const + { + return length () ? false : true; + } + + // single char extraction + const char& at (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // find a char in a string. Return TiXmlString::notfound if not found + unsigned find (char lookup) const + { + return find (lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::notfound if not found + unsigned find (char tofind, unsigned offset) const; + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function clears the content of the TiXmlString if any exists. + */ + void reserve (unsigned size) + { + empty_it (); + if (size) + { + allocated = size; + cstring = new char [size]; + cstring [0] = 0; + current_length = 0; + } + } + + // [] operator + char& operator [] (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // Error value for find primitive + enum { notfound = 0xffffffff, + npos = notfound }; + + void append (const char *str, int len ); + + protected : + + // The base string + char * cstring; + // Number of chars allocated + unsigned allocated; + // Current string size + unsigned current_length; + + // New size computation. It is simplistic right now : it returns twice the amount + // we need + unsigned assign_new_size (unsigned minimum_to_allocate) + { + return minimum_to_allocate * 2; + } + + // Internal function that clears the content of a TiXmlString + void empty_it () + { + if (cstring) + delete [] cstring; + cstring = NULL; + allocated = 0; + current_length = 0; + } + + void append (const char *suffix ); + + // append function for another TiXmlString + void append (const TiXmlString & suffix) + { + append (suffix . c_str ()); + } + + // append for a single char. + void append (char single) + { + if ( cstring && current_length < (allocated-1) ) + { + cstring[ current_length ] = single; + ++current_length; + cstring[ current_length ] = 0; + } + else + { + char smallstr [2]; + smallstr [0] = single; + smallstr [1] = 0; + append (smallstr); + } + } + +} ; + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + TiXmlOutStream () : TiXmlString () {} + + // TiXmlOutStream << operator. Maps to TiXmlString::append + TiXmlOutStream & operator << (const char * in) + { + append (in); + return (* this); + } + + // TiXmlOutStream << operator. Maps to TiXmlString::append + TiXmlOutStream & operator << (const TiXmlString & in) + { + append (in . c_str ()); + return (* this); + } +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff -ruN vdr-1.7.31-ext/tinyxml.c vdr-1.7.31/tinyxml.c --- vdr-1.7.31-ext/tinyxml.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinyxml.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,1427 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include +#include "tinyxml.h" + +#ifdef TIXML_USE_STL +#include +#endif + + +bool TiXmlBase::condenseWhiteSpace = true; + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) +{ + TIXML_STRING buffer; + PutString( str, &buffer ); + (*stream) << buffer; +} + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + outString->append( buf, strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +// <-- Strange class for a bug fix. Search for STL_STRING_BUG +TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) +{ + buffer = new char[ str.length()+1 ]; + if ( buffer ) + { + strcpy( buffer, str.c_str() ); + } +} + + +TiXmlBase::StringToBuffer::~StringToBuffer() +{ + delete [] buffer; +} +// End strange bug fix. --> + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( node->SValue() == TIXML_STRING( _value )) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + +TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + +TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + + +TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +TiXmlElement* TiXmlNode::FirstChildElement() const +{ + TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + + +TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +void TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char * TiXmlElement::Attribute( const char * name ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + + if ( node ) + return node->Value(); + + return 0; +} + + +const char * TiXmlElement::Attribute( const char * name, int* i ) const +{ + const char * s = Attribute( name ); + if ( i ) + { + if ( s ) + *i = atoi( s ); + else + *i = 0; + } + return s; +} + + +const char * TiXmlElement::Attribute( const char * name, double* d ) const +{ + const char * s = Attribute( name ); + if ( d ) + { + if ( s ) + *d = atof( s ); + else + *d = 0; + } + return s; +} + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryIntValue( ival ); +} + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryDoubleValue( dval ); +} + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + char buf[64]; + sprintf( buf, "%d", val ); + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + char buf[128]; + sprintf( buf, "%f", val ); + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetAttribute( const char * name, const char * _value ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + +void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<" << value; + + TiXmlAttribute* attrib; + for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) + { + (*stream) << " "; + attrib->StreamOut( stream ); + } + + // If this node has children, give it a closing tag. Else + // make it an empty tag. + TiXmlNode* node; + if ( firstChild ) + { + (*stream) << ">"; + + for ( node = firstChild; node; node=node->NextSibling() ) + { + node->StreamOut( stream ); + } + (*stream) << ""; + } + else + { + (*stream) << " />"; + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) + return true; + + return false; +} + + +bool TiXmlDocument::SaveFile() const +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && SaveFile( buf.buffer ) ) + return true; + + return false; +} + +bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) +{ + // Delete the existing data: + Clear(); + location.Clear(); + + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the std::string to + // be called. What is strange, is that the std::string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // See STL_STRING_BUG above. + // Fixed with the StringToBuffer class. + value = filename; + + FILE* file = fopen( value.c_str (), "r" ); + + if ( file ) + { + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + fclose( file ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + const int BUF_SIZE = 2048; + char buf[BUF_SIZE]; + + while( fgets( buf, BUF_SIZE, file ) ) + { + data += buf; + } + fclose( file ); + + Parse( data.c_str(), 0, encoding ); + + if ( Error() ) + return false; + else + return true; + } + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; +} + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = fopen( filename, "w" ); + if ( fp ) + { + Print( fp, 0 ); + fclose( fp ); + return true; + } + return false; +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorDesc = errorDesc.c_str (); + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + +void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const +{ + TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->StreamOut( out ); + + // Special rule for streams: stop after the root element. + // The stream in code will only read one element, so don't + // write more than one. + if ( node->ToElement() ) + break; + } +} + + +TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + + +TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXML_STRING n, v; + + PutString( name, &n ); + PutString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + else + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); +} + + +void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const +{ + if (value.find( '\"' ) != TIXML_STRING::npos) + { + PutString( name, stream ); + (*stream) << "=" << "'"; + PutString( value, stream ); + (*stream) << "'"; + } + else + { + PutString( name, stream ); + (*stream) << "=" << "\""; + PutString( value, stream ); + (*stream) << "\""; + } +} + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( sscanf( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + sprintf (buf, "%d", _value); + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [64]; + sprintf (buf, "%lf", _value); + SetValue (buf); +} + +const int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +const double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + +void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << ""; +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXML_STRING buffer; + PutString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); +} + + +void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const +{ + PutString( value, stream ); +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const +{ + fprintf (cfile, ""); +} + +void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << ""; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown. +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + +TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + + +#ifdef TIXML_USE_STL +TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) +{ + base.StreamOut (& out); + return out; +} + + +#ifdef TIXML_USE_STL +std::string & operator<< (std::string& out, const TiXmlNode& base ) +{ + std::ostringstream os_stream( std::ostringstream::out ); + base.StreamOut( &os_stream ); + + out.append( os_stream.str() ); + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} diff -ruN vdr-1.7.31-ext/tinyxmlerror.c vdr-1.7.31/tinyxmlerror.c --- vdr-1.7.31-ext/tinyxmlerror.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinyxmlerror.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,51 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" + +// The goal of the seperate error file is to make the first +// step towards localization. tinyxml (currently) only supports +// latin-1, but at least the error messages could now be translated. +// +// It also cleans up the code a bit. +// + +const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = +{ + "No error", + "Error", + "Failed to open file", + "Memory allocation failed.", + "Error parsing Element.", + "Failed to read Element name", + "Error reading Element value.", + "Error reading Attributes.", + "Error: empty tag.", + "Error reading end tag.", + "Error parsing Unknown.", + "Error parsing Comment.", + "Error parsing Declaration.", + "Error document empty.", + "Error null (0) or unexpected EOF found in input stream.", +}; diff -ruN vdr-1.7.31-ext/tinyxml.h vdr-1.7.31/tinyxml.h --- vdr-1.7.31-ext/tinyxml.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinyxml.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,1370 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#if defined( DEBUG ) && defined( _MSC_VER ) +#include +#define TIXML_LOG OutputDebugString +#else +#define TIXML_LOG printf +#endif + +#ifdef TIXML_USE_STL + #include + #include + #define TIXML_STRING std::string + #define TIXML_ISTREAM std::istream + #define TIXML_OSTREAM std::ostream +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString + #define TIXML_OSTREAM TiXmlOutStream +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 3; +const int TIXML_PATCH_VERSION = 2; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream. + This is a formatted print, and will insert tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + values is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } + void* GetUserData() { return userData; } + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + +protected: + + // See STL_STRING_BUG + // Utility class to overcome a bug. + class StringToBuffer + { + public: + StringToBuffer( const TIXML_STRING& str ); + ~StringToBuffer(); + char* buffer; + }; + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + + virtual void StreamOut (TIXML_OSTREAM *) const = 0; + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); + static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + strncpy( _value, p, *length ); + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Puts a string to a stream, expanding entities as it goes. + // Note this should not contian the '<', '>', etc, or they will be transformed into entities! + static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); + + static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to Engilish words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + + TIXML_ERROR_STRING_COUNT + }; + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #else + // Used internally, not part of the public API. + friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char * Value() const { return value.c_str (); } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : "" ); + } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() const { return parent; } + + TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + + TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + + #ifdef TIXML_USE_STL + TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + TiXmlNode* IterateChildren( TiXmlNode* previous ) const; + + /// This flavor of IterateChildren searches for children with a particular 'value' + TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const; + + #ifdef TIXML_USE_STL + TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + TiXmlNode* PreviousSibling() const { return prev; } + + /// Navigate to a sibling node. + TiXmlNode* PreviousSibling( const char * ) const; + + #ifdef TIXML_USE_STL + TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + TiXmlNode* NextSibling() const { return next; } + + /// Navigate to a sibling node with the given 'value'. + TiXmlNode* NextSibling( const char * ) const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElement* NextSiblingElement() const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElement* NextSiblingElement( const char * ) const; + + #ifdef TIXML_USE_STL + TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + TiXmlElement* FirstChildElement() const; + + /// Convenience function to get through elements. + TiXmlElement* FirstChildElement( const char * value ) const; + + #ifdef TIXML_USE_STL + TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + virtual int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + TiXmlDocument* GetDocument() const; + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + // Internal Value function returning a TIXML_STRING + const TIXML_STRING& SValue() const { return value ; } + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. + const int IntValue() const; ///< Return the value of this attribute, converted to an integer. + const double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int value ); ///< Set the value from an integer. + void SetDoubleValue( double value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) + { + StringToBuffer buf( _name ); + SetName ( buf.buffer ? buf.buffer : "error" ); + } + /// STL std::string form. + void SetValue( const std::string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : "error" ); + } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + TiXmlAttribute* Next() const; + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + TiXmlAttribute* Previous() const; + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual void StreamOut( TIXML_OSTREAM * out ) const; + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Find( const char * name ) const; + +private: + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* value ) const; + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * value ); + + #ifdef TIXML_USE_STL + const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } + const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } + const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); } + int QueryIntAttribute( const std::string& name, int* value ) const { return QueryIntAttribute( name.c_str(), value ); } + int QueryDoubleAttribute( const std::string& name, double* value ) const { return QueryDoubleAttribute( name.c_str(), value ); } + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ) + { + StringToBuffer n( name ); + StringToBuffer v( _value ); + if ( n.buffer && v.buffer ) + SetAttribute (n.buffer, v.buffer ); + } + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ) + { + StringToBuffer n( name ); + if ( n.buffer ) + SetAttribute (n.buffer, _value); + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + /// Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. Contained in an element. +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /// Constructor. + TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + /// Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + +private: +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + /// Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out) const; + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + /// Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && LoadFile( f.buffer, encoding )); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && SaveFile( f.buffer )); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + TiXmlElement* RootElement() const { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + const int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() { return errorLocation.row+1; } + int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Dump the document to standard out. */ + void Print() const { Print( stdout, 0 ); } + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +protected : + virtual void StreamOut ( TIXML_OSTREAM * out) const; + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* node ) { this->node = node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /// Return the handle as a TiXmlNode. This may return null. + TiXmlNode* Node() const { return node; } + /// Return the handle as a TiXmlElement. This may return null. + TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /// Return the handle as a TiXmlText. This may return null. + TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /// Return the handle as a TiXmlUnknown. This may return null; + TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + +private: + TiXmlNode* node; +}; + + +#endif diff -ruN vdr-1.7.31-ext/tinyxmlparser.c vdr-1.7.31/tinyxmlparser.c --- vdr-1.7.31-ext/tinyxmlparser.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/tinyxmlparser.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,1492 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" +#include + +//#define DEBUG_PARSER + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + + + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*p) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case (char)(0xef): + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) ) + p += 3; + else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) ) + p += 3; + else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(p+0)==(char) 0xef + && *(p+1)==(char) 0xbb + && *(p+2)==(char) 0xbf ) + { + p += 3; + continue; + } + else if(*(p+0)==(char) 0xef + && *(p+1)==(char) 0xbf + && *(p+2)==(char) 0xbe ) + { + p += 3; + continue; + } + else if(*(p+0)==(char) 0xef + && *(p+1)==(char) 0xbf + && *(p+2)==(char) 0xbf ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + (*name) += *p; + ++p; + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + unsigned delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + return p + strlen( endTag ); +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + if ( *(p+0) && *(p+0) == (char)(0xef) + && *(p+1) && *(p+1) == (char)(0xbb) + && *(p+2) && *(p+2) == (char)(0xbf) ) + { + encoding = TIXML_ENCODING_UTF8; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + //TiXmlParsingData data( pError, prevData ); + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocument* doc = GetDocument(); + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + p = ReadText( p, &value, false, endTag, false, encoding ); + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + + int tabsize = 4; + if ( document ) + tabsize = document->TabSize(); + +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + + if ( *p == '\'' ) + { + ++p; + end = "\'"; + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == '"' ) + { + ++p; + end = "\""; + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( c == '<' ) + return; + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i ACTIVITYTIMEOUT && !cRecordControls::Active() && !cCutter::Active() && !cFileTransfer::Active() && !Interface->HasSVDRPConnection() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) { +#else if ((Now - LastInteract) > ACTIVITYTIMEOUT && !cRecordControls::Active() && !cCutter::Active() && !Interface->HasSVDRPConnection() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) { +#endif /* LIEMIKUUTIO */ // Handle housekeeping tasks // Shutdown: @@ -1315,6 +1366,9 @@ PluginManager.StopPlugins(); cRecordControls::Shutdown(); +#ifdef USE_LIEMIKUUTIO + cFileTransfer::Stop(); +#endif /* LIEMIKUUTIO */ cCutter::Stop(); delete Menu; cControl::Shutdown(); diff -ruN vdr-1.7.31-ext/vdrttxtsubshooks.c vdr-1.7.31/vdrttxtsubshooks.c --- vdr-1.7.31-ext/vdrttxtsubshooks.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/vdrttxtsubshooks.c 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,63 @@ +/* -*- c++ -*- + * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder + * Copyright (c) 2003 - 2008 Ragnar Sundblad + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include + +#include "vdrttxtsubshooks.h" + +// XXX Really should be a list... +static cVDRTtxtsubsHookListener *gListener; + +// ------ class cVDRTtxtsubsHookProxy ------ + +class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener +{ + public: + virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; + virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; + virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) + { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages, pageCount); }; + virtual int ManualPageNumber(const cChannel *channel) + { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; +}; + + +// ------ class cVDRTtxtsubsHookListener ------ + +cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() +{ + gListener = 0; +} + +void cVDRTtxtsubsHookListener::HookAttach(void) +{ + gListener = this; + //printf("cVDRTtxtsubsHookListener::HookAttach\n"); +} + +static cVDRTtxtsubsHookProxy gProxy; + +cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) +{ + return &gProxy; +} + diff -ruN vdr-1.7.31-ext/vdrttxtsubshooks.h vdr-1.7.31/vdrttxtsubshooks.h --- vdr-1.7.31-ext/vdrttxtsubshooks.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.7.31/vdrttxtsubshooks.h 2012-09-19 23:54:19.000000000 +0200 @@ -0,0 +1,46 @@ +/* -*- c++ -*- + * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder + * Copyright (c) 2003 - 2008 Ragnar Sundblad + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __VDRTTXTSUBSHOOKS_H +#define __VDRTTXTSUBSHOOKS_H + +#define TTXTSUBSVERSNUM 2 + +class cDevice; +class cChannel; +struct tTeletextSubtitlePage; + +class cVDRTtxtsubsHookListener { + public: + cVDRTtxtsubsHookListener(void) {}; + virtual ~cVDRTtxtsubsHookListener(); + + void HookAttach(void); + + virtual void HideOSD(void) {}; + virtual void ShowOSD(void) {}; + virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) {}; + virtual int ManualPageNumber(const cChannel *channel) { return 0; }; + + // used by VDR to call hook listeners + static cVDRTtxtsubsHookListener *Hook(void); +}; + +#endif diff -ruN vdr-1.7.31-ext/videodir.c vdr-1.7.31/videodir.c --- vdr-1.7.31-ext/videodir.c 2012-09-30 14:06:33.000000000 +0200 +++ vdr-1.7.31/videodir.c 2012-10-02 05:11:57.000000000 +0200 @@ -41,6 +41,11 @@ bool Next(void); void Store(void); const char *Adjust(const char *FileName); +#ifdef USE_DVLVIDPREFER + char *GetVidPath(int nVid); + bool GetPreferedVideoDir(void); + bool IsVidDirOK(int nVid, int *freeMB = NULL); +#endif /* DVLVIDPREFER */ }; cVideoDirectory::cVideoDirectory(void) @@ -122,6 +127,9 @@ if ((Flags & O_CREAT) != 0) { cVideoDirectory Dir; if (Dir.IsDistributed()) { +#ifdef USE_DVLVIDPREFER + if (Setup.UseVidPrefer == 0) { +#endif /* DVLVIDPREFER */ // Find the directory with the most free space: int MaxFree = Dir.FreeMB(); while (Dir.Next()) { @@ -131,14 +139,24 @@ MaxFree = Free; } } +#ifdef USE_DVLVIDPREFER + } + else Dir.GetPreferedVideoDir(); +#endif /* DVLVIDPREFER */ if (Dir.Stored()) { ActualFileName = Dir.Adjust(FileName); if (!MakeDirs(ActualFileName, false)) return NULL; // errno has been set by MakeDirs() +#ifdef USE_DVLVIDPREFER + if (strcmp(ActualFileName, FileName) != 0) { +#endif /* DVLVIDPREFER */ if (symlink(ActualFileName, FileName) < 0) { LOG_ERROR_STR(FileName); return NULL; } +#ifdef USE_DVLVIDPREFER + } +#endif /* DVLVIDPREFER */ ActualFileName = strdup(ActualFileName); // must survive Dir! } } @@ -173,6 +191,122 @@ return RemoveFileOrDir(FileName, true); } +#ifdef USE_HARDLINKCUTTER +static bool StatNearestDir(const char *FileName, struct stat *Stat) +{ + cString Name(FileName); + char *p; + while ((p = strrchr((char*)(const char*)Name + 1, '/')) != NULL) { + *p = 0; // truncate at last '/' + if (stat(Name, Stat) == 0) { + isyslog("StatNearestDir: Stating %s", (const char*)Name); + return true; + } + } + return false; +} + +bool HardLinkVideoFile(const char *OldName, const char *NewName) +{ + // Incoming name must be in base video directory: + if (strstr(OldName, VideoDirectory) != OldName) { + esyslog("ERROR: %s not in %s", OldName, VideoDirectory); + return false; + } + if (strstr(NewName, VideoDirectory) != NewName) { + esyslog("ERROR: %s not in %s", NewName, VideoDirectory); + return false; + } + + const char *ActualNewName = NewName; + cString ActualOldName(ReadLink(OldName), true); + + // Some safety checks: + struct stat StatOldName; + if (lstat(ActualOldName, &StatOldName) == 0) { + if (S_ISLNK(StatOldName.st_mode)) { + esyslog("HardLinkVideoFile: Failed to resolve symbolic link %s", (const char*)ActualOldName); + return false; + } + } + else { + esyslog("HardLinkVideoFile: lstat failed on %s", (const char*)ActualOldName); + return false; + } + isyslog("HardLinkVideoFile: %s is on %i", (const char*)ActualOldName, (int)StatOldName.st_dev); + + // Find the video directory where ActualOldName is located + + cVideoDirectory Dir; + struct stat StatDir; + if (!StatNearestDir(NewName, &StatDir)) { + esyslog("HardLinkVideoFile: stat failed on %s", NewName); + return false; + } + + isyslog("HardLinkVideoFile: %s is on %i", NewName, (int)StatDir.st_dev); + if (StatDir.st_dev != StatOldName.st_dev) { + // Not yet found. + + if (!Dir.IsDistributed()) { + esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); + return false; + } + + // Search in video01 and upwards + bool found = false; + while (Dir.Next()) { + Dir.Store(); + const char *TmpNewName = Dir.Adjust(NewName); + if (StatNearestDir(TmpNewName, &StatDir) && StatDir.st_dev == StatOldName.st_dev) { + isyslog("HardLinkVideoFile: %s is on %i (match)", TmpNewName, (int)StatDir.st_dev); + ActualNewName = TmpNewName; + found = true; + break; + } + isyslog("HardLinkVideoFile: %s is on %i", TmpNewName, (int)StatDir.st_dev); + } + if (ActualNewName == NewName) { + esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); + return false; + } + + // Looking good, we have a match. Create necessary folders. + if (!MakeDirs(ActualNewName, false)) + return false; + // There's no guarantee that the directory of ActualNewName + // is on the same device as the dir that StatNearestDir found. + // But worst case is that the link fails. + } + +#ifdef HARDLINK_TEST_ONLY + // Do the hard link to *.vdr_ for testing only + char *name = NULL; + asprintf(&name, "%s_",ActualNewName); + link(ActualOldName, name); + free(name); + return false; +#endif // HARDLINK_TEST_ONLY + + // Try creating the hard link + if (link(ActualOldName, ActualNewName) != 0) { + // Failed to hard link. Maybe not allowed on file system. + LOG_ERROR_STR(ActualNewName); + isyslog("HardLinkVideoFile: failed to hard link from %s to %s", (const char*)ActualOldName, ActualNewName); + return false; + } + + if (ActualNewName != NewName) { + // video01 and up. Do the remaining symlink + if (symlink(ActualNewName, NewName) < 0) { + LOG_ERROR_STR(NewName); + return false; + } + } + return true; +} +#endif /* HARDLINKCUTTER */ + bool VideoFileSpaceAvailable(int SizeMB) { cVideoDirectory Dir; @@ -229,6 +363,24 @@ return NULL; } +#ifdef USE_LIEMIKUUTIO +cString NewVideoFileName(const char *FileName, const char *NewDirName) +{ + char *NewDir = ExchangeChars(strdup(NewDirName), true); + if (NewDir) { + const char *p = FileName + strlen(FileName); // p points at the terminating 0 + while (p-- > FileName) { + if (*p == '/') + break; + } + cString NewName = cString::sprintf("%s/%s%s", VideoDirectory, NewDir, p); + free(NewDir); + return NewName; + } + return NULL; +} +#endif /* LIEMIKUUTIO */ + void RemoveEmptyVideoDirectories(const char *IgnoreFiles[]) { cVideoDirectory Dir; @@ -237,6 +389,129 @@ } while (Dir.Next()); } +#ifdef USE_DVLVIDPREFER +// returns path to nVid'th video directory or NULL if not existing +char *cVideoDirectory::GetVidPath(int nVid) +{ + char *b = strdup(VideoDirectory); + int l = strlen(b), di, n; + + while (l-- > 0 && isdigit(b[ l ])); + + l++; + di = strlen(b) - l; + + // di == number of digits + n = atoi(&b[ l ]); + if (n != 0) + return NULL; + + // add requested number to dir name + sprintf(&b[ l ], "%0*d", di, nVid); + + if (DirectoryOk(b) == true) + return b; + + free(b); + return NULL; +} + +// checks if a video dir is 'valid' +bool cVideoDirectory::IsVidDirOK(int nVid, int *freeMB) +{ + char *dn; + int fMB; + + if (nVid >= Setup.nVidPrefer) + return false; + + if (Setup.VidPreferSize[ nVid ] == -1) + return false; + + dn = GetVidPath(nVid); + if (dn == NULL) + return false; + + fMB = FreeDiskSpaceMB(dn, NULL); + if (freeMB != NULL) + *freeMB = fMB; + + free(dn); + + if (Setup.VidPreferSize[ nVid ] >= fMB) + return false; + return true; +} + + +// calculates which video dir to use +bool cVideoDirectory::GetPreferedVideoDir(void) +{ + cVideoDirectory d; + int nDirs = 1, + vidUse = Setup.nVidPrefer; + int i, top, topFree, x; + + if (name == NULL) + return(false); + + // count available video dirs + while (d.Next() == true) + nDirs++; + + if (vidUse > nDirs) + vidUse = nDirs; + + // check for prefered video dir + for (i = 0, top = -1, topFree = 0; i < vidUse; i++) { + if (IsVidDirOK(i, &x) == true) { + if (top == -1) { + // nothing set yet, use first 'ok' dir + top = i; + topFree = x; + } + else { + // check if we got a higher priority + if (Setup.VidPreferPrio[ i ] >= Setup.VidPreferPrio[ top ]) { + top = i; + topFree = x; + } + // check if we got same priority but more space + else if (Setup.VidPreferPrio[ i ] == Setup.VidPreferPrio[ top ] && x >= topFree) { + top = i; + topFree = x; + } + } + } + } + + if (top == -1) { + isyslog("VidPrefer: no prefered video directory could be determined!"); + + // something went wrong here... + // let VDR determine the video directory + int MaxFree = FreeMB(); + + while (Next()) { + int Free = FreeDiskSpaceMB(Name()); + + if (Free > MaxFree) { + Store(); + MaxFree = Free; + } + } + } + else { + isyslog("VidPrefer: prefered video directory '%d' set.", top); + if (stored != NULL) + free(stored); + stored = GetVidPath(top); + } + + return true; +} +#endif /* DVLVIDPREFER */ + bool IsOnVideoDirectoryFileSystem(const char *FileName) { cVideoDirectory Dir; diff -ruN vdr-1.7.31-ext/videodir.h vdr-1.7.31/videodir.h --- vdr-1.7.31-ext/videodir.h 2012-09-30 13:01:15.000000000 +0200 +++ vdr-1.7.31/videodir.h 2012-10-02 04:27:57.000000000 +0200 @@ -20,9 +20,15 @@ int CloseVideoFile(cUnbufferedFile *File); bool RenameVideoFile(const char *OldName, const char *NewName); bool RemoveVideoFile(const char *FileName); +#ifdef USE_HARDLINKCUTTER +bool HardLinkVideoFile(const char *OldName, const char *NewName); +#endif /* HARDLINKCUTTER */ bool VideoFileSpaceAvailable(int SizeMB); int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent cString PrefixVideoFileName(const char *FileName, char Prefix); +#ifdef USE_LIEMIKUUTIO +cString NewVideoFileName(const char *FileName, const char *NewDirName); +#endif /* LIEMIKUUTIO */ void RemoveEmptyVideoDirectories(const char *IgnoreFiles[] = NULL); bool IsOnVideoDirectoryFileSystem(const char *FileName);