From 34c176a79970b49fd5fdca6162fb16d8e7945475 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 26 May 2024 03:57:26 -0500 Subject: [PATCH] prepare for translations --- CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ po/es.po | 23 +++++++++++++++++++++++ po/furnace.pot | 19 +++++++++++++++++++ po/pl.po | 24 ++++++++++++++++++++++++ po/pt_BR.po | 23 +++++++++++++++++++++++ po/ru.po | 24 ++++++++++++++++++++++++ scripts/update-po.sh | 27 +++++++++++++++++++++++++++ src/gui/debugWindow.cpp | 5 +++++ src/main.cpp | 21 +++++++++++++++++++++ src/ta-utils.h | 7 +++++++ 10 files changed, 203 insertions(+) create mode 100644 po/es.po create mode 100644 po/furnace.pot create mode 100644 po/pl.po create mode 100644 po/pt_BR.po create mode 100644 po/ru.po create mode 100755 scripts/update-po.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a53310bc..17b1200d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,11 @@ else() endif() endif() +# until ready +set(WITH_LOCALE_DEFAULT OFF) + option(BUILD_GUI "Build the tracker (disable to build only a headless player)" ${BUILD_GUI_DEFAULT}) +option(WITH_LOCALE "Use libintl for language support" ${WITH_LOCALE_DEFAULT}) option(USE_RTMIDI "Build with MIDI support using RtMidi." ${USE_RTMIDI_DEFAULT}) option(USE_SDL2 "Build with SDL2. Required to build with GUI." ${USE_SDL2_DEFAULT}) option(USE_SNDFILE "Build with libsndfile. Required in order to work with audio files." ${USE_SNDFILE_DEFAULT}) @@ -171,6 +175,21 @@ if (WIN32) endif() endif() +if (WITH_LOCALE) + if ("${CMAKE_VERSION}" VERSION_LESS "3.2") + message(FATAL_ERROR "CMake 3.2 or later required for locale support.") + else() + include(FindIntl) + if (NOT Intl_FOUND) + message(FATAL_ERROR "Could not find libintl!") + endif() + list(APPEND DEPENDENCIES_DEFINES HAVE_LOCALE) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${Intl_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_LIBRARIES ${Intl_LIBRARIES}) + message(STATUS "Using libintl") + endif() +endif() + if (SYSTEM_FFTW) find_package(PkgConfig REQUIRED) pkg_check_modules(FFTW REQUIRED fftw3>=3.3) @@ -1141,6 +1160,17 @@ else() add_executable(furnace ${USED_SOURCES}) endif() +if (WITH_LOCALE) + set(FURNACE_LANGUAGES es pl pt_BR ru) + set(FURNACE_LANGUAGE_DEPENDS "") + + foreach(I IN LISTS FURNACE_LANGUAGES) + add_custom_command(OUTPUT "locale/${I}/LC_MESSAGES/furnace.mo" COMMAND msgfmt ${CMAKE_SOURCE_DIR}/po/${I}.po -o "${CMAKE_BINARY_DIR}/locale/${I}/LC_MESSAGES/furnace.mo" DEPENDS po/${I}.po WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + list(APPEND FURNACE_LANGUAGE_DEPENDS "locale/${I}/LC_MESSAGES/furnace.mo") + endforeach() + add_custom_target(furnace-locale ALL DEPENDS ${FURNACE_LANGUAGE_DEPENDS}) +endif() + target_include_directories(furnace SYSTEM PRIVATE ${DEPENDENCIES_INCLUDE_DIRS}) target_compile_options(furnace PRIVATE ${DEPENDENCIES_COMPILE_OPTIONS}) target_link_libraries(furnace PRIVATE ${DEPENDENCIES_LIBRARIES}) diff --git a/po/es.po b/po/es.po new file mode 100644 index 000000000..4c01082af --- /dev/null +++ b/po/es.po @@ -0,0 +1,23 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: furnace 0.6.3\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/gui/debugWindow.cpp:662 +msgid "This is a language test." +msgstr "Este es una prueba de idioma." + +#: src/gui/debugWindow.cpp:663 +msgid "This is another language test." +msgstr "Este es otra prueba de idioma." + +#: src/main.cpp:510 +msgid "this is a test!" +msgstr "este es una prueba!" diff --git a/po/furnace.pot b/po/furnace.pot new file mode 100644 index 000000000..74243be7d --- /dev/null +++ b/po/furnace.pot @@ -0,0 +1,19 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: furnace 0.6.3\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/gui/debugWindow.cpp:662 +msgid "This is a language test." +msgstr "" + +#: src/gui/debugWindow.cpp:663 +msgid "This is another language test." +msgstr "" + +#: src/main.cpp:510 +msgid "this is a test!" +msgstr "" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 000000000..477329e1c --- /dev/null +++ b/po/pl.po @@ -0,0 +1,24 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: furnace 0.6.3\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: src/gui/debugWindow.cpp:662 +msgid "This is a language test." +msgstr "" + +#: src/gui/debugWindow.cpp:663 +msgid "This is another language test." +msgstr "" + +#: src/main.cpp:510 +msgid "this is a test!" +msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 000000000..aba8e161f --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,23 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: furnace 0.6.3\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/gui/debugWindow.cpp:662 +msgid "This is a language test." +msgstr "" + +#: src/gui/debugWindow.cpp:663 +msgid "This is another language test." +msgstr "" + +#: src/main.cpp:510 +msgid "this is a test!" +msgstr "" diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 000000000..caf4a0a52 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,24 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: furnace 0.6.3\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: src/gui/debugWindow.cpp:662 +msgid "This is a language test." +msgstr "" + +#: src/gui/debugWindow.cpp:663 +msgid "This is another language test." +msgstr "" + +#: src/main.cpp:510 +msgid "this is a test!" +msgstr "" diff --git a/scripts/update-po.sh b/scripts/update-po.sh new file mode 100755 index 000000000..fbccfdcf8 --- /dev/null +++ b/scripts/update-po.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +FUR_VERSION="0.6.3" + +EXPORT_LANGS=("es" "ru" "pl" "pt_BR") + +echo '# +msgid "" +msgstr ""' > po/furnace.pot +echo '"Project-Id-Version: furnace '"$FUR_VERSION"'\n"' >> po/furnace.pot +echo '"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +' >> po/furnace.pot + +find src/ -type f -regex ".*\(cpp\|h\)$" | xargs xgettext --omit-header -k_ -L C++ -o - >> po/furnace.pot + +cd po +for i in ${EXPORT_LANGS[@]}; do + if [ -e "$i".po ]; then + echo "merging $i"".po..." + msgmerge --backup=none -U "$i".po furnace.pot + else + echo "creating $i"".po..." + msginit -i furnace.pot -l "$i".UTF-8 --no-translator + fi +done diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 53b8aa9ae..c09afe33b 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -658,6 +658,11 @@ void FurnaceGUI::drawDebug() { } ImGui::TreePop(); } + if (ImGui::TreeNode("Locale Test")) { + ImGui::TextUnformatted(_("This is a language test.")); + ImGui::TextUnformatted(_("This is another language test.")); + ImGui::TreePop(); + } if (ImGui::TreeNode("Osc Render Test")) { ImGui::InputInt("Length",&oscDebugLen); ImGui::InputInt("Height",&oscDebugHeight); diff --git a/src/main.cpp b/src/main.cpp index 7254ddcc4..6d1ba1056 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -489,6 +489,27 @@ int main(int argc, char** argv) { zsmOutName=""; cmdOutName=""; +#ifdef HAVE_LOCALE + const char* localeRet=NULL; + if ((localeRet=setlocale(LC_ALL,""))==NULL) { + logE("could not set locale!"); + } else { + logV("locale: %s",localeRet); + } + if ((localeRet=bindtextdomain("furnace","locale"))==NULL) { + logE("could not bind text domain!"); + } else { + logV("text domain 1: %s",localeRet); + } + if ((localeRet=textdomain("furnace"))==NULL) { + logE("could not text domain!"); + } else { + logV("text domain 2: %s",localeRet); + } + + logV(_("this is a test!")); +#endif + initParams(); // parse arguments diff --git a/src/ta-utils.h b/src/ta-utils.h index 93bbdf5b0..7d6f9a9b3 100644 --- a/src/ta-utils.h +++ b/src/ta-utils.h @@ -42,6 +42,13 @@ typedef std::string String; #define MAX(a,b) (((a)>(b))?(a):(b)) #define CLAMP(x,xMin,xMax) (MIN(MAX((x),(xMin)),(xMax))) +#ifdef HAVE_LOCALE +#include +#define _(_str) gettext(_str) +#else +#define _(_str) _str +#endif + typedef std::wstring WString; enum TAParamResult {