-- import addon read namespace from global env local _G = _G local Grichelde = _G.Grichelde or {} local type, print, pairs, tSize, select, unpack, find, cGray, cDarkgray, cRed, cPrefix, format, rep, toString = Grichelde.F.type, Grichelde.F.print, Grichelde.F.pairs, Grichelde.F.tSize, Grichelde.F.select, Grichelde.F.unpack, Grichelde.F.find, Grichelde.F.cGray, Grichelde.F.cDarkgray, Grichelde.F.cRed, Grichelde.F.cPrefix, Grichelde.F.format, Grichelde.F.rep, Grichelde.F.toString -- show strings differently to distinguish them from numbers function Grichelde: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. function Grichelde: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) .. self:plainValue(key) .. " = ") elseif (type(value) == "table") then printF(rep(" ", indent) .. self:plainValue(key) .. " = {") if (tSize(value) > 0) then if not known[value] then self:tPrint(value, indent + 4, known, printF) known[value] = true else printF(" " .. self:plainValue(value)) end end printF(rep(" ", indent) .. "}") else local k = self:plainValue(key) local v = self:plainValue(value) --print( "k: " .. k .. ", v: " ..v) printF(rep(" ", indent) .. k .. " = " .. v) end end else printF(rep(" ", indent) .. "{}") end else printF(rep(" ", indent) .. toString(val)) end end --- Splits 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 --- Splits 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 function Grichelde:Format(message, ...) if (message == nil) then return "" elseif (type(message) == "string") then if (find(message, "%%") == nil) then --print("message: ", message) --print("...: ", ...) 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" --print("packed[i] = ", packed[i]) --packed[i] = gsub(packed[i], "%%(%d)", "%%%%%1") 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)) else return message end end end end function Grichelde:PrefixedPrint(...) print(cPrefix(self.L.AddonName) .. ":", self:Format(...)) end function Grichelde:ErrorPrint(...) print(cPrefix(self.L.AddonName) .. ": " .. cRed(self:Format(...))) end function Grichelde:DebugPrint(obj, ...) if (self.logLevel >= Grichelde.LOG_LEVEL.DEBUG) then self:LogPrint(function(...) print(cGray(self.L.AddonName) .. ":", self:Format(...)) end, obj, ...) end end function Grichelde:TracePrint(obj, ...) if (self.logLevel >= Grichelde.LOG_LEVEL.TRACE) then self:LogPrint(function(...) print(cDarkgray(self.L.AddonName) .. ":", self:Format(...)) end, obj, ...) end end function Grichelde:LogPrint(printFunc, obj, ...) local printF = printFunc or print if obj == nil then printF("") else if type(obj) == "string" then local l = select("#", ...) if (l == 0) or (find(obj, "%%") == nil) 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 self:tPrint(obj, 0, {}, printF) else printF(self:plainValue(obj)) end end end --- Print UI options to chat frame function Grichelde:PrintOptions() self:PrefixedPrint(cPrefix(self.L.Debug_Options)) self:LogPrint(-1, function(...) print(cPrefix(self.L.AddonName) .. ":", self:Format(...)) end, self.options.args.replacements.args) end --- Print current DB profile function Grichelde:PrintProfile() self:PrefixedPrint(cPrefix(self.L.Debug_Profile)) self:LogPrint(-1, function(...) print(cPrefix(self.L.AddonName) .. ":", self:Format(...)) end, self.db.profile) end --- Print DB replacements to chat frame function Grichelde:PrintMappings() self:PrefixedPrint(cPrefix(self.L.Debug_Mappings)) self:LogPrint(-1, function(...) print(cPrefix(self.L.AddonName) .. ":", self:Format(...)) end, self.db.profile.replacements) end --- Open window with DB replacements in it function Grichelde:ToogleMappings() local AceGUI = LibStub("AceGUI-3.0") if (self.debugFrame ~= nil) 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 = "" self: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