mirror of https://github.com/vitalif/openscad
Create basic gettext infrastructure and French language stub.
parent
b66fb597fa
commit
c559be20e1
|
@ -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
|
||||||
|
|
|
@ -120,6 +120,8 @@ unix:!macx {
|
||||||
QMAKE_LIBS_OPENGL *= -lX11
|
QMAKE_LIBS_OPENGL *= -lX11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#QTPLUGIN += qtaccessiblewidgets
|
||||||
|
|
||||||
netbsd* {
|
netbsd* {
|
||||||
QMAKE_LFLAGS += -L/usr/X11R7/lib
|
QMAKE_LFLAGS += -L/usr/X11R7/lib
|
||||||
QMAKE_LFLAGS += -Wl,-R/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-variable
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions
|
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
|
# might want to actually turn this on once in a while
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare
|
||||||
}
|
}
|
||||||
|
@ -208,7 +212,9 @@ win* {
|
||||||
|
|
||||||
RESOURCES = openscad.qrc
|
RESOURCES = openscad.qrc
|
||||||
|
|
||||||
FORMS += src/MainWindow.ui \
|
QMAKE_UIC += -tr _
|
||||||
|
|
||||||
|
FORMS += src/MainWindow.ui \
|
||||||
src/Preferences.ui \
|
src/Preferences.ui \
|
||||||
src/OpenCSGWarningDialog.ui \
|
src/OpenCSGWarningDialog.ui \
|
||||||
src/AboutDialog.ui \
|
src/AboutDialog.ui \
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# available languages
|
||||||
|
fr
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qtgettext.h"
|
||||||
#include "ui_AboutDialog.h"
|
#include "ui_AboutDialog.h"
|
||||||
|
|
||||||
#define STRINGIFY(x) #x
|
#define STRINGIFY(x) #x
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qtgettext.h"
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include "ui_MainWindow.h"
|
#include "ui_MainWindow.h"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qtgettext.h"
|
||||||
#include "ui_OpenCSGWarningDialog.h"
|
#include "ui_OpenCSGWarningDialog.h"
|
||||||
|
|
||||||
class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog
|
class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qtgettext.h"
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include "ui_Preferences.h"
|
#include "ui_Preferences.h"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qtgettext.h"
|
||||||
#include "ui_ProgressWidget.h"
|
#include "ui_ProgressWidget.h"
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/format.hpp>
|
#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);
|
typedef void (OutputHandlerFunc)(const std::string &msg, void *userdata);
|
||||||
extern OutputHandlerFunc *outputhandler;
|
extern OutputHandlerFunc *outputhandler;
|
||||||
extern void *outputhandler_data;
|
extern void *outputhandler_data;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue