Ticket #8695: translation-infrastructure2.patch
File translation-infrastructure2.patch, 42.8 KB (added by , 17 years ago) |
---|
-
configure
74 74 75 75 # more defaults 76 76 _backend=sdl 77 _translation=yes 77 78 _ranlib=ranlib 78 79 _install=install 79 80 _ar="ar cru" … … 372 373 --disable-mt32emu don't enable the integrated MT-32 emulator 373 374 --disable-hq-scalers exclude HQ2x and HQ3x scalers 374 375 --disable-scalers exclude scalers 376 --disable-translation don't build support for translated messages 375 377 376 378 Optional Libraries: 377 379 --with-alsa-prefix=DIR Prefix where alsa is installed (optional) … … 459 461 --enable-plugins) _build_plugins=yes ;; 460 462 --enable-mt32emu) _mt32emu=yes ;; 461 463 --disable-mt32emu) _mt32emu=no ;; 464 --enable-translation) _translation=yes ;; 465 --disable-translation) _translation=no ;; 462 466 --with-fluidsynth-prefix=*) 463 467 arg=`echo $ac_option | cut -d '=' -f 2` 464 468 FLUIDSYNTH_CFLAGS="-I$arg/include" … … 1277 1281 add_to_config_mk_if_no yes 'USE_MPEG2 = 1' 1278 1282 fi 1279 1283 echo "$_mpeg2" 1280 rm -f $TMPC $TMPO$EXEEXT1281 1284 1282 1285 # 1283 1286 # Check for libfluidsynth … … 1299 1302 _def_fluidsynth='#undef USE_FLUIDSYNTH' 1300 1303 fi 1301 1304 echo "$_fluidsynth" 1302 rm -f $TMPC $TMPO$EXEEXT1303 1305 1304 1306 # 1305 1307 # Check for nasm … … 1312 1314 add_to_config_mk_if_yes $_nasm 'HAVE_NASM = 1' 1313 1315 1314 1316 # 1317 # Check whether to build translation support 1318 # 1319 echo_n "Building translation support... " 1320 add_to_config_mk_if_yes $_translation 'ENABLE_TRANSLATION = 1' 1321 add_to_config_h_if_yes $_translation '#define TRANSLATION' 1322 if test "$_translation" = no ; then 1323 echo "no" 1324 else 1325 echo_n "yes (" 1326 1327 cat > $TMPC << EOF 1328 #include <locale.h> 1329 int main(void) { setlocale(LC_ALL, ""); return 0; } 1330 EOF 1331 _detectlang=no 1332 cc_check $LDFLAGS $CXXFLAGS && _detectlang=yes 1333 1334 add_to_config_h_if_yes $_detectlang '#define DETECTLANG' 1335 if test "$_detectlang" = yes ; then 1336 echo_n "with runtime language detection, " 1337 1338 cat > $TMPC << EOF 1339 #include <langinfo.h> 1340 #include <iconv.h> 1341 int main(void) { nl_langinfo(CODESET); iconv_open(0, 0); return 0; } 1342 EOF 1343 _termconv=no 1344 cc_check $LDFLAGS $CXXFLAGS && _termconv=yes 1345 cc_check $LDFLAGS $CXXFLAGS -liconv && LIBS="$LIBS -liconv" && _termconv=yes 1346 1347 add_to_config_h_if_yes $_termconv '#define TERMCONV' 1348 if test "$_termconv" = yes ; then 1349 echo "with terminal conversion)" 1350 else 1351 echo "without terminal conversion)" 1352 fi 1353 else 1354 echo "without runtime language detection)" 1355 fi 1356 fi 1357 rm -f $TMPC $TMPO$EXEEXT 1358 1359 # 1315 1360 # figure out installation directories 1316 1361 # 1317 1362 test -z "$_bindir" && _bindir="$_prefix/bin" -
Makefile.common
39 39 graphics \ 40 40 sound \ 41 41 common \ 42 backends 42 backends \ 43 po 43 44 44 45 ifdef USE_MT32EMU 45 46 MODULES += sound/softsynth/mt32 -
common/module.mk
13 13 stream.o \ 14 14 util.o \ 15 15 system.o \ 16 translation.o \ 16 17 unzip.o 17 18 19 ifdef ENABLE_TRANSLATION 20 common/translation.cpp: common/messages.cpp 21 22 common/messages.cpp: $(wildcard po/*.po) 23 tools/po2c $^ > common/messages.cpp 24 endif 25 18 26 # Include common rules 19 27 include $(srcdir)/rules.mk -
po/module.mk
1 POTFILE := po/scummvm.pot 2 POFILES := $(wildcard po/*.po) 3 4 updatepot: 5 xgettext -f po/POTFILES -k_ -k_t -k_s --copyright-holder="ScummVM" \ 6 --msgid-bugs-address=scummvm-devel@lists.sourceforge.net \ 7 -o $(POTFILE)_ --from-code utf-8 8 sed -e 's/SOME DESCRIPTIVE TITLE/LANGUAGE translation for ScummVM/' \ 9 -e 's/UTF-8/CHARSET/' -e 's/PACKAGE/ScummVM/' $(POTFILE)_ > $(POTFILE).new 10 11 rm $(POTFILE)_ 12 if test -f $(POTFILE); then \ 13 sed -f po/remove-potcdate.sed < $(POTFILE) > $(POTFILE).1 && \ 14 sed -f po/remove-potcdate.sed < $(POTFILE).new > $(POTFILE).2 && \ 15 if cmp $(POTFILE).1 $(POTFILE).2 >/dev/null 2>&1; then \ 16 rm -f $(POTFILE).new; \ 17 else \ 18 rm -f $(POTFILE) && \ 19 mv -f $(POTFILE).new $(POTFILE); \ 20 fi; \ 21 rm -f $(POTFILE).1 $(POTFILE).2; \ 22 else \ 23 mv -f $(POTFILE).new $(POTFILE); \ 24 fi; 25 26 po/%.po: $(POTFILE) 27 msgmerge $@ $(POTFILE) -o $@.new 28 if cmp $@ $@.new >/dev/null 2>&1; then \ 29 rm -f $@.new; \ 30 else \ 31 mv -f $@.new $@; \ 32 fi; 33 34 update-translations: updatepot $(POFILES) 35 @$(foreach file, $(POFILES), echo -n $(notdir $(basename $(file)))": ";msgfmt --statistic $(file);) 36 @rm -f messages.mo 37 38 .PHONY: updatepot update-translations -
common/translation.h
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 #ifndef COMMON_TRANSLATION_H 26 #define COMMON_TRANSLATION_H 27 28 #include "common/stdafx.h" 29 #include "common/singleton.h" 30 #include "common/str.h" 31 #include "common/list.h" 32 33 #ifdef TERMCONV 34 #include <iconv.h> 35 #endif 36 37 namespace Common { 38 39 /** 40 * Message translation manager. 41 */ 42 class TranslationManager : public Singleton<TranslationManager> { 43 private: 44 char _syslang[6]; 45 46 #ifdef TERMCONV 47 iconv_t _conversion; 48 char* _convmsg; 49 int _sizeconv; 50 51 bool convert(const char* message); 52 #endif // TERMCONV 53 54 public: 55 /** 56 * The constructor detects the system language and sets default 57 * language to English. 58 */ 59 TranslationManager(); 60 61 ~TranslationManager(); 62 63 /** 64 * Sets the current translation language to the one specified in the 65 * parameter. If the parameter is an empty string, it sets the default 66 * system language. 67 */ 68 void setLanguage(const char* lang); 69 70 /** 71 * Returns the translation into the current language of the parameter 72 * message. In case the message isn't found in the translation catalog, 73 * it returns the original untranslated message. 74 */ 75 const char* getTranslation(const char* message); 76 77 /** 78 * Converts the message into the terminal character set (which may be 79 * different than the GUI's "native" one. 80 */ 81 const char* convertTerm(const char* message); 82 83 List<String> getSupportedLanguages(); 84 }; 85 86 } // End of namespace Common 87 88 #define TransMan Common::TranslationManager::instance() 89 90 #ifdef TRANSLATION 91 #define _(str) TransMan.getTranslation(str) 92 #define _t(str) TransMan.convertTerm(_(str)) 93 #else 94 #define _(str) str 95 #define _t(str) str 96 #endif 97 98 #define _s(str) str 99 100 #endif -
common/translation.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 #include "translation.h" 26 27 DECLARE_SINGLETON(Common::TranslationManager); 28 29 #ifdef TRANSLATION 30 #include "messages.cpp" 31 #endif 32 33 #ifdef DETECTLANG 34 #include <langinfo.h> 35 #endif 36 37 #ifdef TERMCONV 38 #include <locale.h> 39 #endif 40 41 namespace Common { 42 43 44 #ifdef TRANSLATION 45 46 // Translation enabled 47 48 49 TranslationManager::TranslationManager() { 50 #ifdef DETECTLANG 51 // Activating current locale settings 52 const char* locale = setlocale(LC_ALL, ""); 53 54 // Detect the language from the locale 55 if (!locale) { 56 strcpy(_syslang, "C"); 57 } else { 58 int len = strlen(locale); 59 if (len > 5) 60 len = 5; 61 strncpy(_syslang, locale, len); 62 _syslang[len] = 0; 63 } 64 #else // DETECTLANG 65 strcpy(_syslang, "C"); 66 #endif // DETECTLANG 67 68 #ifdef TERMCONV 69 _convmsg = NULL; 70 _conversion = NULL; 71 #endif // TERMCONV 72 73 // Set the default language 74 setLanguage(""); 75 } 76 77 TranslationManager::~TranslationManager() { 78 #ifdef TERMCONV 79 iconv_close(_conversion); 80 if (_convmsg) 81 delete [] _convmsg; 82 #endif // TERMCONV 83 } 84 85 void TranslationManager::setLanguage(const char* lang) { 86 if (*lang == '\0') 87 po2c_setlang(_syslang); 88 else 89 po2c_setlang(lang); 90 91 #ifdef TERMCONV 92 // Get the locale character set (for terminal output) 93 const char* charset_term = nl_langinfo(CODESET); 94 95 // Get the messages character set 96 const char* charset_po = po2c_getcharset(); 97 98 // Delete previous conversion 99 if (_conversion) 100 iconv_close(_conversion); 101 102 // Initialize the conversion 103 _conversion = iconv_open(charset_term, charset_po); 104 #endif // TERMCONV 105 } 106 107 const char* TranslationManager::getTranslation(const char* message) { 108 return po2c_gettext(message); 109 } 110 111 #ifdef TERMCONV 112 bool TranslationManager::convert(const char* message) { 113 // Preparing conversion origin 114 size_t len = strlen(message); 115 char* msgcpy = new char[len + 1]; 116 strcpy(msgcpy, message); 117 char* msg = msgcpy; 118 char** pmsg = &msg; 119 120 // Preparing conversion destination 121 size_t len2 = _sizeconv; 122 char *conv = _convmsg; 123 char** pconv = &conv; 124 125 // Clean previous conversions 126 iconv(_conversion, NULL, NULL, pconv, &len2); 127 128 // Do the real conversion 129 size_t result = iconv(_conversion, pmsg, &len, pconv, &len2); 130 131 delete [] msgcpy; 132 133 return result != ((size_t)-1); 134 } 135 #endif // TERMCONV 136 137 const char* TranslationManager::convertTerm(const char* message) { 138 #ifdef TERMCONV 139 size_t len = strlen(message); 140 if (!_convmsg) { 141 _sizeconv = len * 2; 142 _convmsg = new char[_sizeconv]; 143 } 144 145 if (!convert(message)) { 146 // Resizing the buffer 147 delete [] _convmsg; 148 _sizeconv = len * 2; 149 _convmsg = new char[_sizeconv]; 150 151 if (!convert(message)) { 152 printf("Error while converting character sets\n"); 153 return "Error while converting character sets"; 154 } 155 } 156 157 return _convmsg; 158 #else // TERMCONV 159 return message; 160 #endif // TERMCONV 161 } 162 163 List<String> TranslationManager::getSupportedLanguages() { 164 List<String> languages; 165 166 int total = po2c_getnumlangs(); 167 for (int i = 0; i < total; i++) { 168 languages.push_back(po2c_getlang(i)); 169 } 170 171 //sort(languages.begin(), languages.end()); 172 173 return languages; 174 } 175 176 177 #else // TRANSLATION 178 179 // Translation disabled 180 181 182 TranslationManager::TranslationManager() {} 183 184 TranslationManager::~TranslationManager() {} 185 186 void TranslationManager::setLanguage(const char* lang) {} 187 188 const char* TranslationManager::getTranslation(const char* message) 189 { 190 return message; 191 } 192 193 const char* TranslationManager::convertTerm(const char* message) 194 { 195 return message; 196 } 197 198 #endif // TRANSLATION 199 200 } // End of namespace Common -
gui/options.h
165 165 StaticTextWidget *_curTheme; 166 166 167 167 PopUpWidget *_autosavePeriodPopUp; 168 169 PopUpWidget *_guiLanguagePopUp; 168 170 }; 169 171 170 172 } // End of namespace GUI -
gui/options.cpp
35 35 #include "common/fs.h" 36 36 #include "common/config-manager.h" 37 37 #include "common/system.h" 38 #include "common/translation.h" 38 39 39 40 #include "graphics/scaler.h" 40 41 … … 64 65 }; 65 66 #endif 66 67 67 static const char *savePeriodLabels[] = { "Never", "every 5 mins", "every 10 mins", "every 15 mins", "every 30 mins", 0 };68 static const char *savePeriodLabels[] = { _s("Never"), _s("every 5 mins"), _s("every 10 mins"), _s("every 15 mins"), _s("every 30 mins"), 0 }; 68 69 static const int savePeriodValues[] = { 0, 5 * 60, 10 * 60, 15 * 60, 30 * 60, -1 }; 69 static const char *outputRateLabels[] = { "<default>", "22 kHz", "8 kHz", "11kHz", "44 kHz", "48 kHz", 0 };70 static const char *outputRateLabels[] = { _s("<default>"), _s("22 kHz"), _s("8 kHz"), _s("11kHz"), _s("44 kHz"), _s("48 kHz"), 0 }; 70 71 static const int outputRateValues[] = { 0, 22050, 8000, 11025, 44100, 48000, -1 }; 71 72 72 73 … … 82 83 } 83 84 84 85 const char *OptionsDialog::_subModeDesc[] = { 85 "Speech Only",86 "Speech and Subtitles",87 "Subtitles Only"86 _s("Speech Only"), 87 _s("Speech and Subtitles"), 88 _s("Subtitles Only") 88 89 }; 89 90 90 91 void OptionsDialog::init() { … … 201 202 202 203 String soundFont(ConfMan.get("soundfont", _domain)); 203 204 if (soundFont.empty() || !ConfMan.hasKey("soundfont", _domain)) { 204 _soundFont->setLabel( "None");205 _soundFont->setLabel(_("None")); 205 206 _soundFontClearButton->setEnabled(false); 206 207 } else { 207 208 _soundFont->setLabel(soundFont); … … 239 240 int sliderMaxValue = _subSpeedSlider->getMaxValue(); 240 241 241 242 _subMode = getSubtitleMode(ConfMan.getBool("subtitles", _domain), ConfMan.getBool("speech_mute", _domain)); 242 _subToggleButton->setLabel(_ subModeDesc[_subMode]);243 _subToggleButton->setLabel(_(_subModeDesc[_subMode])); 243 244 244 245 // Engines that reuse the subtitle speed widget set their own max value. 245 246 // Scale the config value accordingly (see addSubtitleControls) … … 333 334 ConfMan.setInt("midi_gain", _midiGainSlider->getValue(), _domain); 334 335 335 336 String soundFont(_soundFont->getLabel()); 336 if (!soundFont.empty() && (soundFont != "None"))337 if (!soundFont.empty() && (soundFont != _("None"))) 337 338 ConfMan.set("soundfont", soundFont, _domain); 338 339 else 339 340 ConfMan.removeKey("soundfont", _domain); … … 416 417 else 417 418 _subMode = 0; 418 419 419 _subToggleButton->setLabel(_ subModeDesc[_subMode]);420 _subToggleButton->setLabel(_(_subModeDesc[_subMode])); 420 421 _subToggleButton->draw(); 421 422 _subSpeedDesc->draw(); 422 423 _subSpeedSlider->draw(); … … 459 460 _soundFontButton->setEnabled(enabled); 460 461 _soundFont->setEnabled(enabled); 461 462 462 if (enabled && !_soundFont->getLabel().empty() && (_soundFont->getLabel() != "None"))463 if (enabled && !_soundFont->getLabel().empty() && (_soundFont->getLabel() != _("None"))) 463 464 _soundFontClearButton->setEnabled(enabled); 464 465 else 465 466 _soundFontClearButton->setEnabled(false); … … 502 503 int labelWidth = g_gui.evaluator()->getVar("tabPopupsLabelW"); 503 504 504 505 // The GFX mode popup 505 _gfxPopUp = new PopUpWidget(boss, prefix + "grModePopup", "Graphics mode:", labelWidth);506 _gfxPopUp = new PopUpWidget(boss, prefix + "grModePopup", _("Graphics mode:"), labelWidth); 506 507 507 _gfxPopUp->appendEntry( "<default>");508 _gfxPopUp->appendEntry(_("<default>")); 508 509 _gfxPopUp->appendEntry(""); 509 510 while (gm->name) { 510 _gfxPopUp->appendEntry( gm->description, gm->id);511 _gfxPopUp->appendEntry(_(gm->description), gm->id); 511 512 gm++; 512 513 } 513 514 514 515 // RenderMode popup 515 _renderModePopUp = new PopUpWidget(boss, prefix + "grRenderPopup", "Render mode:", labelWidth);516 _renderModePopUp->appendEntry( "<default>", Common::kRenderDefault);516 _renderModePopUp = new PopUpWidget(boss, prefix + "grRenderPopup", _("Render mode:"), labelWidth); 517 _renderModePopUp->appendEntry(_("<default>"), Common::kRenderDefault); 517 518 _renderModePopUp->appendEntry(""); 518 519 const Common::RenderModeDescription *rm = Common::g_renderModes; 519 520 for (; rm->code; ++rm) { 520 _renderModePopUp->appendEntry( rm->description, rm->id);521 _renderModePopUp->appendEntry(_(rm->description), rm->id); 521 522 } 522 523 523 524 // Fullscreen checkbox 524 _fullscreenCheckbox = new CheckboxWidget(boss, prefix + "grFullscreenCheckbox", "Fullscreen mode", 0, 0);525 _fullscreenCheckbox = new CheckboxWidget(boss, prefix + "grFullscreenCheckbox", _("Fullscreen mode"), 0, 0); 525 526 526 527 // Aspect ratio checkbox 527 _aspectCheckbox = new CheckboxWidget(boss, prefix + "grAspectCheckbox", "Aspect ratio correction", 0, 0);528 _aspectCheckbox = new CheckboxWidget(boss, prefix + "grAspectCheckbox", _("Aspect ratio correction"), 0, 0); 528 529 529 530 #ifdef SMALL_SCREEN_DEVICE 530 531 _fullscreenCheckbox->setState(true); … … 539 540 int labelWidth = g_gui.evaluator()->getVar("tabPopupsLabelW"); 540 541 541 542 // The MIDI mode popup & a label 542 _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", "Music driver:", labelWidth);543 _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Music driver:"), labelWidth); 543 544 544 545 // Populate it 545 546 const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers(); 546 547 while (md->name) { 547 _midiPopUp->appendEntry( md->description, md->id);548 _midiPopUp->appendEntry(_(md->description), md->id); 548 549 md++; 549 550 } 550 551 551 552 // Sample rate settings 552 _outputRatePopUp = new PopUpWidget(boss, prefix + "auSampleRatePopup", "Output rate:", labelWidth);553 _outputRatePopUp = new PopUpWidget(boss, prefix + "auSampleRatePopup", _("Output rate:"), labelWidth); 553 554 554 555 for (int i = 0; outputRateLabels[i]; i++) { 555 _outputRatePopUp->appendEntry( outputRateLabels[i], outputRateValues[i]);556 _outputRatePopUp->appendEntry(_(outputRateLabels[i]), outputRateValues[i]); 556 557 } 557 558 558 559 _enableAudioSettings = true; … … 560 561 561 562 void OptionsDialog::addMIDIControls(GuiObject *boss, const String &prefix) { 562 563 // SoundFont 563 _soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", "SoundFont:", kChooseSoundFontCmd, 0);564 _soundFont = new StaticTextWidget(boss, prefix + "mcFontPath", "None");565 _soundFontClearButton = new ButtonWidget(boss, prefix + "mcFontClearButton", "C", kClearSoundFontCmd, 0);564 _soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", _("SoundFont:"), kChooseSoundFontCmd, 0); 565 _soundFont = new StaticTextWidget(boss, prefix + "mcFontPath", _("None")); 566 _soundFontClearButton = new ButtonWidget(boss, prefix + "mcFontClearButton", _("C"), kClearSoundFontCmd, 0); 566 567 567 568 // Multi midi setting 568 _multiMidiCheckbox = new CheckboxWidget(boss, prefix + "mcMixedCheckbox", "Mixed Adlib/MIDI mode", 0, 0);569 _multiMidiCheckbox = new CheckboxWidget(boss, prefix + "mcMixedCheckbox", _("Mixed Adlib/MIDI mode"), 0, 0); 569 570 570 571 // Native mt32 setting 571 _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", "True Roland MT-32 (disable GM emulation)", 0, 0);572 _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _("True Roland MT-32 (disable GM emulation)"), 0, 0); 572 573 573 574 // GS Extensions setting 574 _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", "Enable Roland GS Mode", 0, 0);575 _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Enable Roland GS Mode"), 0, 0); 575 576 576 577 // MIDI gain setting (FluidSynth uses this) 577 _midiGainDesc = new StaticTextWidget(boss, prefix + "mcMidiGainText", "MIDI gain:");578 _midiGainDesc = new StaticTextWidget(boss, prefix + "mcMidiGainText", _("MIDI gain:")); 578 579 _midiGainSlider = new SliderWidget(boss, prefix + "mcMidiGainSlider", kMidiGainChanged); 579 580 _midiGainSlider->setMinValue(0); 580 581 _midiGainSlider->setMaxValue(1000); … … 587 588 // make use of the widgets. The launcher range is 0-255. SCUMM's 0-9 588 589 void OptionsDialog::addSubtitleControls(GuiObject *boss, const String &prefix, int maxSliderVal) { 589 590 590 _subToggleDesc = new StaticTextWidget(boss, prefix + "subToggleDesc", "Text and Speech:");591 _subToggleDesc = new StaticTextWidget(boss, prefix + "subToggleDesc", _("Text and Speech:")); 591 592 _subToggleButton = new ButtonWidget(boss, prefix + "subToggleButton", "", kSubtitleToggle, 0); 592 593 593 594 // Subtitle speed 594 _subSpeedDesc = new StaticTextWidget(boss, prefix + "subSubtitleSpeedDesc", "Subtitle speed:");595 _subSpeedDesc = new StaticTextWidget(boss, prefix + "subSubtitleSpeedDesc", _("Subtitle speed:")); 595 596 _subSpeedSlider = new SliderWidget(boss, prefix + "subSubtitleSpeedSlider", kSubtitleSpeedChanged); 596 597 _subSpeedLabel = new StaticTextWidget(boss, prefix + "subSubtitleSpeedLabel", "100%"); 597 598 _subSpeedSlider->setMinValue(0); _subSpeedSlider->setMaxValue(maxSliderVal); … … 603 604 void OptionsDialog::addVolumeControls(GuiObject *boss, const String &prefix) { 604 605 605 606 // Volume controllers 606 _musicVolumeDesc = new StaticTextWidget(boss, prefix + "vcMusicText", "Music volume:");607 _musicVolumeDesc = new StaticTextWidget(boss, prefix + "vcMusicText", _("Music volume:")); 607 608 _musicVolumeSlider = new SliderWidget(boss, prefix + "vcMusicSlider", kMusicVolumeChanged); 608 609 _musicVolumeLabel = new StaticTextWidget(boss, prefix + "vcMusicLabel", "100%"); 609 610 _musicVolumeSlider->setMinValue(0); 610 611 _musicVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume); 611 612 _musicVolumeLabel->setFlags(WIDGET_CLEARBG); 612 613 613 _sfxVolumeDesc = new StaticTextWidget(boss, prefix + "vcSfxText", "SFX volume:");614 _sfxVolumeDesc = new StaticTextWidget(boss, prefix + "vcSfxText", _("SFX volume:")); 614 615 _sfxVolumeSlider = new SliderWidget(boss, prefix + "vcSfxSlider", kSfxVolumeChanged); 615 616 _sfxVolumeLabel = new StaticTextWidget(boss, prefix + "vcSfxLabel", "100%"); 616 617 _sfxVolumeSlider->setMinValue(0); 617 618 _sfxVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume); 618 619 _sfxVolumeLabel->setFlags(WIDGET_CLEARBG); 619 620 620 _speechVolumeDesc = new StaticTextWidget(boss, prefix + "vcSpeechText" , "Speech volume:");621 _speechVolumeDesc = new StaticTextWidget(boss, prefix + "vcSpeechText" , _("Speech volume:")); 621 622 _speechVolumeSlider = new SliderWidget(boss, prefix + "vcSpeechSlider", kSpeechVolumeChanged); 622 623 _speechVolumeLabel = new StaticTextWidget(boss, prefix + "vcSpeechLabel", "100%"); 623 624 _speechVolumeSlider->setMinValue(0); … … 667 668 // 668 669 // 1) The graphics tab 669 670 // 670 tab->addTab( "Graphics");671 tab->addTab(_("Graphics")); 671 672 addGraphicControls(tab, "globaloptions_"); 672 673 673 674 // 674 675 // 2) The audio tab 675 676 // 676 tab->addTab( "Audio");677 tab->addTab(_("Audio")); 677 678 addAudioControls(tab, "globaloptions_"); 678 679 addSubtitleControls(tab, "globaloptions_"); 679 680 680 tab->addTab( "Volume");681 tab->addTab(_("Volume")); 681 682 addVolumeControls(tab, "globaloptions_"); 682 683 683 684 // TODO: cd drive setting … … 685 686 // 686 687 // 3) The MIDI tab 687 688 // 688 tab->addTab( "MIDI");689 tab->addTab(_("MIDI")); 689 690 addMIDIControls(tab, "globaloptions_"); 690 691 691 692 // 692 693 // 4) The miscellaneous tab 693 694 // 694 tab->addTab( "Paths");695 tab->addTab(_("Paths")); 695 696 696 697 #if !( defined(__DC__) || defined(__GP32__) ) 697 698 // These two buttons have to be extra wide, or the text will be 698 699 // truncated in the small version of the GUI. 699 700 700 701 // Save game path 701 new ButtonWidget(tab, "globaloptions_savebutton", "Save Path: ", kChooseSaveDirCmd, 0);702 new ButtonWidget(tab, "globaloptions_savebutton", _("Save Path:"), kChooseSaveDirCmd, 0); 702 703 _savePath = new StaticTextWidget(tab, "globaloptions_savepath", "/foo/bar"); 703 704 704 new ButtonWidget(tab, "globaloptions_themebutton", "Theme Path:", kChooseThemeDirCmd, 0);705 _themePath = new StaticTextWidget(tab, "globaloptions_themepath", "None");705 new ButtonWidget(tab, "globaloptions_themebutton", _("Theme Path:"), kChooseThemeDirCmd, 0); 706 _themePath = new StaticTextWidget(tab, "globaloptions_themepath", _("None")); 706 707 707 new ButtonWidget(tab, "globaloptions_extrabutton", "Extra Path:", kChooseExtraDirCmd, 0);708 _extraPath = new StaticTextWidget(tab, "globaloptions_extrapath", "None");708 new ButtonWidget(tab, "globaloptions_extrabutton", _("Extra Path:"), kChooseExtraDirCmd, 0); 709 _extraPath = new StaticTextWidget(tab, "globaloptions_extrapath", _("None")); 709 710 #endif 710 711 711 712 #ifdef SMALL_SCREEN_DEVICE 712 new ButtonWidget(tab, "globaloptions_keysbutton", "Keys", kChooseKeyMappingCmd, 0);713 new ButtonWidget(tab, "globaloptions_keysbutton", _("Keys"), kChooseKeyMappingCmd, 0); 713 714 #endif 714 715 715 tab->addTab( "Misc");716 tab->addTab(_("Misc")); 716 717 717 new ButtonWidget(tab, "globaloptions_themebutton2", "Theme:", kChooseThemeCmd, 0);718 new ButtonWidget(tab, "globaloptions_themebutton2", _("Theme:"), kChooseThemeCmd, 0); 718 719 _curTheme = new StaticTextWidget(tab, "globaloptions_curtheme", g_gui.theme()->getThemeName()); 719 720 720 721 int labelWidth = g_gui.evaluator()->getVar("tabPopupsLabelW"); 721 722 722 _autosavePeriodPopUp = new PopUpWidget(tab, "globaloptions_autosaveperiod", "Autosave:", labelWidth);723 _autosavePeriodPopUp = new PopUpWidget(tab, "globaloptions_autosaveperiod", _("Autosave:"), labelWidth); 723 724 724 725 for (int i = 0; savePeriodLabels[i]; i++) { 725 _autosavePeriodPopUp->appendEntry( savePeriodLabels[i], savePeriodValues[i]);726 _autosavePeriodPopUp->appendEntry(_(savePeriodLabels[i]), savePeriodValues[i]); 726 727 } 727 728 729 #ifdef TRANSLATION 730 _guiLanguagePopUp = new PopUpWidget(tab, "globaloptions_guilanguage", _("Interface language:"), labelWidth); 731 732 #ifdef DETECTLANG 733 _guiLanguagePopUp->appendEntry(_("<default>"), 0); 734 #endif // DETECTLANG 735 _guiLanguagePopUp->appendEntry(_("English"), 1); 736 _guiLanguagePopUp->appendEntry("", 0); 737 Common::List<String> languages = TransMan.getSupportedLanguages(); 738 Common::List<String>::iterator lang = languages.begin(); 739 while (lang != languages.end()) { 740 _guiLanguagePopUp->appendEntry(*lang, 2); 741 lang++; 742 } 743 #endif // TRANSLATION 744 728 745 // TODO: joystick setting 729 746 730 747 … … 732 749 tab->setActiveTab(0); 733 750 734 751 // Add OK & Cancel buttons 735 new ButtonWidget(this, "globaloptions_cancel", "Cancel", kCloseCmd, 0);736 new ButtonWidget(this, "globaloptions_ok", "OK", kOKCmd, 0);752 new ButtonWidget(this, "globaloptions_cancel", _("Cancel"), kCloseCmd, 0); 753 new ButtonWidget(this, "globaloptions_ok", _("OK"), kOKCmd, 0); 737 754 738 755 #ifdef SMALL_SCREEN_DEVICE 739 756 _keysDialog = new KeysDialog(); … … 756 773 Common::String extraPath(ConfMan.get("extrapath", _domain)); 757 774 758 775 if (savePath.empty() || !ConfMan.hasKey("savepath", _domain)) { 759 _savePath->setLabel( "None");776 _savePath->setLabel(_("None")); 760 777 } else { 761 778 _savePath->setLabel(savePath); 762 779 } 763 780 764 781 if (themePath.empty() || !ConfMan.hasKey("themepath", _domain)) { 765 _themePath->setLabel( "None");782 _themePath->setLabel(_("None")); 766 783 } else { 767 784 _themePath->setLabel(themePath); 768 785 } 769 786 770 787 if (extraPath.empty() || !ConfMan.hasKey("extrapath", _domain)) { 771 _extraPath->setLabel( "None");788 _extraPath->setLabel(_("None")); 772 789 } else { 773 790 _extraPath->setLabel(extraPath); 774 791 } … … 781 798 if (value == savePeriodValues[i]) 782 799 _autosavePeriodPopUp->setSelected(i); 783 800 } 801 802 #ifdef TRANSLATION 803 _guiLanguagePopUp->setSelected(0); 804 String lang = ConfMan.get("gui_language"); 805 if (lang == "C") 806 _guiLanguagePopUp->setSelectedTag(1); 807 else if (lang != "") { 808 Common::List<String> languages = TransMan.getSupportedLanguages(); 809 Common::List<String>::iterator lang_iter = languages.begin(); 810 int i = 2; 811 #ifdef DETECTLANG 812 i += 1; 813 #endif // DETECTLANG 814 815 // Locate the configured language 816 while (lang_iter != languages.end() && *lang_iter != lang) { 817 lang_iter++; 818 i++; 819 } 820 821 // If the configured language is unknown, select English 822 if (lang_iter == languages.end()) 823 _guiLanguagePopUp->setSelectedTag(1); 824 else 825 _guiLanguagePopUp->setSelected(i); 826 827 } 828 #endif // TRANSLATION 784 829 } 785 830 786 831 void GlobalOptionsDialog::close() { 787 832 if (getResult()) { 788 833 String savePath(_savePath->getLabel()); 789 if (!savePath.empty() && (savePath != "None"))834 if (!savePath.empty() && (savePath != _("None"))) 790 835 ConfMan.set("savepath", savePath, _domain); 791 836 792 837 String themePath(_themePath->getLabel()); 793 if (!themePath.empty() && (themePath != "None"))838 if (!themePath.empty() && (themePath != _("None"))) 794 839 ConfMan.set("themepath", themePath, _domain); 795 840 else 796 841 ConfMan.removeKey("themepath", _domain); 797 842 798 843 String extraPath(_extraPath->getLabel()); 799 if (!extraPath.empty() && (extraPath != "None"))844 if (!extraPath.empty() && (extraPath != _("None"))) 800 845 ConfMan.set("extrapath", extraPath, _domain); 801 846 else 802 847 ConfMan.removeKey("extrapath", _domain); 803 848 804 849 ConfMan.setInt("autosave_period", _autosavePeriodPopUp->getSelectedTag(), _domain); 850 851 #ifdef TRANSLATION 852 String oldLang = ConfMan.get("gui_language"); 853 switch (_guiLanguagePopUp->getSelectedTag()) { 854 case 0: 855 #ifdef DETECTLANG 856 // Default 857 ConfMan.set("gui_language", "", _domain); 858 break; 859 #endif // DETECTLANG 860 case 1: 861 // English 862 ConfMan.set("gui_language", "C", _domain); 863 break; 864 case 2: 865 // Other language 866 ConfMan.set("gui_language", _guiLanguagePopUp->getSelectedString(), _domain); 867 break; 868 } 869 String newLang = ConfMan.get("gui_language").c_str(); 870 if (newLang != oldLang) { 871 /* 872 // Activate the selected language 873 TransMan.setLanguage(newLang.c_str()); 874 875 // Update widgets' strings 876 g_gui.updateTranslation(); // TODO: Currently you have to restart. 877 */ 878 } 879 #endif // TRANSLATION 805 880 } 806 881 OptionsDialog::close(); 807 882 } … … 809 884 void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { 810 885 switch (cmd) { 811 886 case kChooseSaveDirCmd: { 812 BrowserDialog browser( "Select directory for savegames", true);887 BrowserDialog browser(_("Select directory for savegames"), true); 813 888 if (browser.runModal() > 0) { 814 889 // User made his choice... 815 890 FilesystemNode dir(browser.getResult()); … … 820 895 break; 821 896 } 822 897 case kChooseThemeDirCmd: { 823 BrowserDialog browser( "Select directory for GUI themes", true);898 BrowserDialog browser(_("Select directory for GUI themes"), true); 824 899 if (browser.runModal() > 0) { 825 900 // User made his choice... 826 901 FilesystemNode dir(browser.getResult()); … … 830 905 break; 831 906 } 832 907 case kChooseExtraDirCmd: { 833 BrowserDialog browser( "Select directory for extra files", true);908 BrowserDialog browser(_("Select directory for extra files"), true); 834 909 if (browser.runModal() > 0) { 835 910 // User made his choice... 836 911 FilesystemNode dir(browser.getResult()); … … 840 915 break; 841 916 } 842 917 case kChooseSoundFontCmd: { 843 BrowserDialog browser( "Select SoundFont", false);918 BrowserDialog browser(_("Select SoundFont"), false); 844 919 if (browser.runModal() > 0) { 845 920 // User made his choice... 846 921 FilesystemNode file(browser.getResult()); 847 922 _soundFont->setLabel(file.path()); 848 923 849 if (!file.path().empty() && (file.path() != "None"))924 if (!file.path().empty() && (file.path() != _("None"))) 850 925 _soundFontClearButton->setEnabled(true); 851 926 else 852 927 _soundFontClearButton->setEnabled(false); … … 856 931 break; 857 932 } 858 933 case kClearSoundFontCmd: { 859 _soundFont->setLabel( "None");934 _soundFont->setLabel(_("None")); 860 935 _soundFontClearButton->setEnabled(false); 861 936 draw(); 862 937 break; -
base/main.cpp
41 41 #include "common/file.h" 42 42 #include "common/fs.h" 43 43 #include "common/system.h" 44 #include "common/translation.h" 44 45 #include "gui/newgui.h" 45 46 #include "gui/message.h" 46 47 … … 94 95 ConfMan.set("gameid", gameid); 95 96 96 97 // Query the plugins and find one that will handle the specified gameid 97 printf( "Looking for %s\n", gameid.c_str());98 printf(_t("Looking for %s\n"), gameid.c_str()); 98 99 GameDescriptor game = Base::findGame(gameid, &plugin); 99 100 100 101 if (plugin == 0) { 101 printf( "Failed game detection\n");102 warning( "%s is an invalid gameid. Use the --list-games option to list supported gameid", gameid.c_str());102 printf(_t("Failed game detection\n")); 103 warning(_t("%s is an invalid gameid. Use the --list-games option to list supported gameid"), gameid.c_str()); 103 104 return 0; 104 105 } 105 106 106 107 // FIXME: Do we really need this one? 107 printf( "Trying to start game '%s'\n", game.description().c_str());108 printf(_t("Trying to start game '%s'\n"), game.description().c_str()); 108 109 109 110 return plugin; 110 111 } … … 132 133 path = ConfMan.get("path"); 133 134 FilesystemNode dir(path); 134 135 if (!dir.isDirectory()) { 135 warning( "Game directory does not exist (%s)", path.c_str());136 warning(_t("Game directory does not exist (%s)"), path.c_str()); 136 137 return 0; 137 138 } 138 139 } else { 139 140 path = "."; 140 warning( "No path was provided. Assuming the data files are in the current directory");141 warning(_t("No path was provided. Assuming the data files are in the current directory")); 141 142 } 142 143 Common::File::addDefaultDirectory(path); 143 144 … … 152 153 const char *errMsg = 0; 153 154 switch (err) { 154 155 case kInvalidPathError: 155 errMsg = "Invalid game path";156 errMsg = _t("Invalid game path"); 156 157 break; 157 158 case kNoGameDataFoundError: 158 errMsg = "Unable to locate game data";159 errMsg = _t("Unable to locate game data"); 159 160 break; 160 161 default: 161 errMsg = "Unknown error";162 errMsg = _t("Unknown error"); 162 163 } 163 164 164 warning( "%s failed to instantiate engine: %s (target '%s', path '%s')",165 warning(_t("%s failed to instantiate engine: %s (target '%s', path '%s')"), 165 166 plugin->getName(), 166 167 errMsg, 167 168 ConfMan.getActiveDomainName().c_str(), … … 264 265 // Update the config file 265 266 ConfMan.set("versioninfo", gScummVMVersion, Common::ConfigManager::kApplicationDomain); 266 267 268 // Enable translation 269 TransMan.setLanguage(ConfMan.get("gui_language").c_str()); 267 270 268 271 // Load and setup the debuglevel and the debug flags. We do this at the 269 272 // soonest possible moment to ensure debug output starts early on, if -
gui/theme-config.cpp
224 224 "globaloptions_curtheme=(prev.x2 + 20) (yoffset + glOff) (parent.w - (prev.w + 20) - 10) kLineHeight\n" 225 225 "yoffset=(yoffset + buttonHeight + 4)\n" 226 226 "globaloptions_autosaveperiod=10 yoffset (parent.w - 10 - 25) (kLineHeight + 2)\n" 227 "yoffset=(yoffset + buttonHeight + 4)\n" 228 "globaloptions_guilanguage=prev.x yoffset prev.w prev.h\n" 227 229 "\n" 228 230 "globaloptions_cancel=(parent.w - 2 * (buttonWidth + 10)) (parent.h - buttonHeight - 8) buttonWidth buttonHeight\n" 229 231 "globaloptions_ok=(prev.x2 + 10) prev.y prev.w prev.h\n" -
gui/themes/modern.ini
173 173 [XxY] 174 174 skipFor=320xY,256x240 175 175 def_widgetSize=kBigWidgetSize 176 def_buttonWidth=1 20176 def_buttonWidth=130 177 177 def_buttonHeight=25 178 178 def_sliderWidth=kBigSliderWidth 179 179 def_sliderHeight=kBigSliderHeight … … 185 185 def_insetW=(w - buttonWidth - 17 * 2 - insetX) 186 186 def_insetH=(h - 23 - insetY) 187 187 def_optionsVPad=20 188 def_optionsLabelWidth= 110188 def_optionsLabelWidth=buttonWidth 189 189 def_gameOptionsOverrideVPad=20 190 190 def_tabPopupsLabelW=optionsLabelWidth 191 191 def_aboutXOff=8 … … 304 304 globaloptions_curtheme=(prev.x2 + xSeparation) (yoffset + glOff) (parent.w - self.x - xBorder) kLineHeight 305 305 yoffset=(yoffset + buttonHeight + ySeparation) 306 306 globaloptions_autosaveperiod=xBorder yoffset (parent.w - self.x - xBorder) kPopUpHeight 307 yoffset=(yoffset + prev.h + ySeparation) 308 globaloptions_guilanguage=prev.x yoffset prev.w prev.h 307 309 308 310 globaloptions_cancel=(parent.w - 2 * buttonWidth - xSeparation - xBorder) (parent.h - buttonHeight - 8) buttonWidth buttonHeight 309 311 globaloptions_ok=(prev.x2 + xSeparation) prev.y prev.w prev.h -
po/POTFILES
1 #TODO: help_string & usage_string: 2 base/commandLine.cpp 3 base/main.cpp 4 common/advancedDetector.cpp 5 common/config-manager.cpp 6 common/util.cpp 7 graphics/mpeg_player.cpp 8 #gui/about.cpp 9 gui/browser.cpp 10 gui/chooser.cpp 11 #gui/credits.h 12 gui/debugger.cpp 13 gui/KeysDialog.h 14 gui/KeysDialog.cpp 15 gui/launcher.cpp 16 gui/massadd.cpp 17 gui/message.h 18 gui/newgui.cpp 19 gui/options.cpp 20 gui/themebrowser.cpp 21 gui/ThemeClassic.cpp 22 gui/ThemeModern.cpp 23 sound/mididrv.cpp 24 sound/softsynth/fluidsynth.cpp 25 sound/softsynth/mt32.cpp 26 27 backends/platform/sdl/graphics.cpp 28 backends/platform/wince/wince-sdl.cpp 29 30 #TODO: backends engines tools? -
po/remove-potcdate.sed
1 # Sed script that remove the POT-Creation-Date line in the header entry 2 # from a POT file. 3 # 4 # The distinction between the first and the following occurrences of the 5 # pattern is achieved by looking at the hold space. 6 /^"POT-Creation-Date: .*"$/{ 7 x 8 # Test if the hold space is empty. 9 s/P/P/ 10 ta 11 # Yes it was empty. First occurrence. Remove the line. 12 g 13 d 14 bb 15 :a 16 # The hold space was nonempty. Following occurrences. Do nothing. 17 x 18 :b 19 } -
tools/README
51 51 Used to convert scumm-md5.txt into a SCUMM header file, or alternatively 52 52 PHP code for our website. 53 53 54 55 po2c 56 ---- 57 This perl script allows to convert all the translated messages in the .po 58 files into a C++ file so it can be included inside ScummVM without runtime 59 dependencies. 60 -
tools/po2c
1 #!/usr/bin/perl 2 3 # 4 # po2c - Converts .po files to C code 5 # 6 # Copyright (C) 2004 Angel Ortega <angel@triptico.com> 7 # 8 # This program is free software; you can redistribute it and/or modify 9 # it under the terms of the GNU General Public License as published by 10 # the Free Software Foundation; either version 2 of the License, or 11 # (at your option) any later version. 12 # 13 # This program is distributed in the hope that it will be useful, 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 # GNU General Public License for more details. 17 # 18 # You should have received a copy of the GNU General Public License 19 # along with this program; if not, write to the Free Software 20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 # 22 # http://www.triptico.com 23 # 24 25 $VERSION = "1.0.2"; 26 27 if(scalar(@ARGV) == 0) 28 { 29 print "Usage: po2c {po file[s]}\n"; 30 exit 1; 31 } 32 33 %msgs = (); 34 %msgids = (); 35 36 # stage 1: loading 37 38 # arguments are .po files 39 foreach my $f (@ARGV) 40 { 41 my ($lang); 42 43 next unless(($lang) = ($f =~ /([^\/]+)\.po$/)); 44 45 if(open F, $f) 46 { 47 my ($msgid, $val, %a); 48 49 while(<F>) 50 { 51 chomp; 52 53 # ignore blank lines or comments 54 next if /^$/ or /^#/; 55 56 if(/^msgid\s+\"(.*)\"\s*$/) 57 { 58 # store previous msgid 59 if(defined($msgid)) 60 { 61 $a{$msgid} = $val; 62 $msgids{$msgid} ++; 63 } 64 65 # start of msgid 66 $val = $1; 67 } 68 elsif(/^msgstr\s+\"(.*)\"\s*$/) 69 { 70 # store previous msgid 71 $msgid = $val; 72 73 # start of msgstr 74 $val = $1; 75 } 76 elsif(/^\"(.*)\"\s*$/) 77 { 78 # add to current value 79 $val .= $1; 80 } 81 } 82 83 # store previous msgid 84 if(defined($msgid)) 85 { 86 $a{$msgid} = $val; 87 $msgids{$msgid} ++; 88 } 89 90 close F; 91 92 # add to the global message pool 93 $msgs{$lang} = \%a; 94 } 95 } 96 97 # stage 2: convert the data 98 99 # stores all sorted msgids into @msgids 100 @msgids = sort(keys(%msgids)); 101 102 # travels again, storing indexes into %msgids 103 for(my $n = 0;$n < scalar(@msgids);$n++) 104 { 105 $msgids{$msgids[$n]} = $n; 106 } 107 108 # stage 3: dump as C code 109 110 print "/* generated by po2c $VERSION - Do not modify */\n\n"; 111 print "#include <stdio.h>\n"; 112 print "#include <string.h>\n\n"; 113 114 # dump first the msgid array 115 print "static const char * _po2c_msgids[] = {\n"; 116 117 for(my $n = 0;$n < scalar(@msgids);$n++) 118 { 119 print "\t/* $n */ \"" . $msgids[$n] . "\",\n"; 120 } 121 122 print "\tNULL\n};\n\n"; 123 124 # dump the lang structure 125 print "struct _po2c_msg {\n"; 126 print "\tint msgid;\n"; 127 print "\tconst char * msgstr;\n"; 128 print "};\n\n"; 129 130 # dump now each language 131 132 foreach my $l (keys(%msgs)) 133 { 134 print "static struct _po2c_msg _po2c_lang_${l}[] = {\n"; 135 136 # get the translation table for the language $l 137 my ($m) = $msgs{$l}; 138 139 # while (my ($msgstr, $msgid) = each (%$m)) 140 foreach my $msgid (sort(keys(%$m))) 141 { 142 my ($msgstr) = $m->{$msgid}; 143 144 print "\t{ " . $msgids{$msgid} . ", \"" . $msgstr . "\" },\n" 145 if $msgstr; 146 } 147 148 print "\t{ -1, NULL }\n};\n\n"; 149 } 150 151 # finally, dump the languages 152 153 print "static struct {\n"; 154 print "\tconst char * lang;\n"; 155 print "\tconst char * charset;\n"; 156 print "\tstruct _po2c_msg * msgs;\n"; 157 print "} _po2c_langs[] = {\n"; 158 159 foreach my $l (keys(%msgs)) 160 { 161 $header = $msgs{$l}->{""}; 162 $header =~ /charset=([^\\]+)/; 163 $charset = $1; 164 print "\t{ \"" . $l . "\", \"" . $charset . "\", _po2c_lang_${l} },\n"; 165 } 166 167 print "\t{ NULL, NULL, NULL }\n};\n\n"; 168 169 print "/* code */\n"; 170 print << 'EOF'; 171 172 static struct _po2c_msg * _po2c_lang=NULL; 173 static int _po2c_lang_size=0; 174 static const char * _po2c_charset=NULL; 175 176 void po2c_setlang(const char * lang) 177 { 178 int n; 179 180 _po2c_lang=NULL; 181 _po2c_lang_size=0; 182 _po2c_charset=NULL; 183 184 /* if lang is NULL or "", deactivate it */ 185 if(lang == NULL || *lang == '\0') 186 return; 187 188 /* searches for a valid language array */ 189 for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++) 190 { 191 if(strcmp(lang, _po2c_langs[n].lang) == 0) { 192 _po2c_lang=_po2c_langs[n].msgs; 193 _po2c_charset=_po2c_langs[n].charset; 194 } 195 } 196 197 /* try partial searches */ 198 for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++) 199 { 200 if(strncmp(lang, _po2c_langs[n].lang, 2) == 0) { 201 _po2c_lang=_po2c_langs[n].msgs; 202 _po2c_charset=_po2c_langs[n].charset; 203 } 204 } 205 206 /* if found, count entries */ 207 if(_po2c_lang != NULL) 208 { 209 struct _po2c_msg * m; 210 211 for(m=_po2c_lang;m->msgid != -1;m++) 212 _po2c_lang_size++; 213 } 214 } 215 216 const char * po2c_gettext(const char * msgid) 217 { 218 struct _po2c_msg * m; 219 int b, t, n, c; 220 221 /* if no language is set or msgid is empty, return msgid as is */ 222 if(_po2c_lang == NULL || *msgid == '\0') 223 return(msgid); 224 225 /* binary-search for the msgid */ 226 b=0; t=_po2c_lang_size - 1; 227 228 while(t >= b) 229 { 230 n=(b + t) / 2; 231 m=&_po2c_lang[n]; 232 233 c=strcmp(msgid, _po2c_msgids[m->msgid]); 234 235 if(c == 0) 236 return(m->msgstr); 237 else 238 if(c < 0) 239 t=n - 1; 240 else 241 b=n + 1; 242 } 243 244 return(msgid); 245 } 246 247 const char * po2c_getcharset(void) 248 { 249 if (_po2c_charset) 250 return _po2c_charset; 251 else 252 return "ASCII"; 253 } 254 255 int po2c_getnumlangs(void) 256 { 257 int n = 0; 258 while (_po2c_langs[n].lang) 259 n++; 260 261 return n; 262 } 263 264 const char * po2c_getlang(int num) 265 { 266 return _po2c_langs[num].lang; 267 } 268 EOF 269 270 exit 0;