An Internationalized Software Project With Auto Tools | ||
---|---|---|
Prev | Using wxWidgets | Next |
# rm src/main.cpp # rm src/i18n.cpp # rm src/i18n.h # rm src/testproj.h # rm -r src/testmodule # mkdir src/gui # touch src/main.cpp # touch src/i18n.cpp # touch src/i18n.h # touch src/gui/testproj_app.h # touch src/gui/testproj_app.cpp # touch src/gui/testproj_frame.h # touch src/gui/testproj_frame.cpp # touch src/gui/testproj_dlg.h # touch src/gui/testproj_dlg.cpp # touch src/gui/Makefile.am |
configure.ac |
... # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile src/gui/Makefile po/Makefile.in m4/Makefile \ doc/Makefile doc/de/Makefile]) AC_OUTPUT |
src/Makefile.am |
SUBDIRS = gui bin_PROGRAMS = testproj testproj_SOURCES = main.cpp i18n.cpp noinst_HEADERS = |
src/doc/Makefile.am |
... htmlhelp_DATA = $(pictures) |
src/doc/Makefile.lang.am |
... htmlhelp_DATA = $(pictures) |
src/i18n.h |
#include <wx/intl.h> #define i18n(x) sgettext(_T(x)) #define i18nTranslate(x) sgettext(x) #define i18nP(singular, plural, n) wxPLURAL(singular, plural, n) #define i18nM(x) _T(x) const wxChar * sgettext (const wxChar * msgid); int strcntchar(const wxChar * s, wxChar c); |
src/i18n.cpp |
#include "i18n.h" int strcntchar(const wxChar * s, wxChar c) { for (int i = 0; ; ++s, ++i) { if (!(s = wxStrchr(s, c))) return i; } } const wxChar * sgettext (const wxChar * msgid) { const wxChar * msgval = wxGetTranslation(msgid); int pipeCount = strcntchar(msgid, '|'); if (pipeCount && pipeCount == strcntchar(msgval, '|')) msgval = wxStrchr(msgval, '|') + 1; return msgval; } |
src/main.cpp |
#include "gui/testproj_app.h" IMPLEMENT_APP(CTestProjApp); |
src/gui/testproj_app.h |
#ifndef TESTPROJ_APP_INCLUDED #define TESTPROJ_APP_INCLUDED #include <wx/app.h> #include "wx/help.h" class CTestProjFrame; class CTestProjApp : public wxApp { static CTestProjApp * m_app; CTestProjFrame * m_frame; wxHelpController * m_helpController; wxString m_helpFile, m_language; bool m_localeSwitchFound, m_deleteLogger; wxLog * m_oldLogger; wxString getHelpFile(); public: static CTestProjApp * getApplication(); static wxHelpController * getHelpController(); CTestProjApp(); ~CTestProjApp(); virtual bool OnInit(); void OnInitCmdLine(wxCmdLineParser & parser); bool OnCmdLineParsed(wxCmdLineParser & parser); bool OnCmdLineError(wxCmdLineParser & parser); }; #endif |
src/gui/testproj_app.cpp |
#include "testproj_app.h" #include "../i18n.h" #include <wx/cmdline.h> #include <wx/cshelp.h> #include <wx/log.h> #include <wx/filename.h> #include <wx/image.h> #include "testproj_frame.h" #define HELP_DIRECTORY L"" HELPDIR CTestProjApp * CTestProjApp::m_app; wxString CTestProjApp::getHelpFile() { if (m_helpFile.length()) return m_helpFile; #ifdef __WXMSW__ wxString filePrefix = wxT("doc"); filePrefix.Append(wxFileName::GetPathSeparator()); wxString filePostfix = wxT("testproj.chm"); #else wxString filePrefix = HELP_DIRECTORY; if (filePrefix.length() > 0 && filePrefix.at(filePrefix.length() - 1) != wxFileName::GetPathSeparator()) filePrefix.Append(wxFileName::GetPathSeparator()); wxString filePostfix = wxT("testproj.hhp"); #endif wxString s = filePrefix + m_language + wxFileName::GetPathSeparator() + filePostfix; if (::wxFileExists(s)) return s; int i = m_language.find('_'); if (i > 0 && i < (int)m_language.length() - 1) { wxString lang = m_language.substr(0, i); (m_localeSwitchFound?wxLogError:wxLogMessage) (i18n("Help file \"%s\" does not exist. Trying language %s instead"), s.c_str(), lang.c_str()); s = filePrefix + lang + wxFileName::GetPathSeparator() + filePostfix; if (::wxFileExists(s)) return s; } (m_localeSwitchFound?wxLogError:wxLogMessage) (i18n("Help file \"%s\" does not exist. Trying default instead"), s.c_str()); s = filePrefix + filePostfix; if (::wxFileExists(s)) return s; wxLogError(i18n("Default help file \"%s\" does not exist."), s.c_str()); return wxT(""); } |
src/gui/testproj_app.cpp |
... CTestProjApp * CTestProjApp::getApplication() { return m_app; } wxHelpController * CTestProjApp::getHelpController() { return getApplication()->m_helpController; } CTestProjApp::CTestProjApp() : m_helpController(NULL), m_localeSwitchFound(false) , m_deleteLogger(false), m_oldLogger(NULL) { } CTestProjApp::~CTestProjApp() { delete m_helpController; if (m_deleteLogger) { delete wxLog::SetActiveTarget(m_oldLogger); } } bool CTestProjApp::OnInit() { wxLog::SetVerbose(true); #ifndef __WXMSW__ m_oldLogger = wxLog::SetActiveTarget( new wxLogStderr ); m_deleteLogger = true; #endif wxImage::AddHandler(new wxPNGHandler()); m_app = this; if (!wxApp::OnInit()) return false; SetVendorName(wxT("J.T. Kirk")); wxString helpFile = getHelpFile(); wxHelpController * helpController = new wxHelpController(); if (helpFile.length()) wxLogMessage(i18n("Using help file \"%s\"."), helpFile.c_str()); if (!helpFile.length() || !helpController->Initialize(helpFile)) { wxLogWarning(wxT("Cannot initialize the help system")); delete helpController; } else { m_helpController = helpController; wxHelpControllerHelpProvider* provider = new wxHelpControllerHelpProvider; wxHelpProvider::Set(provider); provider->SetHelpController(m_helpController); } m_frame = new CTestProjFrame(i18n("Test Project")); m_frame->Show(TRUE); SetTopWindow(m_frame); return true; } |
src/gui/testproj_app.cpp |
... void CTestProjApp::OnInitCmdLine(wxCmdLineParser & parser) { parser.AddOption(wxT("l"), wxT("language"), i18n("language. Example: de or de_DE")); #ifdef __WXMSW__ parser.AddOption(wxT("d"), wxT("docfile"), i18n("help file. Should be a .chm file")); #else parser.AddOption(wxT("d"), wxT("docfile"), i18n("help file. Should be a .hpp file")); #endif parser.AddSwitch(wxT("?"), wxT("help"), i18n("show this help"), wxCMD_LINE_OPTION_HELP | wxCMD_LINE_PARAM_OPTIONAL); } bool CTestProjApp::OnCmdLineParsed(wxCmdLineParser & parser) { wxLocale::AddCatalogLookupPathPrefix(_T("po")); static wxLocale locale; wxString language; if (parser.Found(wxT("l"), & language)) { m_localeSwitchFound = true; m_language = language; const wxLanguageInfo * languageInfo = wxLocale::FindLanguageInfo(language); if (!languageInfo) { wxLogError(i18n("Locale (language) \"%s\" does not exist"), language.c_str()); return false; } locale.Init(languageInfo->Language); } else { locale.Init(); m_language = locale.GetCanonicalName(); } if (parser.Found(wxT("d"), & m_helpFile)) { if (!::wxFileExists(m_helpFile)) { wxLogError(i18n("Help file \"%s\" does not exist"), m_helpFile.c_str()); return false; } } wxString canonicalName = locale.GetCanonicalName(); wxLogMessage(i18n("Using locale (language): %s"), (canonicalName.length()?canonicalName:wxString(i18n("Default"))).c_str()); if (locale.AddCatalog(wxT("testproj"))) { wxLogMessage(i18n("Locale (language) catalog found")); } else { if (language.length()) { wxLogError(i18n("Locale (language) catalog not found")); return false; } wxLogMessage(i18n("Locale (language) catalog not found. Using default")); } return true; } bool CTestProjApp::OnCmdLineError(wxCmdLineParser & parser) { parser.Usage(); return false; } |
src/gui/testproj_frame.h |
#ifndef TESTPROJ_FRAME_INCLUDED #define TESTPROJ_FRAME_INCLUDED #include <wx/frame.h> class wxCommandEvent; class CTestProjFrame : public wxFrame { enum CTestProjFrameWindowIds {openDialogId = wxID_HIGHEST + 1, helpContentsId, helpPrefaceId}; public: CTestProjFrame(const wxString & title); void OnHelpContents(wxCommandEvent & event); void OnHelpPreface(wxCommandEvent & event); void OnOpenDialog(wxCommandEvent & event); DECLARE_EVENT_TABLE() }; #endif |
src/gui/testproj_frame.cpp |
#include "testproj_frame.h" #include "../i18n.h" #include <wx/menu.h> #include <wx/sizer.h> #include <wx/textctrl.h> #include <wx/stattext.h> #include <wx/settings.h> #include "testproj_app.h" #include "testproj_dlg.h" // These arrays will be instantiated before gettext is initialized. // Nevertheless they will be translated correctly // The string 'right' has two different meanings and is prefixed, so that it // can have different translations. const wxChar * directions [] = {i18nM("directions|right"), i18nM("left")}; const wxChar * results [] = {i18nM("results|right"), i18nM("wrong")}; |
src/gui/testproj_frame.cpp |
... CTestProjFrame::CTestProjFrame(const wxString & title) : wxFrame(NULL, wxID_ANY, title) { wxMenu *menuOpen = new wxMenu; menuOpen->Append(openDialogId, i18n("&Dialog"), i18n("Open a dialog")); wxMenu *menuHelp = new wxMenu; menuHelp->Append(helpContentsId, i18n("&Contents"), i18n("Show the contents of the documentation")); menuHelp->Append(helpPrefaceId, i18n("&Preface"), i18n("Show the preface of the documentation")); wxMenuBar *menuBar = new wxMenuBar; menuBar->Append(menuOpen, i18n("&Open")); menuBar->Append(menuHelp, i18n("&Help")); SetMenuBar( menuBar ); CreateStatusBar(); SetStatusText(i18n("Welcome to TestProj!")); wxString s; s.Printf(_T("%d"), sizeof(wxChar)); s = i18n("Sizeof(wxChar): ") + s + _T("\n"); s += i18n("Possible directions: "); s += i18nTranslate(directions[0]); s += _T(", "); s += i18nTranslate(directions[1]); s += _T("\n"); s += i18n("Possible results: "); s += i18nTranslate(results[0]); s += _T(", "); s += i18nTranslate(results[1]); wxTextCtrl * textCtrl = new wxTextCtrl(this, wxID_ANY, s, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); wxBoxSizer * sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(textCtrl, 1, wxEXPAND, 0); sizer->SetMinSize(wxSize(300, 100)); SetSizer(sizer); sizer->SetSizeHints(this); } |
src/gui/testproj_frame.cpp |
... void CTestProjFrame::OnHelpContents(wxCommandEvent & WXUNUSED(event)) { if (CTestProjApp::getHelpController()) CTestProjApp::getHelpController()->DisplayContents(); } void CTestProjFrame::OnHelpPreface(wxCommandEvent & WXUNUSED(event)) { if (CTestProjApp::getHelpController()) CTestProjApp::getHelpController()->DisplaySection(_T("overview.html")); } void CTestProjFrame::OnOpenDialog(wxCommandEvent & event) { CTestProjDlg testProjDlg(this); testProjDlg.ShowModal(); } BEGIN_EVENT_TABLE(CTestProjFrame, wxFrame) EVT_MENU(CTestProjFrame::helpContentsId, CTestProjFrame::OnHelpContents) EVT_MENU(CTestProjFrame::helpPrefaceId, CTestProjFrame::OnHelpPreface) EVT_MENU(CTestProjFrame::openDialogId, CTestProjFrame::OnOpenDialog) END_EVENT_TABLE() |
src/gui/testproj_dlg.h |
#ifndef TESTPROJ_DLG_INCLUDED #define TESTPROJ_DLG_INCLUDED #include <wx/dialog.h> class wxTextCtrl; class wxStaticText; class wxCommandEvent; class CTestProjDlg : public wxDialog { enum CTestProjFrameWindowIds {numberTextCtrlId = wxID_HIGHEST + 1}; wxTextCtrl * m_numberTextCtrl; wxStaticText * m_resultStaticText; public: CTestProjDlg(wxWindow * parent); void OnNumberCtrlTextChanged(wxCommandEvent & event); void OnHelpButtonClicked(wxCommandEvent & event); DECLARE_EVENT_TABLE() }; #endif |
src/gui/testproj_dlg.cpp |
#include "testproj_dlg.h" #include "testproj_app.h" #include "../i18n.h" #include <wx/sizer.h> #include <wx/textctrl.h> #include <wx/stattext.h> CTestProjDlg::CTestProjDlg(wxWindow * parent) : wxDialog(parent, wxID_ANY, wxString(i18n("A Test Dialog")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { wxBoxSizer * sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer * inputFieldSizer = new wxBoxSizer(wxHORIZONTAL); inputFieldSizer->Add(new wxStaticText(this, wxID_ANY, i18n("&Please enter a number:")) , 0, wxALIGN_CENTER_VERTICAL, 3); m_numberTextCtrl = new wxTextCtrl(this, numberTextCtrlId, _T(""), wxDefaultPosition , wxDefaultSize); inputFieldSizer->Add(m_numberTextCtrl, 1, wxALL | wxEXPAND, 3); sizer->Add(inputFieldSizer, 0, wxALIGN_TOP | wxALL | wxEXPAND); m_resultStaticText = new wxStaticText(this, wxID_ANY, _T(" ")); sizer->Add(m_resultStaticText, 0, wxALL | wxEXPAND); sizer->Add(new wxStaticText(this, wxID_ANY, _T("")), 1, wxEXPAND); wxBoxSizer * button_sizer = new wxBoxSizer(wxHORIZONTAL); button_sizer->Add(new wxButton(this, wxID_HELP, i18n("&Help")), 0, wxALL, 3); wxButton * ok = new wxButton(this, wxID_OK, i18n("&OK")); button_sizer->Add(ok, 0, wxALL, 3); ok->SetDefault(); sizer->Add(button_sizer, 0, wxALIGN_BOTTOM | wxALIGN_RIGHT); SetSizer(sizer); sizer->SetSizeHints(this); } |
src/gui/testproj_dlg.cpp |
... void CTestProjDlg::OnNumberCtrlTextChanged(wxCommandEvent & event) { wxString text = m_numberTextCtrl->GetValue(); long val = -1; bool valid = text.ToLong(& val); if (val < 0) valid = false; wxString s; if (valid) s.Printf(i18nP("You have won one point", "You have won %d points", val), val); else s = i18n("Error: enter a non negative number!"); m_resultStaticText->SetLabel(s); } void CTestProjDlg::OnHelpButtonClicked(wxCommandEvent & event) { if (CTestProjApp::getHelpController()) CTestProjApp::getHelpController()->DisplaySection(_T("test_chapter.html")); } BEGIN_EVENT_TABLE(CTestProjDlg, wxDialog) EVT_TEXT(CTestProjDlg::numberTextCtrlId, CTestProjDlg::OnNumberCtrlTextChanged) EVT_BUTTON(wxID_HELP, CTestProjDlg::OnHelpButtonClicked) END_EVENT_TABLE() |
src/gui/Makefile.am |
noinst_LIBRARIES = libgui.a noinst_HEADERS = testproj_app.h testproj_frame.h testproj_dlg.h libgui_a_SOURCES = testproj_app.cpp testproj_frame.cpp testproj_dlg.cpp DEFS = -DHELPDIR=\"$(helpdir)\" @DEFS@ |
# gmake ... # gmake update-po ... |
po/de.po |
... #: src/gui/testproj_app.cpp:39 #, c-format msgid "Help file \"%s\" does not exist. Trying language %s instead" msgstr "Hilfe-Datei \"%s\" existiert nicht. Versuche statt dessen Sprache %s" #: src/gui/testproj_app.cpp:46 #, c-format msgid "Help file \"%s\" does not exist. Trying default instead" msgstr "Hilfe-Datei \"%s\" existiert nicht. Versuche statt dessen Standardsprache" #: src/gui/testproj_app.cpp:50 #, c-format msgid "Default help file \"%s\" does not exist." msgstr "Standard Hilfe-Datei \"%s\" existiert nicht." #: src/gui/testproj_app.cpp:93 #, c-format msgid "Using help file \"%s\"." msgstr "Verwende Hilfe-Datei \"%s\"." #: src/gui/testproj_app.cpp:106 msgid "Test Project" msgstr "Test Projekt" #: src/gui/testproj_app.cpp:114 msgid "language. Example: de or de_DE" msgstr "Sprache. Beispiel: de oder de_DE" #: src/gui/testproj_app.cpp:116 msgid "help file. Should be a .chm file" msgstr "Hilfe-Datei. Sollte eine .chm Datei sein" #: src/gui/testproj_app.cpp:118 msgid "help file. Should be a .hpp file" msgstr "Hilfe-Datei. Sollte eine .hpp Datei sein" #: src/gui/testproj_app.cpp:120 msgid "show this help" msgstr "Zeige diese Hilfe an" #: src/gui/testproj_app.cpp:137 #, c-format msgid "Locale (language) \"%s\" does not exist" msgstr "\"Locale\" (Sprache) \"%s\" existiert nicht" #: src/gui/testproj_app.cpp:151 #, c-format msgid "Help file \"%s\" does not exist" msgstr "Hilfe-Datei \"%s\" existiert nicht" #: src/gui/testproj_app.cpp:157 #, c-format msgid "Using locale (language): %s" msgstr "Verwende \"Locale\" (Sprache): %s" #: src/gui/testproj_app.cpp:158 msgid "Default" msgstr "Standard" #: src/gui/testproj_app.cpp:161 msgid "Locale (language) catalog found" msgstr "\"Locale\" (Sprach-) Katalog gefunden" #: src/gui/testproj_app.cpp:167 msgid "Locale (language) catalog not found" msgstr "\"Locale\" (Sprach-) Katalog nicht gefunden" #: src/gui/testproj_app.cpp:170 msgid "Locale (language) catalog not found. Using default" msgstr "\"Locale\" (Sprach-) Katalog nicht gefunden.Verwende Standardkatalog" #: src/gui/testproj_dlg.cpp:10 msgid "A Test Dialog" msgstr "Ein Test Dialog" #: src/gui/testproj_dlg.cpp:16 |
# gmake update-gmo ... 37 translated messages. ... # gmake install ... # testproj --help Usage: testproj [-l <str>] [-d <str>] [-?] -l, --language=<str> language. Example: de or de_DE -d, --docfile=<str> help file. Should be a .hpp file -?, --help show this help # testproj ... 21:18:37: Using locale (language): en_GB 21:18:37: looking for catalog 'testproj' in path 'po/en_GB/LC_MESSAGES:po/en_GB:... 21:18:37: catalog file for domain 'testproj' not found. 21:18:37: Locale (language) catalog found 21:18:37: Help file "/usr/local/share/doc/testproj/en_GB/testproj.hhp" does not exist. Trying language en instead 21:18:37: Help file "/usr/local/share/doc/testproj/en/testproj.hhp" does not exist. Trying default instead 21:18:37: Using help file "/usr/local/share/doc/testproj/testproj.hhp". |
# testproj -l de ... 02:16:49: Using locale (language): de_DE 02:16:49: Suche Nachrichtenkatalog 'testproj' in Pfad 'po/de_DE/LC_MESSAGES:po/de_DE:... 02:16:49: Verwende Nachrichtenkatalog 'testproj' von '/usr/local/share/locale/de/LC_MESSAGES/testproj.mo'. 02:16:49: "Locale" (Sprach-) Katalog gefunden 02:16:49: Verwende Hilfe-Datei "/usr/local/share/doc/testproj/de/testproj.hhp". |
Prev | Home | Next |
wxWidgets Overview | Compiling under windows |