Create basic gettext infrastructure and French language stub.

master
don bright 2014-10-18 19:13:57 +02:00 committed by Torsten Paul
parent b66fb597fa
commit c559be20e1
14 changed files with 3365 additions and 1 deletions

85
doc/translation.txt Normal file
View File

@ -0,0 +1,85 @@
OpenSCAD human language translation
===================================
We use the GNU gettext system, both for c++ code as well as QT's .ui files.
The latter is accomplished by the '-tr' feature of QT's uic to insert
a gettext wrapper into the ui_xxxxx.h files.
For somewhat similar designs, see the source code of projects like celestia,
stellarium, licq, merkaartor, etc (although they typically use cmake).
Currently the build system does not auto-update anything. The .mo files must
be generated by running the gettext tools: xgettext, msgmerge, and msgfmt.
There is a script included, translation-update.sh, that automates this process.
File layout:
============
./po/*.po - .po files, one per language
./po/openscad.pot - .pot template, generated by xgettext
./po/POTFILES.in - list of source code files with translatable strings
./po/LINGUAS - list of language codes for which .po files exist
./src/qtgettext.h - wrapper code between QT and GNU gettext
./scripts/translation-update.sh - simple unix helper script
./po/xx/LC_MESSAGES/openscad.mo - 'binaries' of .po files, built by script
To translate the strings:
=========================
Use a text editor or special program (poedit or lokalize) to edit the .po file.
( See http://en.opensuse.org/SDB:Localization_work_with_po_files )
Then submit your new .po file as an OpenSCAD github issue or pull request:
https://github.com/openscad/openscad/issues/
In the future there might be a site to allow translations in a browser:
https://translations.launchpad.net/openscad
If all else fails, email the OpenSCAD mailing list with your new .po
file attached.
To make source code changes:
============================
In .cc files, #include "printutils.h" and change each "text" into
_("text"). In .ui files, #include "qtgettext.h" first in the .h file
(see MainWindow.h). Then clean and rebuild to recreate the ui_xxxx.h
files.
$ make clean && qmake && make
Now make sure your .cc and ui_xxxx.h files are listed in po/POTFILES.in.
Then run the script to scan them, and regenerate .pot & .po files.
$ ./scripts/translate.sh updateall
This will create new .po files with any new untranslated strings you
added to the source code. These .po files can be distributed to
translators for translation. After the translated .po file is obtained,
overwrite the old .po and run the same script to update the .mo files.
$ ./scripts/translate.sh updateall
To add a new language:
======================
First add the language code to file ./po/LINGUAS. Then run msginit, replacing
$LANGCODE with the language code you want.
$ msginit -l $LANGCODE -o ./po/$LANGCODE.po -i ./po/openscad.pot
You will now have a new ./po/xx.po file to edit and translate
Testing:
========
On unix, set the locale related environment variables. For example in
French, run this:
$ LANGUAGE=fr ./openscad
Linux system trace tools can help find errors. To show open()s on .mo files:
$ LANGUAGE=fr strace -f ./openscad 2>&1 | grep LC_MESSAGES

View File

@ -120,6 +120,8 @@ unix:!macx {
QMAKE_LIBS_OPENGL *= -lX11
}
#QTPLUGIN += qtaccessiblewidgets
netbsd* {
QMAKE_LFLAGS += -L/usr/X11R7/lib
QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib
@ -159,6 +161,8 @@ netbsd* {
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions
# gettext
QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security
# might want to actually turn this on once in a while
QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare
}
@ -208,7 +212,9 @@ win* {
RESOURCES = openscad.qrc
FORMS += src/MainWindow.ui \
QMAKE_UIC += -tr _
FORMS += src/MainWindow.ui \
src/Preferences.ui \
src/OpenCSGWarningDialog.ui \
src/AboutDialog.ui \

2
po/LINGUAS Normal file
View File

@ -0,0 +1,2 @@
# available languages
fr

77
po/POTFILES.in Normal file
View File

@ -0,0 +1,77 @@
# see doc/translation.txt
# ui_xxxx.h files created by qt's uic when make is run.
# if you add new .ui files, add their .h counterpart here
objects/ui_AboutDialog.h
objects/ui_OpenCSGWarningDialog.h
objects/ui_ProgressWidget.h
objects/ui_MainWindow.h
objects/ui_Preferences.h
# C++
src/AppleEvents.cc
src/builtin.cc
src/cgaladv.cc
src/cgaladv_minkowski2.cc
src/CGALCache.cc
src/CGALEvaluator.cc
src/CGAL_Nef_polyhedron.cc
src/CGAL_Nef_polyhedron_DxfData.cc
src/CGALRenderer.cc
src/cgalutils.cc
src/cgalworker.cc
src/color.cc
src/context.cc
src/control.cc
src/csgops.cc
src/csgterm.cc
src/CSGTermEvaluator.cc
src/csgtermnormalizer.cc
src/dxfdata.cc
src/dxfdim.cc
src/dxftess.cc
src/dxftess-cgal.cc
src/dxftess-glu.cc
src/editor.cc
src/export.cc
src/expr.cc
src/func.cc
src/glview.cc
src/handle_dep.cc
src/highlighter.cc
src/import.cc
src/linalg.cc
src/linearextrude.cc
src/mainwin.cc
src/mathc99.cc
src/ModuleCache.cc
src/module.cc
src/node.cc
src/nodedumper.cc
src/OpenCSGRenderer.cc
src/OpenCSGWarningDialog.cc
src/openscad.cc
src/parsersettings.cc
src/PolySetCache.cc
src/polyset.cc
src/PolySetCGALEvaluator.cc
src/PolySetEvaluator.cc
src/Preferences.cc
src/primitives.cc
src/printutils.cc
src/progress.cc
src/ProgressWidget.cc
src/projection.cc
src/render.cc
src/renderer.cc
src/rendersettings.cc
src/rotateextrude.cc
src/stl-utils.cc
src/surface.cc
src/svg.cc
src/ThrownTogetherRenderer.cc
src/transform.cc
src/traverser.cc
src/Tree.cc
src/value.cc
src/version_check.cc

1556
po/fr.po Normal file

File diff suppressed because it is too large Load Diff

1553
po/openscad.pot Normal file

File diff suppressed because it is too large Load Diff

58
scripts/translation-update.sh Executable file
View File

@ -0,0 +1,58 @@
#!/bin/sh
# see doc/translation.txt for more info
updatepot()
{
if [ ! -e objects/ui_MainWindow.h ]; then
echo cannot find objects/ui_xxxxx.h files. perhaps if you run make...?
exit 1
fi
VER=`date +"%Y.%m.%d"`
OPTS=
OPTS=$OPTS' --package-name=OpenSCAD'
OPTS=$OPTS' --package-version='$VER
OPTS=$OPTS' --default-domain=openscad'
OPTS=$OPTS' --keyword=_'
OPTS=$OPTS' --files-from=./po/POTFILES.in'
cmd='xgettext '$OPTS' -o ./po/openscad.pot'
echo $cmd
$cmd
if [ ! $? = 0 ]; then
echo error running xgettext
exit 1
fi
sed -i s/"CHARSET"/"UTF-8"/g ./po/openscad.pot
}
updatepo()
{
for LANGCODE in `cat ./po/LINGUAS | grep -v "#"`; do
OPTS='--update --backup=t'
cmd='msgmerge '$OPTS' ./po/'$LANGCODE'.po ./po/openscad.pot'
echo $cmd
$cmd
if [ ! $? = 0 ]; then
echo error running msgmerge
exit 1
fi
done
}
updatemo()
{
for LANGCODE in `cat po/LINGUAS | grep -v "#"`; do
mkdir -p ./po/$LANGCODE/LC_MESSAGES
OPTS='-c -v'
cmd='msgfmt '$OPTS' -o ./po/'$LANGCODE'/LC_MESSAGES/openscad.mo ./po/'$LANGCODE'.po'
echo $cmd
$cmd
if [ ! $? = 0 ]; then
echo error running msgfmt
exit 1
fi
done
}
updatepot && updatepo && updatemo

View File

@ -1,5 +1,6 @@
#pragma once
#include "qtgettext.h"
#include "ui_AboutDialog.h"
#define STRINGIFY(x) #x

View File

@ -1,5 +1,6 @@
#pragma once
#include "qtgettext.h"
#include <QMainWindow>
#include <QIcon>
#include "ui_MainWindow.h"

View File

@ -1,5 +1,6 @@
#pragma once
#include "qtgettext.h"
#include "ui_OpenCSGWarningDialog.h"
class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog

View File

@ -1,5 +1,6 @@
#pragma once
#include "qtgettext.h"
#include <QMainWindow>
#include <QSettings>
#include "ui_Preferences.h"

View File

@ -1,5 +1,6 @@
#pragma once
#include "qtgettext.h"
#include "ui_ProgressWidget.h"
#include <QTime>

View File

@ -5,6 +5,10 @@
#include <iostream>
#include <boost/format.hpp>
#include <libintl.h>
#include <locale.h>
inline char * _( const char * msgid ) { return gettext( msgid ); }
typedef void (OutputHandlerFunc)(const std::string &msg, void *userdata);
extern OutputHandlerFunc *outputhandler;
extern void *outputhandler_data;

18
src/qtgettext.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __openscad_qtgettext_h__
#define __openscad_qtgettext_h__
// see doc/translation.txt
#include "printutils.h"
#include <libintl.h>
#include <locale.h>
#include <QString>
inline QString _( const char *msgid, int category )
{
Q_UNUSED( category );
return QString::fromUtf8( _( msgid ) );
}
#endif