Version 0.5.0
- add replacements via options UI - restructure debug functions
This commit is contained in:
		@@ -3,12 +3,12 @@ All notable changes to this project will be documented in this file.
 | 
			
		||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 
 | 
			
		||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 | 
			
		||||
 | 
			
		||||
## [Unreleased] Version 1.0 - 2020-05-28
 | 
			
		||||
## [Unreleased] Version 1.0 - 2020-06-02
 | 
			
		||||
### Added
 | 
			
		||||
- case sensitivity 
 | 
			
		||||
- consolidate consecutive matches
 | 
			
		||||
 | 
			
		||||
## Version 0.5.0 - 2020-05-31
 | 
			
		||||
## Version 0.5.0 - 2020-06-01
 | 
			
		||||
### Added
 | 
			
		||||
- add replacements via options UI
 | 
			
		||||
- handle replacement via slash command
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------------]] --
 | 
			
		||||
-----------------------------------------------------------------------------]]
 | 
			
		||||
 | 
			
		||||
-- read namespace from global env
 | 
			
		||||
local AddonName, AddonTable = ...
 | 
			
		||||
@@ -34,8 +34,12 @@ _G.Grichelde = Grichelde
 | 
			
		||||
-- Ace3 callbacks
 | 
			
		||||
function Grichelde:OnInitialize()
 | 
			
		||||
    -- Build Interface Options window
 | 
			
		||||
    self:LoadDatabase()
 | 
			
		||||
    self:SetupOptions()
 | 
			
		||||
    self.db = self:LoadDatabase()
 | 
			
		||||
    self.options, self.dialog = self:SetupOptions()
 | 
			
		||||
 | 
			
		||||
    self:RefreshOptions("OnProfileChanged")
 | 
			
		||||
    self:DebugPrint(self.db.profile)
 | 
			
		||||
 | 
			
		||||
    self:SetupSlashCommands()
 | 
			
		||||
 | 
			
		||||
    -- Watch for WIM and Prat to Load, then integrate
 | 
			
		||||
