aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/locales
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/locales')
-rw-r--r--Src/Wasabi/api/locales/LocalesInfo.cpp41
-rw-r--r--Src/Wasabi/api/locales/LocalesInfo.h30
-rw-r--r--Src/Wasabi/api/locales/api_locales.cpp12
-rw-r--r--Src/Wasabi/api/locales/api_locales.h80
-rw-r--r--Src/Wasabi/api/locales/api_localesi.cpp47
-rw-r--r--Src/Wasabi/api/locales/api_localesi.h23
-rw-r--r--Src/Wasabi/api/locales/api_localesx.cpp26
-rw-r--r--Src/Wasabi/api/locales/api_localesx.h31
-rw-r--r--Src/Wasabi/api/locales/localesmgr.cpp462
-rw-r--r--Src/Wasabi/api/locales/localesmgr.h173
-rw-r--r--Src/Wasabi/api/locales/xlatstr.h68
11 files changed, 993 insertions, 0 deletions
diff --git a/Src/Wasabi/api/locales/LocalesInfo.cpp b/Src/Wasabi/api/locales/LocalesInfo.cpp
new file mode 100644
index 00000000..667fb25b
--- /dev/null
+++ b/Src/Wasabi/api/locales/LocalesInfo.cpp
@@ -0,0 +1,41 @@
+#include <precomp.h>
+#include "LocalesInfo.h"
+#include "../xml/obj_xml.h"
+#include <api/xml/XMLAutoInclude.h>
+#include <api/xml/LoadXML.h>
+#include <api/service/waservicefactory.h>
+
+LocalesInfosXmlReader::LocalesInfosXmlReader(const wchar_t *localename) : LocaleItem(localename)
+{
+ parser = 0;
+
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ XMLAutoInclude include(parser, L"Locales");
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition", this);
+ parser->xmlreader_open();
+
+ StringPathCombine fn(L"Locales", localename);
+ LoadXmlFile(parser, fn);
+ parser->xmlreader_unregisterCallback(this);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+
+ }
+}
+
+
+void LocalesInfosXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ language = params->getItemValue(L"language");
+ author = params->getItemValue(L"author");
+}
diff --git a/Src/Wasabi/api/locales/LocalesInfo.h b/Src/Wasabi/api/locales/LocalesInfo.h
new file mode 100644
index 00000000..5179d94a
--- /dev/null
+++ b/Src/Wasabi/api/locales/LocalesInfo.h
@@ -0,0 +1,30 @@
+#ifndef NULLSOFT_WASABI_LOCALESINFO_H
+#define NULLSOFT_WASABI_LOCALESINFO_H
+
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <bfc/string/StringW.h>
+class obj_xml;
+class LocaleItem
+{
+public:
+ LocaleItem(const wchar_t *name) : name(name), language(name) { };
+ const wchar_t *getName() { return name; }
+
+ const wchar_t *getLanguage() { return language; }
+ const wchar_t *getAuthor() { return author; }
+protected:
+ StringW name;
+ StringW language;
+ StringW author;
+};
+
+
+class LocalesInfosXmlReader : public LocaleItem, public ifc_xmlreadercallbackI // XmlReaderCallbackI
+{
+public:
+ LocalesInfosXmlReader(const wchar_t *skinname);
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+private:
+ obj_xml *parser;
+};
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_locales.cpp b/Src/Wasabi/api/locales/api_locales.cpp
new file mode 100644
index 00000000..26cf75ab
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_locales.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_locales.cpp
+// Class : api_locales
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_locales.h"
+
+
diff --git a/Src/Wasabi/api/locales/api_locales.h b/Src/Wasabi/api/locales/api_locales.h
new file mode 100644
index 00000000..0ae75c73
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_locales.h
@@ -0,0 +1,80 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_locales.h
+// Class : api_locales
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_LOCALES_H
+#define __API_LOCALES_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_locales: public Dispatchable {
+ protected:
+ api_locales() {}
+ ~api_locales() {}
+ public:
+ const wchar_t *locales_getTranslation(const wchar_t *str);
+ void locales_addTranslation(const wchar_t *from, const wchar_t *to);
+ const wchar_t *locales_getBindFromAction(int action);
+ int locales_getNumEntries();
+ const wchar_t *locales_enumEntry(int n);
+ void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0);
+
+ protected:
+ enum {
+ API_LOCALES_LOCALES_GETTRANSLATION = 10,
+ API_LOCALES_LOCALES_ADDTRANSLATION = 20,
+ API_LOCALES_LOCALES_GETBINDFROMACTION = 30,
+ API_LOCALES_LOCALES_GETNUMENTRIES = 40,
+ API_LOCALES_LOCALES_ENUMENTRY = 50,
+ API_LOCALES_LOCALES_REGISTERACCELERATORSECTION = 60,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline const wchar_t *api_locales::locales_getTranslation(const wchar_t *str) {
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_GETTRANSLATION, (const wchar_t *)0, str);
+ return __retval;
+}
+
+inline void api_locales::locales_addTranslation(const wchar_t *from, const wchar_t *to)
+{
+ _voidcall(API_LOCALES_LOCALES_ADDTRANSLATION, from, to);
+}
+
+inline const wchar_t *api_locales::locales_getBindFromAction(int action) {
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_GETBINDFROMACTION, (const wchar_t *)0, action);
+ return __retval;
+}
+
+inline int api_locales::locales_getNumEntries() {
+ int __retval = _call(API_LOCALES_LOCALES_GETNUMENTRIES, (int)0);
+ return __retval;
+}
+
+inline const wchar_t *api_locales::locales_enumEntry(int n)
+{
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_ENUMENTRY, (const wchar_t *)0, n);
+ return __retval;
+}
+
+inline void api_locales::locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global) {
+ _voidcall(API_LOCALES_LOCALES_REGISTERACCELERATORSECTION, name, wnd, global);
+}
+
+// ----------------------------------------------------------------------------
+
+// {C1251318-A6F5-4cd2-9142-A4CEAA08B846}
+static const GUID localesApiServiceGuid =
+{ 0xc1251318, 0xa6f5, 0x4cd2, { 0x91, 0x42, 0xa4, 0xce, 0xaa, 0x8, 0xb8, 0x46 } };
+
+extern api_locales *localesApi;
+
+#endif // __API_LOCALES_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesi.cpp b/Src/Wasabi/api/locales/api_localesi.cpp
new file mode 100644
index 00000000..67c99164
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesi.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "api_localesi.h"
+//?>
+
+#include <api/locales/localesmgr.h>
+#include <api/wnd/keyboard.h>
+
+api_locales *localesApi = NULL;
+
+api_localesI::api_localesI() {
+ LocalesManager::init();
+}
+
+api_localesI::~api_localesI() {
+ LocalesManager::deinit();
+}
+
+const wchar_t *api_localesI::locales_getTranslation(const wchar_t *str)
+{
+ return LocalesManager::getTranslation(str);
+}
+
+void api_localesI::locales_addTranslation(const wchar_t *from, const wchar_t *to) {
+ LocalesManager::addTranslation(from, to);
+}
+
+const wchar_t *api_localesI::locales_getBindFromAction(int action)
+{
+ return LocalesManager::getBindFromAction(action);
+}
+
+/* // TODO: benski> maybe hook up to Winamp 5.5's new lang pack stuff
+int api_localesI::locales_getNumEntries()
+{
+ return LocalesManager::getNumLocales();
+}
+
+const wchar_t *api_localesI::locales_enumEntry(int n)
+{
+ return LocalesManager::enumLoadableLocales(n);
+}*/
+
+void api_localesI::locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global)
+{
+ Keyboard::registerAcceleratorSection(name, wnd, global);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesi.h b/Src/Wasabi/api/locales/api_localesi.h
new file mode 100644
index 00000000..eea3ac62
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesi.h
@@ -0,0 +1,23 @@
+#ifndef __API_LOCALESI_IMPL_H
+#define __API_LOCALESI_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_locales.h"
+#include "api_localesx.h"
+/*?>*/
+
+class api_localesI : public api_localesX
+{
+public:
+ api_localesI();
+ virtual ~api_localesI();
+
+ DISPATCH(10) const wchar_t *locales_getTranslation(const wchar_t *str); // if not found, returns the str paramer
+ DISPATCH(20) void locales_addTranslation(const wchar_t *from, const wchar_t *to);
+ DISPATCH(30) const wchar_t *locales_getBindFromAction(int action);
+ //DISPATCH(40) int locales_getNumEntries();
+ //DISPATCH(50) const wchar_t *locales_enumEntry(int n);
+ DISPATCH(60) void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0);
+};
+
+#endif // __API_LOCALESI_IMPL_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesx.cpp b/Src/Wasabi/api/locales/api_localesx.cpp
new file mode 100644
index 00000000..ff4d4d31
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesx.cpp
@@ -0,0 +1,26 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_localesx.cpp
+// Class : api_locales
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_localesx.h"
+#include "api_localesi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_localesX
+START_DISPATCH;
+ CB(API_LOCALES_LOCALES_GETTRANSLATION, locales_getTranslation);
+ VCB(API_LOCALES_LOCALES_ADDTRANSLATION, locales_addTranslation);
+ CB(API_LOCALES_LOCALES_GETBINDFROMACTION, locales_getBindFromAction);
+ //CB(API_LOCALES_LOCALES_GETNUMENTRIES, locales_getNumEntries);
+ //CB(API_LOCALES_LOCALES_ENUMENTRY, locales_enumEntry);
+ VCB(API_LOCALES_LOCALES_REGISTERACCELERATORSECTION, locales_registerAcceleratorSection);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesx.h b/Src/Wasabi/api/locales/api_localesx.h
new file mode 100644
index 00000000..b8efae8e
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesx.h
@@ -0,0 +1,31 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_localesx.h
+// Class : api_locales
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_LOCALESX_H
+#define __API_LOCALESX_H
+
+#include "api_locales.h"
+
+// ----------------------------------------------------------------------------
+
+class api_localesX : public api_locales {
+ protected:
+ api_localesX() {}
+ public:
+ virtual const wchar_t *locales_getTranslation(const wchar_t *str)=0;
+ virtual void locales_addTranslation(const wchar_t *from, const wchar_t *to)=0;
+ virtual const wchar_t *locales_getBindFromAction(int action)=0;
+ //virtual int locales_getNumEntries()=0;
+ //virtual const wchar_t *locales_enumEntry(int n)=0;
+ virtual void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_LOCALESX_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/localesmgr.cpp b/Src/Wasabi/api/locales/localesmgr.cpp
new file mode 100644
index 00000000..610a0432
--- /dev/null
+++ b/Src/Wasabi/api/locales/localesmgr.cpp
@@ -0,0 +1,462 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "localesmgr.h"
+#include <bfc/parse/pathparse.h>
+#include <api/config/items/cfgitem.h>
+#include <bfc/file/readdir.h>
+#include <api/xml/XMLAutoInclude.h>
+#include "../nu/regexp.h"
+#include "../Agave/language/api_language.h"
+#include <bfc/ptrlist.h>
+
+struct StringEntry
+{
+ uint32_t id;
+ wchar_t *string;
+};
+
+typedef PtrList<StringEntry> StringTable;
+struct StringTableData
+{
+ wchar_t *id;
+ StringTable entries;
+};
+
+typedef PtrList<StringTableData> StringTables;
+
+StringTables stringTables;
+
+void LocalesAcceleratorSectionXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *section = params->getItemValue(L"section");
+ if (!section)
+ LocalesManager::setAcceleratorSection(L"general");
+ else
+ LocalesManager::setAcceleratorSection(section);
+}
+
+void LocalesAcceleratorSectionXmlCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ LocalesManager::setAcceleratorSection(L"");
+}
+
+void StringTableXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *section = params->getItemValue(L"id");
+ if (!section)
+ LocalesManager::SetStringTable(L"nullsoft.wasabi");
+ else
+ LocalesManager::SetStringTable(section);
+}
+
+void StringTableXmlCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ LocalesManager::SetStringTable(L"");
+}
+
+void StringTableEntryXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *b = params->getItemValue(L"id");
+ const wchar_t *a = params->getItemValue(L"string");
+ if (b && a)
+ LocalesManager::AddString(WTOI(b), a);
+}
+
+/* ------------------------------------------------------------ */
+void LocalesAcceleratorXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *b = params->getItemValue(L"bind");
+ const wchar_t *a = params->getItemValue(L"action");
+ if (b && a)
+ LocalesManager::addAccelerator(b, a);
+}
+
+/* ------------------------------------------------------------ */
+void LocalesTranslationXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *f = params->getItemValue(L"from");
+ const wchar_t *t = params->getItemValue(L"to");
+ if (f && t)
+ LocalesManager::addTranslation(f, t);
+}
+
+int LocalesSkinCallback::skincb_onUnloading()
+{
+ LocalesManager::ResetStrings();
+ LocalesManager::resetAll();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onReset()
+{
+ //
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onReload()
+{
+ //LocalesManager::load();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onBeforeLoadingElements()
+{
+ LocalesManager::load();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onGuiLoaded()
+{
+ LocalesManager::LoadStringTables();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onLoaded()
+{
+ // TODO: load string table?
+ return 0;
+}
+
+/* ------------------------------------------------------------ */
+void LocalesManager::init()
+{
+ WASABI_API_SYSCB->syscb_registerCallback(&localesSkinCallback);
+ //load();
+}
+
+void LocalesManager::load()
+{
+#ifdef LOCALES_CUSTOM_LOAD
+
+ LOCALES_CUSTOM_LOAD(localePath);
+ // TODO: benski> don't load this here. we should set up a syscallback for skin load (maybe skincb_onBeforeLoadingElements?)
+ // and also we should call deinit() on skin unload (skincb_onReload, skincb_onReset, skincb_onUnloading?)
+ StringPathCombine filetoload(localePath, L"Wasabi.xml");
+ /*
+ PathParserW pp(localeName);
+ localeName = pp.getLastString();
+ int p = localeName.lFindChar('.');
+ if (p > 0) localeName.trunc(p);
+ */
+#else
+ wchar_t tmpbuf[WA_MAX_PATH] = L"english";
+
+ WASABI_API_CONFIG->getStringPrivate(L"LocaleFile", tmpbuf, WA_MAX_PATH, L"english");
+
+ // FG> ok I have no idea why it doesn't work when i read from cfg instead of stringprivate and frankly i don't have time for this
+ // so for now it'll work with both a cfgitem and a stringprivate, i couldn't desync them so it should be ok in the meantime.
+ /* const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (item != NULL)
+ item->getData("Language", tmpbuf, WA_MAX_PATH-1);*/
+
+ localeName = tmpbuf;
+ englishLocale = !WCSICMP(localeName, L"english");
+ loadFile(L"english");
+ StringW filetoload = localeName;
+ if (englishLocale)
+ filetoload.trunc(0);
+#endif
+
+ if (!filetoload.isempty())
+ loadFile(filetoload);
+
+#ifdef WASABI_API_WNDMGR
+ if (WASABI_API_WNDMGR)
+ WASABI_API_WNDMGR->wndTrackInvalidateAll();
+#endif
+}
+
+void LocalesManager::deinit()
+{
+ resetAll();
+ WASABI_API_SYSCB->syscb_deregisterCallback(&localesSkinCallback);
+}
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void LocalesManager::LoadStringTables()
+{
+ StringPathCombine genericStringTable(localePath, L"stringtable.xml");
+ LoadStringTable(genericStringTable);
+
+ StringPathCombine skinStringTable(localePath, WASABI_API_SKIN->getSkinName());
+ skinStringTable.AppendPath(L"stringtable.xml");
+ LoadStringTable(skinStringTable);
+}
+
+void LocalesManager::LoadStringTable(const wchar_t *name)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ const wchar_t *file = Wasabi::Std::filename(name);
+ int fnlen = wcslen(file);
+ StringW path = name;
+ path.trunc( -fnlen);
+ XMLAutoInclude include(parser, path);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\fStringTable", &stringTableXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\fStringTable\fStringEntry", &stringTableXmlEntryCallback);
+ parser->xmlreader_open();
+#ifdef LOCALES_CUSTOM_LOAD
+ LoadXmlFile(parser, name);
+#else
+ LoadXmlFile(parser, StringPrintfW(L"Locales/%s.xml", name));
+#endif
+ parser->xmlreader_unregisterCallback(&stringTableXmlCallback);
+ parser->xmlreader_unregisterCallback(&stringTableXmlEntryCallback);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void LocalesManager::loadFile(const wchar_t *name)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ const wchar_t *file = Wasabi::Std::filename(name);
+ int fnlen = wcslen(file);
+ StringW path = name;
+ path.trunc( -fnlen);
+ XMLAutoInclude include(parser, path);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\faccelerators", &accelSectionXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\faccelerators\faccelerator", &accelXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\ftranslations\ftranslation", &transXmlCallback);
+ parser->xmlreader_open();
+#ifdef LOCALES_CUSTOM_LOAD
+ LoadXmlFile(parser, name);
+#else
+ LoadXmlFile(parser, StringPrintfW(L"Locales/%s.xml", name));
+#endif
+ parser->xmlreader_unregisterCallback(&accelSectionXmlCallback);
+ parser->xmlreader_unregisterCallback(&accelXmlCallback);
+ parser->xmlreader_unregisterCallback(&transXmlCallback);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void LocalesManager::addTranslation(const wchar_t *from, const wchar_t *to)
+{
+ LocTrans *t = translationsList.findItem(from);
+ if (t)
+ translationsList.removeItem(t);
+ translationsList.addItem(new LocTrans(from, to));
+}
+
+
+const wchar_t *LocalesManager::lookupString(const wchar_t *from)
+{
+ if (from == NULL)
+ return NULL;
+
+ if (*from == L'@')
+ {
+
+ const wchar_t *findPound = wcschr(from, L'#');
+ if (findPound && (findPound-from) < 128)
+ {
+ wchar_t table[128] = {0};
+ memcpy(table, from+1, sizeof(wchar_t)*(findPound-from-1));
+ table[findPound-from-1]=0;
+ const wchar_t *string = GetString(table, WTOI(findPound+1));
+ if (string)
+ return string;
+ }
+ }
+ return from;
+}
+
+const wchar_t *LocalesManager::getTranslation(const wchar_t *from)
+{
+ if (!from)
+ return NULL;
+
+ LocTrans *t = translationsList.findItem(from);
+ if (t == NULL)
+ {
+ return from;
+ }
+ return t->getTo();
+}
+
+void LocalesManager::addAccelerator(const wchar_t *bind, const wchar_t *action)
+{
+ LocAccel *a = acceleratorsList.findItem(bind);
+ if (a) // Martin> shouldn't we also check here if it is the same section?
+ // Hm, now that i look closer, we search our list for a wchar_t but we store LocAccels in the list - does this work?
+ acceleratorsList.removeItem(a);
+ acceleratorsList.addItem(new LocAccel(curSection, bind, action));
+}
+
+void LocalesManager::addAcceleratorFromSkin(const wchar_t *bind, const wchar_t *action)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (0 == WCSICMP(acceleratorsList[i]->getSection(), curSection) &&
+ 0 == WCSICMP(acceleratorsList[i]->getKey(), bind))
+ return;
+ }
+ acceleratorsList.addItem(new LocAccel(curSection, bind, action));
+}
+
+const wchar_t *LocalesManager::getBindFromAction(int action)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (acceleratorsList[i]->getActionNum() == action && action != ACTION_NONE)
+ return acceleratorsList[i]->getRealKey();
+ }
+ return NULL;
+}
+
+const wchar_t *LocalesManager::translateAccelerator(const wchar_t *section, const wchar_t *key)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (!WCSICMP(acceleratorsList[i]->getSection(), section))
+ if (!WCSICMP(acceleratorsList[i]->getKey(), key))
+ return acceleratorsList[i]->getAction();
+ }
+ return NULL;
+}
+
+#if 0
+void LocalesManager::setNewLocaleFile(const wchar_t *name)
+{
+ //WASABI_API_CONFIG->setStringPrivate(L"LocaleFile", name);
+ resetAll();
+ init();
+}
+#endif
+
+void LocalesManager::resetAll()
+{
+ translationsList.deleteAll();
+ acceleratorsList.deleteAll();
+}
+
+void LocalesManager::SetStringTable(const wchar_t *table)
+{
+ curTable = table;
+}
+
+void LocalesManager::setAcceleratorSection(const wchar_t *section)
+{
+ curSection = section;
+}
+
+const wchar_t *LocalesManager::getLocaleRoot()
+{
+ return localePath;
+}
+
+void LocalesManager::ResetStrings()
+{
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ FREE(stringTables[i]->id);
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ FREE(stringTables[i]->entries[j]->string);
+ }
+ }
+ stringTables.removeAll();
+}
+
+const wchar_t *LocalesManager::GetString(const wchar_t *table, uint32_t id)
+{
+ if (!table)
+ return 0;
+
+ if (!_wcsicmp(table, L"gen_ff"))
+ return WASABI_API_LNGSTRINGW(id);
+
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ if (!wcscmp(table, stringTables[i]->id))
+ {
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ if (id == stringTables[i]->entries[j]->id)
+ return stringTables[i]->entries[j]->string;
+ }
+ }
+ }
+ return 0;
+}
+
+void LocalesManager::AddString(const wchar_t *table, uint32_t id, const wchar_t *string)
+{
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ if (!wcscmp(table, stringTables[i]->id))
+ {
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ if (id == stringTables[i]->entries[j]->id)
+ {
+ FREE(stringTables[i]->entries[j]->string);
+ stringTables[i]->entries[j]->string=WCSDUP(string);
+ return;
+ }
+ }
+ StringEntry *newEntry = new StringEntry;
+ newEntry->id = id;
+ newEntry->string = WCSDUP(string);
+ stringTables[i]->entries.addItem(newEntry);
+ return;
+ }
+ }
+ StringTableData *newTable = new StringTableData;
+ newTable->id = WCSDUP(table);
+
+ StringEntry *newEntry = new StringEntry;
+ newEntry->id = id;
+ newEntry->string = WCSDUP(string);
+ stringTables.addItem(newTable);
+ newTable->entries.addItem(newEntry);
+}
+
+void LocalesManager::AddString(uint32_t id, const wchar_t *string)
+{
+ AddString(curTable, id, string);
+}
+
+LocalesAcceleratorXmlCallback LocalesManager::accelXmlCallback;
+LocalesAcceleratorSectionXmlCallback LocalesManager::accelSectionXmlCallback;
+LocalesTranslationXmlCallback LocalesManager::transXmlCallback;
+PtrListSorted<LocTrans, PLS_LocTrans, QuickSorted<LocTrans, PLS_LocTrans> > LocalesManager::translationsList;
+PtrListSorted<LocAccel, PLS_LocAccel, QuickSorted<LocAccel, PLS_LocAccel> > LocalesManager::acceleratorsList;
+StringW LocalesManager::localePath;
+//int LocalesManager::localeListLoaded = 0, LocalesManager::curLocaleNum = -1, LocalesManager::englishLocale;
+//PtrList<LocaleItem> LocalesManager::loadableLocalesList;
+StringW LocalesManager::curSection;
+LocalesSkinCallback LocalesManager::localesSkinCallback;
+StringW LocalesManager::curTable;
+StringTableXmlCallback LocalesManager::stringTableXmlCallback;
+StringTableEntryXmlCallback LocalesManager::stringTableXmlEntryCallback; \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/localesmgr.h b/Src/Wasabi/api/locales/localesmgr.h
new file mode 100644
index 00000000..b9495143
--- /dev/null
+++ b/Src/Wasabi/api/locales/localesmgr.h
@@ -0,0 +1,173 @@
+#ifndef _LOCALESMGR_H
+#define _LOCALESMGR_H
+
+#include "../xml/obj_xml.h"
+#include <bfc/ptrlist.h>
+#include <bfc/string/bfcstring.h>
+#include <api/skin/skinparse.h>
+
+#include "LocalesInfo.h"
+
+class LocTrans
+{
+public:
+ LocTrans(const wchar_t *pfrom, const wchar_t *pto) : from(pfrom), to(pto)
+ {
+ //from.toupper();
+ }
+ const wchar_t *getFrom() { return from; }
+ const wchar_t *getTo() { return to; }
+private:
+ StringW from;
+ StringW to;
+};
+
+class PLS_LocTrans
+{
+public:
+ // comparator for sorting
+ static int compareItem(LocTrans *p1, LocTrans* p2) {
+ return wcscmp(p1->getFrom(), p2->getFrom());
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, LocTrans *item) {
+ return wcscmp(attrib, item->getFrom());
+ }
+};
+
+class LocAccel
+{
+public:
+ LocAccel(const wchar_t *psec, const wchar_t *pkey, const wchar_t *paction)
+ : section(psec), key(pkey), realkey(pkey), action(paction)
+ {
+ key.tolower();
+ actionnum = SkinParser::getAction(paction);
+ }
+ const wchar_t *getKey() { return key; }
+ const wchar_t *getRealKey() { return realkey; }
+ const wchar_t *getAction() { return action; }
+ int getActionNum() { return actionnum; }
+ const wchar_t *getSection() { return section; }
+private:
+ StringW section;
+ StringW key;
+ StringW realkey;
+ StringW action;
+ int actionnum;
+};
+
+class PLS_LocAccel
+{
+public:
+ // comparator for sorting
+ static int compareItem(LocAccel *p1, LocAccel *p2)
+ {
+ return wcscmp(p1->getKey(), p2->getKey());
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, LocAccel *item)
+ {
+ return wcscmp(attrib, item->getKey());
+ }
+};
+
+class LocalesAcceleratorSectionXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+};
+
+class LocalesAcceleratorXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class LocalesTranslationXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class StringTableXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+};
+
+class StringTableEntryXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class LocalesSkinCallback : public SkinCallbackI
+{
+public:
+ int skincb_onUnloading();
+ int skincb_onReset();
+ int skincb_onReload();
+ int skincb_onBeforeLoadingElements();
+ int skincb_onGuiLoaded();
+ int skincb_onLoaded();
+
+};
+
+class LocalesManager
+{
+public:
+ static void init();
+ static void load();
+ static void deinit();
+
+ static void loadFile(const wchar_t *name);
+
+ static void addTranslation(const wchar_t *from, const wchar_t *to);
+ static const wchar_t *getTranslation(const wchar_t *from); // will return the from parameter if not found
+ static const wchar_t *lookupString(const wchar_t *from); // will return the from parameter if not found
+
+ static void setAcceleratorSection(const wchar_t *section);
+ static void addAccelerator(const wchar_t *bind, const wchar_t *action);
+ static void addAcceleratorFromSkin(const wchar_t *bind, const wchar_t *action);
+ static const wchar_t *getBindFromAction(int action);
+ static const wchar_t *translateAccelerator(const wchar_t *section, const wchar_t *key);
+
+ //static const wchar_t *enumLoadableLocales(int num);
+ //static int getNumLocales();
+ //static void setNewLocaleFile(const wchar_t *name);
+ //static void setNewLocaleNum(int num);
+ //static int isCurrentLocaleNum(int num) { return num == curLocaleNum; }
+
+ static void resetAll();
+
+ static const wchar_t *getLocaleRoot();
+
+ static void LoadStringTables();
+ static void LoadStringTable(const wchar_t *filename);
+ static void SetStringTable(const wchar_t *table);
+ static void ResetStrings();
+ static const wchar_t *GetString(const wchar_t *table, uint32_t id);
+ static void AddString(const wchar_t *table, uint32_t id, const wchar_t *string);
+ static void AddString(uint32_t id, const wchar_t *string);
+private:
+ static LocalesAcceleratorXmlCallback accelXmlCallback;
+ static LocalesAcceleratorSectionXmlCallback accelSectionXmlCallback;
+ static LocalesTranslationXmlCallback transXmlCallback;
+
+ static PtrListSorted<LocTrans, PLS_LocTrans, QuickSorted<LocTrans, PLS_LocTrans> > translationsList;
+
+ static PtrListSorted<LocAccel, PLS_LocAccel, QuickSorted<LocAccel, PLS_LocAccel> > acceleratorsList;
+
+ static StringW localePath;
+
+ //static PtrList<LocaleItem> loadableLocalesList;
+
+ //static int localeListLoaded, curLocaleNum, englishLocale;
+ static StringW curSection;
+
+ static StringW curTable;
+
+ static LocalesSkinCallback localesSkinCallback;
+ static StringTableXmlCallback stringTableXmlCallback;
+ static StringTableEntryXmlCallback stringTableXmlEntryCallback;
+};
+
+#endif//_LOCALESMGR_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/xlatstr.h b/Src/Wasabi/api/locales/xlatstr.h
new file mode 100644
index 00000000..aca8dac1
--- /dev/null
+++ b/Src/Wasabi/api/locales/xlatstr.h
@@ -0,0 +1,68 @@
+#ifndef _XLATSTR_H
+#define _XLATSTR_H
+
+#include <api/locales/localesmgr.h>
+
+/**
+ Provides string translation for the string
+ used as the constructor parameter.
+
+ The constructor will automatically lookup
+ the translated value of the string it receives
+ in the currently loaded locale.
+
+ @short Translates a string using the currently loaded locale.
+ @author Nullsoft
+ @ver 1.0
+ @see ComponentAPI::locales_getTranslation()
+*/
+
+class _ {
+ public:
+ /**
+ Automatically looks up the translated value of the string
+ it receives as a parameter in the currently loaded
+ locale. The same string is returned if there's no
+ translation.
+
+ @param str String to be translated.
+ @ret Translation found, Translated string; Translation not found, Input string;
+ */
+
+#if defined(WASABI_COMPILE_LOCALES)
+ _(const wchar_t *str) { s=LocalesManager::getTranslation(str); }
+#else
+ _(const wchar_t *str) { s=str; }
+#endif
+ operator const wchar_t *() const { return s; }
+
+ private:
+ const wchar_t *s;
+};
+
+
+class __ {
+ public:
+ /**
+ Automatically looks up the translated value of the string
+ it receives as a parameter in the currently loaded
+ locale. The same string is returned if there's no
+ translation.
+
+ @param str String to be translated.
+ @ret Translation found, Translated string; Translation not found, Input string;
+ */
+
+#if defined(WASABI_COMPILE_LOCALES)
+ __(const wchar_t *str) { s=LocalesManager::lookupString(str); }
+#else
+ __(const wchar_t *str) { s=str; }
+#endif
+ operator const wchar_t *() const { return s; }
+
+ private:
+ const wchar_t *s;
+};
+
+
+#endif \ No newline at end of file