Added support for selecting preferred EPG languages

This commit is contained in:
Klaus Schmidinger 2004-01-09 15:53:59 +01:00
parent bd38a10ff9
commit 6484771bf6
11 changed files with 278 additions and 18 deletions

View File

@ -639,6 +639,7 @@ Teemu Rantanen <tvr@iki.fi>
for fixing faulty calculation of section length in eit.c
for reporting a problem in calculation of channel ids for tv stations that use
the undefined NID value 0
for adding EPG preferred languages
Jan Ekholm <chakie@infa.abo.fi>
for adding/improving some Swedish language OSD texts

View File

@ -2555,3 +2555,5 @@ Video Disk Recorder Revision History
- Changed calculation of channel ids to make it work for tv stations that use
the undefined NID value 0 (thanks to Teemu Rantanen for reporting this one).
- Enhanced the SDT filter to handle multi part sections.
- Added support for selecting preferred EPG languages (based upon a patch by
Teemu Rantanen).

13
MANUAL
View File

@ -482,6 +482,19 @@ Version 1.2
be taken. Note that in order to set the system time from
the transponder data the option "Set system time" must also
be enabled.
Preferred languages = 0
Some tv stations broadcast their EPG data in various
different languages. This option allows you to define
which language(s) you prefer in such cases. By default,
or if none of the preferred languages is broadcast, any
language will be accepted and the EPG data will be
displayed in the first language received from the data
stream. If this option is set to a non-zero value, the
menu page will contain that many "Preferred language"
options which allow you to select the individual preferred
languages. If an actual EPG data record is received in
different languages, the preferred languages are checked
in the given order to decide which one to take.
DVB:

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.c 1.118 2004/01/05 11:45:40 kls Exp $
* $Id: config.c 1.119 2004/01/06 17:09:54 kls Exp $
*/
#include "config.h"
@ -259,6 +259,7 @@ cSetup::cSetup(void)
TimeTransponder = 0;
MarginStart = 2;
MarginStop = 10;
EPGLanguages[0] = -1;
EPGScanTimeout = 5;
EPGBugfixLevel = 2;
SVDRPTimeout = 300;
@ -395,6 +396,39 @@ bool cSetup::ParseCaCaps(const char *Value)
return false;
}
void cSetup::StoreLanguages(const char *Name, int *Values)
{
char buffer[I18nNumLanguages * 4];
char *q = buffer;
for (int i = 0; i < I18nNumLanguages; i++) {
if (Values[i] < 0)
break;
const char *s = I18nLanguageAbbreviation(Values[i]);
if (s) {
if (q > buffer)
*q++ = ' ';
strncpy(q, s, 3);
q += 3;
}
}
*q = 0;
Store(Name, buffer);
}
bool cSetup::ParseLanguages(const char *Value, int *Values)
{
int n = 0;
while (Value && *Value && n < I18nNumLanguages) {
int i = I18nLanguageIndex(Value);
if (i >= 0)
Values[n++] = i;
if ((Value = strchr(Value, ' ')) != NULL)
Value++;
}
Values[n] = -1;
return true;
}
bool cSetup::Parse(const char *Name, const char *Value)
{
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
@ -412,6 +446,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
@ -463,6 +498,7 @@ bool cSetup::Save(void)
Store("TimeTransponder", TimeTransponder);
Store("MarginStart", MarginStart);
Store("MarginStop", MarginStop);
StoreLanguages("EPGLanguages", EPGLanguages);
Store("EPGScanTimeout", EPGScanTimeout);
Store("EPGBugfixLevel", EPGBugfixLevel);
Store("SVDRPTimeout", SVDRPTimeout);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 1.181 2004/01/05 11:31:54 kls Exp $
* $Id: config.h 1.182 2004/01/06 16:47:41 kls Exp $
*/
#ifndef __CONFIG_H
@ -17,6 +17,7 @@
#include <time.h>
#include <unistd.h>
#include "device.h"
#include "i18n.h"
#include "tools.h"
#define VDRVERSION "1.3.1"
@ -195,6 +196,8 @@ class cSetup : public cConfig<cSetupLine> {
private:
void StoreCaCaps(const char *Name);
bool ParseCaCaps(const char *Value);
void StoreLanguages(const char *Name, int *Values);
bool ParseLanguages(const char *Value, int *Values);
bool Parse(const char *Name, const char *Value);
cSetupLine *Get(const char *Name, const char *Plugin = NULL);
void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false);
@ -216,6 +219,7 @@ public:
int SetSystemTime;
int TimeTransponder;
int MarginStart, MarginStop;
int EPGLanguages[I18nNumLanguages + 1];
int EPGScanTimeout;
int EPGBugfixLevel;
int SVDRPTimeout;

47
eit.c
View File

@ -8,11 +8,12 @@
* 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 1.84 2004/01/02 22:27:29 kls Exp $
* $Id: eit.c 1.85 2004/01/09 15:44:43 kls Exp $
*/
#include "eit.h"
#include "epg.h"
#include "i18n.h"
#include "libsi/section.h"
#include "libsi/descriptor.h"
@ -88,19 +89,36 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
pEvent->SetTableID(Tid);
pEvent->SetEventID(SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
int LanguagePreferenceShort = -1;
int LanguagePreferenceExt = -1;
bool UseExtendedEventDescriptor = false;
SI::Descriptor *d;
SI::ExtendedEventDescriptors exGroup;
char text[256];
SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
switch (d->getDescriptorTag()) {
case SI::ExtendedEventDescriptorTag:
exGroup.Add((SI::ExtendedEventDescriptor *)d);
d = NULL; //so that it is not deleted
case SI::ExtendedEventDescriptorTag: {
SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d;
if (I18nIsPreferredLanguage(Setup.EPGLanguages, I18nLanguageIndex(eed->languageCode), LanguagePreferenceExt) || !ExtendedEventDescriptors) {
delete ExtendedEventDescriptors;
ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
UseExtendedEventDescriptor = true;
}
if (UseExtendedEventDescriptor) {
ExtendedEventDescriptors->Add(eed);
d = NULL; // so that it is not deleted
}
if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber())
UseExtendedEventDescriptor = false;
}
break;
case SI::ShortEventDescriptorTag: {
SI::ShortEventDescriptor *sed = (SI::ShortEventDescriptor *)d;
pEvent->SetTitle(sed->name.getText(text));
pEvent->SetShortText(sed->text.getText(text));
if (I18nIsPreferredLanguage(Setup.EPGLanguages, I18nLanguageIndex(sed->languageCode), LanguagePreferenceShort) || !ShortEventDescriptor) {
delete ShortEventDescriptor;
ShortEventDescriptor = sed;
d = NULL; // so that it is not deleted
}
}
break;
case SI::ContentDescriptorTag:
@ -126,9 +144,18 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
}
if (!rEvent) {
char buffer[exGroup.getMaximumTextLength()];
pEvent->SetDescription(exGroup.getText(buffer));
if (ShortEventDescriptor) {
char buffer[256];
pEvent->SetTitle(ShortEventDescriptor->name.getText(buffer));
pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer));
}
if (ExtendedEventDescriptors) {
char buffer[ExtendedEventDescriptors->getMaximumTextLength()];
pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer));
}
}
delete ExtendedEventDescriptors;
delete ShortEventDescriptor;
pEvent->SetStartTime(SiEitEvent.getStartTime());
pEvent->SetDuration(SiEitEvent.getDuration());