@@ -51,22 +55,21 @@ function Grichelde:OnEnable()
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- tell the world we are listening
 | 
			
		||||
    self:DebugPrint(self.L.AddonLoaded, self.L.AddonName)
 | 
			
		||||
    self:Print(self.L.AddonLoaded, self.COLOR_CODES.PREFIX .. self.L.AddonName .. " " .. self.L.VersionAbbr .. self.version .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:OnDisable()
 | 
			
		||||
    self:Unhook("SendChatMessage")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- register 'grichelde' and 'gri' slash commands
 | 
			
		||||
--- Register  slash commands 'gri' and 'grichelde'
 | 
			
		||||
function Grichelde:SetupSlashCommands()
 | 
			
		||||
    local function HandleSlashCommand(input)
 | 
			
		||||
        -- Show the GUI if no input is supplied, otherwise handle the chat input.
 | 
			
		||||
        if not input or input:trim() == "" then
 | 
			
		||||
        if self.functions.nilOrEmpty(input) then
 | 
			
		||||
            LibStub("AceConfigDialog-3.0"):Open(self.name)
 | 
			
		||||
        else
 | 
			
		||||
            -- handle slash ourselves
 | 
			
		||||
            self:Print(self.L.AddonName .. " Version " .. self.version)
 | 
			
		||||
            self:Print("Handle slash command: " .. input)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
@@ -75,8 +78,9 @@ function Grichelde:SetupSlashCommands()
 | 
			
		||||
    self:RegisterChatCommand("gri", HandleSlashCommand)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @param event string
 | 
			
		||||
--- @param addonName string
 | 
			
		||||
--- Hook into WIM to catch whisper sending event.
 | 
			
		||||
-- @param event string
 | 
			
		||||
-- @param addonName string
 | 
			
		||||
function Grichelde:HookIntoForOtherChatAddons(event, addonName)
 | 
			
		||||
    if event == "ADDON_LOADED" then
 | 
			
		||||
        if addonName == "WIM" then
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
## Title: Grichelde
 | 
			
		||||
## Notes: Replaces characters you type in the chat box
 | 
			
		||||
## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile
 | 
			
		||||
## Version: 0.4.0
 | 
			
		||||
## Version: 0.5.0
 | 
			
		||||
## Author: Teilzeit-Jedi
 | 
			
		||||
## eMail: tj@teilzeit-jedi.de
 | 
			
		||||
 | 
			
		||||
@@ -22,5 +22,6 @@ localisation.xml
 | 
			
		||||
Grichelde.lua
 | 
			
		||||
GricheldeConstants.lua
 | 
			
		||||
GricheldeUtils.lua
 | 
			
		||||
GricheldeChat.lua
 | 
			
		||||
GricheldeDatabase.lua
 | 
			
		||||
GricheldeOptions.lua
 | 
			
		||||
GricheldeChat.lua
 | 
			
		||||
 
 | 
			
		||||
@@ -2,22 +2,22 @@
 | 
			
		||||
local _G = _G
 | 
			
		||||
local Grichelde = _G.Grichelde
 | 
			
		||||
 | 
			
		||||
local ipairs, tContains, tFilter, tInsert, tConcat, find, sub, gsub, match, toLower, trim, length
 | 
			
		||||
        = Grichelde.functions.ipairs, Grichelde.functions.tContains, Grichelde.functions.tFilter, Grichelde.functions.tInsert, Grichelde.functions.tConcat, Grichelde.functions.find, Grichelde.functions.sub, Grichelde.functions.gsub, Grichelde.functions.match, Grichelde.functions.toLower, Grichelde.functions.trim, Grichelde.functions.length
 | 
			
		||||
local nilOrEmpty, ipairs, tContains, tFilter, tInsert, tConcat, find, sub, gsub, toLower, trim, length
 | 
			
		||||
    = Grichelde.functions.nilOrEmpty, Grichelde.functions.ipairs, Grichelde.functions.tContains, Grichelde.functions.tFilter, Grichelde.functions.tInsert, Grichelde.functions.tConcat, Grichelde.functions.find, Grichelde.functions.sub, Grichelde.functions.gsub, Grichelde.functions.toLower, Grichelde.functions.trim, Grichelde.functions.length
 | 
			
		||||
 | 
			
		||||
--- Before a chat message is sent, check if replacement is required and replace the text accordingly.
 | 
			
		||||
--- @param message string
 | 
			
		||||
--- @param type string
 | 
			
		||||
--- @param language string
 | 
			
		||||
--- @param channel string
 | 
			
		||||
-- @param message string
 | 
			
		||||
-- @param type string
 | 
			
		||||
-- @param language string
 | 
			
		||||
-- @param channel string
 | 
			
		||||
function Grichelde:SendChatMessage(message, type, language, channel, ...)
 | 
			
		||||
    local replacedText = self:CheckAndReplace(message, type)
 | 
			
		||||
 | 
			
		||||
    self:DebugPrint("SendChatMessage : replacedText: " .. replacedText)
 | 
			
		||||
    self:DebugPrint("SendChatMessage : replacedText:", replacedText)
 | 
			
		||||
 | 
			
		||||
    -- Send text in chunks if length exceeds 255 bytes after replacement
 | 
			
		||||
    local chunks = self:SplitText(replacedText)
 | 
			
		||||
    self:DebugPrint("SendChatMessage : #chunks: " .. #chunks)
 | 
			
		||||
    self:DebugPrint("SendChatMessage : #chunks:", #chunks)
 | 
			
		||||
 | 
			
		||||
    for _, chunk in ipairs(chunks) do
 | 
			
		||||
        self.hooks["SendChatMessage"](chunk, type, language, channel, ...);
 | 
			
		||||
@@ -37,20 +37,26 @@ function Grichelde:CheckAndReplace(message, type)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:CheckReplacement(text, channel)
 | 
			
		||||
    -- skip if not enabled
 | 
			
		||||
    if (not self.db.profile.enabled) then
 | 
			
		||||
        self:DebugPrint("CheckReplacement : disabled")
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- check channel type
 | 
			
		||||
    -- skip if no text
 | 
			
		||||
    if nilOrEmpty(text) then
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- skip if wrong channel
 | 
			
		||||
    local allowedChannels = tFilter(self.db.profile.channels,
 | 
			
		||||
        function(_,v) return v == true end,
 | 
			
		||||
        function(k,_) return k end
 | 
			
		||||
    )
 | 
			
		||||
    self:DebugPrint("CheckReplacement : allowed channels: %s", tConcat(allowedChannels, ", "))
 | 
			
		||||
    self:DebugPrint("CheckReplacement : allowed channels:", tConcat(allowedChannels, ", "))
 | 
			
		||||
    local type = self:ConvertBlizChannelToType(channel)
 | 
			
		||||
    if (type ~= nil and not tContains(allowedChannels, type)) then
 | 
			
		||||
        self:DebugPrint("CheckReplacement : skip channel type %s", type)
 | 
			
		||||
        self:DebugPrint("CheckReplacement : skip channel type:", type)
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@@ -74,56 +80,19 @@ function Grichelde:ConvertBlizChannelToType(channel)
 | 
			
		||||
    return type
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures or raid target icons
 | 
			
		||||
--- and returns the end location of the match, or 0 if no pattern was found
 | 
			
		||||
--- @param text string
 | 
			
		||||
--- @return number
 | 
			
		||||
function Grichelde:CheckForPreversableText(text)
 | 
			
		||||
    self:DebugPrint("CheckForPreversableText : text is " .. text)
 | 
			
		||||
 | 
			
		||||
    -- do not replace these patterns
 | 
			
		||||
    local ignorePatterns = {
 | 
			
		||||
        "|[Cc]%x%x%x%x%x%x%x%x.-|r",    -- colored items (or links)
 | 
			
		||||
        "|H.-|h",                       -- item links (http://www.wowwiki.com/ItemLink)
 | 
			
		||||
        "|T.-|t",                       -- textures
 | 
			
		||||
        "|n",                           -- newline
 | 
			
		||||
        "{rt[1-8]}",                    -- rumbered raid target icons
 | 
			
		||||
        "{Star}",                       -- named raid target icon 1
 | 
			
		||||
        "{Circle}",                     -- named raid target icon 2
 | 
			
		||||
        "{Coin}",                       -- named raid target icon 2
 | 
			
		||||
        "{Diamond}",                    -- named raid target icon 3
 | 
			
		||||
        "{Triangle}",                   -- named raid target icon 4
 | 
			
		||||
        "{Moon}",                       -- named raid target icon 5
 | 
			
		||||
        "{Square}",                     -- named raid target icon 6
 | 
			
		||||
        "{Cross}",                      -- named raid target icon 7
 | 
			
		||||
        "{X}",                          -- named raid target icon 7
 | 
			
		||||
        "{Skull}"                       -- named raid target icon 8
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    -- Calling find on ever pattern might be inefficient but its way less code.
 | 
			
		||||
    for _, pattern in ipairs(ignorePatterns) do
 | 
			
		||||
        local pos1, pos2 = find(text, pattern)
 | 
			
		||||
        if pos1 == 1 and pos2 ~= nil then
 | 
			
		||||
            self:DebugPrint("CheckForPreversableText : Found ignore pattern \"%s\" at (%d, %d)", pattern, pos1, pos2)
 | 
			
		||||
            return pos2
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    self:DebugPrint("CheckForPreversableText : no ignore pattern found")
 | 
			
		||||
    return 0
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Replaces all character occurrences for which replacements have been defined in the options,
 | 
			
		||||
--- while preserving any itemLinks or textures. (http://www.wowwiki.com/ItemLink)
 | 
			
		||||
--- @param text string
 | 
			
		||||
--- @return string
 | 
			
		||||
-- @param text string
 | 
			
		||||
-- @return string
 | 
			
		||||
function Grichelde:ReplaceText(text)
 | 
			
		||||
    local lookAheads = {'|', '{', '%'}
 | 
			
		||||
    local finalText = ""
 | 
			
		||||
    local newText = text
 | 
			
		||||
 | 
			
		||||
    -- don't replace non-chat related slash commands
 | 
			
		||||
    local firstWord, line = self:SplitOnFirstMatch(text)
 | 
			
		||||
    if (firstWord ~= nil and tContains(self.slashCommands, firstWord)) then
 | 
			
		||||
        self:DebugPrint("ReplaceText : Found slash command %s", firstWord )
 | 
			
		||||
        self:DebugPrint("ReplaceText : Found slash command:", firstWord )
 | 
			
		||||
        -- skip chat slash command
 | 
			
		||||
        finalText = finalText .. firstWord .. ' '
 | 
			
		||||
        newText = line
 | 
			
		||||
@@ -136,7 +105,7 @@ function Grichelde:ReplaceText(text)
 | 
			
		||||
        local currentChar = sub(newText, current, current)
 | 
			
		||||
        self:DebugPrint("current/char : %s,%s", current, currentChar)
 | 
			
		||||
 | 
			
		||||
        if currentChar ~= '|' and currentChar ~= '{' then
 | 
			
		||||
        if ( not tContains(lookAheads, currentChar)) then
 | 
			
		||||
            current = current + 1
 | 
			
		||||
        else
 | 
			
		||||
 | 
			
		||||
@@ -153,7 +122,7 @@ function Grichelde:ReplaceText(text)
 | 
			
		||||
                finalText = finalText .. replacement .. preservedText
 | 
			
		||||
                current = current + posEnd
 | 
			
		||||
                lastStart = current
 | 
			
		||||
                self:DebugPrint("ReplaceText : restarting at " .. lastStart)
 | 
			
		||||
                self:DebugPrint("ReplaceText : restarting at", lastStart)
 | 
			
		||||
            else
 | 
			
		||||
                -- no corresponding end was found to start pattern, continue loop with next char
 | 
			
		||||
                current = current + 1
 | 
			
		||||
@@ -166,14 +135,64 @@ function Grichelde:ReplaceText(text)
 | 
			
		||||
    local replacement = self:ReplaceCharacters(remainingText)
 | 
			
		||||
    finalText = finalText .. replacement
 | 
			
		||||
 | 
			
		||||
    self:DebugPrint("ReplaceText : replaced \"" .. text .. "\"")
 | 
			
		||||
    self:DebugPrint("ReplaceText : with         \"" .. finalText .. "\"")
 | 
			
		||||
    self:DebugPrint("ReplaceText : replaced \"%s\"", text)
 | 
			
		||||
    self:DebugPrint("ReplaceText : with         \"%s\"", finalText)
 | 
			
		||||
    return finalText
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures, raid target icons or
 | 
			
		||||
--- %-substitutons and returns the end location of the match, or 0 if no pattern was found
 | 
			
		||||
-- @param text string
 | 
			
		||||
-- @return number
 | 
			
		||||
function Grichelde:CheckForPreversableText(text)
 | 
			
		||||
    self:DebugPrint("CheckForPreversableText : text:", text)
 | 
			
		||||
 | 
			
		||||
    -- do not replace these patterns
 | 
			
		||||
    local ignorePatterns = {
 | 
			
		||||
        "|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links)
 | 
			
		||||
        "|H.-|h", -- item links (http://www.wowwiki.com/ItemLink)
 | 
			
		||||
        "|T.-|t", -- textures
 | 
			
		||||
        "|n", -- newline
 | 
			
		||||
 | 
			
		||||
        "{rt[1-8]}",  -- rumbered raid target icons
 | 
			
		||||
        "{Star}",     -- named raid target icon 1
 | 
			
		||||
        "{Circle}",   -- named raid target icon 2
 | 
			
		||||
        "{Coin}",     -- named raid target icon 2
 | 
			
		||||
        "{Diamond}",  -- named raid target icon 3
 | 
			
		||||
        "{Triangle}", -- named raid target icon 4
 | 
			
		||||
        "{Moon}",     -- named raid target icon 5
 | 
			
		||||
        "{Square}",   -- named raid target icon 6
 | 
			
		||||
        "{Cross}",    -- named raid target icon 7
 | 
			
		||||
        "{X}",        -- named raid target icon 7
 | 
			
		||||
        "{Skull}",    -- named raid target icon 8
 | 
			
		||||
 | 
			
		||||
        "%%n",   -- player's name
 | 
			
		||||
        "%%z",   -- player's currnt zone
 | 
			
		||||
        "%%sz",  -- player's current sub-zone
 | 
			
		||||
        "%%loc", -- player's map coordinates
 | 
			
		||||
        "%%t",   -- name of target
 | 
			
		||||
        "%%f",   -- name of focus target
 | 
			
		||||
        "%%m",   -- name of mouseover unit
 | 
			
		||||
        "%%p",   -- name of player pet
 | 
			
		||||
        "%%tt"   -- name of player's target's target
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    -- Calling find on ever pattern might be inefficient but its way less code.
 | 
			
		||||
    for _, pattern in ipairs(ignorePatterns) do
 | 
			
		||||
        local pos1, pos2 = find(text, pattern)
 | 
			
		||||
        if pos1 == 1 and pos2 ~= nil then
 | 
			
		||||
            self:DebugPrint("CheckForPreversableText : Found ignore pattern \"%s\" at (%d, %d)", pattern, pos1, pos2)
 | 
			
		||||
            return pos2
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    self:DebugPrint("CheckForPreversableText : no ignore pattern found")
 | 
			
		||||
    return 0
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Replaces all character occurrences for which replacements have been defined in the options
 | 
			
		||||
--- @param text string
 | 
			
		||||
--- @return string
 | 
			
		||||
-- @param text string
 | 
			
		||||
-- @return string
 | 
			
		||||
function Grichelde:ReplaceCharacters(text)
 | 
			
		||||
    -- todo: read from options
 | 
			
		||||
    -- todo: case (in)sensitivity
 | 
			
		||||
@@ -189,12 +208,12 @@ function Grichelde:ReplaceCharacters(text)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Splits a long text in longest possible chunks of <= 255 length, split at last available space
 | 
			
		||||
--- @param text string
 | 
			
		||||
--- @return table
 | 
			
		||||
-- @param text string
 | 
			
		||||
-- @return table
 | 
			
		||||
function Grichelde:SplitText(text)
 | 
			
		||||
    local chunks = {}
 | 
			
		||||
    local splitText = text
 | 
			
		||||
    local textSize = length(splitText)
 | 
			
		||||
    local textSize = length(splitText or "")
 | 
			
		||||
 | 
			
		||||
    while textSize > 255 do
 | 
			
		||||
        local chunk = sub(splitText, 1, 255)
 | 
			
		||||
@@ -212,7 +231,7 @@ function Grichelde:SplitText(text)
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        self:DebugPrint("SplitText : chunk: " .. chunk )
 | 
			
		||||
        self:DebugPrint("SplitText : chunk:", chunk)
 | 
			
		||||
 | 
			
		||||
        tInsert(chunks, chunk)
 | 
			
		||||
        splitText = remaining .. sub(splitText, 256)
 | 
			
		||||
@@ -220,26 +239,8 @@ function Grichelde:SplitText(text)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- pickup remaining text < 255
 | 
			
		||||
    self:DebugPrint("SplitText : last chunk: " .. splitText)
 | 
			
		||||
    self:DebugPrint("SplitText : last chunk:", splitText)
 | 
			
		||||
    tInsert(chunks, splitText)
 | 
			
		||||
 | 
			
		||||
    return chunks
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- split at first word of a text line
 | 
			
		||||
function Grichelde:SplitOnFirstMatch(text, start)
 | 
			
		||||
    self:DebugPrint("SplitOnFirstMatch : text: %s, start: %d", text, start)
 | 
			
		||||
    local pos = start or 1
 | 
			
		||||
    local left, right = match(text, "^.- .+", pos)
 | 
			
		||||
    self:DebugPrint("SplitOnFirstMatch : left: %s, right: %s", left, right)
 | 
			
		||||
    return left or text, right
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- split at last word of a text line
 | 
			
		||||
function Grichelde:SplitOnLastMatch(text, start)
 | 
			
		||||
    self:DebugPrint("SplitOnLastMatch : text: %s, start: %d", text, start)
 | 
			
		||||
    local pos = start or 1
 | 
			
		||||
    local left, right = match(text, ".+ .-$", pos)
 | 
			
		||||
    self:DebugPrint("SplitOnLastMatch : left: %s, right: %s", left, right)
 | 
			
		||||
    return left, right or text
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -4,40 +4,6 @@ local Grichelde = _G.Grichelde
 | 
			
		||||
 | 
			
		||||
-- upvalues and constants
 | 
			
		||||
 | 
			
		||||
-- faster function lookups by mapping to local refs
 | 
			
		||||
Grichelde.functions = {}
 | 
			
		||||
Grichelde.functions.type       = _G.type
 | 
			
		||||
Grichelde.functions.print      = _G.print
 | 
			
		||||
Grichelde.functions.pairs      = _G.pairs
 | 
			
		||||
Grichelde.functions.ipairs     = _G.ipairs
 | 
			
		||||
Grichelde.functions.tContains  = _G.tContains
 | 
			
		||||
Grichelde.functions.tFilter    = function(t, cond, extr)
 | 
			
		||||
    local filtered = {}
 | 
			
		||||
    for key, value in Grichelde.functions.pairs(t) do
 | 
			
		||||
        if cond(key, value) then
 | 
			
		||||
            local val = extr(key, value)
 | 
			
		||||
            Grichelde.functions.tInsert(filtered, #filtered + 1, val)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return filtered
 | 
			
		||||
end
 | 
			
		||||
Grichelde.functions.tInsert    = _G.table.insert
 | 
			
		||||
Grichelde.functions.tConcat    = _G.table.concat
 | 
			
		||||
Grichelde.functions.select     = _G.select
 | 
			
		||||
Grichelde.functions.unpack     = _G.unpack
 | 
			
		||||
Grichelde.functions.find       = _G.string.find
 | 
			
		||||
Grichelde.functions.sub        = _G.string.sub
 | 
			
		||||
Grichelde.functions.gsub       = _G.string.gsub
 | 
			
		||||
Grichelde.functions.match      = _G.strmatch
 | 
			
		||||
Grichelde.functions.join       = _G.strjoin
 | 
			
		||||
Grichelde.functions.toLower    = _G.strlower
 | 
			
		||||
Grichelde.functions.toUpper    = _G.strupper
 | 
			
		||||
Grichelde.functions.format     = _G.string.format
 | 
			
		||||
Grichelde.functions.rep        = _G.string.rep
 | 
			
		||||
Grichelde.functions.trim       = _G.strtrim
 | 
			
		||||
Grichelde.functions.length     = _G.string.len
 | 
			
		||||
Grichelde.functions.toString   = _G.tostring
 | 
			
		||||
 | 
			
		||||
-- colors:
 | 
			
		||||
Grichelde.COLOR_CODES = {}
 | 
			
		||||
Grichelde.COLOR_CODES.PREFIX      = "|c00FFAA00"
 | 
			
		||||
@@ -54,41 +20,105 @@ Grichelde.COLOR_CODES.CLOSE       = _G.FONT_COLOR_CODE_CLOSE       or "|r";
 | 
			
		||||
 | 
			
		||||
Grichelde.slashCommands = { "/s", "/say", "/e", "/em", "/me", "/emote", "/y", "/yell", "/sh", "/shout", "/p", "/party", "/pl", "/partyleader", "/g", "/gc", "/guild", "/o", "/osay", "/officer", "/raid", "/rsay", "/rl", "/raidleader", "/rw", "/raidwarning", "/i", "/instance", "/bg", "/battleground", "/w", "/whisper", "/t", "/tell", "/send", "/r", "/reply" }
 | 
			
		||||
 | 
			
		||||
Grichelde.defaultConfig = {
 | 
			
		||||
    global = {},
 | 
			
		||||
    profile = {
 | 
			
		||||
        enabled = true,
 | 
			
		||||
        channels = {
 | 
			
		||||
            ["*"] = false,
 | 
			
		||||
            say = true,
 | 
			
		||||
            emote = false,
 | 
			
		||||
            yell = true,
 | 
			
		||||
            party = true,
 | 
			
		||||
            partyLeader = true,
 | 
			
		||||
            guild = true,
 | 
			
		||||
            officer = true,
 | 
			
		||||
        },
 | 
			
		||||
        replacements = {
 | 
			
		||||
            ["**"] = {
 | 
			
		||||
                searchText = "",
 | 
			
		||||
                replaceText = "",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            },
 | 
			
		||||
            replacement_0 = {
 | 
			
		||||
                order = 1,
 | 
			
		||||
                searchText = "s",
 | 
			
		||||
                replaceText = "ch",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            },
 | 
			
		||||
            replacement_1 = {
 | 
			
		||||
                order = 2,
 | 
			
		||||
                searchText = "t",
 | 
			
		||||
                replaceText = "ck",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
local function nilOrEmpty(s)
 | 
			
		||||
    return s == nil or s:trim() == ""
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function spairs(t , orderFunc)
 | 
			
		||||
    -- collect the keys
 | 
			
		||||
    local sortedKeys = {}
 | 
			
		||||
    -- for every non-nil value
 | 
			
		||||
    for key, _ in Grichelde.functions.pairs(t) do
 | 
			
		||||
        Grichelde.functions.tInsert(sortedKeys, key)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if orderFunc then
 | 
			
		||||
        Grichelde.functions.tSort(sortedKeys, function(a, b) return orderFunc(sortedKeys, a, b) end)
 | 
			
		||||
    else
 | 
			
		||||
        Grichelde.functions.tSort(sortedKeys)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- return the iterator function
 | 
			
		||||
    local it = 0
 | 
			
		||||
    return function()
 | 
			
		||||
        it = it + 1
 | 
			
		||||
        if sortedKeys[it] then
 | 
			
		||||
            return sortedKeys[it], t[sortedKeys[it]]
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function tFilter(t, cond, extr)
 | 
			
		||||
    local filtered = {}
 | 
			
		||||
    for key, value in Grichelde.functions.pairs(t) do
 | 
			
		||||
        if cond(key, value) then
 | 
			
		||||
            local val = extr(key, value)
 | 
			
		||||
            Grichelde.functions.tInsert(filtered, #filtered + 1, val)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return filtered
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function tSize(t)
 | 
			
		||||
    local size = 0
 | 
			
		||||
    if (t) then
 | 
			
		||||
        -- for every non-nil value
 | 
			
		||||
        for _, _ in Grichelde.functions.pairs(t) do
 | 
			
		||||
            size = size + 1
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return size
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function tClone(orig)
 | 
			
		||||
    local orig_type = Grichelde.functions.type(orig)
 | 
			
		||||
    local copy
 | 
			
		||||
    if orig_type == 'table' then
 | 
			
		||||
        copy = {}
 | 
			
		||||
        -- for every non-nil value
 | 
			
		||||
        for orig_key, orig_value in Grichelde.functions.tNext, orig, nil do
 | 
			
		||||
            copy[tClone(orig_key)] = tClone(orig_value)
 | 
			
		||||
        end
 | 
			
		||||
        Grichelde.functions.setmetatable(copy, tClone(Grichelde.functions.getmetatable(orig)))
 | 
			
		||||
    else -- number, string, boolean, etc
 | 
			
		||||
        copy = orig
 | 
			
		||||
    end
 | 
			
		||||
    return copy
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- faster function lookups by mapping to local refs
 | 
			
		||||
Grichelde.functions = {}
 | 
			
		||||
Grichelde.functions.type         = _G.type
 | 
			
		||||
Grichelde.functions.print        = _G.print
 | 
			
		||||
Grichelde.functions.nilOrEmpty   = nilOrEmpty
 | 
			
		||||
Grichelde.functions.pairs        = _G.pairs
 | 
			
		||||
Grichelde.functions.ipairs       = _G.ipairs
 | 
			
		||||
Grichelde.functions.spairs       = spairs
 | 
			
		||||
Grichelde.functions.tContains    = _G.tContains
 | 
			
		||||
Grichelde.functions.tFilter      = tFilter
 | 
			
		||||
Grichelde.functions.tInsert      = _G.table.insert
 | 
			
		||||
Grichelde.functions.tConcat      = _G.table.concat
 | 
			
		||||
Grichelde.functions.tSize        = tSize
 | 
			
		||||
Grichelde.functions.tSort        = _G.table.sort
 | 
			
		||||
Grichelde.functions.tClone       = tClone
 | 
			
		||||
Grichelde.functions.tNext        = _G.next
 | 
			
		||||
Grichelde.functions.setmetatable = _G.setmetatable
 | 
			
		||||
Grichelde.functions.getmetatable = _G.getmetatable
 | 
			
		||||
Grichelde.functions.select       = _G.select
 | 
			
		||||
Grichelde.functions.unpack       = _G.unpack
 | 
			
		||||
Grichelde.functions.find         = _G.string.find
 | 
			
		||||
Grichelde.functions.sub          = _G.string.sub
 | 
			
		||||
Grichelde.functions.gsub         = _G.string.gsub
 | 
			
		||||
Grichelde.functions.match        = _G.strmatch
 | 
			
		||||
Grichelde.functions.join         = _G.strjoin
 | 
			
		||||
Grichelde.functions.split        = _G.strsplit
 | 
			
		||||
Grichelde.functions.toLower      = _G.strlower
 | 
			
		||||
Grichelde.functions.toUpper      = _G.strupper
 | 
			
		||||
Grichelde.functions.format       = _G.string.format
 | 
			
		||||
Grichelde.functions.rep          = _G.string.rep
 | 
			
		||||
Grichelde.functions.trim         = _G.strtrim
 | 
			
		||||
Grichelde.functions.length       = _G.string.len
 | 
			
		||||
Grichelde.functions.toString     = _G.tostring
 | 
			
		||||
Grichelde.functions.toNumber     = _G.tonumber
 | 
			
		||||
Grichelde.functions.max          = _G.math.max
 | 
			
		||||
Grichelde.functions.min          = _G.math.min
 | 
			
		||||
							
								
								
									
										122
									
								
								GricheldeDatabase.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								GricheldeDatabase.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
-- read namespace from global env
 | 
			
		||||
local _G = _G
 | 
			
		||||
local Grichelde = _G.Grichelde
 | 
			
		||||
 | 
			
		||||
local pairs, ipairs, tInsert, tSort, unpack, join, toString
 | 
			
		||||
    = Grichelde.functions.pairs, Grichelde.functions.ipairs, Grichelde.functions.tInsert, Grichelde.functions.tSort, Grichelde.functions.unpack, Grichelde.functions.join, Grichelde.functions.toString
 | 
			
		||||
 | 
			
		||||
local defaultConfig = {
 | 
			
		||||
    global = {},
 | 
			
		||||
    profile = {
 | 
			
		||||
        enabled = true,
 | 
			
		||||
        channels = {
 | 
			
		||||
            ["*"] = false,
 | 
			
		||||
            say = true,
 | 
			
		||||
            emote = false,
 | 
			
		||||
            yell = true,
 | 
			
		||||
            party = true,
 | 
			
		||||
            guild = true,
 | 
			
		||||
            officer = true,
 | 
			
		||||
        },
 | 
			
		||||
        replacements = {
 | 
			
		||||
            ["**"] = {
 | 
			
		||||
                order = 9999,
 | 
			
		||||
                searchText = "",
 | 
			
		||||
                replaceText = "",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            },
 | 
			
		||||
            replacement_0 = {
 | 
			
		||||
                order = 5,
 | 
			
		||||
                searchText = "s",
 | 
			
		||||
                replaceText = "ch",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            },
 | 
			
		||||
            replacement_1 = {
 | 
			
		||||
                order = 9,
 | 
			
		||||
                searchText = "t",
 | 
			
		||||
                replaceText = "ck",
 | 
			
		||||
                caseSensitive = false,
 | 
			
		||||
                consolidate = true,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function Grichelde:LoadDatabase()
 | 
			
		||||
    local db = LibStub("AceDB-3.0"):New(self.name .."DB", defaultConfig, true)
 | 
			
		||||
 | 
			
		||||
    db.RegisterCallback(self, "OnNewProfile", "RefreshOptions")
 | 
			
		||||
    db.RegisterCallback(self, "OnProfileChanged", "RefreshOptions")
 | 
			
		||||
    db.RegisterCallback(self, "OnProfileDeleted", "RefreshOptions")
 | 
			
		||||
    db.RegisterCallback(self, "OnProfileCopied", "RefreshOptions")
 | 
			
		||||
    db.RegisterCallback(self, "OnProfileReset", "RefreshOptions")
 | 
			
		||||
 | 
			
		||||
    return db
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:SyncToDatabase(info, val)
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while (path < #info) do
 | 
			
		||||
        option = option[info[path]] -- or nil
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
    local optionPath = join(".", unpack(info, 1, #info))
 | 
			
		||||
    self:DebugPrint("change option \"%s\" from %s to %s", optionPath, toString(option[info[path]]), toString(val))
 | 
			
		||||
    option[info[path]] = val
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:ReadFromDatabase(info)
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while (path <= #info) do
 | 
			
		||||
        option = option[info[path]] -- or nil
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
    local optionPath = join(".", unpack(info, 1, #info))
 | 
			
		||||
    self:DebugPrint("read option \"%s\": %s", optionPath, toString(option))
 | 
			
		||||
    return option
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Sorts a replacements table by order sub-field.
 | 
			
		||||
--- Usually called with with self.db.profile.replacements
 | 
			
		||||
-- @param replacementsTable table
 | 
			
		||||
-- @return table
 | 
			
		||||
function Grichelde:ReorderReplacements(replacementsTable)
 | 
			
		||||
    local replacements = replacementsTable or {}
 | 
			
		||||
    local sortedByOrder = {}
 | 
			
		||||
    for replName, _ in pairs(replacements) do
 | 
			
		||||
        tInsert(sortedByOrder, replName)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    tSort(sortedByOrder)    -- lexicographical order will do for non-nil values
 | 
			
		||||
    --[[tSort(sortedByOrder, function(a, b)
 | 
			
		||||
        self:DebugPrint("ReorderReplacements : sort ", a, b)
 | 
			
		||||
        if a then
 | 
			
		||||
            if b then
 | 
			
		||||
                return a < b
 | 
			
		||||
            else
 | 
			
		||||
                return a
 | 
			
		||||
            end
 | 
			
		||||
        else
 | 
			
		||||
            return b
 | 
			
		||||
        end
 | 
			
		||||
    end)]]
 | 
			
		||||
 | 
			
		||||
    self:DebugPrint("ReorderReplacements : sortedByOrder")
 | 
			
		||||
    self:DebugPrint(sortedByOrder)
 | 
			
		||||
 | 
			
		||||
    local sortedReplacements = {}
 | 
			
		||||
    local index = 0
 | 
			
		||||
    for _, replName in ipairs(sortedByOrder) do
 | 
			
		||||
        sortedReplacements["replacement_"..index] = replacements[replName]
 | 
			
		||||
        sortedReplacements["replacement_"..index].order = index
 | 
			
		||||
        index = index + 1
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    --self:DebugPrint("ReorderReplacements : sorted table")
 | 
			
		||||
    --self:DebugPrint(sortedReplacements)
 | 
			
		||||
    return sortedReplacements
 | 
			
		||||
end
 | 
			
		||||
@@ -2,7 +2,8 @@
 | 
			
		||||
local _G = _G
 | 
			
		||||
local Grichelde = _G.Grichelde
 | 
			
		||||
 | 
			
		||||
local unpack, join, toString = Grichelde.functions.unpack, Grichelde.functions.join, Grichelde.functions.toString
 | 
			
		||||
local nilOrEmpty, pairs, tSize, unpack, find, join, toString, toNumber
 | 
			
		||||
    = Grichelde.functions.nilOrEmpty, Grichelde.functions.pairs, Grichelde.functions.tSize, Grichelde.functions.unpack, Grichelde.functions.find, Grichelde.functions.join, Grichelde.functions.toString, Grichelde.functions.toNumber
 | 
			
		||||
 | 
			
		||||
function Grichelde:CreateOptionsUI()
 | 
			
		||||
    return {
 | 
			
		||||
@@ -52,56 +53,44 @@ function Grichelde:CreateOptionsUI()
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelParty_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelParty_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    partyLeader = {
 | 
			
		||||
                        order = 4,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelPartyLeader_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelPartyLeader_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    guild = {
 | 
			
		||||
                        order = 5,
 | 
			
		||||
                        order = 4,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelGuild_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelGuild_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    officer = {
 | 
			
		||||
                        order = 6,
 | 
			
		||||
                        order = 5,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelOfficer_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelOfficer_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    raid = {
 | 
			
		||||
                        order = 7,
 | 
			
		||||
                        order = 6,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelRaid_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelRaid_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    raidLeader = {
 | 
			
		||||
                        order = 8,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelRaidLeader_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelRaidLeader_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    raidWarning = {
 | 
			
		||||
                        order = 9,
 | 
			
		||||
                        order = 7,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelRaidWarning_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelRaidWarning_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    instance = {
 | 
			
		||||
                        order = 10,
 | 
			
		||||
                        order = 8,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelInstance_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelInstance_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    battleground = {
 | 
			
		||||
                        order = 11,
 | 
			
		||||
                        order = 9,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelBattleground_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelBattleground_Desc, self.L.AddonName),
 | 
			
		||||
                    },
 | 
			
		||||
                    whisper = {
 | 
			
		||||
                        order = 12,
 | 
			
		||||
                        order = 10,
 | 
			
		||||
                        type = "toggle",
 | 
			
		||||
                        name = self.L.Options_Channels_ChannelWhisper_Name,
 | 
			
		||||
                        desc = self:Format(self.L.Options_Channels_ChannelWhisper_Desc, self.L.AddonName),
 | 
			
		||||
@@ -118,56 +107,19 @@ function Grichelde:CreateOptionsUI()
 | 
			
		||||
                    add = {
 | 
			
		||||
                        order = 0,
 | 
			
		||||
                        type = "execute",
 | 
			
		||||
                        confirm = false,
 | 
			
		||||
                        name = self.L.Options_Replacements_Add_Name,
 | 
			
		||||
                        desc = self.L.Options_Replacements_Add_Desc,
 | 
			
		||||
                        func = function(info) self:AddReplacement(info) end
 | 
			
		||||
                    },
 | 
			
		||||
                    deleteAll = {
 | 
			
		||||
                        order = 0,
 | 
			
		||||
                        order = 1,
 | 
			
		||||
                        type = "execute",
 | 
			
		||||
                        confirm = "",
 | 
			
		||||
                        confirm = true,
 | 
			
		||||
                        confirmText = self.L.Options_Replacements_DeleteAll_ConfirmText,
 | 
			
		||||
                        name = self.L.Options_Replacements_DeleteAll_Name,
 | 
			
		||||
                        desc = self.L.Options_Replacements_DeleteAll_Desc,
 | 
			
		||||
                    },
 | 
			
		||||
                    replacement_0 = {
 | 
			
		||||
                        order = 0,
 | 
			
		||||
                        type = "group",
 | 
			
		||||
                        name = self.L.Options_Replacement_Group_Name,
 | 
			
		||||
                        desc = self.L.Options_Replacement_Group_Desc,
 | 
			
		||||
                        childGroups = "tree",
 | 
			
		||||
                        args = {
 | 
			
		||||
                            searchText = {
 | 
			
		||||
                                order = 0,
 | 
			
		||||
                                type = "input",
 | 
			
		||||
                                name = self.L.Options_Replacement_SearchText_Name,
 | 
			
		||||
                                desc = self.L.Options_Replacement_SearchText_Desc,
 | 
			
		||||
                            },
 | 
			
		||||
                            replaceText = {
 | 
			
		||||
                                order = 1,
 | 
			
		||||
                                type = "input",
 | 
			
		||||
                                name = self.L.Options_Replacement_ReplaceText_Name,
 | 
			
		||||
                                desc = self.L.Options_Replacement_ReplaceText_Desc,
 | 
			
		||||
                            },
 | 
			
		||||
                            caseSensitive = {
 | 
			
		||||
                                order = 2,
 | 
			
		||||
                                type = "toggle",
 | 
			
		||||
                                name = self.L.Options_Replacement_CaseSensitive_Name,
 | 
			
		||||
                                desc = self.L.Options_Replacement_CaseSensitive_Desc,
 | 
			
		||||
                            },
 | 
			
		||||
                            consolidate = {
 | 
			
		||||
                                order = 3,
 | 
			
		||||
                                type = "toggle",
 | 
			
		||||
                                name = self.L.Options_Replacement_Consolidate_Name,
 | 
			
		||||
                                desc = self.L.Options_Replacement_Consolidate_Desc,
 | 
			
		||||
                                width = 2
 | 
			
		||||
                            },
 | 
			
		||||
                            deleteAll = {
 | 
			
		||||
                                order = 4,
 | 
			
		||||
                                type = "execute",
 | 
			
		||||
                                confirm = "",
 | 
			
		||||
                                name = self.L.Options_Replacement_Delete_Name,
 | 
			
		||||
                                desc = self.L.Options_Replacement_Delete_Desc,
 | 
			
		||||
                            },
 | 
			
		||||
                        }
 | 
			
		||||
                        func = function(info) self:DeleteAllReplacements(info) end
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -175,59 +127,64 @@ function Grichelde:CreateOptionsUI()
 | 
			
		||||
    }
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:LoadDatabase()
 | 
			
		||||
    -- Called when the addon is loaded
 | 
			
		||||
    self.db = LibStub("AceDB-3.0"):New(self.name .."DB", self.defaultConfig, true)
 | 
			
		||||
 | 
			
		||||
    -- todo: is this really needed?
 | 
			
		||||
    self.db.RegisterCallback(self, "OnProfileChanged", function (event)
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Loaded, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    end)
 | 
			
		||||
    self.db.RegisterCallback(self, "OnProfileCopied", function(event)
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Copied, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    end)
 | 
			
		||||
    self.db.RegisterCallback(self, "OnProfileReset", function(event)
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Reset, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    end)
 | 
			
		||||
function Grichelde:CreateReplacement(offset)
 | 
			
		||||
    return {
 | 
			
		||||
        order = offset or 9999,
 | 
			
		||||
        type = "group",
 | 
			
		||||
        name = function(info) return self:MappingName(info) end,
 | 
			
		||||
        desc = self.L.Options_Replacement_Group_Desc,
 | 
			
		||||
        childGroups = "tree",
 | 
			
		||||
        args = {
 | 
			
		||||
            searchText = {
 | 
			
		||||
                order = 0,
 | 
			
		||||
                type = "input",
 | 
			
		||||
                name = self.L.Options_Replacement_SearchText_Name,
 | 
			
		||||
                desc = self.L.Options_Replacement_SearchText_Desc,
 | 
			
		||||
            },
 | 
			
		||||
            replaceText = {
 | 
			
		||||
                order = 1,
 | 
			
		||||
                type = "input",
 | 
			
		||||
                name = self.L.Options_Replacement_ReplaceText_Name,
 | 
			
		||||
                desc = self.L.Options_Replacement_ReplaceText_Desc,
 | 
			
		||||
            },
 | 
			
		||||
            caseSensitive = {
 | 
			
		||||
                order = 2,
 | 
			
		||||
                type = "toggle",
 | 
			
		||||
                name = self.L.Options_Replacement_CaseSensitive_Name,
 | 
			
		||||
                desc = self.L.Options_Replacement_CaseSensitive_Desc,
 | 
			
		||||
            },
 | 
			
		||||
            consolidate = {
 | 
			
		||||
                order = 3,
 | 
			
		||||
                type = "toggle",
 | 
			
		||||
                name = self.L.Options_Replacement_Consolidate_Name,
 | 
			
		||||
                desc = self.L.Options_Replacement_Consolidate_Desc,
 | 
			
		||||
                width = 2
 | 
			
		||||
            },
 | 
			
		||||
            delete = {
 | 
			
		||||
                order = 4,
 | 
			
		||||
                type = "execute",
 | 
			
		||||
                confirm = true,
 | 
			
		||||
                confirmText = self.L.Options_Replacements_Delete_ConfirmText,
 | 
			
		||||
                name = self.L.Options_Replacement_Delete_Name,
 | 
			
		||||
                desc = self.L.Options_Replacement_Delete_Desc,
 | 
			
		||||
                func = function(info) self:DeleteReplacement(info) end
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:SetupOptions()
 | 
			
		||||
    -- add DB-backed profiles to UI options
 | 
			
		||||
    self.options = self:CreateOptionsUI()
 | 
			
		||||
    self.options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
 | 
			
		||||
    self.options.args.profiles.disabled = false
 | 
			
		||||
 | 
			
		||||
    local activeProfile = self.db:GetCurrentProfile()
 | 
			
		||||
    self:PrefixedPrint(self.L.Profiles_Loaded, self.COLOR_CODES.GREEN .. activeProfile .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    self:tPrint(self.db.profile)
 | 
			
		||||
    local options = self:CreateOptionsUI()
 | 
			
		||||
    options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
 | 
			
		||||
    options.args.profiles.disabled = false
 | 
			
		||||
 | 
			
		||||
    -- Adding options to blizzard frame
 | 
			
		||||
    LibStub("AceConfig-3.0"):RegisterOptionsTable(self.name, self.options)
 | 
			
		||||
    LibStub("AceConfigDialog-3.0"):AddToBlizOptions(self.name, self.L.AddonName)
 | 
			
		||||
end
 | 
			
		||||
    LibStub("AceConfig-3.0"):RegisterOptionsTable(self.name, options)
 | 
			
		||||
    local dialog = LibStub("AceConfigDialog-3.0")
 | 
			
		||||
    dialog:AddToBlizOptions(self.name, self.L.AddonName)
 | 
			
		||||
 | 
			
		||||
function Grichelde:SyncToDatabase(info, val)
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while ( path < #info) do
 | 
			
		||||
        option = option[info[path]] -- or nil
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
    local optionPath = join(".", unpack(info, 1, #info))
 | 
			
		||||
    self:DebugPrint("change option \"%s\" from %s to %s", optionPath, toString(option[info[path]]), toString(val))
 | 
			
		||||
    option[info[path]] = val
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:ReadFromDatabase(info)
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while (path <= #info) do
 | 
			
		||||
        option = option[info[path]] -- or nil
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
    local optionPath = join(".", unpack(info, 1, #info))
 | 
			
		||||
    self:DebugPrint("read option \"%s\": %s", optionPath, toString(option))
 | 
			
		||||
    return option
 | 
			
		||||
    return options, dialog
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:IsDisabled(info)
 | 
			
		||||
@@ -235,4 +192,112 @@ function Grichelde:IsDisabled(info)
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
    return not self.db.profile.enabled
 | 
			
		||||
end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:MappingName(info)
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while (path <= #info) do
 | 
			
		||||
        option = option[info[path]]
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if nilOrEmpty(option.searchText) and nilOrEmpty(option.replaceText) then
 | 
			
		||||
        return self.L.Options_Replacement_EmptyMapping
 | 
			
		||||
    else
 | 
			
		||||
        return self:Format(self.L.Options_Replacement_Group_Name, option.searchText or "", option.replaceText or "")
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:RefreshOptions(event)
 | 
			
		||||
    self:DebugPrint("RefreshOptions : event:", event)
 | 
			
		||||
    if event == "OnNewProfile" then
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Created, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    elseif event == "OnProfileChanged" then
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Loaded, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    elseif event == "OnProfileDeleted" then
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Deleted, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    elseif event == "OnProfileCopied" then
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Copied, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    elseif event == "OnProfileReset" then
 | 
			
		||||
        self:PrefixedPrint(self.L.Profiles_Reset, self.COLOR_CODES.GREEN .. self.db:GetCurrentProfile() .. self.COLOR_CODES.CLOSE)
 | 
			
		||||
    else
 | 
			
		||||
        self:DebugPrint("Refreshing Profile %s on options change: %s", self.db:GetCurrentProfile(), event)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    self:RefreshReplacements(self:ReorderReplacements(self.db.profile.replacements))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Create UI options for rhe given replacement table (from DB).
 | 
			
		||||
--- Usually called with with self.db.profile.replacements
 | 
			
		||||
-- @param replacementsTable
 | 
			
		||||
function Grichelde:RefreshReplacements(replacementsTable)
 | 
			
		||||
    --self:DebugPrint("RefreshReplacements : DB table:")
 | 
			
		||||
    --self:DebugPrint(replacementsTable)
 | 
			
		||||
 | 
			
		||||
    -- remove all previous replacements from options (not DB), except header and buttons
 | 
			
		||||
    local replacements = self.options.args.replacements.args or {}
 | 
			
		||||
    for k, _ in pairs(replacements) do
 | 
			
		||||
        if k and find(k, "^replacement_") then
 | 
			
		||||
            replacements[k] = nil
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    for replName, _ in pairs(replacementsTable or {}) do
 | 
			
		||||
        local _, replNumber = self:SplitOnFirstMatch(replName, "_")
 | 
			
		||||
        replacements[replName] = self:CreateReplacement(toNumber(replNumber))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    --self:DebugPrint("RefreshReplacements : UI options:")
 | 
			
		||||
    --self:DebugPrint(replacements)
 | 
			
		||||
 | 
			
		||||
    self.dialog:ConfigTableChanged(nil, self.name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:AddReplacement()
 | 
			
		||||
    local replacements = self.db.profile.replacements
 | 
			
		||||
    local maxRepl = tSize(replacements)
 | 
			
		||||
    local newMapping = "replacement_" .. maxRepl
 | 
			
		||||
    self:DebugPrint("AddReplacement : new replacement key:", newMapping)
 | 
			
		||||
 | 
			
		||||
    -- setting replacements[newMapping] = {} will deactivate defaults
 | 
			
		||||
    replacements[newMapping].order = maxRepl
 | 
			
		||||
    --self:DebugPrint("AddReplacements : all DB entries:")
 | 
			
		||||
    --self:DebugPrint(replacements)
 | 
			
		||||
 | 
			
		||||
    --self.db.profile.replacements = replacements
 | 
			
		||||
    self:RefreshOptions("AddReplacement " .. newMapping)
 | 
			
		||||
    self.dialog:SelectGroup(self.name, "replacements", newMapping)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:DeleteReplacement(info)
 | 
			
		||||
    self:DebugPrint("DeleteReplacement")
 | 
			
		||||
    local option = self.db.profile
 | 
			
		||||
    local path = 1
 | 
			
		||||
    while (path < #info - 1) do
 | 
			
		||||
        option = option[info[path]]
 | 
			
		||||
        --self:DebugPrint(option)
 | 
			
		||||
        path = path + 1
 | 
			
		||||
    end
 | 
			
		||||
    local optionPath = join(".", unpack(info, 1, #info))
 | 
			
		||||
    self:DebugPrint("delete option \"%s\": %s", optionPath, toString(option[info[path]]))
 | 
			
		||||
    option[info[path]] = nil
 | 
			
		||||
 | 
			
		||||
    self:RefreshOptions("DeleteReplacement " .. info[path])
 | 
			
		||||
 | 
			
		||||
    local _, replNumber = self:SplitOnFirstMatch(info[path], "_")
 | 
			
		||||
    local newMapping = "replacement_" .. toNumber(replNumber - 1)
 | 
			
		||||
    self.dialog:SelectGroup(self.name, "replacements", newMapping)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:DeleteAllReplacements()
 | 
			
		||||
    self:DebugPrint("DeleteAllReplacements : ")
 | 
			
		||||
 | 
			
		||||
    --self.db.profile.replacements = {}
 | 
			
		||||
    for replName, _ in pairs(self.db.profile.replacements or {}) do
 | 
			
		||||
        self.db.profile.replacements[replName] = nil
 | 
			
		||||
    end
 | 
			
		||||
    self:AddReplacement()
 | 
			
		||||
 | 
			
		||||
    self:RefreshOptions("DeleteAllReplacements")
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -2,58 +2,17 @@
 | 
			
		||||
local _G = _G
 | 
			
		||||
local Grichelde = _G.Grichelde
 | 
			
		||||
 | 
			
		||||
local type, print, pairs, select, unpack, format, rep, toString
 | 
			
		||||
= Grichelde.functions.type, Grichelde.functions.print, Grichelde.functions.pairs, Grichelde.functions.select, Grichelde.functions.unpack, Grichelde.functions.format, Grichelde.functions.rep, Grichelde.functions.toString
 | 
			
		||||
 | 
			
		||||
function Grichelde:Format(message, ...)
 | 
			
		||||
    local msg = message
 | 
			
		||||
    local l = select("#", ...)
 | 
			
		||||
    if l > 0 then
 | 
			
		||||
        -- sanitize nil values in vararg
 | 
			
		||||
        local packed = { ... }
 | 
			
		||||
        for i = 1, l do
 | 
			
		||||
            packed[i] = toString(packed[i]) or "nil"
 | 
			
		||||
        end
 | 
			
		||||
        --      print("packed = ", packed)
 | 
			
		||||
        --      self:tPrint(packed)
 | 
			
		||||
        -- cannot assign unpacked to a vararg variable and print it for debug
 | 
			
		||||
        msg = format(message, unpack(packed))
 | 
			
		||||
    end
 | 
			
		||||
    return msg or "nil"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:Print(...)
 | 
			
		||||
    print(self:Format(...))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function prefixedPrint(colorCode, prefix, endClose, ...)
 | 
			
		||||
    print(colorCode .. prefix .. endClose .. ": " .. ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:PrefixedPrint(...)
 | 
			
		||||
    prefixedPrint(self.COLOR_CODES.PREFIX, self.L.AddonName, self.COLOR_CODES.CLOSE, self:Format(...))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:DebugPrint(...)
 | 
			
		||||
    if (self.debug) then
 | 
			
		||||
        prefixedPrint(self.COLOR_CODES.GRAY, self.L.AddonName, self.COLOR_CODES.CLOSE, self:Format(...))
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function tLen(t)
 | 
			
		||||
    local count = 0
 | 
			
		||||
    for _ in pairs(t) do count = count + 1 end
 | 
			
		||||
    return count
 | 
			
		||||
end
 | 
			
		||||
local type, print, pairs, tSize, select, unpack, find, format, rep, toString
 | 
			
		||||
    = Grichelde.functions.type, Grichelde.functions.print, Grichelde.functions.pairs, Grichelde.functions.tSize, Grichelde.functions.select, Grichelde.functions.unpack, Grichelde.functions.find, Grichelde.functions.format, Grichelde.functions.rep, Grichelde.functions.toString
 | 
			
		||||
 | 
			
		||||
-- show strings differently to distinguish them from numbers
 | 
			
		||||
function Grichelde:PlainValue(val)
 | 
			
		||||
local function plainValue(val)
 | 
			
		||||
    if val == nil then
 | 
			
		||||
        return "<nil>"
 | 
			
		||||
    elseif type(val) == "string" then
 | 
			
		||||
        return '"' .. val .. '"'
 | 
			
		||||
    elseif type(val) == "table" then
 | 
			
		||||
        if tLen(val) > 0 then
 | 
			
		||||
        if tSize(val) > 0 then
 | 
			
		||||
            return toString(val)
 | 
			
		||||
        else
 | 
			
		||||
            return "{}"
 | 
			
		||||
@@ -64,40 +23,134 @@ function Grichelde:PlainValue(val)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Prints any value to default channel, do NOT return a string.
 | 
			
		||||
function Grichelde:tPrint(val, indent, known)
 | 
			
		||||
    if (not self.debug) then return end
 | 
			
		||||
 | 
			
		||||
local function tPrint(val, indent, known, printFunc)
 | 
			
		||||
    local printF = printFunc or print
 | 
			
		||||
    indent = indent or 0
 | 
			
		||||
    known = known or {}
 | 
			
		||||
 | 
			
		||||
    if val == nil then
 | 
			
		||||
        print(rep(" ", indent) .. "<nil>")
 | 
			
		||||
        printF(rep(" ", indent) .. "<nil>")
 | 
			
		||||
    elseif type(val) == "string" then
 | 
			
		||||
        print(rep(" ", indent) .. "\"" .. val .. "\"")
 | 
			
		||||
        printF(rep(" ", indent) .. "\"" .. val .. "\"")
 | 
			
		||||
    elseif type(val) == "table" then
 | 
			
		||||
        if tLen(val) > 0 then
 | 
			
		||||
        if tSize(val) > 0 then
 | 
			
		||||
            for key, value in pairs(val) do
 | 
			
		||||
                if value == nil then
 | 
			
		||||
                    print(rep(" ", indent) .. self:PlainValue(key) .. "= <nil>")
 | 
			
		||||
                    printF(rep(" ", indent) .. plainValue(key) .. "= <nil>")
 | 
			
		||||
                elseif type(value) == "table" then
 | 
			
		||||
                    print(rep(" ", indent) .. self:PlainValue(key) .. "= {")
 | 
			
		||||
                    if tLen(value) > 0 then
 | 
			
		||||
                    printF(rep(" ", indent) .. plainValue(key) .. "= {")
 | 
			
		||||
                    if tSize(value) > 0 then
 | 
			
		||||
                        if not known[value] then
 | 
			
		||||
                            self:tPrint(value, indent + 4, known)
 | 
			
		||||
                            tPrint(value, indent + 4, known, printF)
 | 
			
		||||
                            known[value] = true
 | 
			
		||||
                        else
 | 
			
		||||
                            print("<known table> " .. self:PlainValue(value))
 | 
			
		||||
                            printF("<known table> " .. plainValue(value))
 | 
			
		||||
                        end
 | 
			
		||||
                    end
 | 
			
		||||
                    print(rep(" ", indent) .. "}")
 | 
			
		||||
                    printF(rep(" ", indent) .. "}")
 | 
			
		||||
                else
 | 
			
		||||
                    print(rep(" ", indent) .. self:PlainValue(key) .. " = " .. self:PlainValue(value))
 | 
			
		||||
                    printF(rep(" ", indent) .. plainValue(key) .. " = " .. plainValue(value))
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        else
 | 
			
		||||
            print(rep(" ", indent) .. "{}")
 | 
			
		||||
            printF(rep(" ", indent) .. "{}")
 | 
			
		||||
        end
 | 
			
		||||
    else
 | 
			
		||||
        print(rep(" ", indent) .. toString(val))
 | 
			
		||||
        printF(rep(" ", indent) .. toString(val))
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- split at first word of a text line
 | 
			
		||||
function Grichelde:SplitOnFirstMatch(text, delimPattern, start)
 | 
			
		||||
    if text == nil then return nil end
 | 
			
		||||
    local pattern = "^(.-)" .. (delimPattern or " " ) .."(.*)"
 | 
			
		||||
    local pos = start or 1
 | 
			
		||||
    self:DebugPrint("SplitOnFirstMatch : text: %s, pattern: %s, start: %d", text, pattern, start)
 | 
			
		||||
    local _, _, left, right = find(text, pattern, pos)
 | 
			
		||||
    self:DebugPrint("SplitOnFirstMatch : left: %s, right: %s", left, right)
 | 
			
		||||
    return left or text, right
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- split at last word of a text line
 | 
			
		||||
function Grichelde:SplitOnLastMatch(text, delimPattern, start)
 | 
			
		||||
    local pattern = "(.*)" .. (delimPattern or " ") .. "(.-)$"
 | 
			
		||||
    local pos = start or 1
 | 
			
		||||
    self:DebugPrint("SplitOnLastMatch : text: %s, pattern: %s, start: %d", text, pattern, start)
 | 
			
		||||
    local _, _, left, right = find(text, pattern, pos)
 | 
			
		||||
    self:DebugPrint("SplitOnLastMatch : left: %s, right: %s", left, right)
 | 
			
		||||
    return left, right or text
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- split at last word of a text line
 | 
			
		||||
function Grichelde:TestMatch(text, pattern)
 | 
			
		||||
    local _, _, left, right = find(text, pattern, 1)
 | 
			
		||||
    self:DebugPrint("TestMatch : left: %s, right: %s", left, right)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:Format(message, ...)
 | 
			
		||||
    if ( not message ) then
 | 
			
		||||
        return "<nil>"
 | 
			
		||||
    elseif type(message) == "string" then
 | 
			
		||||
        if ( not find(message, "%%")) then
 | 
			
		||||
            return message, ...
 | 
			
		||||
        else
 | 
			
		||||
            local l = select("#", ...)
 | 
			
		||||
            if l > 0 then
 | 
			
		||||
                -- sanitize nil values in vararg
 | 
			
		||||
                local packed = { ... }
 | 
			
		||||
                for i = 1, l do
 | 
			
		||||
                    packed[i] = toString(packed[i]) or "nil"
 | 
			
		||||
                end
 | 
			
		||||
--              print("packed = ", packed)
 | 
			
		||||
--              self:tPrint(packed)
 | 
			
		||||
                -- cannot assign unpacked to a vararg variable and print it for debug
 | 
			
		||||
                -- Manually set count as unpack() stops on nil (bug with #table)
 | 
			
		||||
                return format(message, unpack(packed, 1, l))
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- deprecated
 | 
			
		||||
function Grichelde:Print(...)
 | 
			
		||||
    print(self:Format(...))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:PrefixedPrint(...)
 | 
			
		||||
    print(self.COLOR_CODES.PREFIX .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function Grichelde:DebugPrint(obj, ...)
 | 
			
		||||
    local function prefixedDebugPrint(...)
 | 
			
		||||
        print(self.COLOR_CODES.GRAY .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if (self.debug) then
 | 
			
		||||
        if obj == nil then
 | 
			
		||||
            prefixedDebugPrint("<nil>")
 | 
			
		||||
        else
 | 
			
		||||
            if type(obj) == "string" then
 | 
			
		||||
                local l = select("#", ...)
 | 
			
		||||
                if ( l == 0 or not find(obj, "%%")) then
 | 
			
		||||
                    prefixedDebugPrint(obj, ...)
 | 
			
		||||
                else
 | 
			
		||||
                    -- sanitize nil values in vararg
 | 
			
		||||
                    local packed = { ... }
 | 
			
		||||
                    for i = 1, l do
 | 
			
		||||
                        packed[i] = toString(packed[i]) or "nil"
 | 
			
		||||
                    end
 | 
			
		||||
 | 
			
		||||
--                  print("packed = ", packed)
 | 
			
		||||
--                  self:tPrint(packed)
 | 
			
		||||
                    -- cannot assign unpacked to a vararg variable and print it for debug
 | 
			
		||||
                    local fmtMsg = format(obj, unpack(packed, 1, l)) -- manually set count as unpack() stops on nil (bug with #table)
 | 
			
		||||
                    prefixedDebugPrint(fmtMsg)
 | 
			
		||||
                end
 | 
			
		||||
            elseif type(obj) == "table" then
 | 
			
		||||
                tPrint(obj, 0, {}, prefixedDebugPrint)
 | 
			
		||||
            else
 | 
			
		||||
                prefixedDebugPrint(plainValue(obj))
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										22
									
								
								libs.xml
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								libs.xml
									
									
									
									
									
								
							@@ -1,15 +1,15 @@
 | 
			
		||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 | 
			
		||||
..\FrameXML\UI.xsd">
 | 
			
		||||
 | 
			
		||||
  <Script file="libs\LibStub\LibStub.lua"/>
 | 
			
		||||
  <Include file="libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceAddon-3.0\AceAddon-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceConfig-3.0\AceConfig-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceConsole-3.0\AceConsole-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceDB-3.0\AceDB-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/>
 | 
			
		||||
  <Include file="libs\AceEvent-3.0\AceEvent-3.0.xml" />
 | 
			
		||||
  <Include file="libs\AceLocale-3.0\AceLocale-3.0.xml" />
 | 
			
		||||
  <Include file="libs\AceHook-3.0\AceHook-3.0.xml"/>
 | 
			
		||||
  <Script file="Libs\LibStub\LibStub.lua"/>
 | 
			
		||||
  <Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceDB-3.0\AceDB-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/>
 | 
			
		||||
  <Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml" />
 | 
			
		||||
  <Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" />
 | 
			
		||||
  <Include file="Libs\AceHook-3.0\AceHook-3.0.xml"/>
 | 
			
		||||
</Ui>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ if not L then return end
 | 
			
		||||
 | 
			
		||||
-- system messages
 | 
			
		||||
L.AddonName = "Grichelde"
 | 
			
		||||
L.VersionAbbr = "v"
 | 
			
		||||
L.AddonLoaded = "%s hilft Euch jetzt bei euren Sprachschwierigkeiten."
 | 
			
		||||
L.Addon_Detected_Misspelled = "Das Addon 'Misspelled' wurde erkannt und alle Nachrichten werden automatisch bereinigt."
 | 
			
		||||
L.Addon_Detected_WIM = "Das Addon 'WIM' wurde erkannt und alle Flüsternnachrichten aus IM-Fenster werden behandelt."
 | 
			
		||||
@@ -58,9 +59,11 @@ L.Options_Replacements_Add_Name = "Hinzu"
 | 
			
		||||
L.Options_Replacements_Add_Desc = "F\195\188gt eine neue Zuordnung hinzu."
 | 
			
		||||
L.Options_Replacements_DeleteAll_Name = "Alle L\195\182schen"
 | 
			
		||||
L.Options_Replacements_DeleteAll_Desc = "L\195\182scht alle Zuweisungen."
 | 
			
		||||
L.Options_Replacements_DeleteAll_ConfirmText="Wirklich ALLE Zuweisungen l\195\182schen?"
 | 
			
		||||
 | 
			
		||||
L.Options_Replacement_Group_Name = "Ersetzung"
 | 
			
		||||
L.Options_Replacement_Group_Name = "%s => %s"
 | 
			
		||||
L.Options_Replacement_Group_Desc = "Dieses Vorkommen wird in den aktivierten Kan\195\164len ersetzt."
 | 
			
		||||
L.Options_Replacement_EmptyMapping = "(keine)"
 | 
			
		||||
L.Options_Replacement_SearchText_Name = "Suchtext:"
 | 
			
		||||
L.Options_Replacement_SearchText_Desc = "Dieser Text wird in der Chateingabe gesucht."
 | 
			
		||||
L.Options_Replacement_ReplaceText_Name = "Ersetzung:"
 | 
			
		||||
@@ -71,3 +74,4 @@ L.Options_Replacement_Consolidate_Name = "Fa\195\159e aufeinanderfolgende Treffe
 | 
			
		||||
L.Options_Replacement_Consolidate_Desc = "Wenn durch die Ersetzung die Zeichenfolge mehrfach hintereinander steht,|nfasse sie zu einem Vorkommen zusammen."
 | 
			
		||||
L.Options_Replacement_Delete_Name = "L\195\182schen"
 | 
			
		||||
L.Options_Replacement_Delete_Desc = "L\195\182scht diese Zuweisung."
 | 
			
		||||
L.Options_Replacements_Delete_ConfirmText="Diese Zuweisung l\195\182schen?"
 | 
			
		||||
@@ -3,9 +3,10 @@ if not L then return end
 | 
			
		||||
 | 
			
		||||
-- system messages
 | 
			
		||||
L.AddonName = "Grichelde"
 | 
			
		||||
L.VersionAbbr = "v"
 | 
			
		||||
L.AddonLoaded = "%s now helps you with your spelling disabilities."
 | 
			
		||||
L.Addon_Detected_Misspelled = "Addon 'Misspelled' has been detected and any messsage will be cleansed automatically."
 | 
			
		||||
L.Addon_Detected_WIM = "Das Addon 'WIM' has been detected and any whispers will be handled from IM windows."
 | 
			
		||||
L.Addon_Detected_Misspelled = "The Addon 'Misspelled' has been detected and any messsage will be cleansed automatically."
 | 
			
		||||
L.Addon_Detected_WIM = "The Addon 'WIM' has been detected and any whispers will be handled from IM windows."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- profiles
 | 
			
		||||
@@ -56,12 +57,14 @@ L.Options_Channels_ChannelWhisper_Desc = "Activates %s in channel \"Whisper\"."
 | 
			
		||||
L.Options_Replacements_Group_Name = "Replacements"
 | 
			
		||||
L.Options_Replacements_Group_Desc = "These lookups will be replaced in activated channels."
 | 
			
		||||
L.Options_Replacements_Add_Name = "Add"
 | 
			
		||||
L.Options_Replacements_Add_Desc = "Add a new replacement mapping."
 | 
			
		||||
L.Options_Replacements_Add_Desc = "Adds a new replacement mapping."
 | 
			
		||||
L.Options_Replacements_DeleteAll_Name = "Delete All"
 | 
			
		||||
L.Options_Replacements_DeleteAll_Desc = "Delete all replacement mappings."
 | 
			
		||||
L.Options_Replacements_DeleteAll_Desc = "Deletes all replacement mappings."
 | 
			
		||||
L.Options_Replacements_DeleteAll_ConfirmText = "Do you really want to delete ALL replacement mappings?"
 | 
			
		||||
 | 
			
		||||
L.Options_Replacement_Group_Name = "Mapping"
 | 
			
		||||
L.Options_Replacement_Group_Name = "%s => %s"
 | 
			
		||||
L.Options_Replacement_Group_Desc = "This lookup will be replaced in activated channels."
 | 
			
		||||
L.Options_Replacement_EmptyMapping = "(none)"
 | 
			
		||||
L.Options_Replacement_SearchText_Name = "Search for:"
 | 
			
		||||
L.Options_Replacement_SearchText_Desc = "This text is looked up in your chat input box."
 | 
			
		||||
L.Options_Replacement_ReplaceText_Name = "Replacement:"
 | 
			
		||||
@@ -71,4 +74,5 @@ L.Options_Replacement_CaseSensitive_Desc = "Will not replace occurrences if case
 | 
			
		||||
L.Options_Replacement_Consolidate_Name = "consolidate consecutive matches"
 | 
			
		||||
L.Options_Replacement_Consolidate_Desc = "If after the replacement a text sequence is repeated|ndirectly after another, treat them as one occurrence."
 | 
			
		||||
L.Options_Replacement_Delete_Name = "Delete"
 | 
			
		||||
L.Options_Replacement_Delete_Desc = "Delete this replacement mapping."
 | 
			
		||||
L.Options_Replacement_Delete_Desc = "Deletes this replacement mapping."
 | 
			
		||||
L.Options_Replacements_Delete_ConfirmText = "Delete this replacement mapping?"
 | 
			
		||||
		Reference in New Issue
	
	Block a user