diff --git a/FORMATS b/FORMATS index 331fe3d5..a86cfd2c 100644 --- a/FORMATS +++ b/FORMATS @@ -47,8 +47,11 @@ Video Disk Recorder File Formats ----F-- = Friday -----S- = Saturday ------S = Sunday - (any combination is possible, for example MTWTF--) or the "day of month" (1..31) - - Star time (first two digits for the hour, second two digits for the minutes) + (any combination is possible, for example MTWTF--, and the days may be + indicated by any characters except '-', so for example ABC---- would set + a timer that records on monday, tuesday and wednesday) or the "day of month" + (1..31) + - Start time (first two digits for the hour, second two digits for the minutes) - End time (first two digits for the hour, second two digits for the minutes) - Priority (from 00 to 99, 00 = lowest prioity, 99 = highest priority) - Guaranteed lifetime of recording (in days) diff --git a/HISTORY b/HISTORY index cc1170ec..5f00ea1e 100644 --- a/HISTORY +++ b/HISTORY @@ -266,9 +266,11 @@ Video Disk Recorder Revision History are programmed via the "Schedules" menu) are now replaced by suitable substitutes. -2000-11-05: Version 0.68 +2000-11-11: Version 0.68 - Date and time in the title of an event info page are now always right adjusted. - The 'current channel' is now handled device specific (in case there is more than one DVB card). - The 'SetSystemTime' option in the "Setup" menu is now shown as "yes/no". +- Implemented "internationalization" (see 'i18n.c' for information on how to + add new languages). diff --git a/MANUAL b/MANUAL index ffcc10b8..b3f1cc72 100644 --- a/MANUAL +++ b/MANUAL @@ -228,6 +228,10 @@ Video Disk Recorder User's Manual displayed as "no" and "yes" in the "Setup" menu, while in the setup file they are stored as '0' and '1', respectively): + OSDLanguage = 0 Defines the language used to display the OSD texts. + 0 = Englisch + 1 = Deutsch + PrimaryDVB = 1 Defines the primary DVB interface (i.e. the one that will display the menus and will react on input through the remote control). Valid values range from '1' to the diff --git a/Makefile b/Makefile index 9db79f39..55038e1a 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,12 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.14 2000/10/28 16:24:16 kls Exp $ +# $Id: Makefile 1.15 2000/11/11 09:59:56 kls Exp $ DVBDIR = ../DVB INCLUDES = -I$(DVBDIR)/driver -OBJS = config.o dvbapi.o dvbosd.o eit.o font.o interface.o menu.o osd.o\ +OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o osd.o\ recording.o remote.o svdrp.o thread.o tools.o vdr.o videodir.o OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1 @@ -35,20 +35,21 @@ font: genfontfile fontosd.c # Dependencies: -config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h +config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h videodir.h dvbosd.o : dvbosd.c dvbosd.h font.h tools.h eit.o : eit.c eit.h thread.h tools.h font.o : font.c font.h fontosd.c tools.h -interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h -menu.o : menu.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h -osd.o : osd.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h osd.h remote.h svdrp.h thread.h tools.h +i18n.o : i18n.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h thread.h tools.h +interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h +menu.o : menu.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h +osd.o : osd.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h osd.h remote.h svdrp.h thread.h tools.h recording.o: recording.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h recording.h remote.h svdrp.h thread.h tools.h videodir.h remote.o : remote.c config.h dvbapi.h dvbosd.h eit.h font.h remote.h thread.h tools.h svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h thread.o : thread.c thread.h tools.o : tools.c tools.h -vdr.o : vdr.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h videodir.h +vdr.o : vdr.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h videodir.h videodir.o : videodir.c tools.h videodir.h # The main program: diff --git a/config.c b/config.c index 8d6415b5..0da6ebf5 100644 --- a/config.c +++ b/config.c @@ -4,13 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.30 2000/11/05 18:18:30 kls Exp $ + * $Id: config.c 1.31 2000/11/11 09:56:01 kls Exp $ */ #include "config.h" #include #include #include "dvbapi.h" +#include "i18n.h" #include "interface.h" // -- cKeys ------------------------------------------------------------------ @@ -270,7 +271,7 @@ bool cChannel::Switch(cDvbApi *DvbApi) return false; } if (DvbApi->Recording()) - Interface->Info("Channel locked (recording)!"); + Interface->Info(tr("Channel locked (recording)!")); return false; } @@ -405,7 +406,7 @@ const char *cTimer::PrintDay(int d) static char buffer[8]; if ((d & 0x80000000) != 0) { char *b = buffer; - char *w = "MTWTFSS"; + const char *w = tr("MTWTFSS"); *b = 0; while (*w) { *b++ = (d & 1) ? *w : '-'; @@ -650,6 +651,7 @@ char *cSetup::fileName = NULL; cSetup::cSetup(void) { + OSDLanguage = 0; PrimaryDVB = 1; ShowInfoOnChSwitch = 1; MenuScrollPage = 1; @@ -667,7 +669,8 @@ bool cSetup::Parse(char *s) char *Name = strtok(s, Delimiters); char *Value = strtok(NULL, Delimiters); if (Name && Value) { - if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); + if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value); + else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value); else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value); @@ -717,6 +720,7 @@ bool cSetup::Save(const char *FileName) FILE *f = fopen(FileName, "w"); if (f) { fprintf(f, "# VDR Setup\n"); + fprintf(f, "OSDLanguage = %d\n", OSDLanguage); fprintf(f, "PrimaryDVB = %d\n", PrimaryDVB); fprintf(f, "ShowInfoOnChSwitch = %d\n", ShowInfoOnChSwitch); fprintf(f, "MenuScrollPage = %d\n", MenuScrollPage); diff --git a/config.h b/config.h index 32e92720..679e88ed 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 1.30 2000/11/05 13:17:03 kls Exp $ + * $Id: config.h 1.31 2000/11/11 10:39:00 kls Exp $ */ #ifndef __CONFIG_H @@ -18,7 +18,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "0.67" +#define VDRVERSION "0.68" #define MaxBuffer 10000 @@ -229,6 +229,7 @@ private: bool Parse(char *s); public: // Also adjust cMenuSetup (menu.c) when adding parameters here! + int OSDLanguage; int PrimaryDVB; int ShowInfoOnChSwitch; int MenuScrollPage; diff --git a/i18n.c b/i18n.c new file mode 100644 index 00000000..06b1241d --- /dev/null +++ b/i18n.c @@ -0,0 +1,366 @@ +/* + * i18n.c: Internationalization + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: i18n.c 1.1 2000/11/11 10:39:27 kls Exp $ + */ + +/* + * How to add a new language: + * + * 1. Announce your translation action on the Linux-DVB mailing + * list to avoid duplicate work. + * 2. Increase the value of 'NumLanguages'. + * 3. Add a new line to every member of the 'Phrases[]' array, + * containing the translated text for the new language. + * For example, assuming you want to add the Italian language, + * + * { "English", + * "Deutsch", + * }, + * + * would become + * + * { "English", + * "Deutsch", + * "Italiano", + * }, + * + * and so on. + * Note that only the characters defined in 'fontosd.c' will + * be available! + * 4. Compile VDR and test the new language by switching to it + * in the "Setup" menu. + * 5. Send the modified 'i18n.c' file to to have + * it included in the next version of VDR. + */ + +#include "i18n.h" +#include +#include "config.h" +#include "tools.h" + +const int NumLanguages = 2; + +typedef const char *tPhrase[NumLanguages]; + +const tPhrase Phrases[] = { + // The name of the language (this MUST be the first phrase!): + { "English", + "Deutsch", + }, + // Menu titles: + { "Main", + "Hauptmenü", + }, + { "Schedule", + "Programm", + }, + { "Channels", + "Kanäle", + }, + { "Timers", + "Timer", + }, + { "Recordings", + "Aufzeichnungen", + }, + { "Setup", + "Einstellungen", + }, + { "Edit Channel", + "Kanal Editieren", + }, + { "Edit Timer", + "Timer Editieren", + }, + { "Event", + "Sendung", + }, + { "Summary", + "Inhalt", + }, + { "Schedule - %s", + "Programm - %s", + }, + { "What's on now?", + "Was läuft jetzt?", + }, + { "What's on next?", + "Was läuft als nächstes?", + }, + // Button texts (must not be more than 10 characters!): + { "Edit", + "Editieren", + }, + { "New", + "Neu", + }, + { "Delete", + "Löschen", + }, + { "Mark", + "Markieren", + }, + { "Record", + "Aufnehmen", + }, + { "Play", + "Wiedergabe", + }, + { "Resume", + "Weiter", + }, + { "Summary", + "Inhalt", + }, + { "Switch", + "Umschalten", + }, + { "Now", + "Jetzt", + }, + { "Next", + "Nächste", + }, + { "Schedule", + "Programm", + }, + // Confirmations: + { "Delete Channel?", + "Kanal löschen?", + }, + { "Delete Timer?", + "Timer löschen?", + }, + { "Delete Recording?", + "Aufzeichnung löschen?", + }, + { "Stop Recording?", + "Aufzeichnung beenden?", + }, + // Channel parameters: + { "Name", + "Name", + }, + { "Frequency", + "Frequenz", + }, + { "Polarization", + "Polarisation", + }, + { "Diseqc", + "Diseqc", + }, + { "Srate", + "Srate", + }, + { "Vpid", + "Vpid", + }, + { "Apid", + "Apid", + }, + { "CA", + "CA", + }, + { "Pnr", + "Pnr", + }, + // Timer parameters: + { "Active", + "Aktiv", + }, + { "Channel", + "Kanal", + }, + { "Day", + "Tag", + }, + { "Start", + "Anfang", + }, + { "Stop", + "Ende", + }, + { "Priority", + "Priorität", + }, + { "Lifetime", + "Lebensdauer", + }, + { "File", + "Datei", + }, + // Error messages: + { "Channel is being used by a timer!", + "Kanal wird von einem Timer benutzt", + }, + { "Can't switch channel!", + "Kanal kann nicht umgeschaltet werden!", + }, + { "Timer is recording!", + "Timer zeichnet gerade auf!", + }, + { "Error while deleting recording!", + "Fehler beim Löschen der Aufzeichnung!", + }, + { "*** Invalid Channel ***", + "*** Ungültiger Kanal ***", + }, + { "No free DVB device to record!", + "Keine freie DVB-Karte zum Aufnehmen!", + }, + { "Channel locked (recording)!", + "Kanal blockiert (zeichnet auf)!", + }, + // Setup parameters: + { "OSD-Language", + "OSD-Sprache", + }, + { "PrimaryDVB", + "Primäres Interface", + }, + { "ShowInfoOnChSwitch", + "Info zeigen", + }, + { "MenuScrollPage", + "Seitenweise scrollen", + }, + { "MarkInstantRecord", + "Direktaufz. markieren", + }, + { "LnbFrequLo", + "Untere LNB-Frequenz", + }, + { "LnbFrequHi", + "Obere LNB-Frequenz", + }, + { "SetSystemTime", + "Systemzeit stellen", + }, + { "MarginStart", + "Zeitpuffer bei Anfang", + }, + { "MarginStop", + "Zeitpuffer bei Ende", + }, + // The days of the week: + { "MTWTFSS", + "MDMDFSS", + }, + // Learning keys: + { "Learning Remote Control Keys", + "Fernbedienungs-Codes lernen", + }, + { "Phase 1: Detecting RC code type", + "Phase 1: FB Code feststellen", + }, + { "Press any key on the RC unit", + "Eine Taste auf der FB drücken", + }, + { "RC code detected!", + "FB Code erkannt!", + }, + { "Do not press any key...", + "Keine Taste drücken...", + }, + { "Phase 2: Learning specific key codes", + "Phase 2: Einzelne Tastencodes lernen", + }, + { "Press key for '%s'", + "Taste für '%s' drücken", + }, + { "Press 'Up' to confirm", + "'Auf' drücken zum Bestätigen", + }, + { "Press 'Down' to continue", + "'Ab' drücken zum Weitermachen", + }, + { "(press 'Up' to go back)", + "('Auf' drücken um zurückzugehen)", + }, + { "(press 'Down' to end key definition)", + "('Ab' drücken zum Beenden", + }, + { "Phase 3: Saving key codes", + "Phase 3: Codes abspeichern", + }, + { "Press 'Up' to save, 'Down' to cancel", + "'Auf' speichert, 'Ab' bricht ab", + }, + // Key names: + { "Up", + "Auf", + }, + { "Down", + "Ab", + }, + { "Menu", + "Menü", + }, + { "Ok", + "Ok", + }, + { "Back", + "Zurück", + }, + { "Left", + "Links", + }, + { "Right", + "Rechts", + }, + { "Red", + "Rot", + }, + { "Green", + "Grün", + }, + { "Yellow", + "Gelb", + }, + { "Blue", + "Blau", + }, + // Miscellaneous: + { "yes", + "ja", + }, + { "no", + "nein", + }, + { "Stop replaying", + "Wiedergabe beenden", + }, + { "Stop recording ", // note the trailing blank! + "Aufzeichnung beenden ", + }, + { "Switching primary DVB...", + "Primäres Interface wird umgeschaltet...", + }, + { "Up/Dn for new location - OK to move", + "Auf/Ab für neue Position, dann OK", + }, + { NULL } + }; + +const char *tr(const char *s) +{ + if (Setup.OSDLanguage) { + for (const tPhrase *p = Phrases; **p; p++) { + if (strcmp(s, **p) == 0) + return (*p)[Setup.OSDLanguage]; + } + esyslog(LOG_ERR, "no translation found for '%s' in language %d (%s)\n", s, Setup.OSDLanguage, Phrases[0][Setup.OSDLanguage]); + } + return s; +} + +const char * const * Languages(void) +{ + return &Phrases[0][0]; +} + diff --git a/i18n.h b/i18n.h new file mode 100644 index 00000000..c94241a5 --- /dev/null +++ b/i18n.h @@ -0,0 +1,19 @@ +/* + * i18n.h: Internationalization + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: i18n.h 1.1 2000/11/11 09:27:25 kls Exp $ + */ + +#ifndef __I18N_H +#define __I18N_H + +extern const int NumLanguages; + +const char *tr(const char *s); + +const char * const * Languages(void); + +#endif //__I18N_H diff --git a/interface.c b/interface.c index ee8a78cb..65008f1b 100644 --- a/interface.c +++ b/interface.c @@ -4,12 +4,13 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.29 2000/11/05 12:50:44 kls Exp $ + * $Id: interface.c 1.30 2000/11/10 17:03:02 kls Exp $ */ #include "interface.h" #include #include +#include "i18n.h" cInterface *Interface = NULL; @@ -321,9 +322,9 @@ void cInterface::QueryKeys(void) { Keys.Clear(); Clear(); - WriteText(1, 1, "Learning Remote Control Keys"); - WriteText(1, 3, "Phase 1: Detecting RC code type"); - WriteText(1, 5, "Press any key on the RC unit"); + WriteText(1, 1, tr("Learning Remote Control Keys")); + WriteText(1, 3, tr("Phase 1: Detecting RC code type")); + WriteText(1, 5, tr("Press any key on the RC unit")); cDvbApi::PrimaryDvbApi->Flush(); #ifndef REMOTE_KBD unsigned char Code = 0; @@ -338,8 +339,8 @@ void cInterface::QueryKeys(void) if (rcIo->DetectCode(&Code, &Address)) { Keys.code = Code; Keys.address = Address; - WriteText(1, 5, "RC code detected!"); - WriteText(1, 6, "Do not press any key..."); + WriteText(1, 5, tr("RC code detected!")); + WriteText(1, 6, tr("Do not press any key...")); cDvbApi::PrimaryDvbApi->Flush(); rcIo->Flush(3000); ClearEol(0, 5); @@ -349,11 +350,11 @@ void cInterface::QueryKeys(void) } #endif } - WriteText(1, 3, "Phase 2: Learning specific key codes"); + WriteText(1, 3, tr("Phase 2: Learning specific key codes")); tKey *k = Keys.keys; while (k->type != kNone) { char *Prompt; - asprintf(&Prompt, "Press key for '%s'", k->name); + asprintf(&Prompt, tr("Press key for '%s'"), tr(k->name)); WriteText(1, 5, Prompt); delete Prompt; for (;;) { @@ -365,8 +366,8 @@ void cInterface::QueryKeys(void) break; } case kDown: if (k > Keys.keys + 1) { - WriteText(1, 5, "Press 'Up' to confirm"); - WriteText(1, 6, "Press 'Down' to continue"); + WriteText(1, 5, tr("Press 'Up' to confirm")); + WriteText(1, 6, tr("Press 'Down' to continue")); ClearEol(0, 7); ClearEol(0, 8); for (;;) { @@ -391,11 +392,11 @@ void cInterface::QueryKeys(void) } } if (k > Keys.keys) - WriteText(1, 7, "(press 'Up' to go back)"); + WriteText(1, 7, tr("(press 'Up' to go back)")); else ClearEol(0, 7); if (k > Keys.keys + 1) - WriteText(1, 8, "(press 'Down' to end key definition)"); + WriteText(1, 8, tr("(press 'Down' to end key definition)")); else ClearEol(0, 8); } @@ -409,9 +410,9 @@ void cInterface::LearnKeys(void) Clear(); QueryKeys(); Clear(); - WriteText(1, 1, "Learning Remote Control Keys"); - WriteText(1, 3, "Phase 3: Saving key codes"); - WriteText(1, 5, "Press 'Up' to save, 'Down' to cancel"); + WriteText(1, 1, tr("Learning Remote Control Keys")); + WriteText(1, 3, tr("Phase 3: Saving key codes")); + WriteText(1, 5, tr("Press 'Up' to save, 'Down' to cancel")); for (;;) { eKeys key = GetKey(); if (key == kUp) { diff --git a/menu.c b/menu.c index 42ce0aaa..8b3a2e55 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 1.43 2000/11/05 18:41:09 kls Exp $ + * $Id: menu.c 1.44 2000/11/11 09:58:12 kls Exp $ */ #include "menu.h" @@ -14,6 +14,7 @@ #include #include "config.h" #include "eit.h" +#include "i18n.h" #define MENUTIMEOUT 120 // seconds @@ -131,7 +132,7 @@ cMenuEditBoolItem::cMenuEditBoolItem(const char *Name, int *Value) void cMenuEditBoolItem::Set(void) { char buf[16]; - snprintf(buf, sizeof(buf), "%s", *value ? "yes" : "no"); + snprintf(buf, sizeof(buf), "%s", *value ? tr("yes") : tr("no")); SetValue(buf); } @@ -493,6 +494,29 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key) return osContinue; } +// --- cMenuEditStraItem ----------------------------------------------------- + +class cMenuEditStraItem : public cMenuEditIntItem { +private: + const char * const *strings; +protected: + virtual void Set(void); +public: + cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings); + }; + +cMenuEditStraItem::cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings) +:cMenuEditIntItem(Name, Value, 0, NumStrings - 1) +{ + strings = Strings; + Set(); +} + +void cMenuEditStraItem::Set(void) +{ + SetValue(strings[*value]); +} + // --- cMenuEditChannel ------------------------------------------------------ class cMenuEditChannel : public cOsdMenu { @@ -505,20 +529,20 @@ public: }; cMenuEditChannel::cMenuEditChannel(int Index) -:cOsdMenu("Edit Channel", 14) +:cOsdMenu(tr("Edit Channel"), 14) { channel = Channels.Get(Index); if (channel) { data = *channel; - Add(new cMenuEditStrItem( "Name", data.name, sizeof(data.name), FileNameChars)); - Add(new cMenuEditIntItem( "Frequency", &data.frequency, 10000, 13000)); //TODO exact limits??? - Add(new cMenuEditChrItem( "Polarization", &data.polarization, "hv")); - Add(new cMenuEditIntItem( "Diseqc", &data.diseqc, 0, 10)); //TODO exact limits??? - Add(new cMenuEditIntItem( "Srate", &data.srate, 22000, 27500)); //TODO exact limits - toggle??? - Add(new cMenuEditIntItem( "Vpid", &data.vpid, 0, 10000)); //TODO exact limits??? - Add(new cMenuEditIntItem( "Apid", &data.apid, 0, 10000)); //TODO exact limits??? - Add(new cMenuEditIntItem( "CA", &data.ca, 0, cDvbApi::NumDvbApis)); - Add(new cMenuEditIntItem( "Pnr", &data.pnr, 0)); + Add(new cMenuEditStrItem( tr("Name"), data.name, sizeof(data.name), FileNameChars)); + Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency, 10000, 13000)); //TODO exact limits??? + Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv")); + Add(new cMenuEditIntItem( tr("Diseqc"), &data.diseqc, 0, 10)); //TODO exact limits??? + Add(new cMenuEditIntItem( tr("Srate"), &data.srate, 22000, 27500)); //TODO exact limits - toggle??? + Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 10000)); //TODO exact limits??? + Add(new cMenuEditIntItem( tr("Apid"), &data.apid, 0, 10000)); //TODO exact limits??? + Add(new cMenuEditIntItem( tr("CA"), &data.ca, 0, cDvbApi::NumDvbApis)); + Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0)); } } @@ -589,7 +613,7 @@ public: }; cMenuChannels::cMenuChannels(void) -:cOsdMenu("Channels", 4) +:cOsdMenu(tr("Channels"), 4) { //TODO int i = 0; @@ -600,7 +624,7 @@ cMenuChannels::cMenuChannels(void) Add(new cMenuChannelItem(i, channel), i == curr); i++; } - SetHelp("Edit", "New", "Delete", "Mark"); + SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("Mark")); } eOSState cMenuChannels::Switch(void) @@ -641,11 +665,11 @@ eOSState cMenuChannels::Del(void) // Check if there is a timer using this channel: for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) { if (ti->channel == DeletedChannel) { - Interface->Error("Channel is being used by a timer!"); + Interface->Error(tr("Channel is being used by a timer!")); return osContinue; } } - if (Interface->Confirm("Delete Channel?")) { + if (Interface->Confirm(tr("Delete Channel?"))) { // Move and renumber the channels: Channels.Del(channel); Channels.ReNumber(); @@ -835,7 +859,7 @@ public: }; cMenuSummary::cMenuSummary(const char *Text) -:cOsdMenu("Summary") +:cOsdMenu(tr("Summary")) { Add(new cMenuTextItem(Text, 1, 2, MenuColumns - 2, MAXOSDITEMS)); } @@ -861,22 +885,22 @@ public: }; cMenuEditTimer::cMenuEditTimer(int Index, bool New) -:cOsdMenu("Edit Timer", 10) +:cOsdMenu(tr("Edit Timer"), 12) { timer = Timers.Get(Index); if (timer) { data = *timer; if (New) data.active = 1; - Add(new cMenuEditBoolItem("Active", &data.active)); - Add(new cMenuEditChanItem("Channel", &data.channel)); - Add(new cMenuEditDayItem( "Day", &data.day)); - Add(new cMenuEditTimeItem("Start", &data.start)); - Add(new cMenuEditTimeItem("Stop", &data.stop)); + Add(new cMenuEditBoolItem(tr("Active"), &data.active)); + Add(new cMenuEditChanItem(tr("Channel"), &data.channel)); + Add(new cMenuEditDayItem( tr("Day"), &data.day)); + Add(new cMenuEditTimeItem(tr("Start"), &data.start)); + Add(new cMenuEditTimeItem(tr("Stop"), &data.stop)); //TODO VPS??? - Add(new cMenuEditIntItem( "Priority", &data.priority, 0, 99)); - Add(new cMenuEditIntItem( "Lifetime", &data.lifetime, 0, 99)); - Add(new cMenuEditStrItem( "File", data.file, sizeof(data.file), FileNameChars)); + Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, 99)); + Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, 99)); + Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file), FileNameChars)); } } @@ -948,7 +972,7 @@ public: }; cMenuTimers::cMenuTimers(void) -:cOsdMenu("Timer", 2, 4, 10, 6, 6) +:cOsdMenu(tr("Timers"), 2, 4, 10, 6, 6) { int i = 0; cTimer *timer; @@ -957,7 +981,7 @@ cMenuTimers::cMenuTimers(void) Add(new cMenuTimerItem(i, timer)); i++; } - SetHelp("Edit", "New", "Delete", "Mark"); + SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("Mark")); } eOSState cMenuTimers::Activate(bool On) @@ -1000,7 +1024,7 @@ eOSState cMenuTimers::Del(void) cTimer *ti = Timers.Get(Index); if (ti) { if (!ti->recording) { - if (Interface->Confirm("Delete Timer?")) { + if (Interface->Confirm(tr("Delete Timer?"))) { Timers.Del(Timers.Get(Index)); cOsdMenu::Del(Index); Timers.Save(); @@ -1009,7 +1033,7 @@ eOSState cMenuTimers::Del(void) } } else - Interface->Error("Timer is recording!"); + Interface->Error(tr("Timer is recording!")); } return osContinue; } @@ -1064,7 +1088,7 @@ public: }; cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch) -:cOsdMenu("Event") +:cOsdMenu(tr("Event")) { eventInfo = EventInfo; if (eventInfo) { @@ -1086,7 +1110,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch) } if (!isempty(p = eventInfo->GetExtendedDescription())) Add(new cMenuTextItem(p, 1, Line, MenuColumns - 2, Height() - Line - 2, clrCyan), true); - SetHelp("Record", NULL, NULL, CanSwitch ? "Switch" : NULL); + SetHelp(tr("Record"), NULL, NULL, CanSwitch ? tr("Switch") : NULL); } } } @@ -1138,7 +1162,7 @@ static int CompareEventChannel(const void *p1, const void *p2) } cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now) -:cOsdMenu(Now ? "What's on now?" : "What's on next?", 4, 7, 6) +:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), 4, 7, 6) { const cSchedule *Schedule = Schedules->First(); const cEventInfo **pArray = NULL; @@ -1164,7 +1188,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now) Add(new cMenuWhatsOnItem(pArray[a])); delete pArray; - SetHelp("Record", Now ? "Next" : "Now", "Schedule", "Switch"); + SetHelp(tr("Record"), Now ? tr("Next") : tr("Now"), tr("Schedule"), tr("Switch")); } eOSState cMenuWhatsOn::Switch(void) @@ -1175,7 +1199,7 @@ eOSState cMenuWhatsOn::Switch(void) if (channel && channel->Switch()) return osEnd; } - Interface->Error("Can't switch channel!"); + Interface->Error(tr("Can't switch channel!")); return osContinue; } @@ -1242,17 +1266,17 @@ public: }; cMenuSchedule::cMenuSchedule(void) -:cOsdMenu("Schedule", 6, 6) +:cOsdMenu("", 6, 6) { now = next = false; cChannel *channel = Channels.GetByNumber(cDvbApi::CurrentChannel()); if (channel) { char *buffer = NULL; - asprintf(&buffer, "Schedule - %s", channel->name); + asprintf(&buffer, tr("Schedule - %s"), channel->name); SetTitle(buffer, false); + PrepareSchedule(); + SetHelp(tr("Record"), tr("Now"), tr("Next")); } - PrepareSchedule(); - SetHelp("Record", "Now", "Next"); } static int CompareEventTime(const void *p1, const void *p2) @@ -1347,7 +1371,7 @@ void cMenuRecordingItem::Set(void) // --- cMenuRecordings ------------------------------------------------------- cMenuRecordings::cMenuRecordings(void) -:cOsdMenu("Recordings", 6, 6) +:cOsdMenu(tr("Recordings"), 6, 6) { if (Recordings.Load()) { const char *lastReplayed = cReplayControl::LastReplayed(); @@ -1357,7 +1381,7 @@ cMenuRecordings::cMenuRecordings(void) recording = Recordings.Next(recording); } } - SetHelp("Play", NULL, "Delete", "Summary"); + SetHelp(tr("Play"), NULL, tr("Delete"), tr("Summary")); Display(); } @@ -1377,18 +1401,18 @@ eOSState cMenuRecordings::Del(void) if (ri) { //XXX what if this recording's file is currently in use??? //XXX if (!ti->recording) { - if (Interface->Confirm("Delete Recording?")) { + if (Interface->Confirm(tr("Delete Recording?"))) { if (ri->recording->Delete()) { cReplayControl::ClearLastReplayed(ri->recording->FileName()); cOsdMenu::Del(Current()); Display(); } else - Interface->Error("Error while deleting recording!"); + Interface->Error(tr("Error while deleting recording!")); } //XXX } //XXX else -//XXX Interface->Error("Timer is recording!"); +//XXX Interface->Error(tr("Timer is recording!")); } return osContinue; } @@ -1425,24 +1449,35 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) class cMenuSetup : public cOsdMenu { private: cSetup data; + int osdLanguage; + void Set(void); public: cMenuSetup(void); virtual eOSState ProcessKey(eKeys Key); }; cMenuSetup::cMenuSetup(void) -:cOsdMenu("Setup", 20) +:cOsdMenu("", 25) { data = Setup; - Add(new cMenuEditIntItem( "PrimaryDVB", &data.PrimaryDVB, 1, cDvbApi::NumDvbApis)); - Add(new cMenuEditBoolItem("ShowInfoOnChSwitch", &data.ShowInfoOnChSwitch)); - Add(new cMenuEditBoolItem("MenuScrollPage", &data.MenuScrollPage)); - Add(new cMenuEditBoolItem("MarkInstantRecord", &data.MarkInstantRecord)); - Add(new cMenuEditIntItem( "LnbFrequLo", &data.LnbFrequLo)); - Add(new cMenuEditIntItem( "LnbFrequHi", &data.LnbFrequHi)); - Add(new cMenuEditBoolItem("SetSystemTime", &data.SetSystemTime)); - Add(new cMenuEditIntItem( "MarginStart", &data.MarginStart)); - Add(new cMenuEditIntItem( "MarginStop", &data.MarginStop)); + osdLanguage = Setup.OSDLanguage; + Set(); +} + +void cMenuSetup::Set(void) +{ + Clear(); + SetTitle(tr("Setup")); + Add(new cMenuEditStraItem(tr("OSD-Language"), &data.OSDLanguage, NumLanguages, Languages())); + Add(new cMenuEditIntItem( tr("PrimaryDVB"), &data.PrimaryDVB, 1, cDvbApi::NumDvbApis)); + Add(new cMenuEditBoolItem(tr("ShowInfoOnChSwitch"), &data.ShowInfoOnChSwitch)); + Add(new cMenuEditBoolItem(tr("MenuScrollPage"), &data.MenuScrollPage)); + Add(new cMenuEditBoolItem(tr("MarkInstantRecord"), &data.MarkInstantRecord)); + Add(new cMenuEditIntItem( tr("LnbFrequLo"), &data.LnbFrequLo)); + Add(new cMenuEditIntItem( tr("LnbFrequHi"), &data.LnbFrequHi)); + Add(new cMenuEditBoolItem(tr("SetSystemTime"), &data.SetSystemTime)); + Add(new cMenuEditIntItem( tr("MarginStart"), &data.MarginStart)); + Add(new cMenuEditIntItem( tr("MarginStop"), &data.MarginStop)); } eOSState cMenuSetup::ProcessKey(eKeys Key) @@ -1451,7 +1486,7 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack; + case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osEnd; cDvbApi::PrimaryDvbApi->SetUseTSTime(data.SetSystemTime); Setup = data; Setup.Save(); @@ -1459,23 +1494,31 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) default: break; } } + if (data.OSDLanguage != osdLanguage) { + int OriginalOSDLanguage = Setup.OSDLanguage; + Setup.OSDLanguage = data.OSDLanguage; + Set(); + Display(); + osdLanguage = data.OSDLanguage; + Setup.OSDLanguage = OriginalOSDLanguage; + } return state; } // --- cMenuMain ------------------------------------------------------------- -#define STOP_RECORDING "Stop recording " +#define STOP_RECORDING tr("Stop recording ") cMenuMain::cMenuMain(bool Replaying) -:cOsdMenu("Main") +:cOsdMenu(tr("Main")) { - Add(new cOsdItem("Schedule", osSchedule)); - Add(new cOsdItem("Channels", osChannels)); - Add(new cOsdItem("Timer", osTimer)); - Add(new cOsdItem("Recordings", osRecordings)); - Add(new cOsdItem("Setup", osSetup)); + Add(new cOsdItem(tr("Schedule"), osSchedule)); + Add(new cOsdItem(tr("Channels"), osChannels)); + Add(new cOsdItem(tr("Timers"), osTimers)); + Add(new cOsdItem(tr("Recordings"), osRecordings)); + Add(new cOsdItem(tr("Setup"), osSetup)); if (Replaying) - Add(new cOsdItem("Stop replaying", osStopReplay)); + Add(new cOsdItem(tr("Stop replaying"), osStopReplay)); const char *s = NULL; while ((s = cRecordControls::GetInstantId(s)) != NULL) { char *buffer = NULL; @@ -1483,7 +1526,7 @@ cMenuMain::cMenuMain(bool Replaying) Add(new cOsdItem(buffer, osStopRecord)); delete buffer; } - SetHelp("Record", NULL, NULL, cReplayControl::LastReplayed() ? "Resume" : NULL); + SetHelp(tr("Record"), NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL); Display(); lastActivity = time(NULL); } @@ -1495,10 +1538,10 @@ eOSState cMenuMain::ProcessKey(eKeys Key) switch (state) { case osSchedule: return AddSubMenu(new cMenuSchedule); case osChannels: return AddSubMenu(new cMenuChannels); - case osTimer: return AddSubMenu(new cMenuTimers); + case osTimers: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); case osSetup: return AddSubMenu(new cMenuSetup); - case osStopRecord: if (Interface->Confirm("Stop Recording?")) { + case osStopRecord: if (Interface->Confirm(tr("Stop Recording?"))) { cOsdItem *item = Get(Current()); if (item) { cRecordControls::Stop(item->Text() + strlen(STOP_RECORDING)); @@ -1571,7 +1614,7 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel) if (Channel && Channel->number) snprintf(buffer, BufSize, "%d %s", Channel->number, Channel->name); else - snprintf(buffer, BufSize, "%s", Channel ? Channel->name : "*** Invalid Channel ***"); + snprintf(buffer, BufSize, "%s", Channel ? Channel->name : tr("*** Invalid Channel ***")); Interface->Fill(0, 0, MenuColumns, 1, clrBackground); Interface->Write(0, 0, buffer); time_t t = time(NULL); @@ -1697,7 +1740,7 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer) timer = new cTimer(true); Timers.Add(timer); Timers.Save(); - asprintf(&instantId, cDvbApi::NumDvbApis > 1 ? "%s on %d" : "%s", Channels.GetChannelNameByNumber(timer->channel), dvbApi->Index() + 1); + asprintf(&instantId, cDvbApi::NumDvbApis > 1 ? "%s - %d" : "%s", Channels.GetChannelNameByNumber(timer->channel), dvbApi->Index() + 1); } timer->SetRecording(true); Channels.SwitchTo(timer->channel, dvbApi); diff --git a/osd.c b/osd.c index f3458274..4f4f0c3a 100644 --- a/osd.c +++ b/osd.c @@ -4,12 +4,13 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.11 2000/11/01 11:21:51 kls Exp $ + * $Id: osd.c 1.12 2000/11/10 16:18:38 kls Exp $ */ #include "osd.h" #include #include +#include "i18n.h" // --- cOsdItem -------------------------------------------------------------- @@ -248,7 +249,7 @@ void cOsdMenu::Mark(void) { if (Count() && marked < 0) { marked = current; - SetStatus("Up/Dn for new location - OK to move"); + SetStatus(tr("Up/Dn for new location - OK to move")); } } diff --git a/osd.h b/osd.h index 473e87de..74794d49 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 1.14 2000/11/01 14:29:07 kls Exp $ + * $Id: osd.h 1.15 2000/11/10 15:28:28 kls Exp $ */ #ifndef __OSD_H @@ -21,7 +21,7 @@ enum eOSState { osUnknown, osContinue, osSchedule, osChannels, - osTimer, + osTimers, osRecordings, osSetup, osRecord, diff --git a/vdr.c b/vdr.c index b4230a43..e39db311 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.43 2000/11/05 18:39:17 kls Exp $ + * $Id: vdr.c 1.44 2000/11/10 16:13:27 kls Exp $ */ #include @@ -31,6 +31,7 @@ #include #include "config.h" #include "dvbapi.h" +#include "i18n.h" #include "interface.h" #include "menu.h" #include "recording.h" @@ -229,7 +230,7 @@ int main(int argc, char *argv[]) break; case osRecord: DELETENULL(Menu); if (!cRecordControls::Start()) - Interface->Error("No free DVB device to record!"); + Interface->Error(tr("No free DVB device to record!")); break; case osRecordings: DELETENULL(Menu); @@ -246,7 +247,7 @@ int main(int argc, char *argv[]) break; case osSwitchDvb: DELETENULL(*Interact); - Interface->Info("Switching primary DVB..."); + Interface->Info(tr("Switching primary DVB...")); cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB); break; case osBack: