| 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 |