-- import addon read namespace from global env local _G = _G local Grichelde = _G.Grichelde 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 local function plainValue(val) if val == nil then return "" elseif type(val) == "string" then return '"' .. val .. '"' elseif type(val) == "table" then if tSize(val) > 0 then return toString(val) else return "{}" end else return toString(val) end end --- Prints any value to default channel, do NOT return a string. local function tPrint(val, indent, known, printFunc) local printF = printFunc or print indent = indent or 0 known = known or {} if val == nil then printF(rep(" ", indent) .. "") elseif type(val) == "string" then printF(rep(" ", indent) .. "\"" .. val .. "\"") elseif type(val) == "table" then if tSize(val) > 0 then for key, value in pairs(val) do if value == nil then printF(rep(" ", indent) .. plainValue(key) .. " = ") elseif type(value) == "table" then printF(rep(" ", indent) .. plainValue(key) .. " = {") if tSize(value) > 0 then if not known[value] then tPrint(value, indent + 4, known, printF) known[value] = true else printF(" " .. plainValue(value)) end end printF(rep(" ", indent) .. "}") else printF(rep(" ", indent) .. plainValue(key) .. " = " .. plainValue(value)) end end else printF(rep(" ", indent) .. "{}") end else 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:TracePrint("SplitOnFirstMatch : text: %s, pattern: %s, start: %d", text, pattern, start) local _, _, left, right = find(text, pattern, pos) self:TracePrint("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:TracePrint("SplitOnLastMatch : text: %s, pattern: %s, start: %d", text, pattern, start) local _, _, left, right = find(text, pattern, pos) self:TracePrint("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 "" 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, ...) self:LogPrint(Grichelde.LOG_LEVEL.DEBUG, function(...) print(self.COLOR_CODES.GRAY .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) end, obj, ...) end function Grichelde:TracePrint(obj, ...) self:LogPrint(Grichelde.LOG_LEVEL.TRACE, function(...) print(self.COLOR_CODES.DARKGRAY .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) end, obj, ...) end function Grichelde:LogPrint(logLevel, printFunc, obj, ...) if (self.logLevel >= logLevel) then local printF = printFunc or print if obj == nil then printF("") else if type(obj) == "string" then local l = select("#", ...) if ( l == 0 or not find(obj, "%%")) then printF(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) printF(fmtMsg) end elseif type(obj) == "table" then tPrint(obj, 0, {}, printF) else printF(plainValue(obj)) end end end end --- Print UI options to chat frame function Grichelde:PrintOptions() self:PrefixedPrint(self.COLOR_CODES.PREFIX .. self.L.Debug_Options .. self.COLOR_CODES.CLOSE) self:LogPrint(-1, function(...) print(self.COLOR_CODES.PREFIX .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) end, self.options.args.replacements.args) end --- Print DB function Grichelde:PrintProfile() self:PrefixedPrint(self.COLOR_CODES.PREFIX .. self.L.Debug_Profile .. self.COLOR_CODES.CLOSE) self:LogPrint(-1, function(...) print(self.COLOR_CODES.PREFIX .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) end, self.db.profile) end --- Print DB replacements to chat frame function Grichelde:PrintMappings() self:PrefixedPrint(self.COLOR_CODES.PREFIX .. self.L.Debug_Mappings .. self.COLOR_CODES.CLOSE) self:LogPrint(-1, function(...) print(self.COLOR_CODES.PREFIX .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) end, self.db.profile.replacements) end --- Open UI windows with replacements in it function Grichelde:ToogleMappings() local AceGUI = LibStub("AceGUI-3.0") if self.debugFrame then AceGUI:Release(self.debugFrame) self.debugFrame = nil else local replacements = self.db.profile.replacements or {} local repls = 0 for k, _ in pairs(replacements) do if k and find(k, "^replacement_") then repls = repls + 1 end end local frame = AceGUI:Create("Frame"); frame:SetTitle(self.L.Debug_Mappings); frame:SetStatusText(self:Format(self.L.Debug_Mappings_Found, repls)) frame:SetWidth(400); frame:SetAutoAdjustHeight(true) --frame:SetFullHeight(true) frame:SetLayout("Flow"); local function closeFrame(widget) AceGUI:Release(widget); self.debugFrame = nil end frame:SetCallback("OnClose", closeFrame) local hint = AceGUI:Create("Label"); hint:SetText(self.L.Debug_Mappings_Hint) hint:SetFullWidth(true) frame:AddChild(hint); local scroll = AceGUI:Create("ScrollFrame"); scroll:SetFullWidth(true) scroll:SetFullHeight(true) scroll:SetLayout("Fill"); local configBox = AceGUI:Create("MultiLineEditBox"); configBox:SetLabel("") local text = "" tPrint(replacements, 0, {}, function(s) text = text .. s .. "|n" end) configBox:SetText(text) configBox:SetFullWidth(true) configBox:SetFullHeight(true) configBox:DisableButton(true) --configBox:SetDisabled(true) configBox:SetNumLines(50); configBox:SetFocus() scroll:AddChild(configBox); frame:AddChild(scroll); self.debugFrame = frame end end