| File: | rootdir/src/amuled.cpp |
| Warning: | line 196, column 6 The 1st argument to 'dup' is -1 but should be >= 0 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // | |||
| 2 | // This file is part of the aMule Project. | |||
| 3 | // | |||
| 4 | // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) | |||
| 5 | // | |||
| 6 | // Any parts of this program derived from the xMule, lMule or eMule project, | |||
| 7 | // or contributed by third-party developers are copyrighted by their | |||
| 8 | // respective authors. | |||
| 9 | // | |||
| 10 | // This program is free software; you can redistribute it and/or modify | |||
| 11 | // it under the terms of the GNU General Public License as published by | |||
| 12 | // the Free Software Foundation; either version 2 of the License, or | |||
| 13 | // (at your option) any later version. | |||
| 14 | // | |||
| 15 | // This program is distributed in the hope that it will be useful, | |||
| 16 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 18 | // GNU General Public License for more details. | |||
| 19 | // | |||
| 20 | // You should have received a copy of the GNU General Public License | |||
| 21 | // along with this program; if not, write to the Free Software | |||
| 22 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |||
| 23 | // | |||
| 24 | ||||
| 25 | ||||
| 26 | #include "amule.h" // Interface declarations. | |||
| 27 | ||||
| 28 | #include <include/common/EventIDs.h> | |||
| 29 | ||||
| 30 | #include "config.h" // Needed for HAVE_SYS_RESOURCE_H, etc | |||
| 31 | ||||
| 32 | ||||
| 33 | // Include the necessary headers for select(2), properly guarded | |||
| 34 | #if defined HAVE_SYS_SELECT_H1 && !defined __IRIX__ | |||
| 35 | # include <sys/select.h> | |||
| 36 | #else | |||
| 37 | # ifdef HAVE_SYS_TIME_H1 | |||
| 38 | # include <sys/time.h> | |||
| 39 | # endif | |||
| 40 | # ifdef HAVE_SYS_TYPES_H1 | |||
| 41 | # include <sys/types.h> | |||
| 42 | # endif | |||
| 43 | # ifdef HAVE_UNISTD_H1 | |||
| 44 | # include <unistd.h> | |||
| 45 | # endif | |||
| 46 | #endif | |||
| 47 | ||||
| 48 | #include <wx/utils.h> | |||
| 49 | ||||
| 50 | #include "Preferences.h" // Needed for CPreferences | |||
| 51 | #include "PartFile.h" // Needed for CPartFile | |||
| 52 | #include "Logger.h" | |||
| 53 | #include <common/Format.h> | |||
| 54 | #include "InternalEvents.h" // Needed for wxEVT_* | |||
| 55 | #include "ThreadTasks.h" | |||
| 56 | #include "GuiEvents.h" // Needed for EVT_MULE_NOTIFY | |||
| 57 | #include "Timer.h" // Needed for EVT_MULE_TIMER | |||
| 58 | ||||
| 59 | #include "ClientUDPSocket.h" // Do_not_auto_remove (forward declaration not enough) | |||
| 60 | #include "ListenSocket.h" // Do_not_auto_remove (forward declaration not enough) | |||
| 61 | ||||
| 62 | ||||
| 63 | #ifdef HAVE_SYS_RESOURCE_H1 | |||
| 64 | #include <sys/resource.h> // Do_not_auto_remove | |||
| 65 | #endif | |||
| 66 | ||||
| 67 | #ifndef __WINDOWS__ | |||
| 68 | #ifdef HAVE_SYS_WAIT_H1 | |||
| 69 | #include <sys/wait.h> // Do_not_auto_remove | |||
| 70 | #endif | |||
| 71 | #include <wx/ffile.h> | |||
| 72 | #endif | |||
| 73 | ||||
| 74 | BEGIN_EVENT_TABLE(CamuleDaemonApp, wxAppConsole)const wxEventTable CamuleDaemonApp::sm_eventTable = { &wxAppConsole ::sm_eventTable, &CamuleDaemonApp::sm_eventTableEntries[0 ] }; const wxEventTable *CamuleDaemonApp::GetEventTable() const { return &CamuleDaemonApp::sm_eventTable; } wxEventHashTable CamuleDaemonApp::sm_eventHashTable(CamuleDaemonApp::sm_eventTable ); wxEventHashTable &CamuleDaemonApp::GetEventHashTable() const { return CamuleDaemonApp::sm_eventHashTable; } const wxEventTableEntry CamuleDaemonApp::sm_eventTableEntries[] = { | |||
| 75 | ||||
| 76 | #ifndef ASIO_SOCKETS | |||
| 77 | // | |||
| 78 | // Socket handlers | |||
| 79 | // | |||
| 80 | ||||
| 81 | // Listen Socket | |||
| 82 | EVT_SOCKET(ID_LISTENSOCKET_EVENT, CamuleDaemonApp::ListenSocketHandler)wxEventTableEntry(wxEVT_SOCKET, ID_LISTENSOCKET_EVENT, wxID_ANY , wxNewEventTableFunctor(wxEVT_SOCKET, wxEventFunctionCast(wxPrivate ::DoCast<wxPrivate::EventArgOf<wxSocketEventFunction> ::type>(&CamuleDaemonApp::ListenSocketHandler))), __null ), | |||
| 83 | ||||
| 84 | // UDP Socket (servers) | |||
| 85 | EVT_SOCKET(ID_SERVERUDPSOCKET_EVENT, CamuleDaemonApp::UDPSocketHandler)wxEventTableEntry(wxEVT_SOCKET, ID_SERVERUDPSOCKET_EVENT, wxID_ANY , wxNewEventTableFunctor(wxEVT_SOCKET, wxEventFunctionCast(wxPrivate ::DoCast<wxPrivate::EventArgOf<wxSocketEventFunction> ::type>(&CamuleDaemonApp::UDPSocketHandler))), __null) , | |||
| 86 | // UDP Socket (clients) | |||
| 87 | EVT_SOCKET(ID_CLIENTUDPSOCKET_EVENT, CamuleDaemonApp::UDPSocketHandler)wxEventTableEntry(wxEVT_SOCKET, ID_CLIENTUDPSOCKET_EVENT, wxID_ANY , wxNewEventTableFunctor(wxEVT_SOCKET, wxEventFunctionCast(wxPrivate ::DoCast<wxPrivate::EventArgOf<wxSocketEventFunction> ::type>(&CamuleDaemonApp::UDPSocketHandler))), __null) , | |||
| 88 | #endif | |||
| 89 | ||||
| 90 | // Socket timer (TCP) | |||
| 91 | EVT_MULE_TIMER(ID_SERVER_RETRY_TIMER_EVENT, CamuleDaemonApp::OnTCPTimer)wxEventTableEntry(MULE_EVT_TIMER, ID_SERVER_RETRY_TIMER_EVENT , -1, wxNewEventTableFunctor(MULE_EVT_TIMER, (wxObjectEventFunction ) (wxEventFunction) static_cast<MuleTimerEventFunction> (&CamuleDaemonApp::OnTCPTimer)), (wxObject*) __null), | |||
| 92 | ||||
| 93 | // Core timer | |||
| 94 | EVT_MULE_TIMER(ID_CORE_TIMER_EVENT, CamuleDaemonApp::OnCoreTimer)wxEventTableEntry(MULE_EVT_TIMER, ID_CORE_TIMER_EVENT, -1, wxNewEventTableFunctor (MULE_EVT_TIMER, (wxObjectEventFunction) (wxEventFunction) static_cast <MuleTimerEventFunction>(&CamuleDaemonApp::OnCoreTimer )), (wxObject*) __null), | |||
| 95 | ||||
| 96 | EVT_MULE_NOTIFY(CamuleDaemonApp::OnNotifyEvent)wxEventTableEntry(MULE_EVT_NOTIFY, -1, -1, wxNewEventTableFunctor (MULE_EVT_NOTIFY, (wxObjectEventFunction) (wxEventFunction) static_cast <MuleNotifyEventFunction>(&CamuleDaemonApp::OnNotifyEvent )), (wxObject*) __null), | |||
| 97 | ||||
| 98 | // Async dns handling | |||
| 99 | EVT_MULE_INTERNAL(wxEVT_CORE_UDP_DNS_DONE, -1, CamuleDaemonApp::OnUDPDnsDone)wxEventTableEntry(wxEVT_CORE_UDP_DNS_DONE, -1, -1, wxNewEventTableFunctor (wxEVT_CORE_UDP_DNS_DONE, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleInternalEventFunction>(&CamuleDaemonApp ::OnUDPDnsDone)), (wxObject*) __null), | |||
| 100 | ||||
| 101 | EVT_MULE_INTERNAL(wxEVT_CORE_SOURCE_DNS_DONE, -1, CamuleDaemonApp::OnSourceDnsDone)wxEventTableEntry(wxEVT_CORE_SOURCE_DNS_DONE, -1, -1, wxNewEventTableFunctor (wxEVT_CORE_SOURCE_DNS_DONE, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleInternalEventFunction>(&CamuleDaemonApp ::OnSourceDnsDone)), (wxObject*) __null), | |||
| 102 | ||||
| 103 | EVT_MULE_INTERNAL(wxEVT_CORE_SERVER_DNS_DONE, -1, CamuleDaemonApp::OnServerDnsDone)wxEventTableEntry(wxEVT_CORE_SERVER_DNS_DONE, -1, -1, wxNewEventTableFunctor (wxEVT_CORE_SERVER_DNS_DONE, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleInternalEventFunction>(&CamuleDaemonApp ::OnServerDnsDone)), (wxObject*) __null), | |||
| 104 | ||||
| 105 | // Hash ended notifier | |||
| 106 | EVT_MULE_HASHING(CamuleDaemonApp::OnFinishedHashing)wxEventTableEntry(MULE_EVT_HASHING, -1, -1, wxNewEventTableFunctor (MULE_EVT_HASHING, (wxObjectEventFunction) (wxEventFunction) static_cast <MuleHashingEventFunction>(&CamuleDaemonApp::OnFinishedHashing )), (wxObject*) __null), | |||
| 107 | EVT_MULE_AICH_HASHING(CamuleDaemonApp::OnFinishedAICHHashing)wxEventTableEntry(MULE_EVT_AICH_HASHING, -1, -1, wxNewEventTableFunctor (MULE_EVT_AICH_HASHING, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleHashingEventFunction>(&CamuleDaemonApp ::OnFinishedAICHHashing)), (wxObject*) __null), | |||
| 108 | ||||
| 109 | // File completion ended notifier | |||
| 110 | EVT_MULE_FILE_COMPLETED(CamuleDaemonApp::OnFinishedCompletion)wxEventTableEntry(MULE_EVT_FILE_COMPLETED, -1, -1, wxNewEventTableFunctor (MULE_EVT_FILE_COMPLETED, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleCompletionEventFunction>(&CamuleDaemonApp ::OnFinishedCompletion)), (wxObject*) __null), | |||
| 111 | ||||
| 112 | // HTTPDownload finished | |||
| 113 | EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, -1, CamuleDaemonApp::OnFinishedHTTPDownload)wxEventTableEntry(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, -1, -1, wxNewEventTableFunctor (wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, (wxObjectEventFunction) ( wxEventFunction) static_cast<MuleInternalEventFunction> (&CamuleDaemonApp::OnFinishedHTTPDownload)), (wxObject*) __null ), | |||
| 114 | ||||
| 115 | // Disk space preallocation finished | |||
| 116 | EVT_MULE_ALLOC_FINISHED(CamuleDaemonApp::OnFinishedAllocation)wxEventTableEntry(MULE_EVT_ALLOC_FINISHED, -1, -1, wxNewEventTableFunctor (MULE_EVT_ALLOC_FINISHED, (wxObjectEventFunction) (wxEventFunction ) static_cast<MuleAllocFinishedEventFunction>(&CamuleDaemonApp ::OnFinishedAllocation)), (wxObject*) __null), | |||
| 117 | END_EVENT_TABLE()wxEventTableEntry(wxEVT_NULL, 0, 0, __null, __null) }; | |||
| 118 | ||||
| 119 | IMPLEMENT_APP(CamuleDaemonApp)int main(int argc, char **argv) { ; ; return wxEntry(argc, argv ); } CamuleDaemonApp& wxGetApp() { return *static_cast< CamuleDaemonApp*>(wxAppConsole::GetInstance()); } wxAppConsole *wxCreateApp() { wxAppConsole::CheckBuildOptions("3" "." "2" " (" "wchar_t" ",compiler with C++ ABI compatible with gcc 4" ",wx containers" ",compatible with 3.0" ")", "your program") ; return new CamuleDaemonApp; } wxAppInitializer wxTheAppInitializer ((wxAppInitializerFunction) wxCreateApp); | |||
| 120 | ||||
| 121 | #ifdef __WINDOWS__ | |||
| 122 | // | |||
| 123 | // CTRL-C-Handler | |||
| 124 | // see http://msdn.microsoft.com/en-us/library/windows/desktop/ms685049%28v=vs.85%29.aspx | |||
| 125 | // | |||
| 126 | static BOOL CtrlHandler(DWORD fdwCtrlType) | |||
| 127 | { | |||
| 128 | switch (fdwCtrlType) { | |||
| 129 | case CTRL_C_EVENT: | |||
| 130 | case CTRL_CLOSE_EVENT: | |||
| 131 | case CTRL_BREAK_EVENT: | |||
| 132 | // handle these | |||
| 133 | AddLogLineNS(wxT("Received break event, exit main loop"))theLogger.AddLogLine(L"amuled.cpp", 133, false, logStandard, L"Received break event, exit main loop" , true); | |||
| 134 | theApp->ExitMainLoop(); | |||
| 135 | return TRUE1; | |||
| 136 | break; | |||
| 137 | case CTRL_LOGOFF_EVENT: | |||
| 138 | case CTRL_SHUTDOWN_EVENT: | |||
| 139 | default: | |||
| 140 | // don't handle these | |||
| 141 | return FALSE0; | |||
| 142 | break; | |||
| 143 | } | |||
| 144 | } | |||
| 145 | ||||
| 146 | #endif // __WINDOWS__ | |||
| 147 | ||||
| 148 | ||||
| 149 | int CamuleDaemonApp::OnRun() | |||
| 150 | { | |||
| 151 | if (!thePrefs::AcceptExternalConnections()) { | |||
| 152 | AddLogLineCS(_("ERROR: aMule daemon cannot be used when external connections are disabled. To enable External Connections, use either a normal aMule, start amuled with the option --ec-config or set the key \"AcceptExternalConnections\" to 1 in the file ~/.aMule/amule.conf"))theLogger.AddLogLine(L"amuled.cpp", 152, true, logStandard, wxGetTranslation (("ERROR: aMule daemon cannot be used when external connections are disabled. To enable External Connections, use either a normal aMule, start amuled with the option --ec-config or set the key \"AcceptExternalConnections\" to 1 in the file ~/.aMule/amule.conf" )), true); | |||
| 153 | return 0; | |||
| 154 | } else if (thePrefs::ECPassword().IsEmpty()) { | |||
| 155 | AddLogLineCS(_("ERROR: A valid password is required to use external connections, and aMule daemon cannot be used without external connections. To run aMule daemon, you must set the \"ECPassword\" field in the file ~/.aMule/amule.conf with an appropriate value. Execute amuled with the flag --ec-config to set the password. More information can be found at http://wiki.amule.org"))theLogger.AddLogLine(L"amuled.cpp", 155, true, logStandard, wxGetTranslation (("ERROR: A valid password is required to use external connections, and aMule daemon cannot be used without external connections. To run aMule daemon, you must set the \"ECPassword\" field in the file ~/.aMule/amule.conf with an appropriate value. Execute amuled with the flag --ec-config to set the password. More information can be found at http://wiki.amule.org" )), true); | |||
| 156 | return 0; | |||
| 157 | } | |||
| 158 | ||||
| 159 | #ifdef __WINDOWS__ | |||
| 160 | SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE1); | |||
| 161 | #endif // __WINDOWS__ | |||
| 162 | ||||
| 163 | return wxAppwxAppConsole::OnRun(); | |||
| 164 | } | |||
| 165 | ||||
| 166 | bool CamuleDaemonApp::OnInit() | |||
| 167 | { | |||
| 168 | if ( !CamuleApp::OnInit() ) { | |||
| 169 | return false; | |||
| 170 | } | |||
| 171 | AddLogLineNS(_("amuled: OnInit - starting timer"))theLogger.AddLogLine(L"amuled.cpp", 171, false, logStandard, wxGetTranslation (("amuled: OnInit - starting timer")), true); | |||
| 172 | core_timer = new CTimer(this,ID_CORE_TIMER_EVENT); | |||
| 173 | core_timer->Start(CORE_TIMER_PERIOD300); | |||
| 174 | glob_prefs->GetCategory(0)->title = GetCatTitle(thePrefs::GetAllcatFilter()); | |||
| 175 | glob_prefs->GetCategory(0)->path = thePrefs::GetIncomingDir(); | |||
| 176 | ||||
| 177 | return true; | |||
| 178 | } | |||
| 179 | ||||
| 180 | int CamuleDaemonApp::InitGui(bool ,wxString &) | |||
| 181 | { | |||
| 182 | #ifndef __WINDOWS__ | |||
| 183 | if ( !enable_daemon_fork ) { | |||
| ||||
| 184 | return 0; | |||
| 185 | } | |||
| 186 | AddLogLineNS(_("amuled: forking to background - see you"))theLogger.AddLogLine(L"amuled.cpp", 186, false, logStandard, wxGetTranslation (("amuled: forking to background - see you")), true); | |||
| 187 | theLogger.SetEnabledStdoutLog(false); | |||
| 188 | // | |||
| 189 | // fork to background and detach from controlling tty | |||
| 190 | // while redirecting stdout to /dev/null | |||
| 191 | // | |||
| 192 | for(int i_fd = 0;i_fd < 3; i_fd++) { | |||
| 193 | close(i_fd); | |||
| 194 | } | |||
| 195 | int fd = open("/dev/null",O_RDWR02); | |||
| 196 | if (dup(fd)){} // prevent GCC warning | |||
| ||||
| 197 | if (dup(fd)){} | |||
| 198 | pid_t pid = fork(); | |||
| 199 | ||||
| 200 | wxASSERT(pid != -1)do { if ( pid != -1 ) { } else if ( wxTheAssertHandler && (wxOnAssert("amuled.cpp", 200, __FUNCTION__, "pid != -1", (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while ( (void)0, 0 ); | |||
| 201 | ||||
| 202 | if ( pid ) { | |||
| 203 | exit(0); | |||
| 204 | } else { | |||
| 205 | pid = setsid(); | |||
| 206 | // | |||
| 207 | // Create a Pid file with the Pid of the Child, so any daemon-manager | |||
| 208 | // can easily manage the process | |||
| 209 | // | |||
| 210 | if (!m_PidFile.IsEmpty()) { | |||
| 211 | wxString temp = CFormat(wxT("%d\n")L"%d\n") % pid; | |||
| 212 | wxFFile ff(m_PidFile, wxT("w")L"w"); | |||
| 213 | if (!ff.Error()) { | |||
| 214 | ff.Write(temp); | |||
| 215 | ff.Close(); | |||
| 216 | } else { | |||
| 217 | AddLogLineNS(_("Cannot Create Pid File"))theLogger.AddLogLine(L"amuled.cpp", 217, false, logStandard, wxGetTranslation (("Cannot Create Pid File")), true); | |||
| 218 | } | |||
| 219 | } | |||
| 220 | } | |||
| 221 | ||||
| 222 | #endif | |||
| 223 | return 0; | |||
| 224 | } | |||
| 225 | ||||
| 226 | bool CamuleDaemonApp::Initialize(int& argc_, wxChar **argv_) | |||
| 227 | { | |||
| 228 | if ( !wxAppConsole::Initialize(argc_, argv_) ) { | |||
| 229 | return false; | |||
| 230 | } | |||
| 231 | ||||
| 232 | #ifdef __UNIX__1 | |||
| 233 | wxString encName; | |||
| 234 | #if wxUSE_INTL1 | |||
| 235 | // if a non default locale is set, | |||
| 236 | // assume that the user wants his | |||
| 237 | // filenames in this locale too | |||
| 238 | encName = wxLocale::GetSystemEncodingName().Upper(); | |||
| 239 | ||||
| 240 | // But don't consider ASCII in this case. | |||
| 241 | if ( !encName.empty() ) { | |||
| 242 | if ( encName == wxT("US-ASCII")L"US-ASCII" ) { | |||
| 243 | // This means US-ASCII when returned | |||
| 244 | // from GetEncodingFromName(). | |||
| 245 | encName.clear(); | |||
| 246 | } | |||
| 247 | } | |||
| 248 | #endif // wxUSE_INTL | |||
| 249 | ||||
| 250 | // in this case, UTF-8 is used by default. | |||
| 251 | if ( encName.empty() ) { | |||
| 252 | encName = wxT("UTF-8")L"UTF-8"; | |||
| 253 | } | |||
| 254 | ||||
| 255 | static wxConvBrokenFileNames fileconv(encName); | |||
| 256 | wxConvFileName = &fileconv; | |||
| 257 | #endif // __UNIX__ | |||
| 258 | ||||
| 259 | return true; | |||
| 260 | } | |||
| 261 | ||||
| 262 | int CamuleDaemonApp::OnExit() | |||
| 263 | { | |||
| 264 | ShutDown(); | |||
| 265 | delete core_timer; | |||
| 266 | return CamuleApp::OnExit(); | |||
| 267 | } | |||
| 268 | ||||
| 269 | ||||
| 270 | int CamuleDaemonApp::ShowAlert(wxString msg, wxString title, int flags) | |||
| 271 | { | |||
| 272 | if ( flags | wxICON_ERROR0x00000200 ) { | |||
| 273 | title = CFormat(_("ERROR: %s")wxGetTranslation(("ERROR: %s"))) % title; | |||
| 274 | } | |||
| 275 | AddLogLineCS(title + wxT(" ") + msg)theLogger.AddLogLine(L"amuled.cpp", 275, true, logStandard, title + L" " + msg, true); | |||
| 276 | ||||
| 277 | return 0; // That's neither yes nor no, ok, cancel | |||
| 278 | } | |||
| 279 | ||||
| 280 | // File_checked_for_headers |
| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: wx/translation.h |
| 3 | // Purpose: Internationalization and localisation for wxWidgets |
| 4 | // Author: Vadim Zeitlin, Vaclav Slavik, |
| 5 | // Michael N. Filippov <michael@idisys.iae.nsk.su> |
| 6 | // Created: 2010-04-23 |
| 7 | // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> |
| 8 | // (c) 2010 Vaclav Slavik <vslavik@fastmail.fm> |
| 9 | // Licence: wxWindows licence |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | #ifndef _WX_TRANSLATION_H_ |
| 13 | #define _WX_TRANSLATION_H_ |
| 14 | |
| 15 | #include "wx/defs.h" |
| 16 | #include "wx/string.h" |
| 17 | |
| 18 | #if wxUSE_INTL1 |
| 19 | |
| 20 | #include "wx/buffer.h" |
| 21 | #include "wx/language.h" |
| 22 | #include "wx/hashmap.h" |
| 23 | #include "wx/strconv.h" |
| 24 | #include "wx/scopedptr.h" |
| 25 | |
| 26 | // ============================================================================ |
| 27 | // global decls |
| 28 | // ============================================================================ |
| 29 | |
| 30 | // ---------------------------------------------------------------------------- |
| 31 | // macros |
| 32 | // ---------------------------------------------------------------------------- |
| 33 | |
| 34 | // gettext() style macros (notice that xgettext should be invoked with |
| 35 | // --keyword="_" --keyword="wxPLURAL:1,2" options |
| 36 | // to extract the strings from the sources) |
| 37 | #ifndef WXINTL_NO_GETTEXT_MACRO |
| 38 | #ifndef wxNO_IMPLICIT_WXSTRING_ENCODING |
| 39 | #define _(s)wxGetTranslation((s)) wxGetTranslation((s)) |
| 40 | #else |
| 41 | #define _(s)wxGetTranslation((s)) wxGetTranslation(wxASCII_STR(s)wxString::FromAscii(s)) |
| 42 | #endif |
| 43 | #define wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n) wxGetTranslation((sing), (plur), n) |
| 44 | #endif |
| 45 | |
| 46 | // wx-specific macro for translating strings in the given context: if you use |
| 47 | // them, you need to also add |
| 48 | // --keyword="wxGETTEXT_IN_CONTEXT:1c,2" --keyword="wxGETTEXT_IN_CONTEXT_PLURAL:1c,2,3" |
| 49 | // options to xgettext invocation. |
| 50 | #ifndef wxNO_IMPLICIT_WXSTRING_ENCODING |
| 51 | #define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) \ |
| 52 | wxGetTranslation((s), wxString(), c) |
| 53 | #else |
| 54 | #define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) \ |
| 55 | wxGetTranslation(wxASCII_STR(s)wxString::FromAscii(s), wxString(), c) |
| 56 | #endif |
| 57 | #define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n)wxGetTranslation((sing), (plur), n, wxString(), c) \ |
| 58 | wxGetTranslation((sing), (plur), n, wxString(), c) |
| 59 | |
| 60 | // another one which just marks the strings for extraction, but doesn't |
| 61 | // perform the translation (use -kwxTRANSLATE with xgettext!) |
| 62 | #define wxTRANSLATE(str)str str |
| 63 | |
| 64 | // another one which just marks the strings, with a context, for extraction, |
| 65 | // but doesn't perform the translation (use -kwxTRANSLATE_IN_CONTEXT:1c,2 with |
| 66 | // xgettext!) |
| 67 | #define wxTRANSLATE_IN_CONTEXT(c, str)str str |
| 68 | |
| 69 | // ---------------------------------------------------------------------------- |
| 70 | // forward decls |
| 71 | // ---------------------------------------------------------------------------- |
| 72 | |
| 73 | class WXDLLIMPEXP_FWD_BASE wxArrayString; |
| 74 | class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader; |
| 75 | class WXDLLIMPEXP_FWD_BASE wxLocale; |
| 76 | |
| 77 | class wxPluralFormsCalculator; |
| 78 | wxDECLARE_SCOPED_PTR(wxPluralFormsCalculator, wxPluralFormsCalculatorPtr)class wxPluralFormsCalculatorPtr { private: wxPluralFormsCalculator * m_ptr; wxPluralFormsCalculatorPtr(wxPluralFormsCalculatorPtr const &); wxPluralFormsCalculatorPtr & operator=(wxPluralFormsCalculatorPtr const &); public: explicit wxPluralFormsCalculatorPtr(wxPluralFormsCalculator * ptr = __null) : m_ptr(ptr) { } ~wxPluralFormsCalculatorPtr (); void reset(wxPluralFormsCalculator * ptr = __null); wxPluralFormsCalculator *release() { wxPluralFormsCalculator *ptr = m_ptr; m_ptr = __null ; return ptr; } wxPluralFormsCalculator & operator*() const { do { if ( m_ptr != __null ) { } else if ( wxTheAssertHandler && (wxOnAssert("/usr/include/wx-3.2/wx/translation.h" , 78, __FUNCTION__, "m_ptr != __null", (const char*)__null), wxTrapInAssert ) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return *m_ptr; } wxPluralFormsCalculator * operator ->() const { do { if ( m_ptr != __null ) { } else if ( wxTheAssertHandler && (wxOnAssert("/usr/include/wx-3.2/wx/translation.h" , 78, __FUNCTION__, "m_ptr != __null", (const char*)__null), wxTrapInAssert ) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return m_ptr; } wxPluralFormsCalculator * get () const { return m_ptr; } void swap(wxPluralFormsCalculatorPtr & ot) { wxPluralFormsCalculator * tmp = ot.m_ptr; ot.m_ptr = m_ptr; m_ptr = tmp; } }; |
| 79 | |
| 80 | // ---------------------------------------------------------------------------- |
| 81 | // wxMsgCatalog corresponds to one loaded message catalog. |
| 82 | // ---------------------------------------------------------------------------- |
| 83 | |
| 84 | class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxMsgCatalog |
| 85 | { |
| 86 | public: |
| 87 | // Ctor is protected, because CreateFromXXX functions must be used, |
| 88 | // but destruction should be unrestricted |
| 89 | #if !wxUSE_UNICODE1 |
| 90 | ~wxMsgCatalog(); |
| 91 | #endif |
| 92 | |
| 93 | // load the catalog from disk or from data; caller is responsible for |
| 94 | // deleting them if not NULL |
| 95 | static wxMsgCatalog *CreateFromFile(const wxString& filename, |
| 96 | const wxString& domain); |
| 97 | |
| 98 | static wxMsgCatalog *CreateFromData(const wxScopedCharBuffer& data, |
| 99 | const wxString& domain); |
| 100 | |
| 101 | // get name of the catalog |
| 102 | wxString GetDomain() const { return m_domain; } |
| 103 | |
| 104 | // get the translated string: returns NULL if not found |
| 105 | const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX(2147483647 *2U +1U), const wxString& ct = wxEmptyString) const; |
| 106 | |
| 107 | protected: |
| 108 | wxMsgCatalog(const wxString& domain) |
| 109 | : m_pNext(NULL__null), m_domain(domain) |
| 110 | #if !wxUSE_UNICODE1 |
| 111 | , m_conv(NULL__null) |
| 112 | #endif |
| 113 | {} |
| 114 | |
| 115 | private: |
| 116 | // variable pointing to the next element in a linked list (or NULL) |
| 117 | wxMsgCatalog *m_pNext; |
| 118 | friend class wxTranslations; |
| 119 | |
| 120 | wxStringToStringHashMap m_messages; // all messages in the catalog |
| 121 | wxString m_domain; // name of the domain |
| 122 | |
| 123 | #if !wxUSE_UNICODE1 |
| 124 | // the conversion corresponding to this catalog charset if we installed it |
| 125 | // as the global one |
| 126 | wxCSConv *m_conv; |
| 127 | #endif |
| 128 | |
| 129 | wxPluralFormsCalculatorPtr m_pluralFormsCalculator; |
| 130 | }; |
| 131 | |
| 132 | // ---------------------------------------------------------------------------- |
| 133 | // wxTranslations: message catalogs |
| 134 | // ---------------------------------------------------------------------------- |
| 135 | |
| 136 | // this class allows to get translations for strings |
| 137 | class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxTranslations |
| 138 | { |
| 139 | public: |
| 140 | wxTranslations(); |
| 141 | ~wxTranslations(); |
| 142 | |
| 143 | // returns current translations object, may return NULL |
| 144 | static wxTranslations *Get(); |
| 145 | // sets current translations object (takes ownership; may be NULL) |
| 146 | static void Set(wxTranslations *t); |
| 147 | |
| 148 | // changes loader to non-default one; takes ownership of 'loader' |
| 149 | void SetLoader(wxTranslationsLoader *loader); |
| 150 | |
| 151 | void SetLanguage(wxLanguage lang); |
| 152 | void SetLanguage(const wxString& lang); |
| 153 | |
| 154 | // get languages available for this app |
| 155 | wxArrayString GetAvailableTranslations(const wxString& domain) const; |
| 156 | |
| 157 | #if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30203 |
| 158 | // find best available translation language for given domain |
| 159 | wxString GetBestAvailableTranslation(const wxString& domain); |
| 160 | #endif // wxABI_VERSION >= 3.2.3 |
| 161 | |
| 162 | wxString GetBestTranslation(const wxString& domain, wxLanguage msgIdLanguage); |
| 163 | wxString GetBestTranslation(const wxString& domain, |
| 164 | const wxString& msgIdLanguage = wxASCII_STR("en")wxString::FromAscii("en")); |
| 165 | |
| 166 | #if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30203 |
| 167 | // add catalog for the given domain returning true if it could be found by |
| 168 | // wxTranslationsLoader |
| 169 | bool AddAvailableCatalog(const wxString& domain); |
| 170 | #endif // wxABI_VERSION >= 3.2.3 |
| 171 | #if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30206 |
| 172 | bool AddAvailableCatalog(const wxString& domain, wxLanguage msgIdLanguage); |
| 173 | #endif // wxABI_VERSION >= 3.2.5 |
| 174 | |
| 175 | // add standard wxWidgets catalog ("wxstd") |
| 176 | bool AddStdCatalog(); |
| 177 | |
| 178 | // add catalog with given domain name and language, looking it up via |
| 179 | // wxTranslationsLoader -- unlike AddAvailableCatalog(), this function also |
| 180 | // returns true if this catalog is not needed at all because msgIdLanguage |
| 181 | // is an acceptable language to use directly |
| 182 | bool AddCatalog(const wxString& domain, |
| 183 | wxLanguage msgIdLanguage = wxLANGUAGE_ENGLISH_US); |
| 184 | #if !wxUSE_UNICODE1 |
| 185 | bool AddCatalog(const wxString& domain, |
| 186 | wxLanguage msgIdLanguage, |
| 187 | const wxString& msgIdCharset); |
| 188 | #endif |
| 189 | |
| 190 | // check if the given catalog is loaded |
| 191 | bool IsLoaded(const wxString& domain) const; |
| 192 | |
| 193 | // access to translations |
| 194 | const wxString *GetTranslatedString(const wxString& origString, |
| 195 | const wxString& domain = wxEmptyString, |
| 196 | const wxString& context = wxEmptyString) const; |
| 197 | const wxString *GetTranslatedString(const wxString& origString, |
| 198 | unsigned n, |
| 199 | const wxString& domain = wxEmptyString, |
| 200 | const wxString& context = wxEmptyString) const; |
| 201 | |
| 202 | wxString GetHeaderValue(const wxString& header, |
| 203 | const wxString& domain = wxEmptyString) const; |
| 204 | |
| 205 | // this is hack to work around a problem with wxGetTranslation() which |
| 206 | // returns const wxString& and not wxString, so when it returns untranslated |
| 207 | // string, it needs to have a copy of it somewhere |
| 208 | static const wxString& GetUntranslatedString(const wxString& str); |
| 209 | |
| 210 | private: |
| 211 | enum Translations |
| 212 | { |
| 213 | Translations_NotNeeded = -1, |
| 214 | Translations_NotFound = 0, |
| 215 | Translations_Found = 1 |
| 216 | }; |
| 217 | |
| 218 | Translations DoAddCatalog(const wxString& domain, wxLanguage msgIdLanguage); |
| 219 | |
| 220 | // perform loading of the catalog via m_loader |
| 221 | bool LoadCatalog(const wxString& domain, const wxString& lang, const wxString& msgIdLang); |
| 222 | |
| 223 | // find catalog by name in a linked list, return NULL if !found |
| 224 | wxMsgCatalog *FindCatalog(const wxString& domain) const; |
| 225 | |
| 226 | // same as Set(), without taking ownership; only for wxLocale |
| 227 | static void SetNonOwned(wxTranslations *t); |
| 228 | friend class wxLocale; |
| 229 | |
| 230 | wxString DoGetBestAvailableTranslation(const wxString& domain, const wxString& additionalAvailableLanguage); |
| 231 | |
| 232 | private: |
| 233 | wxString m_lang; |
| 234 | wxTranslationsLoader *m_loader; |
| 235 | |
| 236 | wxMsgCatalog *m_pMsgCat; // pointer to linked list of catalogs |
| 237 | |
| 238 | // In addition to keeping all the catalogs in the linked list, we also |
| 239 | // store them in a hash map indexed by the domain name to allow finding |
| 240 | // them by name efficiently. |
| 241 | WX_DECLARE_HASH_MAP(wxString, wxMsgCatalog *, wxStringHash, wxStringEqual, wxMsgCatalogMap)class wxMsgCatalogMap_wxImplementation_Pair { public: typedef wxString first_type; typedef wxMsgCatalog * second_type; typedef wxString t1; typedef wxMsgCatalog * t2; typedef const wxString const_t1; typedef const wxMsgCatalog * const_t2; wxMsgCatalogMap_wxImplementation_Pair (const const_t1& f, const const_t2& s) : first(const_cast <t1&>(f)), second(const_cast<t2&>(s)) {} t1 first; t2 second; }; class wxMsgCatalogMap_wxImplementation_KeyEx { typedef wxString key_type; typedef wxMsgCatalogMap_wxImplementation_Pair pair_type; typedef const key_type const_key_type; typedef const pair_type const_pair_type; typedef const_key_type& const_key_reference ; typedef const_pair_type& const_pair_reference; public: wxMsgCatalogMap_wxImplementation_KeyEx () { } const_key_reference operator()( const_pair_reference pair ) const { return pair.first; }}; class wxMsgCatalogMap_wxImplementation_HashTable : protected _wxHashTableBase2 { public: typedef wxString key_type ; typedef wxMsgCatalogMap_wxImplementation_Pair value_type; typedef wxStringHash hasher; typedef wxStringEqual key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef value_type* pointer; typedef const value_type* const_pointer ; typedef value_type& reference; typedef const value_type & const_reference; typedef const wxString const_key_type; typedef const wxMsgCatalogMap_wxImplementation_Pair const_mapped_type ; public: typedef wxMsgCatalogMap_wxImplementation_KeyEx key_extractor ; typedef wxMsgCatalogMap_wxImplementation_HashTable Self; protected : _wxHashTable_NodeBase** m_table; size_t m_tableBuckets; size_t m_items; hasher m_hasher; key_equal m_equals; key_extractor m_getKey ; public: struct Node:public _wxHashTable_NodeBase { public: Node ( const value_type& value ) : m_value( value ) {} Node* next () { return static_cast<Node*>(m_next); } value_type m_value ; }; protected: static void DeleteNode( _wxHashTable_NodeBase * node ) { delete static_cast<Node*>(node); } public: class Iterator { public: Node* m_node; Self* m_ht; Iterator() : m_node (__null), m_ht(__null) {} Iterator( Node* node, const Self* ht ) : m_node(node), m_ht(const_cast<Self*>(ht)) {} bool operator ==( const Iterator& it ) const { return m_node == it.m_node ; } bool operator !=( const Iterator& it ) const { return m_node != it.m_node; } protected: Node* GetNextNode() { size_type bucket = GetBucketForNode(m_ht,m_node); for( size_type i = bucket + 1; i < m_ht->m_tableBuckets; ++i ) { if( m_ht->m_table [i] ) return static_cast<Node*>(m_ht->m_table[i]); } return __null; } void PlusPlus() { Node* next = m_node->next (); m_node = next ? next : GetNextNode(); } }; friend class Iterator ; public: class iterator : public Iterator { public: iterator () : Iterator() {} iterator( Node* node, Self* ht ) : Iterator ( node, ht ) {} iterator& operator++() { PlusPlus(); return *this; } iterator operator++(int) { iterator it=*this;PlusPlus ();return it; } reference operator *() const { return m_node-> m_value; } pointer operator ->() const { return &(m_node ->m_value); } }; class const_iterator : public Iterator { public : const_iterator() : Iterator() {} const_iterator(iterator i) : Iterator(i) {} const_iterator( Node* node, const Self* ht ) : Iterator(node, const_cast<Self*>(ht)) {} const_iterator & operator++() { PlusPlus();return *this; } const_iterator operator++(int) { const_iterator it=*this;PlusPlus();return it ; } const_reference operator *() const { return m_node->m_value ; } const_pointer operator ->() const { return &(m_node ->m_value); } }; wxMsgCatalogMap_wxImplementation_HashTable ( size_type sz = 10, const hasher& hfun = hasher(), const key_equal& k_eq = key_equal(), const key_extractor& k_ex = key_extractor() ) : m_tableBuckets( GetNextPrime( (unsigned long) sz ) ), m_items( 0 ), m_hasher( hfun ), m_equals( k_eq ), m_getKey( k_ex ) { m_table = (_wxHashTable_NodeBase**)AllocTable (m_tableBuckets); } wxMsgCatalogMap_wxImplementation_HashTable ( const Self& ht ) : m_table(__null), m_tableBuckets( 0 ) , m_items( ht.m_items ), m_hasher( ht.m_hasher ), m_equals( ht .m_equals ), m_getKey( ht.m_getKey ) { HashCopy( ht ); } const Self& operator=( const Self& ht ) { if (&ht != this ) { clear(); m_hasher = ht.m_hasher; m_equals = ht.m_equals; m_getKey = ht.m_getKey; m_items = ht.m_items; HashCopy( ht ); } return *this; } ~wxMsgCatalogMap_wxImplementation_HashTable() { clear (); FreeTable(m_table); } hasher hash_funct() { return m_hasher ; } key_equal key_eq() { return m_equals; } void clear() { DeleteNodes (m_tableBuckets, m_table, DeleteNode); m_items = 0; } size_type size() const { return m_items; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } const_iterator end() const { return const_iterator(__null , this); } iterator end() { return iterator(__null, this); } const_iterator begin() const { return const_iterator(static_cast<Node*> (GetFirstNode(m_tableBuckets, m_table)), this); } iterator begin () { return iterator(static_cast<Node*>(GetFirstNode(m_tableBuckets , m_table)), this); } size_type erase( const const_key_type& key ) { _wxHashTable_NodeBase** node = GetNodePtr(key); if( ! node ) return 0; --m_items; _wxHashTable_NodeBase* temp = (*node )->m_next; delete static_cast<Node*>(*node); (*node) = temp; if( never_shrink( m_tableBuckets, m_items ) ) ResizeTable ( GetPreviousPrime( (unsigned long) m_tableBuckets ) - 1 ); return 1; } protected: static size_type GetBucketForNode( Self* ht, Node* node ) { return ht->m_hasher( ht->m_getKey( node ->m_value ) ) % ht->m_tableBuckets; } static Node* CopyNode ( Node* node ) { return new Node( *node ); } Node* GetOrCreateNode ( const value_type& value, bool& created ) { const const_key_type & key = m_getKey( value ); size_t bucket = m_hasher( key ) % m_tableBuckets; Node* node = static_cast<Node*>(m_table [bucket]); while( node ) { if( m_equals( m_getKey( node->m_value ), key ) ) { created = false; return node; } node = node-> next(); } created = true; return CreateNode( value, bucket); } Node * CreateNode( const value_type& value, size_t bucket ) { Node* node = new Node( value ); node->m_next = m_table [bucket]; m_table[bucket] = node; ++m_items; if( grow_lf70( m_tableBuckets , m_items ) ) ResizeTable( m_tableBuckets ); return node; } void CreateNode( const value_type& value ) { CreateNode(value , m_hasher( m_getKey(value) ) % m_tableBuckets ); } _wxHashTable_NodeBase ** GetNodePtr(const const_key_type& key) const { size_t bucket = m_hasher( key ) % m_tableBuckets; _wxHashTable_NodeBase** node = &m_table[bucket]; while( *node ) { if (m_equals(m_getKey (static_cast<Node*>(*node)->m_value), key)) return node ; node = &(*node)->m_next; } return __null; } Node* GetNode ( const const_key_type& key ) const { size_t bucket = m_hasher ( key ) % m_tableBuckets; Node* node = static_cast<Node*> (m_table[bucket]); while( node ) { if( m_equals( m_getKey( node ->m_value ), key ) ) return node; node = node->next(); } return __null; } void ResizeTable( size_t newSize ) { newSize = GetNextPrime( (unsigned long)newSize ); _wxHashTable_NodeBase ** srcTable = m_table; size_t srcBuckets = m_tableBuckets; m_table = (_wxHashTable_NodeBase**)AllocTable( newSize ); m_tableBuckets = newSize; CopyHashTable( srcTable, srcBuckets, this, m_table , (BucketFromNode)GetBucketForNode, (ProcessNode)&DummyProcessNode ); FreeTable(srcTable); } void HashCopy( const Self& ht ) { ResizeTable( ht.size() ); CopyHashTable( ht.m_table, ht.m_tableBuckets , (_wxHashTableBase2*)this, m_table, (BucketFromNode)GetBucketForNode , (ProcessNode)CopyNode ); } }; class wxMsgCatalogMap:public wxMsgCatalogMap_wxImplementation_HashTable { public: typedef wxMsgCatalog * mapped_type; class Insert_Result { public: typedef iterator first_type; typedef bool second_type ; typedef iterator t1; typedef bool t2; typedef const iterator const_t1; typedef const bool const_t2; Insert_Result(const const_t1 & f, const const_t2& s) : first(const_cast<t1& >(f)), second(const_cast<t2&>(s)) {} t1 first; t2 second; }; explicit wxMsgCatalogMap( size_type hint = 100, hasher hf = hasher(), key_equal eq = key_equal() ) : wxMsgCatalogMap_wxImplementation_HashTable ( hint, hf, eq, wxMsgCatalogMap_wxImplementation_KeyEx() ) {} mapped_type& operator[]( const const_key_type& key ) { bool created; return GetOrCreateNode( wxMsgCatalogMap_wxImplementation_Pair ( key, mapped_type() ), created)->m_value.second; } const_iterator find( const const_key_type& key ) const { return const_iterator ( GetNode( key ), this ); } iterator find( const const_key_type & key ) { return iterator( GetNode( key ), this ); } Insert_Result insert( const value_type& v ) { bool created; Node *node = GetOrCreateNode( wxMsgCatalogMap_wxImplementation_Pair( v. first, v.second ), created); return Insert_Result(iterator(node , this), created); } size_type erase( const key_type& k ) { return wxMsgCatalogMap_wxImplementation_HashTable::erase( k ); } void erase( const iterator& it ) { erase( (*it).first ); } size_type count( const const_key_type& key ) { return GetNode( key ) ? 1u : 0u; } }; |
| 242 | wxMsgCatalogMap m_catalogMap; |
| 243 | }; |
| 244 | |
| 245 | |
| 246 | // abstraction of translations discovery and loading |
| 247 | class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxTranslationsLoader |
| 248 | { |
| 249 | public: |
| 250 | wxTranslationsLoader() {} |
| 251 | virtual ~wxTranslationsLoader() {} |
| 252 | |
| 253 | virtual wxMsgCatalog *LoadCatalog(const wxString& domain, |
| 254 | const wxString& lang) = 0; |
| 255 | |
| 256 | virtual wxArrayString GetAvailableTranslations(const wxString& domain) const = 0; |
| 257 | }; |
| 258 | |
| 259 | |
| 260 | // standard wxTranslationsLoader implementation, using filesystem |
| 261 | class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxFileTranslationsLoader |
| 262 | : public wxTranslationsLoader |
| 263 | { |
| 264 | public: |
| 265 | static void AddCatalogLookupPathPrefix(const wxString& prefix); |
| 266 | |
| 267 | virtual wxMsgCatalog *LoadCatalog(const wxString& domain, |
| 268 | const wxString& lang) wxOVERRIDEoverride; |
| 269 | |
| 270 | virtual wxArrayString GetAvailableTranslations(const wxString& domain) const wxOVERRIDEoverride; |
| 271 | }; |
| 272 | |
| 273 | |
| 274 | #ifdef __WINDOWS__ |
| 275 | // loads translations from win32 resources |
| 276 | class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxResourceTranslationsLoader |
| 277 | : public wxTranslationsLoader |
| 278 | { |
| 279 | public: |
| 280 | virtual wxMsgCatalog *LoadCatalog(const wxString& domain, |
| 281 | const wxString& lang) wxOVERRIDEoverride; |
| 282 | |
| 283 | virtual wxArrayString GetAvailableTranslations(const wxString& domain) const wxOVERRIDEoverride; |
| 284 | |
| 285 | protected: |
| 286 | // returns resource type to use for translations |
| 287 | virtual wxString GetResourceType() const { return wxASCII_STR("MOFILE")wxString::FromAscii("MOFILE"); } |
| 288 | |
| 289 | // returns module to load resources from |
| 290 | virtual WXHINSTANCE GetModule() const { return NULL__null; } |
| 291 | }; |
| 292 | #endif // __WINDOWS__ |
| 293 | |
| 294 | |
| 295 | // ---------------------------------------------------------------------------- |
| 296 | // global functions |
| 297 | // ---------------------------------------------------------------------------- |
| 298 | |
| 299 | // get the translation of the string in the current locale |
| 300 | inline const wxString& wxGetTranslation(const wxString& str, |
| 301 | const wxString& domain = wxString(), |
| 302 | const wxString& context = wxString()) |
| 303 | { |
| 304 | wxTranslations *trans = wxTranslations::Get(); |
| 305 | const wxString *transStr = trans ? trans->GetTranslatedString(str, domain, context) |
| 306 | : NULL__null; |
| 307 | if ( transStr ) |
| 308 | return *transStr; |
| 309 | else |
| 310 | // NB: this function returns reference to a string, so we have to keep |
| 311 | // a copy of it somewhere |
| 312 | return wxTranslations::GetUntranslatedString(str); |
| 313 | } |
| 314 | |
| 315 | inline const wxString& wxGetTranslation(const wxString& str1, |
| 316 | const wxString& str2, |
| 317 | unsigned n, |
| 318 | const wxString& domain = wxString(), |
| 319 | const wxString& context = wxString()) |
| 320 | { |
| 321 | wxTranslations *trans = wxTranslations::Get(); |
| 322 | const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain, context) |
| 323 | : NULL__null; |
| 324 | if ( transStr ) |
| 325 | return *transStr; |
| 326 | else |
| 327 | // NB: this function returns reference to a string, so we have to keep |
| 328 | // a copy of it somewhere |
| 329 | return n == 1 |
| 330 | ? wxTranslations::GetUntranslatedString(str1) |
| 331 | : wxTranslations::GetUntranslatedString(str2); |
| 332 | } |
| 333 | |
| 334 | #ifdef wxNO_IMPLICIT_WXSTRING_ENCODING |
| 335 | |
| 336 | /* |
| 337 | * It must always be possible to call wxGetTranslation() with const |
| 338 | * char* arguments. |
| 339 | */ |
| 340 | inline const wxString& wxGetTranslation(const char *str, |
| 341 | const char *domain = "", |
| 342 | const char *context = "") { |
| 343 | const wxMBConv &conv = wxConvWhateverWorkswxGet_wxConvWhateverWorks(); |
| 344 | return wxGetTranslation(wxString(str, conv), wxString(domain, conv), |
| 345 | wxString(context, conv)); |
| 346 | } |
| 347 | |
| 348 | inline const wxString& wxGetTranslation(const char *str1, |
| 349 | const char *str2, |
| 350 | unsigned n, |
| 351 | const char *domain = "", |
| 352 | const char *context = "") { |
| 353 | const wxMBConv &conv = wxConvWhateverWorkswxGet_wxConvWhateverWorks(); |
| 354 | return wxGetTranslation(wxString(str1, conv), wxString(str2, conv), n, |
| 355 | wxString(domain, conv), |
| 356 | wxString(context, conv)); |
| 357 | } |
| 358 | |
| 359 | #endif // wxNO_IMPLICIT_WXSTRING_ENCODING |
| 360 | |
| 361 | #else // !wxUSE_INTL |
| 362 | |
| 363 | // the macros should still be defined - otherwise compilation would fail |
| 364 | |
| 365 | #if !defined(WXINTL_NO_GETTEXT_MACRO) |
| 366 | #if !defined(_) |
| 367 | #ifndef wxNO_IMPLICIT_WXSTRING_ENCODING |
| 368 | #define _(s)wxGetTranslation((s)) (s) |
| 369 | #else |
| 370 | #define _(s)wxGetTranslation((s)) wxASCII_STR(s)wxString::FromAscii(s) |
| 371 | #endif |
| 372 | #endif |
| 373 | #define wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n) ((n) == 1 ? (sing) : (plur)) |
| 374 | #define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) (s) |
| 375 | #define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n)wxGetTranslation((sing), (plur), n, wxString(), c) wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n) |
| 376 | #endif |
| 377 | |
| 378 | #define wxTRANSLATE(str)str str |
| 379 | #define wxTRANSLATE_IN_CONTEXT(c, str)str str |
| 380 | |
| 381 | // NB: we use a template here in order to avoid using |
| 382 | // wxLocale::GetUntranslatedString() above, which would be required if |
| 383 | // we returned const wxString&; this way, the compiler should be able to |
| 384 | // optimize wxGetTranslation() away |
| 385 | |
| 386 | template<typename TString> |
| 387 | inline TString wxGetTranslation(TString str) |
| 388 | { return str; } |
| 389 | |
| 390 | template<typename TString, typename TDomain> |
| 391 | inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain)) |
| 392 | { return str; } |
| 393 | |
| 394 | template<typename TString, typename TDomain, typename TContext> |
| 395 | inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain), TContext WXUNUSED(context)) |
| 396 | { return str; } |
| 397 | |
| 398 | template<typename TString, typename TDomain> |
| 399 | inline TString wxGetTranslation(TString str1, TString str2, size_t n) |
| 400 | { return n == 1 ? str1 : str2; } |
| 401 | |
| 402 | template<typename TString, typename TDomain> |
| 403 | inline TString wxGetTranslation(TString str1, TString str2, size_t n, |
| 404 | TDomain WXUNUSED(domain)) |
| 405 | { return n == 1 ? str1 : str2; } |
| 406 | |
| 407 | template<typename TString, typename TDomain, typename TContext> |
| 408 | inline TString wxGetTranslation(TString str1, TString str2, size_t n, |
| 409 | TDomain WXUNUSED(domain), |
| 410 | TContext WXUNUSED(context)) |
| 411 | { return n == 1 ? str1 : str2; } |
| 412 | |
| 413 | #endif // wxUSE_INTL/!wxUSE_INTL |
| 414 | |
| 415 | // define this one just in case it occurs somewhere (instead of preferred |
| 416 | // wxTRANSLATE) too |
| 417 | #if !defined(WXINTL_NO_GETTEXT_MACRO) |
| 418 | #if !defined(gettext_noop) |
| 419 | #define gettext_noop(str)(str) (str) |
| 420 | #endif |
| 421 | #if !defined(N_) |
| 422 | #define N_(s)(s) (s) |
| 423 | #endif |
| 424 | #endif |
| 425 | |
| 426 | #endif // _WX_TRANSLATION_H_ |