flickerstreak@1: --[[ flickerstreak@1: Name: AceLocale-2.1 flickerstreak@1: Revision: $Rev: 18753 $ flickerstreak@1: Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) flickerstreak@1: Inspired By: Ace 1.x by Turan (turan@gryphon.com) flickerstreak@1: Website: http://www.wowace.com/ flickerstreak@1: Documentation: http://www.wowace.com/index.php/AceLocale-2.1 flickerstreak@1: SVN: http://svn.wowace.com/root/trunk/Ace2/AceLocale-2.1 flickerstreak@1: Description: Localization library for addons to use to handle proper flickerstreak@1: localization and internationalization. flickerstreak@1: Dependencies: AceLibrary flickerstreak@1: ]] flickerstreak@1: flickerstreak@1: local MAJOR_VERSION = "AceLocale-2.1" flickerstreak@1: local MINOR_VERSION = "$Revision: 18753 $" flickerstreak@1: flickerstreak@1: if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end flickerstreak@1: if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end flickerstreak@1: flickerstreak@1: local curTranslation, baseTranslation, translations, baseLocale, curLocale, strictTranslations, dynamic, reverseTranslation flickerstreak@1: local AceLocale = {} flickerstreak@1: local backbone = {} flickerstreak@1: backbone.class, backbone.super = false, false flickerstreak@1: flickerstreak@1: local function initReverse(self) flickerstreak@1: self[reverseTranslation] = {} flickerstreak@1: flickerstreak@1: for k, v in pairs(self[curTranslation]) do self[reverseTranslation][v] = k end flickerstreak@1: flickerstreak@1: setmetatable(self[reverseTranslation], { flickerstreak@1: __index = function(tbl, key) flickerstreak@1: AceLocale:error("Reverse translation for %s not found", key) flickerstreak@1: end flickerstreak@1: }) flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function __call(obj, text, flag) flickerstreak@1: if flag == nil then return obj[text] end flickerstreak@1: flickerstreak@1: if flag == true then flickerstreak@1: if rawget(obj[curTranslation], text) then AceLocale:error("Strict translation for %s not found", text) end flickerstreak@1: return rawget(obj[curTranslation], text) flickerstreak@1: elseif flag == false then flickerstreak@1: return rawget(obj[curTranslation], arg2) or obj[baseTranslation][arg2] flickerstreak@1: elseif flag == "reverse" then flickerstreak@1: if not rawget(obj, reverseTranslation) then initReverse(obj) end flickerstreak@1: return obj[reverseTranslation][text] flickerstreak@1: else flickerstreak@1: AceLocale:error("Invalid flag given to __call. Should be true/false/\"reverse\" but %s was given", flag) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function NewInstance(self, uid) flickerstreak@1: if self.registry[uid] then return self.registry[uid] end flickerstreak@1: flickerstreak@1: self.registry[uid] = {} flickerstreak@1: self.registry[uid][translations] = {} flickerstreak@1: flickerstreak@1: setmetatable(self.registry[uid], { flickerstreak@1: __tostring = function() flickerstreak@1: return "AceLocale(" .. uid .. ")" flickerstreak@1: end, flickerstreak@1: __call = __call, flickerstreak@1: __index = backbone flickerstreak@1: }) flickerstreak@1: flickerstreak@1: return self.registry[uid] flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceLocale:RegisterTranslation(uid, locale, func) flickerstreak@1: error(MAJOR_VERSION .. " is not supported in WoW 2.0", 2) flickerstreak@1: self:argCheck(uid, 1, "string") flickerstreak@1: self:argCheck(locale, 2, "string") flickerstreak@1: self:argCheck(func, 3, "function") flickerstreak@1: flickerstreak@1: local instance = self.registry[uid] or NewInstance(self, uid) flickerstreak@1: flickerstreak@1: if instance[translations][locale] then flickerstreak@1: self:error("Cannot provide the same locale more than once. %q provided twice for %s.", locale, uid) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if rawget(instance, baseLocale) then flickerstreak@1: for k, v in pairs(func()) do flickerstreak@1: if not rawget(instance[baseTranslation], k) then flickerstreak@1: self:error("Improper translation exists. %q is likely misspelled for locale %s.", k, locale) flickerstreak@1: elseif value == true then flickerstreak@1: self:error( "Can only accept true as a value on the base locale. %q is the base locale, %q is not.", instance[baseLocale], locale) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: else flickerstreak@1: instance[baseTranslation] = func() flickerstreak@1: instance[baseLocale] = locale flickerstreak@1: flickerstreak@1: for k, v in pairs(instance[baseTranslation]) do flickerstreak@1: if type(v) ~= "string" and type(v) ~= "table" then flickerstreak@1: if type(v) == "boolean" then flickerstreak@1: instance[baseTranslation][k] = k flickerstreak@1: else flickerstreak@1: self:error("Translation for %s is invalid. Must be either string or boolean", k) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: setmetatable(instance[baseTranslation], {__index = backbone}) flickerstreak@1: end flickerstreak@1: flickerstreak@1: instance[translations][locale] = func flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceLocale:GetInstance(uid, locale) flickerstreak@1: self:argCheck(uid, 1, "string") flickerstreak@1: flickerstreak@1: local instance = self.registry[uid] flickerstreak@1: flickerstreak@1: if not instance then self:error("At least one translation must be registered before you can GetInstance().") end flickerstreak@1: flickerstreak@1: instance:SetLocale(locale) flickerstreak@1: flickerstreak@1: return instance flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceLocale:HasInstance(uid) flickerstreak@1: self:argCheck(uid, 1, "string") flickerstreak@1: return self.registry[uid] and true or false flickerstreak@1: end flickerstreak@1: flickerstreak@1: setmetatable(backbone, {__index = flickerstreak@1: function(tbl, key) flickerstreak@1: AceLocale:error("Translation for %s not found", key) flickerstreak@1: end}) flickerstreak@1: flickerstreak@1: function backbone:SetLocale(locale) flickerstreak@1: local loose = false flickerstreak@1: if locale == nil then return end flickerstreak@1: flickerstreak@1: if locale == true then flickerstreak@1: locale = GetLocale() flickerstreak@1: if rawget(self, curLocale) and self[curLocale] == locale then return end flickerstreak@1: if not self[translations][locale] then locale = self[baseLocale] end flickerstreak@1: end flickerstreak@1: flickerstreak@1: if rawget(self, curLocale) and self[curLocale] == locale then return end flickerstreak@1: flickerstreak@1: if not self[translations][locale] then flickerstreak@1: AceLocale:error("Cannot SetLocale to %s for %s, It has not been registered.", locale, tostring(self)) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if self[translations][locale] and self[baseLocale] == locale then flickerstreak@1: self[curLocale] = self[baseLocale] flickerstreak@1: self[curTranslation] = {} flickerstreak@1: getmetatable(self).__index = self[baseTranslation] flickerstreak@1: else flickerstreak@1: self[curLocale] = locale flickerstreak@1: self[curTranslation] = self[translations][locale]() flickerstreak@1: getmetatable(self).__index = self[curTranslation] flickerstreak@1: end flickerstreak@1: flickerstreak@1: if rawget(self, strictTranslations) then flickerstreak@1: setmetatable(self[curTranslation], { flickerstreak@1: __index = function(tbl, key) flickerstreak@1: AceLocale:error("Translation for %s not found", key) flickerstreak@1: end flickerstreak@1: }) flickerstreak@1: else flickerstreak@1: setmetatable(self[curTranslation], { flickerstreak@1: __index = self[baseTranslation] flickerstreak@1: }) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if not rawget(self, dynamic) then flickerstreak@1: self[translations] = {} flickerstreak@1: end flickerstreak@1: flickerstreak@1: if rawget(self, reverseTranslation) then flickerstreak@1: self[reverseTranslation] = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:ClearLocales() flickerstreak@1: self[translations] = {} flickerstreak@1: self[curLocale] = nil flickerstreak@1: self[baseLocale] = nil flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:SetDynamicLocales(flag) flickerstreak@1: AceLocale:argCheck(flag, 1, "boolean") flickerstreak@1: self[dynamic] = flag flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:SetStrictness(flag) flickerstreak@1: AceLocale:argCheck(flag, 1, "boolean") flickerstreak@1: local mt flickerstreak@1: flickerstreak@1: if rawget(self, curTranslation) then flickerstreak@1: mt = getmetatable(self[curTranslation]) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if strict and mt then flickerstreak@1: mt.__index = function(tbl, key) flickerstreak@1: AceLocale:error("Translation for %s not found", key) flickerstreak@1: end flickerstreak@1: elseif mt then flickerstreak@1: mt.__index = self[baseTranslation] flickerstreak@1: end flickerstreak@1: flickerstreak@1: self[strictTranslations] = strict flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:HasTranslation(text) flickerstreak@1: AceLocale:argCheck(text, 1, "string") flickerstreak@1: flickerstreak@1: if not rawget(self, curTranslation) then AceLocale:error("A locale must be chosen before you can call HasTranslation().") end flickerstreak@1: flickerstreak@1: return rawget(self[curTranslation], text) and true or false flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:HasReverseTranslation(text) flickerstreak@1: AceLocale:argCheck(text, 1, "string") flickerstreak@1: flickerstreak@1: if not rawget(self, curTranslation) then AceLocale:error("A locale must be chosen before you can call HasReverseTranslation().") end flickerstreak@1: flickerstreak@1: if not rawget(self, reverseTranslation) then flickerstreak@1: initReverse(self) flickerstreak@1: end flickerstreak@1: flickerstreak@1: return rawget(self[reverseTranslation], text) and true or false flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:GetIterator() flickerstreak@1: if not rawget(self, curTranslation) then AceLocale:error("A locale must be chosen before you can call GetIterator().") end flickerstreak@1: return pairs(self[curTranslation]) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:GetReverseIterator() flickerstreak@1: if not rawget(self, curTranslation) then AceLocale:error("A locale must be chosen before you can call HasReverseTranslation().") end flickerstreak@1: flickerstreak@1: if not rawget(self, reverseTranslation) then flickerstreak@1: initReverse(self) flickerstreak@1: end flickerstreak@1: flickerstreak@1: return pairs(self[reverseTranslation]) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function backbone:GetLocaleList() flickerstreak@1: local results = {} flickerstreak@1: for k, v in pairs(self[translations]) do tinsert(results, k) end flickerstreak@1: return results flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function activate(self, oldLib, oldDeactivate) flickerstreak@1: AceLocale = self flickerstreak@1: flickerstreak@1: if oldLib then flickerstreak@1: self.registry = oldLib.registry flickerstreak@1: self.curTranslation = oldLib.curTranslation flickerstreak@1: self.baseTranslation = oldLib.baseTranslation flickerstreak@1: self.translations = oldLib.translations flickerstreak@1: self.baseLocale = oldLib.baseLocale flickerstreak@1: self.curLocale = oldLib.curLocale flickerstreak@1: self.strictTranslations = oldLib.strictTranslations flickerstreak@1: self.dynamic = oldLib.dynamic flickerstreak@1: self.reverseTranslation = oldLib.reverseTranslation flickerstreak@1: end flickerstreak@1: flickerstreak@1: if not self.registry then self.registry = {} end flickerstreak@1: if not self.curTranslation then self.curTranslation = {} end flickerstreak@1: if not self.baseTranslation then self.baseTranslation = {} end flickerstreak@1: if not self.translations then self.translations = {} end flickerstreak@1: if not self.baseLocale then self.baseLocale = {} end flickerstreak@1: if not self.curLocale then self.curLocale = {} end flickerstreak@1: if not self.strictTranslations then self.strictTranslations = {} end flickerstreak@1: if not self.dynamic then self.dynamic = {} end flickerstreak@1: if not self.reverseTranslation then self.reverseTranslation = {} end flickerstreak@1: flickerstreak@1: if oldDeactivate then flickerstreak@1: oldDeactivate(oldLib) flickerstreak@1: end flickerstreak@1: flickerstreak@1: curTranslation = self.curTranslation flickerstreak@1: baseTranslation = self.baseTranslation flickerstreak@1: translations = self.translations flickerstreak@1: baseLocale = self.baseLocale flickerstreak@1: curLocale = self.curLocale flickerstreak@1: strictTranslations = self.strictTranslations flickerstreak@1: dynamic = self.dynamic flickerstreak@1: reverseTranslation = self.reverseTranslation flickerstreak@1: end flickerstreak@1: flickerstreak@1: AceLibrary:Register(AceLocale, MAJOR_VERSION, MINOR_VERSION, activate) flickerstreak@1: AceLocale = AceLibrary(MAJOR_VERSION)