18
epg.c
View File

@ -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 1.3 2004/01/04 15:20:42 kls Exp $
* $Id: epg.c 1.4 2004/01/09 15:22:18 kls Exp $
*/
#include "epg.h"
@ -486,6 +486,12 @@ bool cSchedule::SetFollowingEvent(cEvent *Event)
return true;
}
void cSchedule::ResetVersions(void)
{
for (cEvent *p = events.First(); p; p = events.Next(p))
p->SetVersion(0xFF);
}
void cSchedule::Cleanup(void)
{
Cleanup(time(NULL));
@ -613,6 +619,16 @@ void cSchedules::Cleanup(bool Force)
}
}
void cSchedules::ResetVersions(void)
{
cSchedulesLock SchedulesLock(true);
cSchedules *s = (cSchedules *)Schedules(SchedulesLock);
if (s) {
for (cSchedule *Schedule = s->First(); Schedule; Schedule = s->Next(Schedule))
Schedule->ResetVersions();
}
}
bool cSchedules::ClearAll(void)
{
cSchedulesLock SchedulesLock(true, 1000);

4
epg.h
View File

@ -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 1.3 2004/01/03 17:00:25 kls Exp $
* $Id: epg.h 1.4 2004/01/09 15:21:05 kls Exp $
*/
#ifndef __EPG_H
@ -84,6 +84,7 @@ public:
tChannelID ChannelID(void) const { return channelID; }
bool SetPresentEvent(cEvent *Event);
bool SetFollowingEvent(cEvent *Event);
void ResetVersions(void);
void Cleanup(time_t Time);
void Cleanup(void);
cEvent *AddEvent(cEvent *Event);
@ -122,6 +123,7 @@ public:
///< time the returned cSchedules is accessed. Once the cSchedules is no
///< longer used, the cSchedulesLock must be destroyed.
static void Cleanup(bool Force = false);
static void ResetVersions(void);
static bool ClearAll(void);
static bool Dump(FILE *f, const char *Prefix = "");
static bool Read(FILE *f = NULL);

92
i18n.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: i18n.c 1.138 2004/01/05 11:56:24 kls Exp $
* $Id: i18n.c 1.139 2004/01/09 15:48:03 kls Exp $
*
* Translations provided by:
*
@ -111,6 +111,24 @@ const tI18nPhrase Phrases[] = {
"iso8859-1",
"iso8859-1",
},
// The 3-letter names of the language (this MUST be the third phrase!):
{ "eng",
"deu,ger",
"slv",
"ita",
"dut,nla",
"por",
"fra,fre",
"nor",
"fin",
"pol",
"esl,spa",
"ell,gre",
"sve,swe",
"ron,rum",
"hun",
"cat,cln",
},
// Menu titles:
{ "VDR",
"VDR",
@ -2227,6 +2245,40 @@ const tI18nPhrase Phrases[] = {
"Idöhöz tartozó Transponder",
"Usar el temps del múltiplex",
},
{ "Setup.EPG$Preferred languages",
"Bevorzugte Sprachen",
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"Suosikkikielet",
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
},
{ "Setup.EPG$Preferred language",
"Bevorzugte Sprache",
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"Suosikkikieli",
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
"",// TODO
},
{ "Setup.DVB$Primary DVB interface",
"Primäres DVB Interface",
"Primarna naprava",
@ -3920,3 +3972,41 @@ const char * const * I18nCharSets(void)
{
return &Phrases[1][0];
}
const char * I18nLanguageAbbreviation(int Index)
{
return Index < I18nNumLanguages ? Phrases[2][Index] : NULL;
}
int I18nLanguageIndex(const char Code[3])
{
char s[4];
memcpy(s, Code, 3);
s[3] = 0;
for (int i = 0; i < I18nNumLanguages; i++) {
if (strcasestr(Phrases[2][i], s))
return i;
}
//dsyslog("unknown language code: '%s'", s);
return -1;
}
bool I18nIsPreferredLanguage(int *PreferredLanguages, int LanguageIndex, int &OldPreference)
{
for (int i = 0; i < I18nNumLanguages; i++) {
if (PreferredLanguages[i] < 0)
break; // the language is not a preferred one
if (PreferredLanguages[i] == LanguageIndex) {
if (OldPreference < 0 || i < OldPreference) {
OldPreference = i;
return true;
}
break;
}
}
if (OldPreference < 0) {
OldPreference = I18nNumLanguages; // higher than the maximum possible value
return true; // if we don't find a preferred one, we take the first one
}
return false;
}

5
i18n.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: i18n.h 1.7 2003/10/19 15:02:05 kls Exp $
* $Id: i18n.h 1.8 2004/01/06 15:56:53 kls Exp $
*/
#ifndef __I18N_H
@ -22,6 +22,9 @@ const char *I18nTranslate(const char *s, const char *Plugin = NULL);
const char * const * I18nLanguages(void);
const char * const * I18nCharSets(void);
const char * I18nLanguageAbbreviation(int Index);
int I18nLanguageIndex(const char Code[3]);
bool I18nIsPreferredLanguage(int *PreferredLanguages, int LanguageIndex, int &OldPreference);
#ifdef PLUGIN_NAME_I18N
#define tr(s) I18nTranslate(s, PLUGIN_NAME_I18N)

70
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 1.277 2004/01/05 11:51:33 kls Exp $
* $Id: menu.c 1.278 2004/01/09 15:42:59 kls Exp $
*/
#include "menu.h"
@ -2029,17 +2029,83 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
// --- cMenuSetupEPG ---------------------------------------------------------
class cMenuSetupEPG : public cMenuSetupBase {
private:
int originalNumLanguages;
int numLanguages;
void Setup(void);
public:
cMenuSetupEPG(void);
virtual eOSState ProcessKey(eKeys Key);
};
cMenuSetupEPG::cMenuSetupEPG(void)
{
for (numLanguages = 0; numLanguages < I18nNumLanguages && data.EPGLanguages[numLanguages] >= 0; numLanguages++)
;
originalNumLanguages = numLanguages;
SetSection(tr("EPG"));
Setup();
}
void cMenuSetupEPG::Setup(void)
{
int current = Current();
Clear();
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout));
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL));
Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime));
Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder));
if (data.SetSystemTime)
Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder));
Add(new cMenuEditIntItem( tr("Setup.EPG$Preferred languages"), &numLanguages, 0, I18nNumLanguages));
for (int i = 0; i < numLanguages; i++)
Add(new cMenuEditStraItem(tr("Setup.EPG$Preferred language"), &data.EPGLanguages[i], I18nNumLanguages, I18nLanguages()));
SetCurrent(Get(current));
Display();
}
eOSState cMenuSetupEPG::ProcessKey(eKeys Key)
{
int oldnumLanguages = numLanguages;
int oldSetSystemTime = data.SetSystemTime;
eOSState state = cMenuSetupBase::ProcessKey(Key);
if (Key == kOk) {
bool Modified = numLanguages != originalNumLanguages;
if (!Modified) {
for (int i = 0; i < numLanguages; i++) {
if (data.EPGLanguages[i] != ::Setup.EPGLanguages[i]) {
Modified = true;
break;
}
}
}
if (Modified)
cSchedules::ResetVersions();
}
else if (Key != kNone) {
if (numLanguages != oldnumLanguages || data.SetSystemTime != oldSetSystemTime) {
for (int i = oldnumLanguages; i < numLanguages; i++) {
data.EPGLanguages[i] = 0;
for (int l = 0; l < I18nNumLanguages; l++) {
int k;
for (k = 0; k < oldnumLanguages; k++) {
if (data.EPGLanguages[k] == l)
break;
}
if (k >= oldnumLanguages) {
data.EPGLanguages[i] = l;
break;
}
}
}
data.EPGLanguages[numLanguages] = -1;
Setup();
}
}
return state;
}
// --- cMenuSetupDVB ---------------------------------------------------------