summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS14
-rw-r--r--HISTORY33
-rw-r--r--INSTALL11
-rw-r--r--MANUAL22
-rw-r--r--Makefile4
-rw-r--r--PLUGINS/src/dvbsddevice/HISTORY5
-rw-r--r--PLUGINS/src/dvbsddevice/dvbsddevice.c4
-rw-r--r--PLUGINS/src/dvbsddevice/dvbsdffdevice.c4
-rw-r--r--Syd0
-rw-r--r--config.c236
-rw-r--r--config.h61
-rw-r--r--device.c15
-rw-r--r--dvbspu.c4
-rw-r--r--eit.c6
-rw-r--r--epg.c28
-rw-r--r--epg.h35
-rw-r--r--menu.c402
-rw-r--r--menu.h27
-rw-r--r--osd.c22
-rw-r--r--osd.h4
-rw-r--r--osdbase.c4
-rw-r--r--osdbase.h4
-rw-r--r--po/ca_ES.po36
-rw-r--r--po/cs_CZ.po36
-rw-r--r--po/da_DK.po36
-rw-r--r--po/de_DE.po38
-rw-r--r--po/el_GR.po36
-rw-r--r--po/es_ES.po36
-rw-r--r--po/et_EE.po200
-rw-r--r--po/fi_FI.po36
-rw-r--r--po/fr_FR.po36
-rw-r--r--po/hr_HR.po36
-rw-r--r--po/hu_HU.po36
-rw-r--r--po/it_IT.po198
-rw-r--r--po/lt_LT.po36
-rw-r--r--po/nl_NL.po36
-rw-r--r--po/nn_NO.po36
-rw-r--r--po/pl_PL.po36
-rw-r--r--po/pt_PT.po36
-rw-r--r--po/ro_RO.po36
-rw-r--r--po/ru_RU.po36
-rw-r--r--po/sk_SK.po36
-rw-r--r--po/sl_SI.po36
-rw-r--r--po/sv_SE.po36
-rw-r--r--po/tr_TR.po36
-rw-r--r--po/uk_UA.po36
-rw-r--r--po/zh_CN.po36
-rw-r--r--receiver.c75
-rw-r--r--receiver.h37
-rw-r--r--recorder.c20
-rw-r--r--recorder.h8
-rw-r--r--recording.c26
-rw-r--r--recording.h4
-rw-r--r--remux.c21
-rw-r--r--remux.h14
-rwxr-xr-xrunvdr.template (renamed from runvdr)14
-rw-r--r--svdrp.c4
-rw-r--r--timers.c4
-rw-r--r--transfer.c12
-rw-r--r--transfer.h6
-rw-r--r--vdr.560
-rw-r--r--vdr.c7
62 files changed, 2030 insertions, 455 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 1c1da69..90dce69 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1090,6 +1090,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi>
in some syslog calls
for a patch that was used to implement handling the "component descriptor" ("genre")
for a patch that was used to implement handling the "parental rating descriptor"
+ suggesting to add plain text error messages to log entries from cOsd::SetAreas()
Ralf Klueber <ralf.klueber@vodafone.com>
for reporting a bug in cutting a recording if there is only a single editing mark
@@ -1562,6 +1563,8 @@ Martin Dauskardt <md001@gmx.de>
recorded
for suggesting to add a table of the used trick speed values to the description of
cDevice::TrickSpeed()
+ for renaming 'runvdr' to 'runvdr.template' and no longer copying it to the BINDIR
+ in 'make install'
Maynard Cedric <maynard.cedric@wanadoo.fr>
for reporting a problem in handling the color button texts in cMenuEditStrItem
@@ -2494,6 +2497,7 @@ Johann Friedrichs <johann.friedrichs@web.de>
for removing the workaround for short channel names of "Kabel Deutschland"
for some fixes to dvbspu.[hc]
for fixing a busy loop when moving editing marks
+ for making cPalette::ClosestColor() treat fully transparent colors as "equal"
Timo Helkio <timolavi@mbnet.fi>
for reporting a hangup when replaying a TS recording with subtitles activated
@@ -2526,6 +2530,8 @@ Valdemaras Pipiras <valdemaras@ambernet.lt>
Manuel Reimer <Manuel.Reimer@gmx.de>
for fixing saving terminal settings when running in background
+ for making the SVDRP port open only for the local host if svdrphosts.conf
+ contains only the address of the local host
Rene van den Braken <rene@vandenbraken.name>
for reporting a bug in writing the PCR pid into the PMT in
@@ -2539,7 +2545,11 @@ Andreas Schaefers <andreas_schaefers@gmx.de>
Matthieu Castet <castet.matthieu@free.fr>
for improving SPU handling on devices with limited OSD capabilities
+ for making cPalette::ClosestColor() treat fully transparent colors as "equal"
Francesco Saverio Schiavarelli <fschiava@libero.it>
- for reporting a problem with channels that have some encrypted components that
- VDR doesn't use
+ for reporting a problem with channels that have some encrypted components that
+ VDR doesn't use
+
+Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ for implementing the setup option "Miscellaneous/Channels wrap"
diff --git a/HISTORY b/HISTORY
index 84430d5..df1bf60 100644
--- a/HISTORY
+++ b/HISTORY
@@ -6275,3 +6275,36 @@ Video Disk Recorder Revision History
the others on the same adapter.
- Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to
Anssi Hannula).
+
+2010-01-31: Version 1.7.12
+
+- Changed the EVCONTENTMASK_* macros to enums and changed "mask" to "group".
+- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
+- The "Edit timer" menu can now set the folder for the recording from a list of
+ folders stored in "folders.conf".
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- If svdrphosts.conf contains only the address of the local host, the SVDRP port
+ is opened only for the local host (thanks to Manuel Reimer).
+- Renamed 'runvdr' to 'runvdr.template' and no longer copying it to the BINDIR
+ in 'make install' (thanks to Martin Dauskardt).
+- Added plain text error messages to log entries from cOsd::SetAreas() (suggested
+ by Rolf Ahrenberg).
+- cPalette::ClosestColor() now treats fully transparent colors as "equal"; improved
+ cDvbSpuBitmap::getMinBpp() (thanks to Matthieu Castet and Johann Friedrichs).
+- The new setup option "Miscellaneous/Channels wrap" controls whether the current
+ channel wraps around the beginning or end of the channel list when zapping (thanks
+ to Matti Lehtimäki).
+- Fixed determining the frame duration on channels where the PTS deltas jitter by
+ +/-1 around 1800.
+- The PCR pid in generated PMTs is now set to the channel's PCR pid again.
+- Fixed determining the frame duration on channels where the PTS deltas jitter by
+ +/-1 around 3600.
+- The PCR pid is now recorded for channels where this is different from the video
+ PID. To facilitate this, the interfaces of cTransfer, cTransferControl, cRecorder
+ and cReceiver have been modified, so that the PIDs are no longer given in separate
+ parameters, but rather the whole channel is handed down for processing. The old
+ constructor of cReceiver is still available, but it is recommended to plugin authors
+ that they switch to the new interface as soon as possible.
+ When replaying such a recording, the PCR packets are sent to PlayTsVideo()
+- The files "commands.conf" and "reccmd.conf" can now contain nested lists of
+ commands. See vdr.5 for information about the new file format.
diff --git a/INSTALL b/INSTALL
index 3af62d7..e0fc016 100644
--- a/INSTALL
+++ b/INSTALL
@@ -121,8 +121,12 @@ Users who want to set the default character set to something different can
do this by setting the environment variable VDR_CHARSET_OVERRIDE to something
like ISO-8859-9.
-Automatic restart in case of hangups:
--------------------------------------
+Start script with automatic restart in case of hangups:
+-------------------------------------------------------
+
+The VDR source directory contains a 'runvdr.template'. Just copy it as 'runvdr'
+into your /usr/bin or /usr/local/bin directory and adjust it to your particular
+requirements. (See the comments inside the script for more information.)
If you run VDR using the 'runvdr' shell script it will use the built-in
watchdog timer to restart the program in case something happens that
@@ -131,9 +135,6 @@ call to the VDR program, be sure to NOT use the '-d' option! Otherwise
VDR will go into 'daemon' mode and the initial program call will return
immediately! 'runvdr' needs to be started as user 'root'. Use the '-u'
option to run the actual 'vdr' program under a different user id.
-Note that the 'runvdr' script needs to be adjusted to your particular
-requirements before you can actually use it. See the comments inside
-the script for more information.
Setting the system time:
------------------------
diff --git a/MANUAL b/MANUAL
index 7382a8d..405f6a8 100644
--- a/MANUAL
+++ b/MANUAL
@@ -474,6 +474,23 @@ Version 1.6
A timer can also be programmed by pressing the "Red" key on the "Schedule",
"Now", "Next" or "Event" menus.
+ The "Red" key in the "Edit timer" menu opens a list of folders, which can be
+ used to define the file name in which the recording will be stored.
+
+* Managing folders
+
+ The "Select folder" menu, which can be accessed by pressing the "Red" key in
+ the "Edit timer" menu, offers a list of folders that can be used for storing
+ a recording. In this menu, the "Green" key allows you to define a new folder
+ within the current one; if the "Sub folder" option is set to "yes", this will
+ be a folder that contains other folders (indicated by "..." following the
+ folder name in the list). The "Yellow" key deletes the current folder (note
+ that this will merely delete the folder definition stored in 'folders.conf'
+ and has no effect on existing timers or recordings). The "Blue" key can be
+ used to edit an existing folder definition. The "Red" key selects the current
+ folder, or enters a sub folder. Once a folder has been selected, the entire
+ path of the timer's file name will be replaced with the selected folder.
+
* Parameters in the "Setup" menu
Select "Setup" from the "VDR" menu to enter the setup menu. From there you can
@@ -860,6 +877,11 @@ Version 1.6
VDR was stopped will be used. The valid range is from
0 (silent) to 255 (loudest).
+ Channels wrap = no During zapping with the "Up" and "Down" keys (or the
+ "Channel+" and "Channel-" keys) the current channel will
+ wrap around the beginning or end of the channel list if
+ this parameter is set to 'yes'.
+
Emergency exit = yes If, for some reason, a recording fails because the video
data stream is broken, or the CAM doesn't decrypt etc.,
VDR automatically exits in order to allow the surrounding
diff --git a/Makefile b/Makefile
index e13ea5e..01408cb 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 2.5 2009/12/29 11:20:50 kls Exp $
+# $Id: Makefile 2.6 2010/01/17 12:32:18 kls Exp $
.DELETE_ON_ERROR:
@@ -164,7 +164,7 @@ install: install-bin install-conf install-doc install-plugins install-i18n
install-bin: vdr
@mkdir -p $(DESTDIR)$(BINDIR)
- @cp --remove-destination vdr runvdr svdrpsend.pl $(DESTDIR)$(BINDIR)
+ @cp --remove-destination vdr svdrpsend.pl $(DESTDIR)$(BINDIR)
# Configuration files:
diff --git a/PLUGINS/src/dvbsddevice/HISTORY b/PLUGINS/src/dvbsddevice/HISTORY
index 18cd625..0d1047b 100644
--- a/PLUGINS/src/dvbsddevice/HISTORY
+++ b/PLUGINS/src/dvbsddevice/HISTORY
@@ -10,3 +10,8 @@ VDR Plugin 'dvbsddevice' Revision History
- Calling the MakePrimaryDevice() function of the base class to allow
the cDevice to stop displaying subtitles.
- Added support for DVB cards with multiple fontends.
+
+2010-01-30: Version 0.0.3
+
+- The PCR pid is now recorded for channels where this is different from the
+ video PID.
diff --git a/PLUGINS/src/dvbsddevice/dvbsddevice.c b/PLUGINS/src/dvbsddevice/dvbsddevice.c
index e2248e9..cc48b28 100644
--- a/PLUGINS/src/dvbsddevice/dvbsddevice.c
+++ b/PLUGINS/src/dvbsddevice/dvbsddevice.c
@@ -3,13 +3,13 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: dvbsddevice.c 1.2 2010/01/01 15:01:01 kls Exp $
+ * $Id: dvbsddevice.c 1.3 2010/01/30 10:05:42 kls Exp $
*/
#include <vdr/plugin.h>
#include "dvbsdffdevice.h"
-static const char *VERSION = "0.0.2";
+static const char *VERSION = "0.0.3";
static const char *DESCRIPTION = "SD Full Featured DVB device";
class cPluginDvbsddevice : public cPlugin {
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffdevice.c b/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
index 21a60a5..483381f 100644
--- a/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
+++ b/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
@@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: dvbsdffdevice.c 2.25 2010/01/04 12:56:56 kls Exp $
+ * $Id: dvbsdffdevice.c 2.26 2010/01/30 10:05:23 kls Exp $
*/
#include "dvbsdffdevice.h"
@@ -434,7 +434,7 @@ bool cDvbSdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
}
else if (StartTransferMode)
- cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), vpid, Channel->Apids(), Channel->Dpids(), Channel->Spids()));
+ cControl::Launch(new cTransferControl(this, Channel));
return true;
}
diff --git a/Syd b/Syd
deleted file mode 100644
index e69de29..0000000
--- a/Syd
+++ /dev/null
diff --git a/config.c b/config.c
index 61de0f5..acdf4c4 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.c 2.6 2009/12/05 15:30:30 kls Exp $
+ * $Id: config.c 2.10 2010/01/31 12:36:36 kls Exp $
*/
#include "config.h"
@@ -22,71 +22,6 @@
#define ChkDoublePlausibility(Variable, Default) { if (Variable < 0.00001) Variable = Default; }
-// --- cCommand --------------------------------------------------------------
-
-char *cCommand::result = NULL;
-
-cCommand::cCommand(void)
-{
- title = command = NULL;
- confirm = false;
-}
-
-cCommand::~cCommand()
-{
- free(title);
- free(command);
-}
-
-bool cCommand::Parse(const char *s)
-{
- const char *p = strchr(s, ':');
- if (p) {
- int l = p - s;
- if (l > 0) {
- title = MALLOC(char, l + 1);
- stripspace(strn0cpy(title, s, l + 1));
- if (!isempty(title)) {
- int l = strlen(title);
- if (l > 1 && title[l - 1] == '?') {
- confirm = true;
- title[l - 1] = 0;
- }
- command = stripspace(strdup(skipspace(p + 1)));
- return !isempty(command);
- }
- }
- }
- return false;
-}
-
-const char *cCommand::Execute(const char *Parameters)
-{
- free(result);
- result = NULL;
- cString cmdbuf;
- if (Parameters)
- cmdbuf = cString::sprintf("%s %s", command, Parameters);
- const char *cmd = *cmdbuf ? *cmdbuf : command;
- dsyslog("executing command '%s'", cmd);
- cPipe p;
- if (p.Open(cmd, "r")) {
- int l = 0;
- int c;
- while ((c = fgetc(p)) != EOF) {
- if (l % 20 == 0)
- result = (char *)realloc(result, l + 21);
- result[l++] = char(c);
- }
- if (result)
- result[l] = 0;
- p.Close();
- }
- else
- esyslog("ERROR: can't open pipe for command '%s'", cmd);
- return result;
-}
-
// --- cSVDRPhost ------------------------------------------------------------
cSVDRPhost::cSVDRPhost(void)
@@ -118,20 +53,180 @@ bool cSVDRPhost::Parse(const char *s)
return result != 0 && (mask != 0 || addr.s_addr == 0);
}
+bool cSVDRPhost::IsLocalhost(void)
+{
+ return addr.s_addr == htonl(INADDR_LOOPBACK);
+}
+
bool cSVDRPhost::Accepts(in_addr_t Address)
{
return (Address & mask) == (addr.s_addr & mask);
}
-// --- cCommands -------------------------------------------------------------
+// --- cNestedItem -----------------------------------------------------------
+
+cNestedItem::cNestedItem(const char *Text, bool WithSubItems)
+{
+ text = strdup(Text ? Text : "");
+ subItems = WithSubItems ? new cList<cNestedItem> : NULL;
+}
+
+cNestedItem::~cNestedItem()
+{
+ delete subItems;
+ free(text);
+}
-cCommands Commands;
-cCommands RecordingCommands;
+int cNestedItem::Compare(const cListObject &ListObject) const
+{
+ return strcasecmp(text, ((cNestedItem *)&ListObject)->text);
+}
+
+void cNestedItem::AddSubItem(cNestedItem *Item)
+{
+ if (!subItems)
+ subItems = new cList<cNestedItem>;
+ if (Item)
+ subItems->Add(Item);
+}
+
+void cNestedItem::SetText(const char *Text)
+{
+ free(text);
+ text = strdup(Text ? Text : "");
+}
+
+void cNestedItem::SetSubItems(bool On)
+{
+ if (On && !subItems)
+ subItems = new cList<cNestedItem>;
+ else if (!On && subItems) {
+ delete subItems;
+ subItems = NULL;
+ }
+}
+
+// --- cNestedItemList -------------------------------------------------------
+
+cNestedItemList::cNestedItemList(void)
+{
+ fileName = NULL;
+}
+
+cNestedItemList::~cNestedItemList()
+{
+ free(fileName);
+}
+
+bool cNestedItemList::Parse(FILE *f, cList<cNestedItem> *List, int &Line)
+{
+ char *s;
+ cReadLine ReadLine;
+ while ((s = ReadLine.Read(f)) != NULL) {
+ Line++;
+ char *p = strchr(s, '#');
+ if (p)
+ *p = 0;
+ s = skipspace(stripspace(s));
+ if (!isempty(s)) {
+ p = s + strlen(s) - 1;
+ if (*p == '{') {
+ *p = 0;
+ stripspace(s);
+ cNestedItem *Item = new cNestedItem(s, true);
+ List->Add(Item);
+ if (!Parse(f, Item->SubItems(), Line))
+ return false;
+ }
+ else if (*s == '}')
+ break;
+ else
+ List->Add(new cNestedItem(s));
+ }
+ }
+ return true;
+}
+
+bool cNestedItemList::Write(FILE *f, cList<cNestedItem> *List, int Indent)
+{
+ for (cNestedItem *Item = List->First(); Item; Item = List->Next(Item)) {
+ if (Item->SubItems()) {
+ fprintf(f, "%*s%s {\n", Indent, "", Item->Text());
+ Write(f, Item->SubItems(), Indent + 2);
+ fprintf(f, "%*s}\n", Indent + 2, "");
+ }
+ else
+ fprintf(f, "%*s%s\n", Indent, "", Item->Text());
+ }
+ return true;
+}
+
+void cNestedItemList::Clear(void)
+{
+ free(fileName);
+ fileName = NULL;
+ cList<cNestedItem>::Clear();
+}
+
+bool cNestedItemList::Load(const char *FileName)
+{
+ cList<cNestedItem>::Clear();
+ if (FileName) {
+ free(fileName);
+ fileName = strdup(FileName);
+ }
+ bool result = false;
+ if (fileName && access(fileName, F_OK) == 0) {
+ isyslog("loading %s", fileName);
+ FILE *f = fopen(fileName, "r");
+ if (f) {
+ int Line = 0;
+ result = Parse(f, this, Line);
+ fclose(f);
+ }
+ else {
+ LOG_ERROR_STR(fileName);
+ result = false;
+ }
+ }
+ return result;
+}
+
+bool cNestedItemList::Save(void)
+{
+ bool result = true;
+ cSafeFile f(fileName);
+ if (f.Open()) {
+ result = Write(f, this);
+ if (!f.Close())
+ result = false;
+ }
+ else
+ result = false;
+ return result;
+}
+
+// --- Folders and Commands --------------------------------------------------
+
+cNestedItemList Folders;
+cNestedItemList Commands;
+cNestedItemList RecordingCommands;
// --- cSVDRPhosts -----------------------------------------------------------
cSVDRPhosts SVDRPhosts;
+bool cSVDRPhosts::LocalhostOnly(void)
+{
+ cSVDRPhost *h = First();
+ while (h) {
+ if (!h->IsLocalhost())
+ return false;
+ h = (cSVDRPhost *)h->Next();
+ }
+ return true;
+}
+
bool cSVDRPhosts::Acceptable(in_addr_t Address)
{
cSVDRPhost *h = First();
@@ -299,6 +394,7 @@ cSetup::cSetup(void)
CurrentDolby = 0;
InitialChannel = 0;
InitialVolume = -1;
+ ChannelsWrap = 0;
EmergencyExit = 1;
}
@@ -486,6 +582,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value);
else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = atoi(Value);
else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value);
+ else if (!strcasecmp(Name, "ChannelsWrap")) ChannelsWrap = atoi(Value);
else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value);
else
return false;
@@ -578,6 +675,7 @@ bool cSetup::Save(void)
Store("CurrentDolby", CurrentDolby);
Store("InitialChannel", InitialChannel);
Store("InitialVolume", InitialVolume);
+ Store("ChannelsWrap", ChannelsWrap);
Store("EmergencyExit", EmergencyExit);
Sort();
diff --git a/config.h b/config.h
index f0cc67b..be1d7bd 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 2.16 2009/11/22 19:55:04 kls Exp $
+ * $Id: config.h 2.21 2010/01/31 11:14:02 kls Exp $
*/
#ifndef __CONFIG_H
@@ -22,13 +22,13 @@
// VDR's own version number:
-#define VDRVERSION "1.7.11"
-#define VDRVERSNUM 10711 // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION "1.7.12"
+#define VDRVERSNUM 10712 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number:
-#define APIVERSION "1.7.11"
-#define APIVERSNUM 10711 // Version * 10000 + Major * 100 + Minor
+#define APIVERSION "1.7.12"
+#define APIVERSNUM 10712 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to
@@ -48,21 +48,6 @@
#define MaxSkinName 16
#define MaxThemeName 16
-class cCommand : public cListObject {
-private:
- char *title;
- char *command;
- bool confirm;
- static char *result;
-public:
- cCommand(void);
- virtual ~cCommand();
- bool Parse(const char *s);
- const char *Title(void) { return title; }
- bool Confirm(void) { return confirm; }
- const char *Execute(const char *Parameters = NULL);
- };
-
typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2)
class cSVDRPhost : public cListObject {
@@ -72,6 +57,7 @@ private:
public:
cSVDRPhost(void);
bool Parse(const char *s);
+ bool IsLocalhost(void);
bool Accepts(in_addr_t Address);
};
@@ -158,15 +144,43 @@ public:
}
};
-class cCommands : public cConfig<cCommand> {};
+class cNestedItem : public cListObject {
+private:
+ char *text;
+ cList<cNestedItem> *subItems;
+public:
+ cNestedItem(const char *Text, bool WithSubItems = false);
+ virtual ~cNestedItem();
+ virtual int Compare(const cListObject &ListObject) const;
+ const char *Text(void) const { return text; }
+ cList<cNestedItem> *SubItems(void) { return subItems; }
+ void AddSubItem(cNestedItem *Item);
+ void SetText(const char *Text);
+ void SetSubItems(bool On);
+ };
+
+class cNestedItemList : public cList<cNestedItem> {
+private:
+ char *fileName;
+ bool Parse(FILE *f, cList<cNestedItem> *List, int &Line);
+ bool Write(FILE *f, cList<cNestedItem> *List, int Indent = 0);
+public:
+ cNestedItemList(void);
+ virtual ~cNestedItemList();
+ void Clear(void);
+ bool Load(const char *FileName);
+ bool Save(void);
+ };
class cSVDRPhosts : public cConfig<cSVDRPhost> {
public:
+ bool LocalhostOnly(void);
bool Acceptable(in_addr_t Address);
};
-extern cCommands Commands;
-extern cCommands RecordingCommands;
+extern cNestedItemList Folders;
+extern cNestedItemList Commands;
+extern cNestedItemList RecordingCommands;
extern cSVDRPhosts SVDRPhosts;
class cSetupLine : public cListObject {
@@ -272,6 +286,7 @@ public:
int CurrentDolby;
int InitialChannel;
int InitialVolume;
+ int ChannelsWrap;
int EmergencyExit;
int __EndData__;
cSetup(void);
diff --git a/device.c b/device.c
index 3228af2..cb31b83 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 2.31 2010/01/01 15:40:35 kls Exp $
+ * $Id: device.c 2.32 2010/01/30 11:06:51 kls Exp $
*/
#include "device.h"
@@ -30,8 +30,8 @@ public:
};
cLiveSubtitle::cLiveSubtitle(int SPid)
-:cReceiver(tChannelID(), -1, SPid)
{
+ AddPid(SPid);
}
cLiveSubtitle::~cLiveSubtitle()
@@ -676,7 +676,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (Device && CanReplay()) {
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
- cControl::Launch(new cTransferControl(Device, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids()));
+ cControl::Launch(new cTransferControl(Device, Channel));
else
Result = scrNoTransfer;
}
@@ -1364,10 +1364,10 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
return Played + Skipped;
}
+ int Pid = TsPid(Data);
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
int PayloadOffset = TsPayloadOffset(Data);
if (PayloadOffset < TS_SIZE) {
- int Pid = TsPid(Data);
if (Pid == 0)
patPmtParser.ParsePat(Data, TS_SIZE);
else if (Pid == patPmtParser.PmtPid())
@@ -1396,6 +1396,13 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
}
}
}
+ else if (Pid == patPmtParser.Ppid()) {
+ int w = PlayTsVideo(Data, TS_SIZE);
+ if (w < 0)
+ return Played ? Played : w;
+ if (w == 0)
+ break;
+ }
Played += TS_SIZE;
Length -= TS_SIZE;
Data += TS_SIZE;
diff --git a/dvbspu.c b/dvbspu.c
index 488bd89..951e2f8 100644
--- a/dvbspu.c
+++ b/dvbspu.c
@@ -8,7 +8,7 @@
*
* parts of this file are derived from the OMS program.
*
- * $Id: dvbspu.c 2.7 2009/12/26 15:51:15 kls Exp $
+ * $Id: dvbspu.c 2.8 2010/01/17 13:43:27 kls Exp $
*/
#include "dvbspu.h"
@@ -347,7 +347,7 @@ int cDvbSpuBitmap::getMinBpp(const aDvbSpuPalDescr paldescr)
col++;
}
}
- return col > 2 ? 4 : 2;
+ return col > 2 ? 2 : 1;
}
int cDvbSpuDecoder::CalcAreaBpp(cBitmap *fgbmp, cBitmap *bgbmp)
diff --git a/eit.c b/eit.c
index 72d05cb..37a4a4b 100644
--- a/eit.c
+++ b/eit.c
@@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
- * $Id: eit.c 2.10 2010/01/03 15:35:21 kls Exp $
+ * $Id: eit.c 2.11 2010/01/08 15:17:09 kls Exp $
*/
#include "eit.h"
@@ -157,9 +157,9 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
SI::ContentDescriptor *cd = (SI::ContentDescriptor *)d;
SI::ContentDescriptor::Nibble Nibble;
int NumContents = 0;
- uchar Contents[MAXEVCONTENTS] = { 0 };
+ uchar Contents[MaxEventContents] = { 0 };
for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3); ) {
- if (NumContents < MAXEVCONTENTS) {
+ if (NumContents < MaxEventContents) {
Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF);
NumContents++;
}
diff --git a/epg.c b/epg.c
index e1cfe18..006a5de 100644
--- a/epg.c
+++ b/epg.c
@@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
*
- * $Id: epg.c 2.4 2010/01/03 14:10:20 kls Exp $
+ * $Id: epg.c 2.5 2010/01/08 15:20:28 kls Exp $
*/
#include "epg.h"
@@ -190,7 +190,7 @@ void cEvent::SetComponents(cComponents *Components)
void cEvent::SetContents(uchar *Contents)
{
- for (int i = 0; i < MAXEVCONTENTS; i++)
+ for (int i = 0; i < MaxEventContents; i++)
contents[i] = Contents[i];
}
@@ -250,7 +250,7 @@ bool cEvent::IsRunning(bool OrAboutToStart) const
const char *cEvent::ContentToString(uchar Content)
{
switch (Content & 0xF0) {
- case EVCONTENTMASK_MOVIEDRAMA:
+ case ecgMovieDrama:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Movie/Drama");
@@ -264,7 +264,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x08: return tr("Content$Adult Movie/Drama");
}
break;
- case EVCONTENTMASK_NEWSCURRENTAFFAIRS:
+ case ecgNewsCurrentAffairs:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$News/Current Affairs");
@@ -274,7 +274,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x04: return tr("Content$Discussion/Inverview/Debate");
}
break;
- case EVCONTENTMASK_SHOW:
+ case ecgShow:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Show/Game Show");
@@ -283,7 +283,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x03: return tr("Content$Talk Show");
}
break;
- case EVCONTENTMASK_SPORTS:
+ case ecgSports:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Sports");
@@ -300,7 +300,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x0B: return tr("Content$Martial Sports");
}
break;
- case EVCONTENTMASK_CHILDRENYOUTH:
+ case ecgChildrenYouth:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Children's/Youth Programme");
@@ -311,7 +311,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x05: return tr("Content$Cartoons/Puppets");
}
break;
- case EVCONTENTMASK_MUSICBALLETDANCE:
+ case ecgMusicBalletDance:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Music/Ballet/Dance");
@@ -323,7 +323,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x06: return tr("Content$Ballet");
}
break;
- case EVCONTENTMASK_ARTSCULTURE:
+ case ecgArtsCulture:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Arts/Culture");
@@ -340,7 +340,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x0B: return tr("Content$Fashion");
}
break;
- case EVCONTENTMASK_SOCIALPOLITICALECONOMICS:
+ case ecgSocialPoliticalEconomics:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Social/Political/Economics");
@@ -349,7 +349,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x03: return tr("Content$Remarkable People");
}
break;
- case EVCONTENTMASK_EDUCATIONALSCIENCE:
+ case ecgEducationalScience:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Education/Science/Factual");
@@ -362,7 +362,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x07: return tr("Content$Languages");
}
break;
- case EVCONTENTMASK_LEISUREHOBBIES:
+ case ecgLeisureHobbies:
switch (Content & 0x0F) {
default:
case 0x00: return tr("Content$Leisure/Hobbies");
@@ -375,7 +375,7 @@ const char *cEvent::ContentToString(uchar Content)
case 0x07: return tr("Content$Gardening");
}
break;
- case EVCONTENTMASK_SPECIAL:
+ case ecgSpecial:
switch (Content & 0x0F) {
case 0x00: return tr("Content$Original Language");
case 0x01: return tr("Content$Black & White");
@@ -468,7 +468,7 @@ bool cEvent::Parse(char *s)
break;
case 'G': {
memset(contents, 0, sizeof(contents));
- for (int i = 0; i < MAXEVCONTENTS; i++) {
+ for (int i = 0; i < MaxEventContents; i++) {
char *tail = NULL;
int c = strtol(t, &tail, 16);
if (0x00 < c && c <= 0xFF) {
diff --git a/epg.h b/epg.h
index fbc9e06..5555c2e 100644
--- a/epg.h
+++ b/epg.h
@@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
*
- * $Id: epg.h 2.3 2010/01/03 14:39:14 kls Exp $
+ * $Id: epg.h 2.4 2010/01/08 15:20:34 kls Exp $
*/
#ifndef __EPG_H
@@ -19,19 +19,22 @@
#define MAXEPGBUGFIXLEVEL 3
-#define MAXEVCONTENTS 4
-#define EVCONTENTMASK_MOVIEDRAMA 0x10
-#define EVCONTENTMASK_NEWSCURRENTAFFAIRS 0x20
-#define EVCONTENTMASK_SHOW 0x30
-#define EVCONTENTMASK_SPORTS 0x40
-#define EVCONTENTMASK_CHILDRENYOUTH 0x50
-#define EVCONTENTMASK_MUSICBALLETDANCE 0x60
-#define EVCONTENTMASK_ARTSCULTURE 0x70
-#define EVCONTENTMASK_SOCIALPOLITICALECONOMICS 0x80
-#define EVCONTENTMASK_EDUCATIONALSCIENCE 0x90
-#define EVCONTENTMASK_LEISUREHOBBIES 0xA0
-#define EVCONTENTMASK_SPECIAL 0xB0
-#define EVCONTENTMASK_USERDEFINED 0xF0
+enum { MaxEventContents = 4 };
+
+enum eEventContentGroup {
+ ecgMovieDrama = 0x10,
+ ecgNewsCurrentAffairs = 0x20,
+ ecgShow = 0x30,
+ ecgSports = 0x40,
+ ecgChildrenYouth = 0x50,
+ ecgMusicBalletDance = 0x60,
+ ecgArtsCulture = 0x70,
+ ecgSocialPoliticalEconomics = 0x80,
+ ecgEducationalScience = 0x90,
+ ecgLeisureHobbies = 0xA0,
+ ecgSpecial = 0xB0,
+ ecgUserDefined = 0xF0
+ };
enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
@@ -78,7 +81,7 @@ private:
char *shortText; // Short description of this event (typically the episode name in case of a series)
char *description; // Description of this event
cComponents *components; // The stream components of this event
- uchar contents[MAXEVCONTENTS]; // Contents of this event
+ uchar contents[MaxEventContents]; // Contents of this event
time_t startTime; // Start time of this event
int duration; // Duration of this event in seconds
time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
@@ -97,7 +100,7 @@ public:
const char *ShortText(void) const { return shortText; }
const char *Description(void) const { return description; }
const cComponents *Components(void) const { return components; }
- uchar Contents(int i = 0) const { return (0 <= i && i < MAXEVCONTENTS) ? contents[i] : 0; }
+ uchar Contents(int i = 0) const { return (0 <= i && i < MaxEventContents) ? contents[i] : 0; }
int ParentalRating(void) const { return parentalRating; }
time_t StartTime(void) const { return startTime; }
time_t EndTime(void) const { return startTime + duration; }
diff --git a/menu.c b/menu.c
index b0077a0..7ddf0cf 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 2.10 2009/12/06 11:29:05 kls Exp $
+ * $Id: menu.c 2.14 2010/01/31 12:43:24 kls Exp $
*/
#include "menu.h"
@@ -623,11 +623,276 @@ eOSState cMenuText::ProcessKey(eKeys Key)
return state;
}
+// --- cMenuFolderItem -------------------------------------------------------
+
+class cMenuFolderItem : public cOsdItem {
+private:
+ cNestedItem *folder;
+public:
+ cMenuFolderItem(cNestedItem *Folder);
+ cNestedItem *Folder(void) { return folder; }
+ };
+
+cMenuFolderItem::cMenuFolderItem(cNestedItem *Folder)
+:cOsdItem(Folder->Text())
+{
+ folder = Folder;
+ if (folder->SubItems())
+ SetText(cString::sprintf("%s...", folder->Text()));
+}
+
+// --- cMenuEditFolder -------------------------------------------------------
+
+class cMenuEditFolder : public cOsdMenu {
+private:
+ cList<cNestedItem> *list;
+ cNestedItem *folder;
+ char name[PATH_MAX];
+ int subFolder;
+ eOSState Confirm(void);
+public:
+ cMenuEditFolder(const char *Dir, cList<cNestedItem> *List, cNestedItem *Folder = NULL);
+ cString GetFolder(void);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditFolder::cMenuEditFolder(const char *Dir, cList<cNestedItem> *List, cNestedItem *Folder)
+:cOsdMenu(Folder ? tr("Edit folder") : tr("New folder"), 12)
+{
+ list = List;
+ folder = Folder;
+ if (folder) {
+ strn0cpy(name, folder->Text(), sizeof(name));
+ subFolder = folder->SubItems() != NULL;
+ }
+ else {
+ *name = 0;
+ subFolder = 0;
+ cRemote::Put(kRight, true); // go right into string editing mode
+ }
+ if (!isempty(Dir)) {
+ cOsdItem *DirItem = new cOsdItem(Dir);
+ DirItem->SetSelectable(false);
+ Add(DirItem);
+ }
+ Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name)));
+ Add(new cMenuEditBoolItem(tr("Sub folder"), &subFolder));
+}
+
+cString cMenuEditFolder::GetFolder(void)
+{
+ return folder ? folder->Text() : "";
+}
+
+eOSState cMenuEditFolder::Confirm(void)
+{
+ if (!folder || strcmp(folder->Text(), name) != 0) {
+ // each name may occur only once in a folder list
+ for (cNestedItem *Folder = list->First(); Folder; Folder = list->Next(Folder)) {
+ if (strcmp(Folder->Text(), name) == 0) {
+ Skins.Message(mtError, tr("Folder name already exists!"));
+ return osContinue;
+ }
+ }
+ char *p = strpbrk(name, "\\{}#~"); // FOLDERDELIMCHAR
+ if (p) {
+ Skins.Message(mtError, cString::sprintf(tr("Folder name must not contain '%c'!"), *p));
+ return osContinue;
+ }
+ }
+ if (folder) {
+ folder->SetText(name);
+ folder->SetSubItems(subFolder);
+ }
+ else
+ list->Add(folder = new cNestedItem(name, subFolder));
+ return osEnd;
+}
+
+eOSState cMenuEditFolder::ProcessKey(eKeys Key)
+{
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk: return Confirm();
+ case kRed:
+ case kGreen:
+ case kYellow:
+ case kBlue: return osContinue;
+ default: break;
+ }
+ }
+ return state;
+}
+
+// --- cMenuFolder -----------------------------------------------------------
+
+cMenuFolder::cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path)
+:cOsdMenu(Title)
+{
+ list = nestedItemList = NestedItemList;
+ firstFolder = NULL;
+ editing = false;
+ Set();
+ SetHelpKeys();
+ DescendPath(Path);
+}
+
+cMenuFolder::cMenuFolder(const char *Title, cList<cNestedItem> *List, cNestedItemList *NestedItemList, const char *Dir, const char *Path)
+:cOsdMenu(Title)
+{
+ list = List;
+ nestedItemList = NestedItemList;
+ dir = Dir;
+ firstFolder = NULL;
+ editing = false;
+ Set();
+ SetHelpKeys();
+ DescendPath(Path);
+}
+
+void cMenuFolder::SetHelpKeys(void)
+{
+ SetHelp(firstFolder ? tr("Button$Select") : NULL, tr("Button$New"), firstFolder ? tr("Button$Delete") : NULL, firstFolder ? tr("Button$Edit") : NULL);
+}
+
+void cMenuFolder::Set(const char *CurrentFolder)
+{
+ firstFolder = NULL;
+ Clear();
+ if (!isempty(dir)) {
+ cOsdItem *DirItem = new cOsdItem(dir);
+ DirItem->SetSelectable(false);
+ Add(DirItem);
+ }
+ list->Sort();
+ for (cNestedItem *Folder = list->First(); Folder; Folder = list->Next(Folder)) {
+ cOsdItem *FolderItem = new cMenuFolderItem(Folder);
+ Add(FolderItem, CurrentFolder ? strcmp(Folder->Text(), CurrentFolder) == 0 : false);
+ if (!firstFolder)
+ firstFolder = FolderItem;
+ }
+}
+
+void cMenuFolder::DescendPath(const char *Path)
+{
+ if (Path) {
+ const char *p = strchr(Path, FOLDERDELIMCHAR);
+ if (p) {
+ for (cMenuFolderItem *Folder = (cMenuFolderItem *)firstFolder; Folder; Folder = (cMenuFolderItem *)Next(Folder)) {
+ if (strncmp(Folder->Folder()->Text(), Path, p - Path) == 0) {
+ SetCurrent(Folder);
+ if (Folder->Folder()->SubItems())
+ AddSubMenu(new cMenuFolder(Title(), Folder->Folder()->SubItems(), nestedItemList, !isempty(dir) ? *cString::sprintf("%s%c%s", *dir, FOLDERDELIMCHAR, Folder->Folder()->Text()) : Folder->Folder()->Text(), p + 1));
+ break;
+ }
+ }
+ }
+ }
+}
+
+eOSState cMenuFolder::Select(void)
+{
+ if (firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ if (Folder->Folder()->SubItems())
+ return AddSubMenu(new cMenuFolder(Title(), Folder->Folder()->SubItems(), nestedItemList, !isempty(dir) ? *cString::sprintf("%s%c%s", *dir, FOLDERDELIMCHAR, Folder->Folder()->Text()) : Folder->Folder()->Text()));
+ else
+ return osEnd;
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::New(void)
+{
+ editing = true;
+ return AddSubMenu(new cMenuEditFolder(dir, list));
+}
+
+eOSState cMenuFolder::Delete(void)
+{
+ if (!HasSubMenu() && firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder && Interface->Confirm(Folder->Folder()->SubItems() ? tr("Delete folder and all sub folders?") : tr("Delete folder?"))) {
+ list->Del(Folder->Folder());
+ Del(Folder->Index());
+ firstFolder = Get(isempty(dir) ? 0 : 1);
+ Display();
+ SetHelpKeys();
+ nestedItemList->Save();
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::Edit(void)
+{
+ if (!HasSubMenu() && firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ editing = true;
+ return AddSubMenu(new cMenuEditFolder(dir, list, Folder->Folder()));
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::SetFolder(void)
+{
+ cMenuEditFolder *mef = (cMenuEditFolder *)SubMenu();
+ if (mef) {
+ Set(mef->GetFolder());
+ SetHelpKeys();
+ Display();
+ nestedItemList->Save();
+ }
+ return CloseSubMenu();
+}
+
+cString cMenuFolder::GetFolder(void)
+{
+ if (firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ cMenuFolder *mf = (cMenuFolder *)SubMenu();
+ if (mf)
+ return cString::sprintf("%s%c%s", Folder->Folder()->Text(), FOLDERDELIMCHAR, *mf->GetFolder());
+ return Folder->Folder()->Text();
+ }
+ }
+ return "";
+}
+
+eOSState cMenuFolder::ProcessKey(eKeys Key)
+{
+ if (!HasSubMenu())
+ editing = false;
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk:
+ case kRed: return Select();
+ case kGreen: return New();
+ case kYellow: return Delete();
+ case kBlue: return Edit();
+ default: state = osContinue;
+ }
+ }
+ else if (state == osEnd && HasSubMenu() && editing)
+ state = SetFolder();
+ return state;
+}
+
// --- cMenuEditTimer --------------------------------------------------------
cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
:cOsdMenu(tr("Edit timer"), 12)
{
+ file = NULL;
firstday = NULL;
timer = Timer;
addIfConfirmed = New;
@@ -644,9 +909,10 @@ cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
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));
- Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file)));
+ Add(file = new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file)));
SetFirstDayItem();
}
+ SetHelpKeys();
Timers.IncBeingEdited();
}
@@ -657,6 +923,11 @@ cMenuEditTimer::~cMenuEditTimer()
Timers.DecBeingEdited();
}
+void cMenuEditTimer::SetHelpKeys(void)
+{
+ SetHelp(tr("Button$Folder"));
+}
+
void cMenuEditTimer::SetFirstDayItem(void)
{
if (!firstday && !data.IsSingleEvent()) {
@@ -670,6 +941,26 @@ void cMenuEditTimer::SetFirstDayItem(void)
}
}
+eOSState cMenuEditTimer::SetFolder(void)
+{
+ cMenuFolder *mf = (cMenuFolder *)SubMenu();
+ if (mf) {
+ cString Folder = mf->GetFolder();
+ char *p = strrchr(data.file, FOLDERDELIMCHAR);
+ if (p)
+ p++;
+ else
+ p = data.file;
+ if (!isempty(*Folder))
+ strn0cpy(data.file, cString::sprintf("%s%c%s", *Folder, FOLDERDELIMCHAR, p), sizeof(data.file));
+ else if (p != data.file)
+ memmove(data.file, p, strlen(p) + 1);
+ SetCurrent(file);
+ Display();
+ }
+ return CloseSubMenu();
+}
+
eOSState cMenuEditTimer::ProcessKey(eKeys Key)
{
eOSState state = cOsdMenu::ProcessKey(Key);
@@ -699,13 +990,15 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
}
}
return osBack;
- case kRed:
+ case kRed: return AddSubMenu(new cMenuFolder(tr("Select folder"), &Folders, data.file));
case kGreen:
case kYellow:
case kBlue: return osContinue;
default: break;
}
}
+ else if (state == osEnd && HasSubMenu())
+ state = SetFolder();
if (Key != kNone)
SetFirstDayItem();
return state;
@@ -1490,44 +1783,100 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
class cMenuCommands : public cOsdMenu {
private:
- cCommands *commands;
- char *parameters;
+ cList<cNestedItem> *commands;
+ cString parameters;
+ cString title;
+ cString command;
+ bool confirm;
+ char *result;
+ bool Parse(const char *s);
eOSState Execute(void);
public:
- cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL);
+ cMenuCommands(const char *Title, cList<cNestedItem> *Commands, const char *Parameters = NULL);
virtual ~cMenuCommands();
virtual eOSState ProcessKey(eKeys Key);
};
-cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters)
+cMenuCommands::cMenuCommands(const char *Title, cList<cNestedItem> *Commands, const char *Parameters)
:cOsdMenu(Title)
{
+ result = NULL;
SetHasHotkeys();
commands = Commands;
- parameters = Parameters ? strdup(Parameters) : NULL;
- for (cCommand *command = commands->First(); command; command = commands->Next(command))
- Add(new cOsdItem(hk(command->Title())));
+ parameters = Parameters;
+ for (cNestedItem *Command = commands->First(); Command; Command = commands->Next(Command)) {
+ const char *s = Command->Text();
+ if (Command->SubItems())
+ Add(new cOsdItem(hk(cString::sprintf("%s...", s))));
+ else if (Parse(s))
+ Add(new cOsdItem(hk(title)));
+ }
}
cMenuCommands::~cMenuCommands()
{
- free(parameters);
+ free(result);
+}
+
+bool cMenuCommands::Parse(const char *s)
+{
+ const char *p = strchr(s, ':');
+ if (p) {
+ int l = p - s;
+ if (l > 0) {
+ char t[l + 1];
+ stripspace(strn0cpy(t, s, l + 1));
+ l = strlen(t);
+ if (l > 1 && t[l - 1] == '?') {
+ t[l - 1] = 0;
+ confirm = true;
+ }
+ else
+ confirm = false;
+ title = t;
+ command = skipspace(p + 1);
+ return true;
+ }
+ }
+ return false;
}
eOSState cMenuCommands::Execute(void)
{
- cCommand *command = commands->Get(Current());
- if (command) {
- bool confirmed = true;
- if (command->Confirm())
- confirmed = Interface->Confirm(cString::sprintf("%s?", command->Title()));
- if (confirmed) {
- Skins.Message(mtStatus, cString::sprintf("%s...", command->Title()));
- const char *Result = command->Execute(parameters);
- Skins.Message(mtStatus, NULL);
- if (Result)
- return AddSubMenu(new cMenuText(command->Title(), Result, fontFix));
- return osEnd;
+ cNestedItem *Command = commands->Get(Current());
+ if (Command) {
+ if (Command->SubItems())
+ return AddSubMenu(new cMenuCommands(Title(), Command->SubItems(), parameters));
+ if (Parse(Command->Text())) {
+ if (!confirm || Interface->Confirm(cString::sprintf("%s?", *title))) {
+ Skins.Message(mtStatus, cString::sprintf("%s...", *title));
+ free(result);
+ result = NULL;
+ cString cmdbuf;
+ if (!isempty(parameters))
+ cmdbuf = cString::sprintf("%s %s", *command, *parameters);
+ const char *cmd = *cmdbuf ? *cmdbuf : *command;
+ dsyslog("executing command '%s'", cmd);
+ cPipe p;
+ if (p.Open(cmd, "r")) {
+ int l = 0;
+ int c;
+ while ((c = fgetc(p)) != EOF) {
+ if (l % 20 == 0)
+ result = (char *)realloc(result, l + 21);
+ result[l++] = char(c);
+ }
+ if (result)
+ result[l] = 0;
+ p.Close();
+ }
+ else
+ esyslog("ERROR: can't open pipe for command '%s'", cmd);
+ Skins.Message(mtStatus, NULL);
+ if (result)
+ return AddSubMenu(new cMenuText(title, result, fontFix));
+ return osEnd;
+ }
}
}
return osContinue;
@@ -1921,7 +2270,7 @@ void cMenuRecordings::Set(bool Refresh)
Clear();
Recordings.Sort();
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
- if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == '~')) {
+ if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) {
cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
Add(Item);
@@ -2746,6 +3095,7 @@ cMenuSetupMisc::cMenuSetupMisc(void)
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")));
+ Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Channels wrap"), &data.ChannelsWrap));
Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit));
}
@@ -3245,6 +3595,8 @@ cChannel *cDisplayChannel::NextAvailableChannel(cChannel *Channel, int Direction
if (Direction) {
while (Channel) {
Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel);
+ if (!Channel && Setup.ChannelsWrap)
+ Channel = Direction > 0 ? Channels.First() : Channels.Last();
if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0, true))
return Channel;
}
@@ -3759,7 +4111,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
isyslog("record %s", fileName);
if (MakeDirs(fileName, true)) {
const cChannel *ch = timer->Channel();
- recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids());
+ recorder = new cRecorder(fileName, ch, timer->Priority());
if (device->AttachReceiver(recorder)) {
Recording.WriteInfo();
cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
diff --git a/menu.h b/menu.h
index 6ab9904..d428a8d 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 2.0 2008/02/10 16:01:53 kls Exp $
+ * $Id: menu.h 2.1 2010/01/17 11:21:42 kls Exp $
*/
#ifndef __MENU_H
@@ -31,14 +31,39 @@ public:
virtual eOSState ProcessKey(eKeys Key);
};
+class cMenuFolder : public cOsdMenu {
+private:
+ cNestedItemList *nestedItemList;
+ cList<cNestedItem> *list;
+ cString dir;
+ cOsdItem *firstFolder;
+ bool editing;
+ void SetHelpKeys(void);
+ void Set(const char *CurrentFolder = NULL);
+ void DescendPath(const char *Path);
+ eOSState SetFolder(void);
+ eOSState Select(void);
+ eOSState New(void);
+ eOSState Delete(void);
+ eOSState Edit(void);
+ cMenuFolder(const char *Title, cList<cNestedItem> *List, cNestedItemList *NestedItemList, const char *Dir, const char *Path = NULL);
+public:
+ cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path = NULL);
+ cString GetFolder(void);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
class cMenuEditTimer : public cOsdMenu {
private:
cTimer *timer;
cTimer data;
int channel;
bool addIfConfirmed;
+ cMenuEditStrItem *file;
cMenuEditDateItem *firstday;
+ eOSState SetFolder(void);
void SetFirstDayItem(void);
+ void SetHelpKeys(void);
public:
cMenuEditTimer(cTimer *Timer, bool New = false);
virtual ~cMenuEditTimer();
diff --git a/osd.c b/osd.c
index 5529f12..cc60337 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 2.6 2009/12/06 11:33:47 kls Exp $
+ * $Id: osd.c 2.9 2010/01/22 15:58:39 kls Exp $
*/
#include "osd.h"
@@ -145,12 +145,14 @@ int cPalette::ClosestColor(tColor Color, int MaxDiff) const
int R1 = (Color & 0x00FF0000) >> 16;
int G1 = (Color & 0x0000FF00) >> 8;
int B1 = (Color & 0x000000FF);
- for (int i = 0; i < numColors; i++) {
+ for (int i = 0; i < numColors && d > 0; i++) {
int A2 = (color[i] & 0xFF000000) >> 24;
int R2 = (color[i] & 0x00FF0000) >> 16;
int G2 = (color[i] & 0x0000FF00) >> 8;
int B2 = (color[i] & 0x000000FF);
- int diff = (abs(A1 - A2) << 1) + (abs(R1 - R2) << 1) + (abs(G1 - G2) << 1) + (abs(B1 - B2) << 1);
+ int diff = 0;
+ if (A1 || A2) // fully transparent colors are considered equal
+ diff = (abs(A1 - A2) << 1) + (abs(R1 - R2) << 1) + (abs(G1 - G2) << 1) + (abs(B1 - B2) << 1);
if (diff < d) {
d = diff;
n = i;
@@ -724,6 +726,18 @@ void cBitmap::ShrinkBpp(int NewBpp)
// --- cOsd ------------------------------------------------------------------
+static const char *OsdErrorTexts[] = {
+ "ok",
+ "too many areas",
+ "too many colors",
+ "bpp not supported",
+ "areas overlap",
+ "wrong alignment",
+ "out of memory",
+ "wrong area size",
+ "unknown",
+ };
+
int cOsd::osdLeft = 0;
int cOsd::osdTop = 0;
int cOsd::osdWidth = 0;
@@ -814,7 +828,7 @@ eOsdError cOsd::SetAreas(const tArea *Areas, int NumAreas)
}
}
else
- esyslog("ERROR: cOsd::SetAreas returned %d", Result);
+ esyslog("ERROR: cOsd::SetAreas returned %d (%s)", Result, Result < oeUnknown ? OsdErrorTexts[Result] : OsdErrorTexts[oeUnknown]);
return Result;
}
diff --git a/osd.h b/osd.h
index f10247e..aa8a35a 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 2.4 2009/05/08 13:41:03 kls Exp $
+ * $Id: osd.h 2.5 2010/01/17 13:23:50 kls Exp $
*/
#ifndef __OSD_H
@@ -36,7 +36,7 @@ enum {
clrWhite = 0xFFFCFCFC,
};
-enum eOsdError { oeOk,
+enum eOsdError { oeOk, // see also OsdErrorTexts in osd.c
oeTooManyAreas,
oeTooManyColors,
oeBppNotSupported,
diff --git a/osdbase.c b/osdbase.c
index 9b59c05..0cdedb2 100644
--- a/osdbase.c
+++ b/osdbase.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osdbase.c 2.1 2009/06/01 11:54:50 kls Exp $
+ * $Id: osdbase.c 2.2 2010/01/17 11:36:12 kls Exp $
*/
#include "osdbase.h"
@@ -41,7 +41,7 @@ cOsdItem::~cOsdItem()
void cOsdItem::SetText(const char *Text, bool Copy)
{
free(text);
- text = Copy ? strdup(Text) : (char *)Text; // text assumes ownership!
+ text = Copy ? strdup(Text ? Text : "") : (char *)Text; // text assumes ownership!
}
void cOsdItem::SetSelectable(bool Selectable)
diff --git a/osdbase.h b/osdbase.h
index 0997c27..91c5ff7 100644
--- a/osdbase.h
+++ b/osdbase.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osdbase.h 2.0 2007/11/03 14:50:52 kls Exp $
+ * $Id: osdbase.h 2.1 2010/01/16 14:25:31 kls Exp $
*/
#ifndef __OSDBASE_H
@@ -102,6 +102,7 @@ protected:
void SetCols(int c0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
void SetHasHotkeys(bool HasHotkeys = true);
virtual void Clear(void);
+ const char *Title(void) { return title; }
bool SelectableItem(int idx);
void SetCurrent(cOsdItem *Item);
void RefreshCurrent(void);
@@ -116,6 +117,7 @@ protected:
eOSState AddSubMenu(cOsdMenu *SubMenu);
eOSState CloseSubMenu();
bool HasSubMenu(void) { return subMenu; }
+ cOsdMenu *SubMenu(void) { return subMenu; }
void SetStatus(const char *s);
void SetTitle(const char *Title);
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 14f3c21..fcdf672 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-02 19:02+0100\n"
"Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
"Language-Team: Catalanian\n"
@@ -586,6 +586,31 @@ msgstr "Canal en ús per un temporitzador!"
msgid "Delete channel?"
msgstr "Esborrar el canal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Editar temporitzador"
@@ -616,9 +641,15 @@ msgstr "Durada"
msgid "File"
msgstr "Arxiu"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Primer dia"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Temporitzadors"
@@ -1047,6 +1078,9 @@ msgstr "anterior"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volum inicial"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Sortida d'emergència"
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 6394008..3bbd6eb 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-28 15:00+0200\n"
"Last-Translator: Vladimír Bárta <vladimir.barta@k2atmitec.cz>, Jiøí Dobrı <jdobry@centrum.cz>\n"
"Language-Team: Czech\n"
@@ -584,6 +584,31 @@ msgstr "Kanál je dr¾enı èasovaèem nahrávek!"
msgid "Delete channel?"
msgstr "Smazat kanál?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Editace èasovaèe"
@@ -614,9 +639,15 @@ msgstr "®ivotnost"
msgid "File"
msgstr "Soubor"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "První den"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Èasovaèe"
@@ -1045,6 +1076,9 @@ msgstr "jako naposledy"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Hlasitost po spu¹tìní"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Nouzové ukonèení"
diff --git a/po/da_DK.po b/po/da_DK.po
index faa3632..fbad909 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
"Language-Team: Danish\n"
@@ -583,6 +583,31 @@ msgstr "Kanal anvendes af en timer!"
msgid "Delete channel?"
msgstr "Slet kanal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Rediger timer"
@@ -613,9 +638,15 @@ msgstr "Levetid"
msgid "File"
msgstr "Fil"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Første dag"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timere"
@@ -1044,6 +1075,9 @@ msgstr "som før"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Lydstyrke ved opstart"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Nødudgang"
diff --git a/po/de_DE.po b/po/de_DE.po
index ff25a33..ad6401b 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
-"PO-Revision-Date: 2007-11-25 15:19+0200\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
+"PO-Revision-Date: 2010-01-16 16:46+0100\n"
"Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
"Language-Team: German\n"
"MIME-Version: 1.0\n"
@@ -583,6 +583,31 @@ msgstr "Kanal wird von einem Timer benutzt!"
msgid "Delete channel?"
msgstr "Kanal löschen?"
+msgid "Edit folder"
+msgstr "Verzeichnis editieren"
+
+msgid "New folder"
+msgstr "Neues Verzeichnis"
+
+msgid "Sub folder"
+msgstr "Unterverzeichnis"
+
+msgid "Folder name already exists!"
+msgstr "Verzeichnisname existiert bereits!"
+
+#, fuzzy, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr "Verzeichnisname darf kein '{', '}' oder '#' enthalten!"
+
+msgid "Button$Select"
+msgstr "Auswählen"
+
+msgid "Delete folder and all sub folders?"
+msgstr "Verzeichnis und alle Unterverzeichnisse löschen?"
+
+msgid "Delete folder?"
+msgstr "Verzeichnis löschen?"
+
msgid "Edit timer"
msgstr "Timer editieren"
@@ -613,9 +638,15 @@ msgstr "Lebensdauer"
msgid "File"
msgstr "Datei"
+msgid "Button$Folder"
+msgstr "Verzeichnis"
+
msgid "First day"
msgstr "Erster Tag"
+msgid "Select folder"
+msgstr "Verzeichnis wählen"
+
msgid "Timers"
msgstr "Timer"
@@ -1044,6 +1075,9 @@ msgstr "wie vorher"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Lautstärke beim Einschalten"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr "Rundum zappen"
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Notausstieg"
diff --git a/po/el_GR.po b/po/el_GR.po
index 2c310ab..e8382b8 100644
--- a/po/el_GR.po
+++ b/po/el_GR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
"Language-Team: Greek\n"
@@ -583,6 +583,31 @@ msgstr "Ôï êáíÜëç ÷ñéóéìïğïéåßôáé áğü ÷ñïíïğñïãñáììáôéóìü!"
msgid "Delete channel?"
msgstr "ÄéáãñáöŞ êáíáëéïı?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Ôñïğïğïßçóç ÷ñïíïğñïãñáììáôéóìïı"
@@ -613,9 +638,15 @@ msgstr "Äéİñêåéá ĞáñáìïíŞò"
msgid "File"
msgstr "Áñ÷åßï"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Ğñşôç ìİñá"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "×ñïíïğñïãñáììáôéóìïß"
@@ -1044,6 +1075,9 @@ msgstr ""
msgid "Setup.Miscellaneous$Initial volume"
msgstr ""
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr ""
diff --git a/po/es_ES.po b/po/es_ES.po
index 6cb029c..d2bf5b0 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-02 19:02+0100\n"
"Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
"Language-Team: Spanish\n"
@@ -584,6 +584,31 @@ msgstr "¡Hay una grabación programada para este canal!"
msgid "Delete channel?"
msgstr "¿Eliminar canal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Modificar programación"
@@ -614,9 +639,15 @@ msgstr "Duración"
msgid "File"
msgstr "Fichero"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Primer día"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Programar grabaciones"
@@ -1045,6 +1076,9 @@ msgstr "anterior"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volumen inicial"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Salida de emergencia"
diff --git a/po/et_EE.po b/po/et_EE.po
index f8a0f60..97e2aee 100644
--- a/po/et_EE.po
+++ b/po/et_EE.po
@@ -1,13 +1,13 @@
# VDR language source file.
# Copyright (C) 2008 Klaus Schmidinger <kls@tvdr.de>
# This file is distributed under the same license as the VDR package.
-# Arthur Konovalov <artlov@gmail.com>, 2004-2009
+# Arthur Konovalov <artlov@gmail.com>, 2004-2010
#
msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
"Language-Team: Estonian\n"
@@ -34,251 +34,251 @@ msgid "Channel not available!"
msgstr "Kanal ei ole kättesaadav!"
msgid "Can't start Transfer Mode!"
-msgstr "Siirdemooduse start nurjus!"
+msgstr "Ülekandemooduse start nurjus!"
msgid "Starting EPG scan"
msgstr "EPG skaneerimine käivitatud"
msgid "Content$Movie/Drama"
-msgstr ""
+msgstr "Film/draama"
msgid "Content$Detective/Thriller"
-msgstr ""
+msgstr "Krimi/triller"
msgid "Content$Adventure/Western/War"
-msgstr ""
+msgstr "Seiklus/western/sõda"
msgid "Content$Science Fiction/Fantasy/Horror"
-msgstr ""
+msgstr "Scifi/fantaasia/õudus"
msgid "Content$Comedy"
-msgstr ""
+msgstr "Komöödia"
msgid "Content$Soap/Melodrama/Folkloric"
-msgstr ""
+msgstr "Sari/Melodraama/pärimuslik"
msgid "Content$Romance"
-msgstr ""
+msgstr "Romanss"
msgid "Content$Serious/Classical/Religious/Historical Movie/Drama"
-msgstr ""
+msgstr "Tõsine/klassikaline/religioosne/ajaloofilm/draama"
msgid "Content$Adult Movie/Drama"
-msgstr ""
+msgstr "Täiskasvanutele/draama"
msgid "Content$News/Current Affairs"
-msgstr ""
+msgstr "Uudised/päevakajaline"
msgid "Content$News/Weather Report"
-msgstr ""
+msgstr "Uudised/ilmateade"
msgid "Content$News Magazine"
-msgstr ""
+msgstr "Uudisteajakiri"
msgid "Content$Documentary"
-msgstr ""
+msgstr "Dokumentaal"
msgid "Content$Discussion/Inverview/Debate"
-msgstr ""
+msgstr "Diskussioon/intervjuu/debatt"
msgid "Content$Show/Game Show"
-msgstr ""
+msgstr "Meelelahutus"
msgid "Content$Game Show/Quiz/Contest"
-msgstr ""
+msgstr "Sõumäng/mälumäng/võistlus"
msgid "Content$Variety Show"
-msgstr ""
+msgstr "Varietee"
msgid "Content$Talk Show"
-msgstr ""
+msgstr "Vestlussaade"
msgid "Content$Sports"
-msgstr ""
+msgstr "Sport"
msgid "Content$Special Event"
-msgstr ""
+msgstr "Erisündmus"
msgid "Content$Sport Magazine"
-msgstr ""
+msgstr "Spordiajakiri"
msgid "Content$Football/Soccer"
-msgstr ""
+msgstr "Jalgpall"
msgid "Content$Tennis/Squash"
-msgstr ""
+msgstr "Tennis/squash"
msgid "Content$Team Sports"
-msgstr ""
+msgstr "Meeskonnasport"
msgid "Content$Athletics"
-msgstr ""
+msgstr "Kergejõustik"
msgid "Content$Motor Sport"
-msgstr ""
+msgstr "Autosport"
msgid "Content$Water Sport"
-msgstr ""
+msgstr "Veesport"
msgid "Content$Winter Sports"
-msgstr ""
+msgstr "Talvesport"
msgid "Content$Equestrian"
-msgstr ""
+msgstr "Ratsutamine"
msgid "Content$Martial Sports"
-msgstr ""
+msgstr "Võitluskunst"
msgid "Content$Children's/Youth Programme"
-msgstr ""
+msgstr "Laste- ja noortesaade"
msgid "Content$Pre-school Children's Programme"
-msgstr ""
+msgstr "Koolieelikutele"
msgid "Content$Entertainment Programme for 6 to 14"
-msgstr ""
+msgstr "Meelelahutus 6-14 aastastele"
msgid "Content$Entertainment Programme for 10 to 16"
-msgstr ""
+msgstr "Meelelahutus 10-16 aastastele"
msgid "Content$Informational/Educational/School Programme"
-msgstr ""
+msgstr "Õppe- ja haridussaade"
msgid "Content$Cartoons/Puppets"
-msgstr ""
+msgstr "Joonisfilm/Nukufilm"
msgid "Content$Music/Ballet/Dance"
-msgstr ""
+msgstr "Muusika/ballett/tants"
msgid "Content$Rock/Pop"
-msgstr ""
+msgstr "Rock/pop"
msgid "Content$Serious/Classical Music"
-msgstr ""
+msgstr "Klassikaline muusika"
msgid "Content$Folk/Tradional Music"
-msgstr ""
+msgstr "Folk/rahvamuusika"
msgid "Content$Jazz"
-msgstr ""
+msgstr "Jazz"
msgid "Content$Musical/Opera"
-msgstr ""
+msgstr "Muusikal/ooper"
msgid "Content$Ballet"
-msgstr ""
+msgstr "Ballett"
msgid "Content$Arts/Culture"
-msgstr ""
+msgstr "Kunst/kultuur"
msgid "Content$Performing Arts"
-msgstr ""
+msgstr "Performance"
msgid "Content$Fine Arts"
-msgstr ""
+msgstr "Kaunid kunstid"
msgid "Content$Religion"
-msgstr ""
+msgstr "Religioon"
msgid "Content$Popular Culture/Traditional Arts"
-msgstr ""
+msgstr "Rahvakultuur/traditsiooniline kunst"
msgid "Content$Literature"
-msgstr ""
+msgstr "Kirjandus"
msgid "Content$Film/Cinema"
-msgstr ""
+msgstr "Filmikunst"
msgid "Content$Experimental Film/Video"
-msgstr ""
+msgstr "Eksperimentaalfilm/video"
msgid "Content$Broadcasting/Press"
-msgstr ""
+msgstr "TV/raadio/ajakirjandus"
msgid "Content$New Media"
-msgstr ""
+msgstr "Uus meedia"
msgid "Content$Arts/Culture Magazine"
-msgstr ""
+msgstr "Kultuuriajakiri"
msgid "Content$Fashion"
-msgstr ""
+msgstr "Mood"
msgid "Content$Social/Political/Economics"
-msgstr ""
+msgstr "Ühiskond/poliitika/majandus"
msgid "Content$Magazine/Report/Documentary"
-msgstr ""
+msgstr "Ajakiri/reportaaş/dokumentaal"
msgid "Content$Economics/Social Advisory"
-msgstr ""
+msgstr "Majandus/majandusnõuanne"
msgid "Content$Remarkable People"
-msgstr ""
+msgstr "Tähelepanuväärsed isikud"
msgid "Content$Education/Science/Factual"
-msgstr ""
+msgstr "Haridus/teadus/faktid"
msgid "Content$Nature/Animals/Environment"
-msgstr ""
+msgstr "Loodus/loomad/keskkond"
msgid "Content$Technology/Natural Sciences"
-msgstr ""
+msgstr "Tehnoloogia/loodusteadus"
msgid "Content$Medicine/Physiology/Psychology"
-msgstr ""
+msgstr "Meditsiin/füsioloogia/psühholoogia"
msgid "Content$Foreign Countries/Expeditions"
-msgstr ""
+msgstr "Välisriigid/ekspeditsioon"
msgid "Content$Social/Spiritual Sciences"
-msgstr ""
+msgstr "Ühiskondlik/Hingeteadus"
msgid "Content$Further Education"
-msgstr ""
+msgstr "Täiendõpe"
msgid "Content$Languages"
-msgstr ""
+msgstr "Keeled"
msgid "Content$Leisure/Hobbies"
-msgstr ""
+msgstr "Vaba aeg/hobi"
msgid "Content$Tourism/Travel"
-msgstr ""
+msgstr "Turism/reisimine"
msgid "Content$Handicraft"
-msgstr ""
+msgstr "Käsitöö"
msgid "Content$Motoring"
-msgstr ""
+msgstr "Autondus"
msgid "Content$Fitness & Health"
-msgstr ""
+msgstr "Tervis"
msgid "Content$Cooking"
-msgstr ""
+msgstr "Kokasaade"
msgid "Content$Advertisement/Shopping"
-msgstr ""
+msgstr "Reklaam/teleturg"
msgid "Content$Gardening"
-msgstr ""
+msgstr "Aiandus"
msgid "Content$Original Language"
-msgstr ""
+msgstr "Originaalkeel"
msgid "Content$Black & White"
-msgstr ""
+msgstr "Mustvalge"
msgid "Content$Unpublished"
-msgstr ""
+msgstr "Avaldamata"
msgid "Content$Live Broadcast"
-msgstr ""
+msgstr "Otseülekanne"
#, c-format
msgid "ParentalRating$from %d"
-msgstr ""
+msgstr "alates %d"
msgid "No title"
msgstr "Pealkiri puudub"
@@ -583,6 +583,31 @@ msgstr "Kanal on taimeri kasutuses!"
msgid "Delete channel?"
msgstr "Kustutada kanal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Taimeri redigeerimine"
@@ -613,9 +638,15 @@ msgstr "Eluiga"
msgid "File"
msgstr "Fail"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Esimene päev"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Taimer"
@@ -1044,6 +1075,9 @@ msgstr "endine"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Helitugevus käivitamisel"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Hädaväljumine"
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 410bd67..916b51e 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-08-15 15:52+0200\n"
"Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
"Language-Team: Finnish\n"
@@ -586,6 +586,31 @@ msgstr "Kanava on ajastimen käytössä!"
msgid "Delete channel?"
msgstr "Poistetaanko kanava?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Muokkaa ajastinta"
@@ -616,9 +641,15 @@ msgstr "Elinikä"
msgid "File"
msgstr "Tiedosto"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "1. päivä"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Ajastimet"
@@ -1047,6 +1078,9 @@ msgstr "edellinen"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Äänenvoimakkuus käynnistettäessä"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Käytä hätäsammutusta"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 9f2768a..4c4dcce 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-27 18:14+0100\n"
"Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n"
"Language-Team: French\n"
@@ -589,6 +589,31 @@ msgstr "Cette chaîne est en cours d'utilisation !"
msgid "Delete channel?"
msgstr "Supprimer la chaîne ?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Changer la programmation"
@@ -619,9 +644,15 @@ msgstr "Durée de vie"
msgid "File"
msgstr "Fichier"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Premier jour"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Programmation"
@@ -1050,6 +1081,9 @@ msgstr "comme avant"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volume initial"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Arrêt d'urgence"
diff --git a/po/hr_HR.po b/po/hr_HR.po
index 7d923af..b7cf5a0 100644
--- a/po/hr_HR.po
+++ b/po/hr_HR.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-17 19:00+0100\n"
"Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
"Language-Team: Croatian\n"
@@ -585,6 +585,31 @@ msgstr "Program je trenutno zauzet tajmerom!"
msgid "Delete channel?"
msgstr "Obrisati program?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Ureğivanje tajmera"
@@ -615,9 +640,15 @@ msgstr "Trajanje"
msgid "File"
msgstr "Datoteka"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Prvi dan"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Tajmeri"
@@ -1046,6 +1077,9 @@ msgstr "kao prethodno"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Poèetna jaèina zvuka"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Izlaz u sluèaju nu¾de"
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 1517920..d09c8dd 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-12-01 21:42+0200\n"
"Last-Translator: István Füley <ifuley@tigercomp.ro>\n"
"Language-Team: Hungarian\n"
@@ -586,6 +586,31 @@ msgstr "Az adót az idõzítõ használja!"
msgid "Delete channel?"
msgstr "Csatorna törlése?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Idõzítõ megváltoztatása"
@@ -616,9 +641,15 @@ msgstr "Élettartam"
msgid "File"
msgstr "File"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Elsõ nap"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Idõzítõ"
@@ -1047,6 +1078,9 @@ msgstr "ahogy az elõbb"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Hangerõ a bekapcsolásnál"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr ""
diff --git a/po/it_IT.po b/po/it_IT.po
index 1a403ad..3a8f2e2 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
-"PO-Revision-Date: 2009-11-28 22:50+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
+"PO-Revision-Date: 2010-01-12 23:53+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: Italian\n"
"MIME-Version: 1.0\n"
@@ -47,245 +47,245 @@ msgid "Starting EPG scan"
msgstr "Inizio scansione EPG"
msgid "Content$Movie/Drama"
-msgstr ""
+msgstr "Film/Dramma"
msgid "Content$Detective/Thriller"
-msgstr ""
+msgstr "Investigativo/Giallo"
msgid "Content$Adventure/Western/War"
-msgstr ""
+msgstr "Avventura/Western/Guerra"
msgid "Content$Science Fiction/Fantasy/Horror"
-msgstr ""
+msgstr "Finzione/Fantasia/Horror"
msgid "Content$Comedy"
-msgstr ""
+msgstr "Commedia"
msgid "Content$Soap/Melodrama/Folkloric"
-msgstr ""
+msgstr "Telenovella/Melodramma/Folcloristico"
msgid "Content$Romance"
-msgstr ""
+msgstr "Romanzo"
msgid "Content$Serious/Classical/Religious/Historical Movie/Drama"
-msgstr ""
+msgstr "Serio/Classico/Religioso/Film storico/Dramma"
msgid "Content$Adult Movie/Drama"
-msgstr ""
+msgstr "Film per adulti/Dramma"
msgid "Content$News/Current Affairs"
-msgstr ""
+msgstr "Notizie/Ultima ora"
msgid "Content$News/Weather Report"
-msgstr ""
+msgstr "Notizie/Previsioni meteo"
msgid "Content$News Magazine"
-msgstr ""
+msgstr "Settimanale di attualità"
msgid "Content$Documentary"
-msgstr ""
+msgstr "Documentario"
msgid "Content$Discussion/Inverview/Debate"
-msgstr ""
+msgstr "Discussione/Intervista/Dibattito"
msgid "Content$Show/Game Show"
-msgstr ""
+msgstr "Spettacolo/Gioco a premi"
msgid "Content$Game Show/Quiz/Contest"
-msgstr ""
+msgstr "Gioco a premi/Quiz/Gara"
msgid "Content$Variety Show"
-msgstr ""
+msgstr "Spettacolo di varietà"
msgid "Content$Talk Show"
-msgstr ""
+msgstr "Talk Show"
msgid "Content$Sports"
-msgstr ""
+msgstr "Sport"
msgid "Content$Special Event"
-msgstr ""
+msgstr "Evento speciale"
msgid "Content$Sport Magazine"
-msgstr ""
+msgstr "Settimanale di sport"
msgid "Content$Football/Soccer"
-msgstr ""
+msgstr "Calcio"
msgid "Content$Tennis/Squash"
-msgstr ""
+msgstr "Tennis/Squash"
msgid "Content$Team Sports"
-msgstr ""
+msgstr "Sport di squadra"
msgid "Content$Athletics"
-msgstr ""
+msgstr "Atletica"
msgid "Content$Motor Sport"
-msgstr ""
+msgstr "Sport motoristici"
msgid "Content$Water Sport"
-msgstr ""
+msgstr "Sport acquatici"
msgid "Content$Winter Sports"
-msgstr ""
+msgstr "Sport invernali"
msgid "Content$Equestrian"
-msgstr ""
+msgstr "Equitazione"
msgid "Content$Martial Sports"
-msgstr ""
+msgstr "Arti marziali"
msgid "Content$Children's/Youth Programme"
-msgstr ""
+msgstr "Programmi per ragazzi/giovani"
msgid "Content$Pre-school Children's Programme"
-msgstr ""
+msgstr "Programmi per ragazzi prescolastici"
msgid "Content$Entertainment Programme for 6 to 14"
-msgstr ""
+msgstr "Programmi di intrattenimento da 6 a 14"
msgid "Content$Entertainment Programme for 10 to 16"
-msgstr ""
+msgstr "Programmi di intrattenimento da 10 a 16"
msgid "Content$Informational/Educational/School Programme"
-msgstr ""
+msgstr "Informativo/Educativo/Programma scolastico"
msgid "Content$Cartoons/Puppets"
-msgstr ""
+msgstr "Cartoni/Pupazzi"
msgid "Content$Music/Ballet/Dance"
-msgstr ""
+msgstr "Musica/Balletto/Danza"
msgid "Content$Rock/Pop"
-msgstr ""
+msgstr "Rock/Pop"
msgid "Content$Serious/Classical Music"
-msgstr ""
+msgstr "Musica Classica/Seria"
msgid "Content$Folk/Tradional Music"
-msgstr ""
+msgstr "Musica Tradizionale/Folclore"
msgid "Content$Jazz"
-msgstr ""
+msgstr "Jazz"
msgid "Content$Musical/Opera"
-msgstr ""
+msgstr "Musical/Opera"
msgid "Content$Ballet"
-msgstr ""
+msgstr "Balletto"
msgid "Content$Arts/Culture"
-msgstr ""
+msgstr "Arte/Cultura"
msgid "Content$Performing Arts"
-msgstr ""
+msgstr "Arti di rendimento"
msgid "Content$Fine Arts"
-msgstr ""
+msgstr "Arti fine"
msgid "Content$Religion"
-msgstr ""
+msgstr "Religione"
msgid "Content$Popular Culture/Traditional Arts"
-msgstr ""
+msgstr "Cultura popolare/Arti tradizionali"
msgid "Content$Literature"
-msgstr ""
+msgstr "Letteratura"
msgid "Content$Film/Cinema"
-msgstr ""
+msgstr "Film/Cinema"
msgid "Content$Experimental Film/Video"
-msgstr ""
+msgstr "Film sperimentale/Video"
msgid "Content$Broadcasting/Press"
-msgstr ""
+msgstr "Trasmissione/Stampa"
msgid "Content$New Media"
-msgstr ""
+msgstr "Nuovo programma"
msgid "Content$Arts/Culture Magazine"
-msgstr ""
+msgstr "Arte/Settimanale di cultura"
msgid "Content$Fashion"
-msgstr ""
+msgstr "Moda"
msgid "Content$Social/Political/Economics"
-msgstr ""
+msgstr "Società/Politica/Economia"
msgid "Content$Magazine/Report/Documentary"
-msgstr ""
+msgstr "Settimanale/Reportage/Documentario"
msgid "Content$Economics/Social Advisory"
-msgstr ""
+msgstr "Economia/Consulenza sociale"
msgid "Content$Remarkable People"
-msgstr ""
+msgstr "Personaggi importanti"
msgid "Content$Education/Science/Factual"
-msgstr ""
+msgstr "Educazione/Scienza/Fatti"
msgid "Content$Nature/Animals/Environment"
-msgstr ""
+msgstr "Natura/Animali/Ambiente"
msgid "Content$Technology/Natural Sciences"
-msgstr ""
+msgstr "Tecnologia/Scienze naturali"
msgid "Content$Medicine/Physiology/Psychology"
-msgstr ""
+msgstr "Medicina/Filosofia/Psicologia"
msgid "Content$Foreign Countries/Expeditions"
-msgstr ""
+msgstr "Paesi esteri/Spedizioni"
msgid "Content$Social/Spiritual Sciences"
-msgstr ""
+msgstr "Società/Scienze spirituali"
msgid "Content$Further Education"
-msgstr ""
+msgstr "Altra educazione"
msgid "Content$Languages"
-msgstr ""
+msgstr "Lingue"
msgid "Content$Leisure/Hobbies"
-msgstr ""
+msgstr "Tempo libero/Hobby"
msgid "Content$Tourism/Travel"
-msgstr ""
+msgstr "Turismo/Viaggi"
msgid "Content$Handicraft"
-msgstr ""
+msgstr "Artigianato"
msgid "Content$Motoring"
-msgstr ""
+msgstr "Motori"
msgid "Content$Fitness & Health"
-msgstr ""
+msgstr "Culturismo & Salute"
msgid "Content$Cooking"
-msgstr ""
+msgstr "Cucina"
msgid "Content$Advertisement/Shopping"
-msgstr ""
+msgstr "Pubblicità/Acquisti"
msgid "Content$Gardening"
-msgstr ""
+msgstr "Giardinaggio"
msgid "Content$Original Language"
-msgstr ""
+msgstr "Lingua madre"
msgid "Content$Black & White"
-msgstr ""
+msgstr "Bianco & Nero"
msgid "Content$Unpublished"
-msgstr ""
+msgstr "Non pubblicato"
msgid "Content$Live Broadcast"
-msgstr ""
+msgstr "Trasmissione dal vivo"
#, c-format
msgid "ParentalRating$from %d"
-msgstr ""
+msgstr "da %d"
msgid "No title"
msgstr "Senza titolo"
@@ -590,6 +590,31 @@ msgstr "Canale occupato da un timer!"
msgid "Delete channel?"
msgstr "Eliminare il canale?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Modifica timer"
@@ -620,9 +645,15 @@ msgstr "Scadenza"
msgid "File"
msgstr "Nome"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "1° giorno"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timer"
@@ -1051,6 +1082,9 @@ msgstr "come prima"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volume iniziale"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Uscita di emergenza"
diff --git a/po/lt_LT.po b/po/lt_LT.po
index dd36754..93583c5 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.7.9\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2009-10-17 14:19+0200\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian\n"
@@ -583,6 +583,31 @@ msgstr "KanalÄ… Å¡iuo metu naudoja laikmaÄio procesas!"
msgid "Delete channel?"
msgstr "IÅ¡trinti kanalÄ…?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Koreguoti laikmatį"
@@ -613,9 +638,15 @@ msgstr "Galiojimas"
msgid "File"
msgstr "Failas"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Pirma diena"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "LaikmaÄiai"
@@ -1044,6 +1075,9 @@ msgstr "kaip anksÄiau"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Garsas įjungimo metu"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Avarinis išėjimas"
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 3634438..fdfaf8d 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-26 17:20+0100\n"
"Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n"
"Language-Team: Dutch\n"
@@ -587,6 +587,31 @@ msgstr "Kanaal wordt gebruikt door een timer!"
msgid "Delete channel?"
msgstr "Kanaal verwijderen?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Timer veranderen"
@@ -617,9 +642,15 @@ msgstr "Bewaarduur"
msgid "File"
msgstr "Bestandnaam"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Eerste dag"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timers"
@@ -1048,6 +1079,9 @@ msgstr "zoals eerder"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Opstartvolume"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Nooduitgang"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index 56975a5..1f50117 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
"Language-Team: Norwegian\n"
@@ -584,6 +584,31 @@ msgstr "Kanalen er i bruk av en timer!"
msgid "Delete channel?"
msgstr "Slette kanal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Editer timer"
@@ -614,9 +639,15 @@ msgstr "Levetid"
msgid "File"
msgstr "Filnavn"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Første dag"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timere"
@@ -1045,6 +1076,9 @@ msgstr ""
msgid "Setup.Miscellaneous$Initial volume"
msgstr ""
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr ""
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 0143db8..038d058 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-09 12:59+0100\n"
"Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
"Language-Team: Polish\n"
@@ -584,6 +584,31 @@ msgstr "Kana³ jest u¿ywany przez timer!"
msgid "Delete channel?"
msgstr "Usun±æ kana³?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Edycja timera"
@@ -614,9 +639,15 @@ msgstr "Czas ¿ycia"
msgid "File"
msgstr "Plik"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Pierwszy dzieñ"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timery"
@@ -1045,6 +1076,9 @@ msgstr "jak ostatnio"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Pocz±tkowa g³o¶no¶æ"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Wyj¶cie awaryjne"
diff --git a/po/pt_PT.po b/po/pt_PT.po
index e863f8c..e409581 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-18 17:04+0100\n"
"Last-Translator: anonymous\n"
"Language-Team: Portuguese\n"
@@ -583,6 +583,31 @@ msgstr "Canal a ser utilizador por uma gravação programada!"
msgid "Delete channel?"
msgstr "Apagar o canal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Editar gavação programada"
@@ -613,9 +638,15 @@ msgstr "Duração"
msgid "File"
msgstr "Ficheiro"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Primeiro dia"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Gravações programadas"
@@ -1044,6 +1075,9 @@ msgstr "Como estava"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volume inicial"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Saída de emergência"
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 79a2690..f52a7d8 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-25 00:39+0100\n"
"Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
"Language-Team: Romanian\n"
@@ -586,6 +586,31 @@ msgstr "Canalul este utilizat de un timer!"
msgid "Delete channel?"
msgstr "ªterg canalul?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Modificare timer"
@@ -616,9 +641,15 @@ msgstr "Timp de pãstrare"
msgid "File"
msgstr "Fiºier"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Prima zi"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timer-e"
@@ -1047,6 +1078,9 @@ msgstr "ca mai înainte"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Volumul la pornire"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Oprire de urgenşã"
diff --git a/po/ru_RU.po b/po/ru_RU.po
index eb71a20..c6d6aca 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-12-15 14:37+0100\n"
"Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
"Language-Team: Russian\n"
@@ -584,6 +584,31 @@ msgstr "ºĞİĞÛ ×Ğİïâ âĞÙÜÕàŞÜ!"
msgid "Delete channel?"
msgstr "ÃÔĞÛØâì ÚĞİĞÛ?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "ÃáâĞİŞÒÚĞ âĞÙÜÕàĞ"
@@ -614,9 +639,15 @@ msgstr "ÁàŞÚ åàĞİÕİØï"
msgid "File"
msgstr "ÄĞÙÛ"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "¿ÕàÒëÙ ÔÕİì"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "ÂĞÙÜÕàë"
@@ -1045,6 +1076,9 @@ msgstr "ÚĞÚ àĞİìèÕ"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "³àŞÜÚŞáâì ßàØ ÒÚÛîçÕİØØ"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "°ÒĞàØÙİëÙ ÒëåŞÔ"
diff --git a/po/sk_SK.po b/po/sk_SK.po
index 5068882..c66132a 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2009-09-30 12:50+0100\n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak\n"
@@ -584,6 +584,31 @@ msgstr "Plán nahrávania práve pou¾íva kanál!"
msgid "Delete channel?"
msgstr "Odstráni» kanál?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Úprava plánu nahrávania"
@@ -614,9 +639,15 @@ msgstr "®ivotnos»"
msgid "File"
msgstr "Súbor"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Prvı deò"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Plány nahrávania"
@@ -1045,6 +1076,9 @@ msgstr "ako naposledy"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Hlasitos» po spustení"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Núdzové ukonèenie"
diff --git a/po/sl_SI.po b/po/sl_SI.po
index 7b3b05f..2c20440 100644
--- a/po/sl_SI.po
+++ b/po/sl_SI.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-28 19:44+0100\n"
"Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
"Language-Team: Slovenian\n"
@@ -584,6 +584,31 @@ msgstr "Kanal je zavzet s terminom za snemanje!"
msgid "Delete channel?"
msgstr "Izbri¹i kanal?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Uredi termin"
@@ -614,9 +639,15 @@ msgstr "Veljavnost"
msgid "File"
msgstr "Datoteka"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Prvi dan"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Termini"
@@ -1045,6 +1076,9 @@ msgstr "kot prej"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Privzeta glasnost"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Izhod v sili"
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 17a1da6..4ac9a0f 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-03-12 18:25+0100\n"
"Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n"
"Language-Team: Swedish\n"
@@ -586,6 +586,31 @@ msgstr "Kanalen används av en timer!"
msgid "Delete channel?"
msgstr "Ta bort kanalen?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Ändra timer"
@@ -616,9 +641,15 @@ msgstr "Livstid"
msgid "File"
msgstr "Filnamn"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Första dag"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Timers"
@@ -1047,6 +1078,9 @@ msgstr "som förut"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Ljudstyrka vid uppstart"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Oförutsedd avslutning"
diff --git a/po/tr_TR.po b/po/tr_TR.po
index e921986..02a9642 100644
--- a/po/tr_TR.po
+++ b/po/tr_TR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2008-02-28 00:33+0100\n"
"Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
"Language-Team: Turkish\n"
@@ -583,6 +583,31 @@ msgstr "Kanal zamanlayıcıdan kullanılıyor!"
msgid "Delete channel?"
msgstr "Kanalı sil?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "Zamanlayıcıyı ayarla"
@@ -613,9 +638,15 @@ msgstr "Ömrü"
msgid "File"
msgstr "Kütük"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "İlk gün"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Zamanlayıcı"
@@ -1044,6 +1075,9 @@ msgstr "önceki gibi"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "Açılışdaki ses"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Acil cıkış"
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 17c8371..7e3010c 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.7.7\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2009-05-31 13:17+0200\n"
"Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
"Language-Team: Ukrainian\n"
@@ -583,6 +583,31 @@ msgstr "Канал зайнÑтий таймером!"
msgid "Delete channel?"
msgstr "Видалити канал?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "ĞĞ°Ğ»Ğ°ÑˆÑ‚ÑƒĞ²Ğ°Ğ½Ğ½Ñ Ñ‚Ğ°Ğ¹Ğ¼ĞµÑ€Ğ°"
@@ -613,9 +638,15 @@ msgstr "Строк зберіганнÑ"
msgid "File"
msgstr "Файл"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "Перший день"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "Таймери"
@@ -1044,6 +1075,9 @@ msgstr "Ñк раніше"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "ГучніÑÑ‚ÑŒ при вклÑченні"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "Ğварійний вихід"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 1f6eaac..1d12f71 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.6.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-01-03 15:10+0100\n"
+"POT-Creation-Date: 2010-01-17 16:18+0100\n"
"PO-Revision-Date: 2009-09-23 23:50+0800\n"
"Last-Translator: Nan Feng <nfgx@21cn.com>\n"
"Language-Team: Chinese\n"
@@ -586,6 +586,31 @@ msgstr "频é“正在录åƒï¼"
msgid "Delete channel?"
msgstr "是å¦åˆ é™¤é¢‘é“?"
+msgid "Edit folder"
+msgstr ""
+
+msgid "New folder"
+msgstr ""
+
+msgid "Sub folder"
+msgstr ""
+
+msgid "Folder name already exists!"
+msgstr ""
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr ""
+
+msgid "Button$Select"
+msgstr ""
+
+msgid "Delete folder and all sub folders?"
+msgstr ""
+
+msgid "Delete folder?"
+msgstr ""
+
msgid "Edit timer"
msgstr "编辑计时器"
@@ -616,9 +641,15 @@ msgstr "终生"
msgid "File"
msgstr "文件"
+msgid "Button$Folder"
+msgstr ""
+
msgid "First day"
msgstr "第一天"
+msgid "Select folder"
+msgstr ""
+
msgid "Timers"
msgstr "录åƒä¸­åˆ—表"
@@ -1047,6 +1078,9 @@ msgstr "之å‰"
msgid "Setup.Miscellaneous$Initial volume"
msgstr "åˆå§‹åŒ–声音"
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr ""
+
msgid "Setup.Miscellaneous$Emergency exit"
msgstr "çªå‘事件退出"
diff --git a/receiver.c b/receiver.c
index 08346e4..f922e98 100644
--- a/receiver.c
+++ b/receiver.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: receiver.c 2.1 2010/01/01 15:38:48 kls Exp $
+ * $Id: receiver.c 2.2 2010/01/30 10:25:38 kls Exp $
*/
#include "receiver.h"
@@ -12,28 +12,26 @@
#include <stdio.h>
#include "tools.h"
+#ifdef LEGACY_CRECEIVER
cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3)
{
device = NULL;
channelID = ChannelID;
priority = Priority;
numPids = 0;
- if (Pid)
- pids[numPids++] = Pid;
- if (Pids1) {
- while (*Pids1 && numPids < MAXRECEIVEPIDS)
- pids[numPids++] = *Pids1++;
- }
- if (Pids2) {
- while (*Pids2 && numPids < MAXRECEIVEPIDS)
- pids[numPids++] = *Pids2++;
- }
- if (Pids3) {
- while (*Pids3 && numPids < MAXRECEIVEPIDS)
- pids[numPids++] = *Pids3++;
- }
- if (numPids >= MAXRECEIVEPIDS)
- dsyslog("too many PIDs in cReceiver");
+ AddPid(Pid);
+ AddPids(Pids1);
+ AddPids(Pids2);
+ AddPids(Pids3);
+}
+#endif
+
+cReceiver::cReceiver(const cChannel *Channel, int Priority)
+{
+ device = NULL;
+ priority = Priority;
+ numPids = 0;
+ SetPids(Channel);
}
cReceiver::~cReceiver()
@@ -46,6 +44,49 @@ cReceiver::~cReceiver()
}
}
+bool cReceiver::AddPid(int Pid)
+{
+ if (Pid) {
+ if (numPids < MAXRECEIVEPIDS)
+ pids[numPids++] = Pid;
+ else {
+ dsyslog("too many PIDs in cReceiver (Pid = %d)", Pid);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cReceiver::AddPids(const int *Pids)
+{
+ if (Pids) {
+ while (*Pids) {
+ if (!AddPid(*Pids++))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cReceiver::AddPids(int Pid1, int Pid2, int Pid3, int Pid4, int Pid5, int Pid6, int Pid7, int Pid8, int Pid9)
+{
+ return AddPid(Pid1) && AddPid(Pid2) && AddPid(Pid3) && AddPid(Pid4) && AddPid(Pid5) && AddPid(Pid6) && AddPid(Pid7) && AddPid(Pid8) && AddPid(Pid9);
+}
+
+bool cReceiver::SetPids(const cChannel *Channel)
+{
+ numPids = 0;
+ if (Channel) {
+ channelID = Channel->GetChannelID();
+ return AddPid(Channel->Vpid()) &&
+ (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
+ AddPids(Channel->Apids()) &&
+ (!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
+ AddPids(Channel->Spids());
+ }
+return true;
+}
+
bool cReceiver::WantsPid(int Pid)
{
if (Pid) {
diff --git a/receiver.h b/receiver.h
index 35930d2..bd98a42 100644
--- a/receiver.h
+++ b/receiver.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: receiver.h 2.0 2007/01/05 11:00:36 kls Exp $
+ * $Id: receiver.h 2.1 2010/01/30 10:25:19 kls Exp $
*/
#ifndef __RECEIVER_H
@@ -14,6 +14,8 @@
#define MAXRECEIVEPIDS 64 // the maximum number of PIDs per receiver
+#define LEGACY_CRECEIVER // Code enclosed with this macro is deprecated and may be removed in a future version
+
class cReceiver {
friend class cDevice;
private:
@@ -38,20 +40,35 @@ protected:
///< will be delivered only ONCE, so the cReceiver must make sure that
///< it will be able to buffer the data if necessary.
public:
+#ifdef LEGACY_CRECEIVER
cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
- ///< Creates a new receiver for the channel with the given ChannelID with
- ///< the given Priority. Pid is a single PID (typically the video PID), while
- ///< Pids1...Pids3 are pointers to zero terminated lists of PIDs.
- ///< If any of these PIDs are 0, they will be silently ignored.
- ///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS.
+#endif
+ cReceiver(const cChannel *Channel = NULL, int Priority = -1);
+ ///< Creates a new receiver for the given Channel with the given Priority.
+ ///< If Channel is not NULL, its pids set by a call to SetPids().
+ ///< Otherwise pids can be added to the receiver by separate calls to the AddPid[s]
+ ///< functions.
+ ///< The total number of PIDs added to a receiver must not exceed MAXRECEIVEPIDS.
///< Priority may be any value in the range -99..99. Negative values indicate
///< that this cReceiver may be detached at any time (without blocking the
///< cDevice it is attached to).
- ///< The ChannelID is necessary to allow the device that will be used for this
- ///< receiver to detect and store whether the channel can be decrypted in case
- ///< this is an encrypted channel. If the channel is not encrypted or this
- ///< detection is not wanted, an invalid tChannelID may be given.
virtual ~cReceiver();
+ bool AddPid(int Pid);
+ ///< Adds the given Pid to the list of PIDs of this receiver.
+ bool AddPids(const int *Pids);
+ ///< Adds the given izero terminated list of Pids to the list of PIDs of this
+ ///< receiver.
+ bool AddPids(int Pid1, int Pid2, int Pid3 = 0, int Pid4 = 0, int Pid5 = 0, int Pid6 = 0, int Pid7 = 0, int Pid8 = 0, int Pid9 = 0);
+ ///< Adds the given Pids to the list of PIDs of this receiver.
+ bool SetPids(const cChannel *Channel);
+ ///< Sets the PIDs of this receiver to those of the given Channel,
+ ///< replacing and previously stored PIDs. If Channel is NULL, all
+ ///< PIDs will be cleared. Parameters in the Setup may control whether
+ ///< certain types of PIDs (like Dolby Digital, for instance) are
+ ///< actually set. The Channel's ID is stored and can later be retrieved
+ ///< through ChannelID(). The ChannelID is necessary to allow the device
+ ///< that will be used for this receiver to detect and store whether the
+ ///< channel can be decrypted in case this is an encrypted channel.
tChannelID ChannelID(void) { return channelID; }
bool IsAttached(void) { return device != NULL; }
///< Returns true if this receiver is (still) attached to a device.
diff --git a/recorder.c b/recorder.c
index 7d01b07..60631e0 100644
--- a/recorder.c
+++ b/recorder.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recorder.c 2.7 2009/12/06 11:34:41 kls Exp $
+ * $Id: recorder.c 2.8 2010/01/29 16:37:22 kls Exp $
*/
#include "recorder.h"
@@ -21,8 +21,8 @@
// --- cRecorder -------------------------------------------------------------
-cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids)
-:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
+cRecorder::cRecorder(const char *FileName, const cChannel *Channel, int Priority)
+:cReceiver(Channel, Priority)
,cThread("recording")
,recordingInfo(FileName)
{
@@ -32,15 +32,15 @@ cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, i
ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE, true, "Recorder");
ringBuffer->SetTimeouts(0, 100);
- cChannel *Channel = Channels.GetByChannelID(ChannelID);
- int Pid = VPid;
- int Type = Channel ? Channel->Vtype() : 0;
- if (!Pid && APids) {
- Pid = APids[0];
+
+ int Pid = Channel->Vpid();
+ int Type = Channel->Vtype();
+ if (!Pid && Channel->Apid(0)) {
+ Pid = Channel->Apid(0);
Type = 0x04;
}
- if (!Pid && DPids) {
- Pid = DPids[0];
+ if (!Pid && Channel->Dpid(0)) {
+ Pid = Channel->Dpid(0);
Type = 0x06;
}
frameDetector = new cFrameDetector(Pid, Type);
diff --git a/recorder.h b/recorder.h
index 40a3222..d11d7ad 100644
--- a/recorder.h
+++ b/recorder.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recorder.h 2.1 2009/01/06 10:44:58 kls Exp $
+ * $Id: recorder.h 2.2 2010/01/29 16:32:32 kls Exp $
*/
#ifndef __RECORDER_H
@@ -34,9 +34,9 @@ protected:
virtual void Receive(uchar *Data, int Length);
virtual void Action(void);
public:
- cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids);
- // Creates a new recorder for the channel with the given ChannelID and
- // the given Priority that will record the given PIDs into the file FileName.
+ cRecorder(const char *FileName, const cChannel *Channel, int Priority);
+ // Creates a new recorder for the given Channel and
+ // the given Priority that will record into the file FileName.
virtual ~cRecorder();
};
diff --git a/recording.c b/recording.c
index 41ad47a..ef78c40 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.c 2.21 2010/01/02 13:46:05 kls Exp $
+ * $Id: recording.c 2.22 2010/01/16 11:18:30 kls Exp $
*/
#include "recording.h"
@@ -524,8 +524,8 @@ bool cRecordingInfo::Write(void) const
struct tCharExchange { char a; char b; };
tCharExchange CharExchange[] = {
- { '~', '/' },
- { '/', '~' },
+ { FOLDERDELIMCHAR, '/' },
+ { '/', FOLDERDELIMCHAR },
{ ' ', '_' },
// backwards compatibility:
{ '\'', '\'' },
@@ -546,10 +546,10 @@ char *ExchangeChars(char *s, bool ToFileSystem)
switch (*p) {
// characters that can be mapped to other characters:
case ' ': *p = '_'; break;
- case '~': *p = '/'; break;
+ case FOLDERDELIMCHAR: *p = '/'; break;
// characters that have to be encoded:
default:
- if (strchr(InvalidChars, *p) || *p == '.' && (!*(p + 1) || *(p + 1) == '~')) { // Windows can't handle '.' at the end of file/directory names
+ if (strchr(InvalidChars, *p) || *p == '.' && (!*(p + 1) || *(p + 1) == FOLDERDELIMCHAR)) { // Windows can't handle '.' at the end of file/directory names
int l = p - s;
s = (char *)realloc(s, strlen(s) + 10);
p = s + l;
@@ -565,7 +565,7 @@ char *ExchangeChars(char *s, bool ToFileSystem)
switch (*p) {
// mapped characters:
case '_': *p = ' '; break;
- case '/': *p = '~'; break;
+ case '/': *p = FOLDERDELIMCHAR; break;
// encoded characters:
case '#': {
if (strlen(p) > 2 && isxdigit(*(p + 1)) && isxdigit(*(p + 2))) {
@@ -635,7 +635,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event)
// avoid blanks at the end:
int l = strlen(name);
while (l-- > 2) {
- if (name[l] == ' ' && name[l - 1] != '~')
+ if (name[l] == ' ' && name[l - 1] != FOLDERDELIMCHAR)
name[l] = 0;
else
break;
@@ -853,7 +853,7 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons
struct tm tm_r;
struct tm *t = localtime_r(&start, &tm_r);
char *s;
- if (Level > 0 && (s = strrchr(name, '~')) != NULL)
+ if (Level > 0 && (s = strrchr(name, FOLDERDELIMCHAR)) != NULL)
s++;
else
s = name;
@@ -867,18 +867,18 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons
New,
Delimiter,
s));
- // let's not display a trailing '~':
+ // let's not display a trailing FOLDERDELIMCHAR:
if (!NewIndicator)
stripspace(titleBuffer);
s = &titleBuffer[strlen(titleBuffer) - 1];
- if (*s == '~')
+ if (*s == FOLDERDELIMCHAR)
*s = 0;
}
else if (Level < HierarchyLevels()) {
const char *s = name;
const char *p = s;
while (*++s) {
- if (*s == '~') {
+ if (*s == FOLDERDELIMCHAR) {
if (Level--)
p = s + 1;
else
@@ -911,7 +911,7 @@ int cRecording::HierarchyLevels(void) const
const char *s = name;
int level = 0;
while (*++s) {
- if (*s == '~')
+ if (*s == FOLDERDELIMCHAR)
level++;
}
return level;
@@ -919,7 +919,7 @@ int cRecording::HierarchyLevels(void) const
bool cRecording::IsEdited(void) const
{
- const char *s = strrchr(name, '~');
+ const char *s = strrchr(name, FOLDERDELIMCHAR);
s = !s ? name : s + 1;
return *s == '%';
}
diff --git a/recording.h b/recording.h
index 663d66d..ac52ada 100644
--- a/recording.h
+++ b/recording.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.h 2.12 2010/01/02 12:10:07 kls Exp $
+ * $Id: recording.h 2.13 2010/01/16 11:16:20 kls Exp $
*/
#ifndef __RECORDING_H
@@ -18,6 +18,8 @@
#include "timers.h"
#include "tools.h"
+#define FOLDERDELIMCHAR '~'
+
extern bool VfatFileSystem;
extern int InstanceId;
diff --git a/remux.c b/remux.c
index 6d00692..070a06a 100644
--- a/remux.c
+++ b/remux.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remux.c 2.37 2009/12/29 15:56:33 kls Exp $
+ * $Id: remux.c 2.41 2010/01/30 10:43:12 kls Exp $
*/
#include "remux.h"
@@ -144,7 +144,7 @@ void TsSetTeiOnBrokenPackets(uchar *p, int l)
// --- cPatPmtGenerator ------------------------------------------------------
-cPatPmtGenerator::cPatPmtGenerator(cChannel *Channel)
+cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
{
numPmtPackets = 0;
patCounter = pmtCounter = 0;
@@ -243,7 +243,7 @@ int cPatPmtGenerator::MakeCRC(uchar *Target, const uchar *Data, int Length)
#define P_PMT_PID 0x0084 // pseudo PMT pid
#define MAXPID 0x2000 // the maximum possible number of pids
-void cPatPmtGenerator::GeneratePmtPid(cChannel *Channel)
+void cPatPmtGenerator::GeneratePmtPid(const cChannel *Channel)
{
bool Used[MAXPID] = { false };
#define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
@@ -287,7 +287,7 @@ void cPatPmtGenerator::GeneratePat(void)
IncVersion(patVersion);
}
-void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
+void cPatPmtGenerator::GeneratePmt(const cChannel *Channel)
{
// generate the complete PMT section:
uchar buf[MAX_SECTION_SIZE];
@@ -295,7 +295,7 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
numPmtPackets = 0;
if (Channel) {
int Vpid = Channel->Vpid();
- int Ppid = 0x1FFF; // no PCR pid
+ int Ppid = Channel->Ppid();
uchar *p = buf;
int i = 0;
p[i++] = 0x02; // table id
@@ -364,7 +364,7 @@ void cPatPmtGenerator::SetVersions(int PatVersion, int PmtVersion)
pmtVersion = PmtVersion & 0x1F;
}
-void cPatPmtGenerator::SetChannel(cChannel *Channel)
+void cPatPmtGenerator::SetChannel(const cChannel *Channel)
{
if (Channel) {
GeneratePmtPid(Channel);
@@ -402,6 +402,7 @@ void cPatPmtParser::Reset(void)
patVersion = pmtVersion = -1;
pmtPid = -1;
vpid = vtype = 0;
+ ppid = 0;
}
void cPatPmtParser::ParsePat(const uchar *Data, int Length)
@@ -486,6 +487,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
int NumDpids = 0;
int NumSpids = 0;
vpid = vtype = 0;
+ ppid = 0;
apids[0] = 0;
dpids[0] = 0;
spids[0] = 0;
@@ -500,6 +502,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
case 0x1B: // MPEG4
vpid = stream.getPid();
vtype = stream.getStreamType();
+ ppid = Pmt.getPCRPid();
break;
case 0x03: // STREAMTYPE_11172_AUDIO
case 0x04: // STREAMTYPE_13818_AUDIO
@@ -842,10 +845,12 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
// determine frame info:
if (isVideo) {
if (Delta % 3600 == 0)
- frameDuration = 3600; // PAL, 25 fps
+ frameDuration = 3600; // PAL, 25 fps, exact timing
+ else if (abs(Delta % 3600) == 3599 || abs(Delta % 3600) == 1)
+ frameDuration = 3600; // PAL, 25 fps, timing with jitter
else if (Delta % 3003 == 0)
frameDuration = 3003; // NTSC, 29.97 fps
- else if (Delta == 1800) {
+ else if (abs(Delta - 1800) <= 1) {
frameDuration = 3600; // PAL, 25 fps
framesPerPayloadUnit = -2;
}
diff --git a/remux.h b/remux.h
index 39d6e09..1115c4a 100644
--- a/remux.h
+++ b/remux.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remux.h 2.23 2009/12/29 15:53:54 kls Exp $
+ * $Id: remux.h 2.24 2010/01/29 16:51:26 kls Exp $
*/
#ifndef __REMUX_H
@@ -172,16 +172,16 @@ protected:
int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
int MakeLanguageDescriptor(uchar *Target, const char *Language);
int MakeCRC(uchar *Target, const uchar *Data, int Length);
- void GeneratePmtPid(cChannel *Channel);
+ void GeneratePmtPid(const cChannel *Channel);
///< Generates a PMT pid that doesn't collide with any of the actual
///< pids of the Channel.
void GeneratePat(void);
///< Generates a PAT section for later use with GetPat().
- void GeneratePmt(cChannel *Channel);
+ void GeneratePmt(const cChannel *Channel);
///< Generates a PMT section for the given Channel, for later use
///< with GetPmt().
public:
- cPatPmtGenerator(cChannel *Channel = NULL);
+ cPatPmtGenerator(const cChannel *Channel = NULL);
void SetVersions(int PatVersion, int PmtVersion);
///< Sets the version numbers for the generated PAT and PMT, in case
///< this generator is used to, e.g., continue a previously interrupted
@@ -191,7 +191,7 @@ public:
///< higher bits will automatically be cleared.
///< SetVersions() needs to be called before SetChannel() in order to
///< have an effect from the very start.
- void SetChannel(cChannel *Channel);
+ void SetChannel(const cChannel *Channel);
///< Sets the Channel for which the PAT/PMT shall be generated.
uchar *GetPat(void);
///< Returns a pointer to the PAT section, which consists of exactly
@@ -213,6 +213,7 @@ private:
int pmtVersion;
int pmtPid;
int vpid;
+ int ppid;
int vtype;
int apids[MAXAPIDS + 1]; // list is zero-terminated
int atypes[MAXAPIDS + 1]; // list is zero-terminated
@@ -252,6 +253,9 @@ public:
int Vpid(void) const { return vpid; }
///< Returns the video pid as defined by the current PMT, or 0 if no video
///< pid has been detected, yet.
+ int Ppid(void) const { return ppid; }
+ ///< Returns the PCR pid as defined by the current PMT, or 0 if no PCR
+ ///< pid has been detected, yet.
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.
diff --git a/runvdr b/runvdr.template
index 1c3cc7e..8eb21cf 100755
--- a/runvdr
+++ b/runvdr.template
@@ -20,10 +20,20 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: runvdr 2.0 2006/05/14 16:02:05 kls Exp $
+# $Id: runvdr 2.1 2010/01/17 12:39:27 kls Exp $
VDRPRG="./vdr"
-VDRCMD="$VDRPRG -w 60 $*"
+
+VDROPTIONS="-w 60"
+# For other options see manpage vdr.1
+
+VDRPLUGINS=""
+# You will need to select your output device plugin if you want
+# to use VDR to watch video. For instance, for a "Full Featured"
+# DVB card that would be
+# VDRPLUGINS="-P dvbsddevice"
+
+VDRCMD="$VDRPRG $VDROPTIONS $VDRPLUGINS $*"
KILL="/usr/bin/killall -q -TERM"
diff --git a/svdrp.c b/svdrp.c
index b181fcd..cb9a935 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 2.7 2010/01/03 15:41:26 kls Exp $
+ * $Id: svdrp.c 2.8 2010/01/17 12:23:31 kls Exp $
*/
#include "svdrp.h"
@@ -79,7 +79,7 @@ bool cSocket::Open(void)
struct sockaddr_in name;
name.sin_family = AF_INET;
name.sin_port = htons(port);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
+ name.sin_addr.s_addr = SVDRPhosts.LocalhostOnly() ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
LOG_ERROR;
Close();
diff --git a/timers.c b/timers.c
index a684bb4..246fd86 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 2.3 2009/08/09 12:43:20 kls Exp $
+ * $Id: timers.c 2.4 2010/01/16 11:18:53 kls Exp $
*/
#include "timers.h"
@@ -301,7 +301,7 @@ bool cTimer::Parse(const char *s)
//TODO add more plausibility checks
result = ParseDay(daybuffer, day, weekdays);
if (VfatFileSystem) {
- char *p = strrchr(filebuffer, '~');
+ char *p = strrchr(filebuffer, FOLDERDELIMCHAR);
if (p)
p++;
else
diff --git a/transfer.c b/transfer.c
index 02ef042..096fda3 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,17 +4,17 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: transfer.c 2.4 2009/12/06 14:22:23 kls Exp $
+ * $Id: transfer.c 2.5 2010/01/30 11:10:25 kls Exp $
*/
#include "transfer.h"
// --- cTransfer -------------------------------------------------------------
-cTransfer::cTransfer(tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids)
-:cReceiver(ChannelID, -1, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
+cTransfer::cTransfer(const cChannel *Channel)
+:cReceiver(Channel)
{
- patPmtGenerator.SetChannel(Channels.GetByChannelID(ChannelID));
+ patPmtGenerator.SetChannel(Channel);
}
cTransfer::~cTransfer()
@@ -55,8 +55,8 @@ void cTransfer::Receive(uchar *Data, int Length)
cDevice *cTransferControl::receiverDevice = NULL;
-cTransferControl::cTransferControl(cDevice *ReceiverDevice, tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids)
-:cControl(transfer = new cTransfer(ChannelID, VPid, APids, DPids, SPids), true)
+cTransferControl::cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel)
+:cControl(transfer = new cTransfer(Channel), true)
{
ReceiverDevice->AttachReceiver(transfer);
receiverDevice = ReceiverDevice;
diff --git a/transfer.h b/transfer.h
index be75fde..004d5b0 100644
--- a/transfer.h
+++ b/transfer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: transfer.h 2.1 2008/05/25 12:44:49 kls Exp $
+ * $Id: transfer.h 2.2 2010/01/29 16:38:09 kls Exp $
*/
#ifndef __TRANSFER_H
@@ -21,7 +21,7 @@ protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
public:
- cTransfer(tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids);
+ cTransfer(const cChannel *Channel);
virtual ~cTransfer();
};
@@ -30,7 +30,7 @@ private:
cTransfer *transfer;
static cDevice *receiverDevice;
public:
- cTransferControl(cDevice *ReceiverDevice, tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids);
+ cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel);
~cTransferControl();
virtual void Hide(void) {}
static cDevice *ReceiverDevice(void) { return receiverDevice; }
diff --git a/vdr.5 b/vdr.5
index 875a7de..4b2cb90 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 2.11 2010/01/03 13:37:07 kls Exp $
+.\" $Id: vdr.5 2.13 2010/01/31 12:59:50 kls Exp $
.\"
.TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
.SH NAME
@@ -489,6 +489,46 @@ Note that the color keys will only execute their macro function
in "normal viewing" mode (i.e. when no other menu or player is active). The
\fIUser1\fR...\fIUser9\fR keys will always execute their macro function.
There may be up to 15 keys in such a key sequence.
+.SS FOLDERS
+The file \fIfolders.conf\fR contains the definitions of folders that can be used
+in the "Edit timer" menu. Each line contains one folder definition. Leading whitespace
+and everything after and including a '#' is ignored. A line ending with '{'
+defines a sub folder (i.e. a folder that contains other folders), and a line
+consisting of only '}' ends the definition of a sub folder.
+
+Example:
+
+Daily {
+.br
+ News
+.br
+ Soaps
+.br
+ }
+.br
+Archive {
+.br
+ Movies
+.br
+ Sports
+.br
+ Sci-Fi {
+.br
+ Star Trek
+.br
+ U.F.O.
+.br
+ }
+.br
+ }
+.br
+Comedy
+.br
+Science
+
+Note that these folder definitions are only used to set the file name under which
+a timer will store its recording. Changing these definitions in any way has no
+effect on existing timers or recordings.
.SS COMMANDS
The file \fIcommands.conf\fR contains the definitions of commands that can
be executed from the \fBvdr\fR main menu's "Commands" option.
@@ -506,6 +546,24 @@ to make sure they are not executed inadvertently.
Everything following (and including) a '#' character is considered to be comment.
+You can have nested layers of command menus by surrounding a sequence of
+commands with '{'...'}' and giving it a title, as in
+
+My Commands {
+.br
+ First list {
+ Do something: some command
+ Do something else: another command
+ }
+ Second list {
+ Even more: yet another command
+ So much more: and yet another one
+ }
+.br
+ }
+
+Command lists can be nested to any depth.
+
By default the menu entries in the "Commands" menu will be numbered '1'...'9'
to make them selectable by pressing the corresponding number key. If you want
to use your own numbering scheme (maybe to skip certain numbers), just precede
diff --git a/vdr.c b/vdr.c
index e1bfc16..e077301 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
- * $Id: vdr.c 2.14 2010/01/02 11:52:40 kls Exp $
+ * $Id: vdr.c 2.16 2010/01/31 11:14:40 kls Exp $
*/
#include <getopt.h>
@@ -582,11 +582,12 @@ int main(int argc, char *argv[])
Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC);
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true);
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
- Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true);
- RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true);
+ Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"));
+ RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"));
SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true);
Keys.Load(AddDirectory(ConfigDirectory, "remote.conf"));
KeyMacros.Load(AddDirectory(ConfigDirectory, "keymacros.conf"), true);
+ Folders.Load(AddDirectory(ConfigDirectory, "folders.conf"));
if (!*cFont::GetFontFileName(Setup.FontOsd)) {
const char *msg = "no fonts available - OSD will not show any text!";