From c36eeee589a610f093b3b95c555cc110baf27c3c Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 10 Nov 2005 01:00:20 +0000 Subject: [PATCH] I18n improvements. German translation added. Centre text justify. Options code improvements --- Makefile | 4 + box.cc | 5 + box.h | 1 + command.cc | 4 +- i18n.cc | 451 +++++++++++------------------------------------- i18n.h | 121 ++++++------- language-data.h | 350 +++++++++++++++++++++++++++++++++++++ message.h | 1 + surface.cc | 18 ++ surface.h | 1 + tcp.cc | 4 + vconnect.cc | 9 +- vinfo.cc | 22 ++- vinfo.h | 4 + voptions.cc | 123 ++++++++----- voptions.h | 22 +-- vquestion.cc | 4 +- vvideolive.cc | 2 +- vwelcome.cc | 51 ++++-- vwelcome.h | 5 +- 20 files changed, 716 insertions(+), 486 deletions(-) create mode 100644 language-data.h diff --git a/Makefile b/Makefile index d3ed82b..dd29a01 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,10 @@ OBJECTS = main.o command.o log.o remote.o led.o mtd.o video.o audio.o tcp.o dire default: dev fresh: clean default +temp: + $(CC) -E $(CXXFLAGS_DEV) -c i18n.cc + + vompclient: $(OBJECTS) $(CC) $(LDFLAGS) $(LIBPATHS) $(RELEASE) -o vompclient $(OBJECTS) $(CROSSLIBS) $(LIBS) diff --git a/box.cc b/box.cc index ef441a4..3c7a5d5 100644 --- a/box.cc +++ b/box.cc @@ -200,6 +200,11 @@ void Box::drawTextRJ(char* text, int x, int y, Colour& colour) surface->drawTextRJ(text, offsetX + x, offsetY + y, colour.red, colour.green, colour.blue); } +void Box::drawTextCentre(char* text, int x, int y, Colour& colour) +{ + surface->drawTextCentre(text, offsetX + x, offsetY + y, colour.red, colour.green, colour.blue); +} + void Box::drawPixel(UINT x, UINT y, Colour& colour) { int c = ( (0xFF000000 ) diff --git a/box.h b/box.h index cbefd60..50d5598 100644 --- a/box.h +++ b/box.h @@ -51,6 +51,7 @@ class Box void rectangle(int x1, int y1, int x2, int y2, Colour& colour); void drawText(char* text, int x, int y, Colour& colour); void drawTextRJ(char* text, int x, int y, Colour& colour); + void drawTextCentre(char* text, int x, int y, Colour& colour); void drawPixel(UINT x, UINT y, Colour& colour); int getScreenX(); diff --git a/command.cc b/command.cc index ee9cf36..a200193 100644 --- a/command.cc +++ b/command.cc @@ -251,7 +251,7 @@ void Command::doReboot() void Command::doJustConnected(VConnect* vconnect) { - I18n::Initialize(); + I18n::initialize(); Video* video = Video::getInstance(); viewman->removeView(vconnect, 0); @@ -262,7 +262,7 @@ void Command::doJustConnected(VConnect* vconnect) else vi->setScreenPos(160, 150); - vi->setMainText(tr("\n Connected, loading config")); + vi->setOneLiner(tr("Connected, loading config")); vi->draw(); vi->show(); viewman->add(vi); diff --git a/i18n.cc b/i18n.cc index 5b60efe..4c04d83 100644 --- a/i18n.cc +++ b/i18n.cc @@ -1,349 +1,102 @@ -/* - * i18n.c: Internationalization - * - * This code is taken from the VDR project and modified for VOMP. - * See the main source file 'vdr.c' for original copyright information. - * Modifications (C) 2005 D Pickles. - - This file is part of VOMP. - - VOMP is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - VOMP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with VOMP; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * How to add a new language: - * - * 1. Announce your translation action on the VOMP mailing - * list to avoid duplicate work. - * 2. Increase the value of 'NUM_LANGUAGES' in i18n.h. - * 3. Insert a new line in the 'Languages' array containing the name of your - * language IN YOUR LANGUAGE, so 'Italiano' not 'Italian' for example. - * Append your language after the last existing language - * but before the 'test' language - * 4. Insert a new line in the charSets array containing the name of the character - * set needed for your language. Note that at present only ISO8859-1 is - * supported - * 5. Insert a new line in the languageCodes array containing the 3-letter - * abbreviation(s) for your language as used in the channels.conf. - * 6. Insert a line in evry member of the 'Phrases[]' array, - * containing the translated text for your language. You can use the 'test' - * language to see where the phrases appear on the screen. - * 7. Add the name of your language to the i18nLanguages array in voptions.h. - * 8. If your language requires a character set other than the default iso8859-1 - * then work will be needed elsewhere in vomp to manage multiple font files. - * 9. Compile VOMP and test the new language by switching to it - * in the "Options" menu. - *10. Send the modified files to Chris to have it included in the next version. - * - * In case an English phrase is used in more than one context (and might need - * different translations in other languages) it can be preceeded with an - * arbitrary string to describe its context, separated from the actual phrase - * by a '$' character (see for instance "Button$Stop" vs. "Stop"). - * Of course this means that no English phrase may contain the '$' character! - * If this should ever become necessary, the existing '$' would have to be - * replaced with something different... - */ - -#include "i18n.h" -#include "log.h" -#include "vdr.h" - - // The names of the languages (English MUST be first!): -static char *Languages[] = - { "English", - "Test" - }; - - // The character set needed for each language: -const static char *charSets[] = - { "iso8859-1", - "iso8859-1" - }; - - // The 3-letter names of the language (this MUST be the third phrase!): -const char *languageCodes[] = - { "eng,dos", - "tst,xxx" - }; - - // The phrases to be translated: - -const static tI18nPhrase Phrases[] = { - // Menu titles: - { "VDR", - "VDR", - }, - { "Schedule", - "0", - }, - // Welcome screen - { "Welcome", - "1", - }, - { "1. Live TV", - "2", - }, - { "2. Radio", - "3", - }, - { "3. Recordings", - "4", - }, - { "4. Options", - "5", - }, - { "5. Stand by", - "6", - }, - { "6. Reboot", - "7", - }, - { "\n Downloading recordings list", - "8", - }, - // Recordings list - { "Recordings - %s", - "9 - %s", - }, - { "Recordings", - "10", - }, - { " %lu\t%s", - "11 %lu\t%s", - }, - { "[ok] = menu", - "12", - }, - { "%lu%% used, %iGB free", - "13 %lu%% %i", - }, - { "%i to %i of %i", // Also used in channels list - "14 %i %i %i", - }, - // Question - { "Yes", - "15", - }, - { "No", - "16", - }, - // Recording Menu - { "Programme menu", - "17", - }, - { "Play", - "18", - }, - { "Resume", - "19", - }, - { "Summary", - "20", - }, - { "Delete", - "21", - }, - { "Programme summary", - "22", - }, - { "Summary unavailable", - "23", - }, - { "Delete recording", - "24", - }, - { "Are you sure you want to delete this recording?", - "25", - }, - // Server select - { "Choose a VDR server", - "26", - }, - - // Option menus - { "Options", - "27", - }, - { "TV connection type", - "28", - }, - { "Remote control type", - "29", - }, - { "TV aspect ratio", - "30", - }, - { "16:9 on 4:3 display mode", - "30a", - }, - { "Power state after bootup", - "31", - }, - { "Display channels", - "32", - }, - { "Language", - "33", - }, - { "Press back to exit, <, > or [ok] to change", - "34", - }, - { "VDR-Pri 0=OK !See forums!", - "34a", - }, - // Option choices - { "Old", - "35", - }, - { "New", - "36", - }, - { "RGB+composite", - "37", - }, - { "S-Video", - "38", - }, - { "Chop sides", - "39", - }, - { "Letterbox", - "40", - }, - { "Last state", - "41", - }, - { "All", - "42", - }, - { "FTA only", - "43", - }, - { "On", - "44", - }, - { "Off", - "45", - }, - - // Channel Lists - { "Channels", - "46", - }, - { "Radio Stations", - "47", - }, - // Banners - { "No channel data available", - "48", - }, - { "info", - "49", - }, - { "info", - "50", - }, - { "\n Channel unavailable", - "51", - }, - // Connect screen - { "\n Locating server", - "52", - }, - { "\n Connecting to VDR", - "53", - }, - { "\n Login failed", - "54", - }, - { "\n Connection failed", - "55", - }, - // Command - { "\n Connected, loading config", - "56", - }, - // End marker. - { NULL } - }; - - static int LanguageID = INITIAL_LANGUAGE_INDEX; - - -int I18n::Initialize(void) { - - VDR *vdr = VDR::getInstance(); - char *lang = vdr->configLoad("General", "Language"); - if (lang) { - LanguageID = LanguageIndex(lang); - if (LanguageID == -1) { - LanguageID = 0; - } - } - else { - LanguageID = LanguageIndex(INITIAL_LANGUAGE); - } - return LanguageID; -} - -char *I18n::Translate(char *s) -{ - if (LanguageID >= 0) { - const tI18nPhrase *p = Phrases; - for (int i = ((p == Phrases) ? 1 : 2); i--; ) { - for (; **p; p++) { - if (strcmp(s, **p) == 0) { - char *t = (*p)[LanguageID]; - if (t && *t) return t; - } - } - p = Phrases; - } - Log::getInstance()->log("I18n", Log::ERR, "no translation found for '%s' in language %d (%s)\n", - s, LanguageID, LanguageName(LanguageID)); - } - char *p = strchr(s, '$'); - return p ? p + 1 : s; -} - -const char * const * I18n::CharSets(void) -{ - return charSets; -} - -const char * I18n::LanguageCode(int Index) -{ - return 0 <= Index && Index < I18nNumLanguages ? languageCodes[Index] : NULL; -} - -char * I18n::LanguageName(int Index) -{ - return 0 <= Index && Index < I18nNumLanguages ? Languages[Index] : NULL; -} - -int I18n::LanguageIndex(const char *Name) -{ - for (int i = 0; i < I18nNumLanguages; i++) { - if (strcasestr(Languages[i], Name)) - return i; - } - Log::getInstance()->log("I18n", Log::ERR, "unknown language: '%s'", Name); - return -1; -} - -int I18n::GetNumLanguages(void) { - return I18nNumLanguages; -} - +/* + * i18n.c: Internationalization + * + * This code is taken from the VDR project and modified for VOMP. + * See the main source file 'vdr.c' for original copyright information. + * Modifications (C) 2005 D Pickles. + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "i18n.h" +#include "language-data.h" + +int I18n::LanguageID = DEFAULT_LANGUAGE_INDEX; + +int I18n::initialize(void) +{ + VDR *vdr = VDR::getInstance(); + char *lang = vdr->configLoad("General", "Language"); + if (lang) + { + LanguageID = LanguageIndex(lang); + if (LanguageID == -1) + { + LanguageID = 0; + } + } + else + { + LanguageID = DEFAULT_LANGUAGE_INDEX; + } + return LanguageID; +} + +char* I18n::translate(char* s) +{ + if (LanguageID >= 0) + { + const tI18nPhrase *p = Phrases; + for (int i = ((p == Phrases) ? 1 : 2); i--; ) + { + for (; **p; p++) + { + if (strcmp(s, **p) == 0) + { + char *t = (*p)[LanguageID]; + if (t && *t) return t; + } + } + p = Phrases; + } + Log::getInstance()->log("I18n", Log::ERR, "No translation found for '%s' in language %d (%s)", + s, LanguageID, LanguageName(LanguageID)); + } + + char *p = strchr(s, '$'); + return p ? p + 1 : s; +} + +const char* const * I18n::CharSets(void) +{ + return charSets; +} + +const char* const I18n::LanguageCode(int Index) +{ + return 0 <= Index && Index < NumLanguages ? languageCodes[Index] : NULL; +} + +const char* I18n::LanguageName(int Index) +{ + return 0 <= Index && Index < NumLanguages ? Languages[Index] : NULL; +} + +int I18n::LanguageIndex(const char* Name) +{ + for (int i = 0; i < NumLanguages; i++) + { + if (strcasestr(Languages[i], Name)) return i; + } + Log::getInstance()->log("I18n", Log::ERR, "Unknown language: '%s'", Name); + return -1; +} + +int I18n::GetNumLanguages(void) +{ + return NumLanguages; +} diff --git a/i18n.h b/i18n.h index f34b00a..0bc8515 100644 --- a/i18n.h +++ b/i18n.h @@ -1,58 +1,63 @@ -/* - * i18n.h: Internationalization - * - * This code is taken from the VDR project and modified for VOMP. - * See the main source file 'vdr.c' for original copyright information. - * Modifications (C) 2005 D Pickles. - - This file is part of VOMP. - - VOMP is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - VOMP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with VOMP; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __I18N_H -#define __I18N_H - -#include - -#define NUM_LANGUAGES 2 -#define INITIAL_LANGUAGE "English" -#define INITIAL_LANGUAGE_INDEX 0 -#define tr(s) I18n::Translate(s) - - -typedef char *tI18nPhrase[NUM_LANGUAGES]; - - -class I18n -{ - public: - static char *Translate(char *s); - const char * const * CharSets(void); - const char * LanguageCode(int Index); - static int Initialize(void); - - static char * LanguageName(int Index); - static int LanguageIndex(const char *Name); - static int GetNumLanguages(void); - - private: - - const static int I18nNumLanguages = NUM_LANGUAGES; -}; - - -#endif //__I18N_H - +/* + * i18n.h: Internationalization + * + * This code is taken from the VDR project and modified for VOMP. + * See the main source file 'vdr.c' for original copyright information. + * Modifications (C) 2005 D Pickles. + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef I18N_H +#define I18N_H + +#include +#include "log.h" +#include "vdr.h" + +#define I18N_HEADER +#include "language-data.h" +#undef I18N_HEADER + +#define tr(s) I18n::translate(s) + +class I18n +{ + public: + static int initialize(void); + static char* translate(char* s); + + static const char* LanguageName(int index); + static int LanguageIndex(const char* name); + static int GetNumLanguages(void); + + const char* const * CharSets(void); + const char* const LanguageCode(int Index); + + const static int NumLanguages = NUM_LANGUAGES; + const static char* const Languages[]; + + private: + static int LanguageID; + const static char* const charSets[]; + const static char* const languageCodes[]; + typedef char* tI18nPhrase[NumLanguages]; + const static tI18nPhrase Phrases[]; +}; + + +#endif diff --git a/language-data.h b/language-data.h new file mode 100644 index 0000000..47bef6f --- /dev/null +++ b/language-data.h @@ -0,0 +1,350 @@ +/* + * i18n.h: Internationalization + * + * This code is taken from the VDR project and modified for VOMP. + * See the main source file 'vdr.c' for original copyright information. + * Modifications (C) 2005 D Pickles. + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * How to add a new language: + * + * 1. Announce your translation action on the VOMP forum + * to avoid duplicate work. + * 2. Increase the value of 'NUM_LANGUAGES' below. + * 3. Insert a new line in the 'Languages' array containing the name of your + * language IN YOUR LANGUAGE, so 'Italiano' not 'Italian' for example. + * Append your language after the last existing language + * but before the 'test' language + * 4. Insert a new line in the charSets array containing the name of the character + * set needed for your language. Note that at present only ISO8859-1 is + * supported + * 5. Insert a new line in the languageCodes array containing the 3-letter + * abbreviation(s) for your language as used in the channels.conf. + * 6. Insert a line in every member of the 'Phrases[]' array, + * containing the translated text for your language. You can use the 'test' + * language to see where the phrases appear on the screen. + * 7. If your language requires a character set other than the default iso8859-1 + * then work will be needed elsewhere in vomp to manage multiple font files. + * 8. Compile VOMP and test the new language by switching to it + * in the "Options" menu. + * 9. Send the modified files to Chris to have it included in the next version. + * + * In case an English phrase is used in more than one context (and might need + * different translations in other languages) it can be preceeded with an + * arbitrary string to describe its context, separated from the actual phrase + * by a '$' character (see for instance "Button$Stop" vs. "Stop"). + * Of course this means that no English phrase may contain the '$' character! + * If this should ever become necessary, the existing '$' would have to be + * replaced with something different... + */ + +#ifdef I18N_HEADER + +#define NUM_LANGUAGES 3 +#define DEFAULT_LANGUAGE_INDEX 0 + +#else + +// The names of the languages (English MUST be first!): +const char* const I18n::Languages[] = +{ + "English", + "Deutsch", // By André Jagusch + "Test" +}; + +// The character set needed for each language: +const char* const I18n::charSets[] = +{ + "iso8859-1", + "iso8859-1", + "iso8859-1" +}; + +// The 3-letter names of the language (this MUST be the third phrase!): +const char* const I18n::languageCodes[] = +{ + "eng,dos", + "deu,ger", + "tst,xxx" +}; + +// The phrases to be translated: +const I18n::tI18nPhrase I18n::Phrases[] = +{ + // Menu titles: + { "VDR", + "VDR", + "VDR", + }, + { "Schedule", + "Programm", + "0", + }, + // Welcome screen + { "Welcome", + "Willkommen", + "1", + }, + { "1. Live TV", + "1. Fernsehen", + "2", + }, + { "2. Radio", + "2. Radio", + "3", + }, + { "3. Recordings", + "3. Aufnahmen", + "4", + }, + { "4. Options", + "4. Einstellungen", + "5", + }, + { "5. Stand by", + "5. Stand-by", + "6", + }, + { "6. Reboot", + "6. Neustart", + "7", + }, + { "Downloading recordings list", + "Lade die Aufnahmen-Liste", + "8", + }, + // Recordings list + { "Recordings - %s", + "Aufnahmen - %s", + "9 - %s", + }, + { "Recordings", + "Aufnahmen", + "10", + }, + { " %lu\t%s", + " %lu\t%s", + "11 %lu\t%s", + }, + { "[ok] = menu", + "[ok] = Menü", + "12", + }, + { "%lu%% used, %iGB free", + "%lu%% belegt, %iGB frei", + "13 %lu%% %i", + }, + { "%i to %i of %i", // Also used in channels list + "%i bis %i (von %i)", + "14 %i %i %i", + }, + // Question + { "Yes", + "Ja", + "15", + }, + { "No", + "Nein", + "16", + }, + // Recording Menu + { "Programme menu", + "Programm-Menü", + "17", + }, + { "Play", + "Wiedergeben", + "18", + }, + { "Resume", + "Fortsetzen", + "19", + }, + { "Summary", + "Inhalt", + "20", + }, + { "Delete", + "Löschen", + "21", + }, + { "Programme summary", + "Programminhalt", + "22", + }, + { "Summary unavailable", + "Inhalt nicht verfügbar", + "23", + }, + { "Delete recording", + "Aufnahme löschen", + "24", + }, + { "Are you sure you want to delete this recording?", + "Sind Sie sich sicher, dass Sie diese Aufnahme löschen möchten?", + "25", + }, + // Server select + { "Choose a VDR server", + "Wählen Sie einen VDR-Server", + "26", + }, + + // Option menus + { "Options", + "Einstellungen", + "27", + }, + { "TV connection type", + "TV-Anschlußart", + "28", + }, + { "Remote control type", + "Fernbedienungstyp", + "29", + }, + { "TV aspect ratio", + "Seitenverhältnis", + "30", + }, + { "16:9 on 4:3 display mode", + "16:9 auf 4:3-Modus", + "30a", + }, + { "Power state after bootup", + "Einschalten nach Neustart", + "31", + }, + { "Display channels", + "Kanäle anzeigen", + "32", + }, + { "Language", + "Sprache", + "33", + }, + { "Press back to exit, <, > or [ok] to change", + "Zum Verlassen back drpcken, <, > oder [ok] zum Wechseln", + "34", + }, + { "VDR-Pri 0=OK !See forums!", + "VDR-Pri 0=OK !Siehe Forum!", + "34a", + }, + // Option choices + { "Old", + "Alt", + "35", + }, + { "New", + "Neu", + "36", + }, + { "RGB+composite", + "RGB+composite", + "37", + }, + { "S-Video", + "S-Video", + "38", + }, + { "Chop sides", + "Seiten abschneiden", + "39", + }, + { "Letterbox", + "Letterbox", + "40", + }, + { "Last state", + "Letzter Zustand", + "41", + }, + { "All", + "Alle", + "42", + }, + { "FTA only", + "nur FTA", + "43", + }, + { "On", + "An", + "44", + }, + { "Off", + "Aus", + "45", + }, + + // Channel Lists + { "Channels", + "Fernsehkanäle", + "46", + }, + { "Radio Stations", + "Radiokanäle", + "47", + }, + // Banners + { "No channel data available", + "Keine Daten für diesen Kanal verfügbar", + "48", + }, + { "info", + "Info", + "49", + }, + { "info", + "Info", + "50", + }, + { "Channel unavailable", + "Kanal nicht verfügbar", + "51", + }, + // Connect screen + { "Locating server", + "Lokalisiere Server", + "52", + }, + { "Connecting to VDR", + "Verbinde zum VDR", + "53", + }, + { "Login failed", + "Login fehlgeschlagen", + "54", + }, + { "Connection failed", + "Verbindung fehlgeschlagen", + "55", + }, + // Command + { "Connected, loading config", + "Verbunden, lade Einstellungen", + "56", + }, + // End marker. + { NULL } +}; + +#endif diff --git a/message.h b/message.h index 2624faa..844b1f1 100644 --- a/message.h +++ b/message.h @@ -54,6 +54,7 @@ class Message const static ULONG CHANNEL_DOWN = 15; const static ULONG STREAM_END = 16; const static ULONG CHILD_CLOSE = 17; + const static ULONG REDRAW_LANG = 18; }; #endif diff --git a/surface.cc b/surface.cc index 9f6c54e..6ba701d 100644 --- a/surface.cc +++ b/surface.cc @@ -362,6 +362,24 @@ int Surface::drawTextRJ(char* text, int x, int y, int r, int g, int b) else return drawText(text, x, y, r, g, b); } +int Surface::drawTextCentre(char* text, int x, int y, int r, int g, int b) +{ + int i, n, w; + w = 0; + + n = strlen(text); + + for (i = 0; i < n; i++) + { + w += font->width[text[i]]; + } + + x -= w / 2; + + if (x < 0) return 0; + else return drawText(text, x, y, r, g, b); +} + int Surface::getCharWidth(char c) { return font->width[c]; diff --git a/surface.h b/surface.h index ac11deb..5eaef78 100644 --- a/surface.h +++ b/surface.h @@ -185,6 +185,7 @@ class Surface int drawText(char* text, int x, int y, int r, int g, int b); int drawTextRJ(char* text, int x, int y, int r, int g, int b); + int drawTextCentre(char* text, int x, int y, int r, int g, int b); int getCharWidth(char c); void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b); void yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb); diff --git a/tcp.cc b/tcp.cc index f6a4edf..a9939e9 100644 --- a/tcp.cc +++ b/tcp.cc @@ -64,6 +64,10 @@ int TCP::connectTo(char* host, unsigned short port) oldflags |= O_NONBLOCK; fcntl(sock, F_SETFL, oldflags); + // Set receive window + size_t rxBufferSize = 2048; + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rxBufferSize, sizeof(size_t)); + // ok, how to open a connection in non blocking mode (and therefore have a self set timeout!!) int success = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); diff --git a/vconnect.cc b/vconnect.cc index 9f025a5..d4480bd 100644 --- a/vconnect.cc +++ b/vconnect.cc @@ -72,7 +72,7 @@ void VConnect::threadMethod() do { - setMainText(tr("\n Locating server")); + setOneLiner(tr("Locating server")); draw(); show(); @@ -113,7 +113,7 @@ void VConnect::threadMethod() for(UINT k = 0; k < serverIPs.size(); k++) delete[] serverIPs[k]; serverIPs.clear(); - setMainText(tr("\n Connecting to VDR")); + setOneLiner(tr("Connecting to VDR")); draw(); show(); @@ -125,21 +125,20 @@ void VConnect::threadMethod() if (success) { - // setMainText("\n Connected"); ts.tv_sec = 0; ts.tv_nsec = 000000000; } else { vdr->disconnect(); - setMainText(tr("\n Login failed")); + setOneLiner(tr("Login failed")); ts.tv_sec = 3; ts.tv_nsec = 0; } } else { - setMainText(tr("\n Connection failed")); + setOneLiner(tr("Connection failed")); ts.tv_sec = 3; ts.tv_nsec = 0; } diff --git a/vinfo.cc b/vinfo.cc index bb43cff..a687c73 100644 --- a/vinfo.cc +++ b/vinfo.cc @@ -51,13 +51,33 @@ void VInfo::setMainText(char* takeText) int length = strlen(takeText); mainText = new char[length + 1]; strcpy(mainText, takeText); + mainTextType = NORMAL; +} + +void VInfo::setOneLiner(char* takeText) +{ + int length = strlen(takeText); + mainText = new char[length + 1]; + strcpy(mainText, takeText); + mainTextType = ONELINER; } void VInfo::draw() { View::draw(); - if (mainText) drawPara(mainText, 10, 45, Colour::LIGHTTEXT); + if (mainText) + { + if (mainTextType == NORMAL) + { + drawPara(mainText, 10, 45, Colour::LIGHTTEXT); + } + + if (mainTextType == ONELINER) + { + drawTextCentre(mainText, area.w / 2, 75, Colour::LIGHTTEXT); + } + } } int VInfo::handleCommand(int command) diff --git a/vinfo.h b/vinfo.h index c33cecd..5a8b286 100644 --- a/vinfo.h +++ b/vinfo.h @@ -36,6 +36,7 @@ class VInfo : public View virtual ~VInfo(); void setMainText(char* title); + void setOneLiner(char* text); void setExitable(); void setDropThrough(); @@ -46,6 +47,9 @@ class VInfo : public View char* mainText; UCHAR exitable; UCHAR dropThrough; + UCHAR mainTextType; + const static UCHAR NORMAL = 1; + const static UCHAR ONELINER = 2; }; #endif diff --git a/voptions.cc b/voptions.cc index bb1e6a8..171069c 100644 --- a/voptions.cc +++ b/voptions.cc @@ -22,14 +22,14 @@ VOptions::VOptions() { - create(500, 75+(NUM_OPTIONS*30)); + create(530, 85+(NUM_OPTIONS*30)); if (Video::getInstance()->getFormat() == Video::PAL) { - setScreenPos(120, 140); + setScreenPos(104, 130); } else { - setScreenPos(110, 80); + setScreenPos(94, 70); } setBackgroundColour(Colour::VIEWBACKGROUND); @@ -43,14 +43,12 @@ VOptions::VOptions() for (i = 0; i < numOptions; i++) { optionBox[i].setSurface(surface); - optionBox[i].setSurfaceOffset(330, 45 + (i * 30)); + optionBox[i].setSurfaceOffset(346, 45 + (i * 30)); optionBox[i].setDimensions(150, fontHeight); for (UINT j = 0; j < optionData[i].optionCount; j++) { - Log::getInstance()->log("Options", Log::DEBUG, "Add option"); Log::getInstance()->log("Options", Log::DEBUG, "Add option: %s", optionData[i].options[j]); - optionBox[i].addOption(tr(optionData[i].options[j])); - Log::getInstance()->log("Options", Log::DEBUG, "Done add option"); + optionBox[i].addOption(tr((char*)optionData[i].options[j])); } } @@ -59,7 +57,7 @@ VOptions::VOptions() for (i = 0; i < numOptions; i++) { - optionBox[i].setSelected(tr(optionData[i].options[optionData[i].defaultOption])); + optionBox[i].setSelected(tr((char*)optionData[i].options[optionData[i].defaultOption])); config = vdr->configLoad(optionData[i].configSection, optionData[i].configParam); if (config) { @@ -67,19 +65,28 @@ VOptions::VOptions() { if (!strcasecmp(config, optionData[i].options[j])) { - optionBox[i].setSelected(tr(optionData[i].options[j])); + optionBox[i].setSelected(tr((char*)optionData[i].options[j])); } } delete[] config; } } + // After setup, save all current indexes + optionsAtStart = new int[numOptions]; + + for (i = 0; i < numOptions; i++) + { + optionsAtStart[i] = optionBox[i].getSelectedIndex(); + } + selectedOption = 0; optionBox[0].setActive(1); } VOptions::~VOptions() { + delete[] optionsAtStart; } void VOptions::draw() @@ -89,7 +96,7 @@ void VOptions::draw() WSymbol wsy; Colour cl; - drawText(tr("Press back to exit, <, > or [ok] to change"), 10, 45+numOptions*30, Colour::LIGHTTEXT); + drawText(tr("Press back to exit, <, > or [ok] to change"), 10, 55+numOptions*30, Colour::LIGHTTEXT); wsy.setSurface(surface); @@ -103,10 +110,10 @@ void VOptions::draw() wsy.nextSymbol = WSymbol::LEFTARROW; wsy.nextColour = cl; - wsy.setSurfaceOffset(312, 47 + (i * 30)); + wsy.setSurfaceOffset(328, 47 + (i * 30)); wsy.draw(); wsy.nextSymbol = WSymbol::RIGHTARROW; - wsy.setSurfaceOffset(482, 47 + (i * 30)); + wsy.setSurfaceOffset(498, 47 + (i * 30)); wsy.draw(); optionBox[i].draw(); optionBox[i].show(); @@ -182,56 +189,82 @@ void VOptions::doSave() for (UINT i = 0; i < numOptions; i++) { result[i] = optionBox[i].getSelectedIndex(); - vdr->configSave(optionData[i].configSection, optionData[i].configParam, - optionData[i].options[result[i]]); + + if (result[i] != optionsAtStart[i]) + { + Log::getInstance()->log("Options", Log::DEBUG, "Option %i has changed", i); + + vdr->configSave(optionData[i].configSection, optionData[i].configParam, + optionData[i].options[result[i]]); + } } // Apply changes Video* video = Video::getInstance(); - if (result[0] == 1) + if (result[0] != optionsAtStart[0]) { - Log::getInstance()->log("Options", Log::DEBUG, "Setting New Remote"); - Remote::getInstance()->setRemoteType(Remote::NEWREMOTE); - } - else - { - Log::getInstance()->log("Options", Log::DEBUG, "Setting Old Remote"); - Remote::getInstance()->setRemoteType(Remote::OLDREMOTE); + if (result[0] == 1) + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting New Remote"); + Remote::getInstance()->setRemoteType(Remote::NEWREMOTE); + } + else + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting Old Remote"); + Remote::getInstance()->setRemoteType(Remote::OLDREMOTE); + } } - if (result[2] == 1) - { - Log::getInstance()->log("Options", Log::DEBUG, "Setting S-Video"); - video->setConnection(Video::SVIDEO); - } - else + if (result[1] != optionsAtStart[1]) { - Log::getInstance()->log("Options", Log::DEBUG, "Setting RGB/Composite"); - video->setConnection(Video::COMPOSITERGB); + I18n::initialize(); + Message *m = new Message(); + m->to = VWelcome::getInstance(); + m->message = Message::REDRAW_LANG; + ViewMan::getInstance()->postMessage(m); } - if (result[3] == 1) + if (result[2] != optionsAtStart[2]) { - Log::getInstance()->log("Options", Log::DEBUG, "Setting 16:9 TV"); - video->setTVsize(Video::ASPECT16X9); - } - else - { - Log::getInstance()->log("Options", Log::DEBUG, "Setting 4:3 TV"); - video->setTVsize(Video::ASPECT4X3); + if (result[2] == 1) + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting S-Video"); + video->setConnection(Video::SVIDEO); + } + else + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting RGB/Composite"); + video->setConnection(Video::COMPOSITERGB); + } } - if (result[4] == 1) + if (result[3] != optionsAtStart[3]) { - Log::getInstance()->log("Options", Log::DEBUG, "Setting letterbox"); - video->setMode(Video::LETTERBOX); + if (result[3] == 1) + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting 16:9 TV"); + video->setTVsize(Video::ASPECT16X9); + } + else + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting 4:3 TV"); + video->setTVsize(Video::ASPECT4X3); + } } - else + + if (result[4] != optionsAtStart[4]) { - Log::getInstance()->log("Options", Log::DEBUG, "Setting chop-sides"); - video->setMode(Video::NORMAL); + if (result[4] == 1) + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting letterbox"); + video->setMode(Video::LETTERBOX); + } + else + { + Log::getInstance()->log("Options", Log::DEBUG, "Setting chop-sides"); + video->setMode(Video::NORMAL); + } } - I18n::Initialize(); } diff --git a/voptions.h b/voptions.h index 1c1fd54..5745110 100644 --- a/voptions.h +++ b/voptions.h @@ -30,6 +30,7 @@ #include "woptionbox.h" #include "wsymbol.h" #include "i18n.h" +#include "vwelcome.h" #define NUM_OPTIONS 8 typedef struct @@ -39,22 +40,21 @@ typedef struct char *configParam; // Parameter name in the config file UINT optionCount; // How many choices? UINT defaultOption; // Serial of the default choice (base 0) - char **options; // Text for the options + const char * const * options; // Text for the options } OPTIONDATA; -static char* options0[] = {"Old", "New"}; -static char* options1[] = {"RGB+composite", "S-Video"}; -static char* options2[] = {"4:3", "16:9"}; -static char* options3[] = {"Chop sides", "Letterbox"}; -static char* options4[] = {"On", "Off", "Last state"}; -static char* options5[] = {"All", "FTA only"}; -static char* options6[] = {"0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "99"}; -static char *i18nLanguages[] = { "English", "Test" }; +static const char* options0[] = {"Old", "New"}; +static const char* options1[] = {"RGB+composite", "S-Video"}; +static const char* options2[] = {"4:3", "16:9"}; +static const char* options3[] = {"Chop sides", "Letterbox"}; +static const char* options4[] = {"On", "Off", "Last state"}; +static const char* options5[] = {"All", "FTA only"}; +static const char* options6[] = {"0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "99"}; const static OPTIONDATA optionData[NUM_OPTIONS] = { {"Remote control type", "General", "Remote type", 2, 0, options0 }, - {"Language", "General", "Language", NUM_LANGUAGES, 0, i18nLanguages }, + {"Language", "General", "Language", I18n::NumLanguages, 0, I18n::Languages }, {"TV connection type", "TV", "Connection", 2, 0, options1 }, {"TV aspect ratio", "TV", "Aspect", 2, 0, options2 }, {"16:9 on 4:3 display mode", "TV", "Widemode", 2, 0, options3 }, @@ -79,6 +79,8 @@ class VOptions : public View UINT selectedOption; WOptionBox optionBox[numOptions]; VDR* vdr; + int* optionsAtStart; }; #endif + diff --git a/vquestion.cc b/vquestion.cc index d34c4de..de8f6ff 100644 --- a/vquestion.cc +++ b/vquestion.cc @@ -25,8 +25,8 @@ VQuestion::VQuestion() mainText = NULL; selectedOption = NO; - buttonYes.setSurfaceOffset(40, 120); - buttonNo.setSurfaceOffset(140, 120); + buttonYes.setSurfaceOffset(40, 130); + buttonNo.setSurfaceOffset(140, 130); buttonYes.setText(tr("Yes")); buttonNo.setText(tr("No")); diff --git a/vvideolive.cc b/vvideolive.cc index bb0c33a..e0475c7 100644 --- a/vvideolive.cc +++ b/vvideolive.cc @@ -188,7 +188,7 @@ void VVideoLive::showUnavailable(int active) unavailableView->setScreenPos(160, 150); } unavailableView->setTitleText((*chanList)[currentChannel]->name); - unavailableView->setMainText(tr("\n Channel unavailable")); + unavailableView->setOneLiner(tr("Channel unavailable")); unavailableView->setDropThrough(); Message* m = new Message(); diff --git a/vwelcome.cc b/vwelcome.cc index 313be10..ade1c41 100644 --- a/vwelcome.cc +++ b/vwelcome.cc @@ -20,8 +20,12 @@ #include "vwelcome.h" +VWelcome* VWelcome::instance = NULL; + VWelcome::VWelcome() { + instance = this; + create(460, 200); if (Video::getInstance()->getFormat() == Video::PAL) { @@ -32,34 +36,44 @@ VWelcome::VWelcome() setScreenPos(130, 140); } - sl.setSurface(surface); - jpeg.setSurface(surface); - setBackgroundColour(Colour::VIEWBACKGROUND); setTitleBarOn(1); setTitleBarColour(Colour::TITLEBARBACKGROUND); - setTitleText(tr("Welcome")); + sl.setSurface(surface); sl.setSurfaceOffset(20, 40); sl.setDimensions(170, 140); + jpeg.setSurface(surface); + jpeg.setSurfaceOffset(240, 60); + + setup(); +} + +VWelcome::~VWelcome() +{ + instance = NULL; +} + +VWelcome* VWelcome::getInstance() +{ + return instance; +} + +void VWelcome::setup() +{ + sl.clear(); + setTitleText(tr("Welcome")); sl.addOption(tr("1. Live TV"), 1); sl.addOption(tr("2. Radio"), 0); sl.addOption(tr("3. Recordings"), 0); sl.addOption(tr("4. Options"), 0); sl.addOption(tr("5. Stand by"), 0); sl.addOption(tr("6. Reboot"), 0); - - jpeg.setSurfaceOffset(240, 60); -} - -VWelcome::~VWelcome() -{ } void VWelcome::draw() { - View::draw(); sl.draw(); @@ -221,7 +235,7 @@ void VWelcome::doRecordingsList() { viewWait->setScreenPos(130, 140); } - viewWait->setMainText(tr("\n Downloading recordings list")); + viewWait->setOneLiner(tr("Downloading recordings list")); viewWait->draw(); viewWait->show(); viewman->addNoLock(viewWait); @@ -253,3 +267,16 @@ void VWelcome::doOptions() voptions->draw(); voptions->show(); } + +void VWelcome::processMessage(Message* m) +{ + if (m->message == Message::REDRAW_LANG) + { + Log::getInstance()->log("VWelcome", Log::DEBUG, "Got redraw lang message"); + setup(); + draw(); + show(); // careful, this only works properly because the only place + // this is called from is voptions and that disappears before + // this message is delivered + } +} diff --git a/vwelcome.h b/vwelcome.h index e78f01a..e90242f 100644 --- a/vwelcome.h +++ b/vwelcome.h @@ -45,12 +45,15 @@ class VWelcome : public View public: VWelcome(); ~VWelcome(); + static VWelcome* getInstance(); + void setup(); int handleCommand(int command); + void processMessage(Message* m); void draw(); private: - + static VWelcome* instance; WSelectList sl; WJpeg jpeg; -- 2.39.2