diff --git a/ElvUI_SLE/modules/baginfo.lua b/ElvUI_SLE/modules/baginfo.lua new file mode 100644 index 0000000..75c4be7 --- /dev/null +++ b/ElvUI_SLE/modules/baginfo.lua @@ -0,0 +1,137 @@ +local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB, Localize Underscore +-- local BI = E:NewModule('SLE_BagInfo', 'AceHook-3.0', 'AceEvent-3.0', 'AceTimer-3.0') +local BI = E:GetModule('SLE_BagInfo') +local B = E:GetModule('Bags') + +local byte, format = string.byte, string.format +local tinsert, twipe = table.insert, table.wipe + +local updateTimer +local containers = {} +local infoArray = {} +local equipmentMap = {} + +local function Utf8Sub(str, start, numChars) + local currentIndex = start + while numChars > 0 and currentIndex <= #str do + local char = byte(str, currentIndex) + if char > 240 then + currentIndex = currentIndex + 4 + elseif char > 225 then + currentIndex = currentIndex + 3 + elseif char > 192 then + currentIndex = currentIndex + 2 + else + currentIndex = currentIndex + 1 + end + numChars = numChars -1 + end + return str:sub(start, currentIndex - 1) +end + +local function MapKey(bag, slot) + return format("%d_%d", bag, slot) +end + +local quickFormat = { + [0] = function(font, map) font:SetText() end, + [1] = function(font, map) font:SetFormattedText("|cffffffaa%s|r", Utf8Sub(map[1], 1, 4)) end, + [2] = function(font, map) font:SetFormattedText("|cffffffaa%s %s|r", Utf8Sub(map[1], 1, 4), Utf8Sub(map[2], 1, 4)) end, + [3] = function(font, map) font:SetFormattedText("|cffffffaa%s %s %s|r", Utf8Sub(map[1], 1, 4), Utf8Sub(map[2], 1, 4), Utf8Sub(map[3], 1, 4)) end, +} + +function BI:BuildEquipmentMap(clear) + -- clear mapped names + for k, v in pairs(equipmentMap) do + twipe(v) + end + if clear then return end + + local name, player, bank, bags, slot, bag, key + for i = 1, GetNumEquipmentSets() do + name = GetEquipmentSetInfo(i) + GetEquipmentSetLocations(name, infoArray) + for _, location in pairs(infoArray) do + if location < -1 or location > 1 then + player, bank, bags, _, slot, bag = EquipmentManager_UnpackLocation(location) + if ((bank or bags) and slot and bag) then + key = MapKey(bag, slot) + equipmentMap[key] = equipmentMap[key] or {} + tinsert(equipmentMap[key], name) + end + end + end + end +end + +function BI:UpdateContainerFrame(frame, bag, slot) + if (not frame.equipmentinfo) then + frame.equipmentinfo = frame:CreateFontString(nil, "OVERLAY") + frame.equipmentinfo:FontTemplate(E.media.font, 12, "THINOUTLINE") + frame.equipmentinfo:SetWordWrap(true) + frame.equipmentinfo:SetJustifyH('CENTER') + frame.equipmentinfo:SetJustifyV('MIDDLE') + end + + if (frame.equipmentinfo) then + frame.equipmentinfo:SetAllPoints(frame) + + local key = MapKey(bag, slot) + if equipmentMap[key] then + quickFormat[#equipmentMap[key] < 4 and #equipmentMap[key] or 3](frame.equipmentinfo, equipmentMap[key]) + else + quickFormat[0](frame.equipmentinfo, nil) + end + end +end + +function BI:UpdateBagInformation(clear) + updateTimer = nil + + self:BuildEquipmentMap(clear) + for _, container in pairs(containers) do + for _, bagID in ipairs(container.BagIDs) do + for slotID = 1, GetContainerNumSlots(bagID) do + self:UpdateContainerFrame(container.Bags[bagID][slotID], bagID, slotID) + end + end + end +end + +function BI:DelayUpdateBagInformation(event) + -- delay to make sure multiple bag events are consolidated to one update. + if not updateTimer then + updateTimer = BI:ScheduleTimer("UpdateBagInformation", .25) + end +end + +function BI:ToggleSettings() + if updateTimer then + self:CancelTimer(updateTimer) + end + + if E.private.sle.equip.setoverlay then + self:RegisterEvent("EQUIPMENT_SETS_CHANGED", "DelayUpdateBagInformation") + self:RegisterEvent("BAG_UPDATE", "DelayUpdateBagInformation") + BI:UpdateBagInformation() + else + self:UnregisterEvent("EQUIPMENT_SETS_CHANGED") + self:UnregisterEvent("BAG_UPDATE") + BI:UpdateBagInformation(true) + end +end + +function BI:Initialize() + if not E.private.bags.enable then return end + + tinsert(containers, _G["ElvUI_ContainerFrame"]) + self:SecureHook(B, "OpenBank", function() + self:Unhook(B, "OpenBank") + tinsert(containers, _G["ElvUI_BankContainerFrame"]) + BI:ToggleSettings() + end) + + BI:ToggleSettings() +end + +-- E:RegisterModule(BI:GetName()) \ No newline at end of file diff --git a/ElvUI_SLE/modules/chat.lua b/ElvUI_SLE/modules/chat.lua new file mode 100644 index 0000000..8b35a1f --- /dev/null +++ b/ElvUI_SLE/modules/chat.lua @@ -0,0 +1,1147 @@ +local E, L, V, P, G, _ = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB, Localize Underscore +local CH = E:GetModule('Chat') +local SLE = E:GetModule('SLE'); +local LSM = LibStub("LibSharedMedia-3.0") +local CreatedFrames = 0; +local lfgRoles = {}; +local chatFilters = {}; +local lfgChannels = { + "PARTY_LEADER", + "PARTY", + "RAID", + "RAID_LEADER", + "INSTANCE_CHAT", + "INSTANCE_CHAT_LEADER", +} + +local Myname = E.myname +local GetGuildRosterInfo = GetGuildRosterInfo +local IsInGuild = IsInGuild +local GuildMaster = "" +local GMName, GMRealm + +local len, gsub, find, sub, gmatch, format, random = string.len, string.gsub, string.find, string.sub, string.gmatch, string.format, math.random +local tinsert, tremove, tsort, twipe, tconcat = table.insert, table.remove, table.sort, table.wipe, table.concat + +local PLAYER_REALM = gsub(E.myrealm,'[%s%-]','') +local PLAYER_NAME = Myname.."-"..PLAYER_REALM + +local rolePaths = { + TANK = [[|TInterface\AddOns\ElvUI\media\textures\tank:15:15:0:0:64:64:2:56:2:56|t]], + HEALER = [[|TInterface\AddOns\ElvUI\media\textures\healer:15:15:0:0:64:64:2:56:2:56|t]], + DAMAGER = [[|TInterface\AddOns\ElvUI\media\textures\dps:15:15|t]] +} + +--Chat icon paths +local elvui = "|TInterface\\AddOns\\ElvUI\\media\\textures\\ElvUI_Chat_Logo:13:22|t" +local affinity = "|TInterface\\AddOns\\ElvUI\\media\\textures\\Bathrobe_Chat_Logo:15:15|t" +local adapt = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\adapt:0:2|t" +local repooc = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\SLE_Chat_Logo:0:2|t" +local darth = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\SLE_Chat_LogoD:0:2|t" +local friend = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\Chat_Friend:13:13|t" +local test = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\Chat_Test:13:13|t" +local rpg = "|TInterface\\AddOns\\ElvUI_SLE\\media\\textures\\Chat_RPG:13:35|t" +local tyrone = "|TInterface\\AddOns\\ElvUI\\media\\textures\\tyrone_biggums_chat_logo:16:18|t" +local hulkhead = "|TInterface\\AddOns\\ElvUI\\media\\textures\\hulk_head:18:22|t" +local hellokitty = "|TInterface\\AddOns\\ElvUI\\media\\textures\\helloKittyChatLogo:18:20|t" +local shortbus = "|TInterface\\AddOns\\ElvUI\\media\\textures\\short_bus:16:16|t" +local kitalie = "|TInterface\\Icons\\%s:12:12:0:0:64:64:4:60:4:60|t" +local leader = [[|TInterface\GroupFrame\UI-Group-LeaderIcon:12:12|t]] + + +local specialChatIcons = { + ["BleedingHollow"] = { + ["Tirain"] = tyrone + }, + ["Spirestone"] = { + ["Aeriane"] = true, + ["Sinth"] = tyrone, + ["Elvz"] = elvui, + ["Sarah"] = hellokitty, + ["Sara"] = hellokitty, + ["Sarâh"] = hellokitty, + ["Itzjonny"] = hulkhead, + ["Elv"] = elvui, + ["Incision"] = shortbus, + --SLE stuff + ["Sifupooc"] = repooc, + ["Dapooc"] = repooc, + ["Lapooc"] = repooc, + ["Warpooc"] = repooc, + ["Repooc"] = repooc, + --Adapt Roster + ["Mobius"] = adapt, + ["Urgfelstorm"] = adapt, + ["Kilashandra"] = adapt, + ["Electrro"] = adapt, + ["Afterthot"] = adapt, + ["Lavathing"] = adapt, + ["Finkle"] = adapt, + ["Chopsti"] = adapt, + ["Taiin"] = adapt + }, + ["Illidan"] = { + --Original Stuff + ["Affinichi"] = affinity, + ["Uplift"] = affinity, + ["Affinitii"] = affinity, + ["Affinity"] = affinity, + --Darth's toon + ["Darthpred"] = darth, + --Repooc's Toon + ["Repøøc"] = repooc, + ["Repooc"] = repooc + }, + ["WyrmrestAccord"] = { + ["Kìtalie"] = kitalie:format("inv_cloth_challengewarlock_d_01helm"), + ["Sagome"] = kitalie:format("inv_helm_leather_challengemonk_d_01"), + ["Ainy"] = kitalie:format("inv_helm_plate_challengedeathknight_d_01"), + ["Norinael"] = kitalie:format("inv_helmet_plate_challengepaladin_d_01"), + ["Tritalie"] = kitalie:format("inv_helm_cloth_challengemage_d_01"), + ["Myùn"] = kitalie:format("inv_helmet_mail_challengeshaman_d_01"), + ["Nevaleigh"] = kitalie:format("inv_helmet_leather_challengerogue_d_01"), + ["Celenii"] = kitalie:format("inv_helmet_cloth_challengepriest_d_01"), + ["Varysa"] = kitalie:format("inv_helmet_mail_challengehunter_d_01"), + ["Caylasena"] = kitalie:format("inv_helm_plate_challengewarrior_d_01"), + ["Arillora"] = kitalie:format("inv_helmet_challengedruid_d_01"), + ["Dapooc"] = repooc, + }, + ["СвежевательДуш"] = { + --Darth's toons + ["Большойгном"] = test, --Testing toon + ["Фергесон"] = friend + }, + ["ВечнаяПесня"] = { + --Darth's toons + ["Дартпредатор"] = darth, + ["Алея"] = darth, + ["Ваззули"] = darth, + ["Сиаранна"] = darth, + ["Джатон"] = darth, + ["Фикстер"] = darth, + ["Киландра"] = darth, + ["Нарджо"] = darth, + ["Келинира"] = darth, + ["Крениг"] = darth, + ["Мейжи"] = darth, + --Darth's friends + ["Леани"] = friend, + --Da tester lol + ["Харореанн"] = test, + ["Нерререанн"] = test + }, + ["Ревущийфьорд"] = { + ["Рыжая"] = friend, + ["Рыжа"] = friend, + --Some people + ["Брэгар"] = test + }, + ["Азурегос"] = { + ["Брэгари"] = test + }, + ["Korialstrasz"] = { + ["Cursewordz"] = repooc + }, + ["Andorhal"] = { + ["Dapooc"] = repooc, + ["Rovert"] = repooc, + ["Sliceoflife"] = repooc + }, +} + +SLE.SpecialChatIcons = specialChatIcons; + +CH.StyleChatSLE = CH.StyleChat +function CH:StyleChat(frame) + CH:StyleChatSLE(frame) + CreatedFrames = frame:GetID() +end + +--Replacement of chat tab position and size function +local PixelOff = E.PixelMode and 31 or 27 + +function CH:PositionChat(override) + if not self.db.lockPositions or ((InCombatLockdown() and not override and self.initialMove) or (IsMouseButtonDown("LeftButton") and not override)) then return end + if not RightChatPanel or not LeftChatPanel then return; end + RightChatPanel:SetSize(E.db.chat.panelWidth, E.db.chat.panelHeight) + LeftChatPanel:SetSize(E.db.chat.panelWidth, E.db.chat.panelHeight) + + if E.private.chat.enable ~= true then return end + + local chat, chatbg, tab, id, point, button, isDocked, chatFound + for _, frameName in pairs(CHAT_FRAMES) do + chat = _G[frameName] + id = chat:GetID() + point = GetChatWindowSavedPosition(id) + + if point == "BOTTOMRIGHT" and chat:IsShown() then + chatFound = true + break + end + end + + if chatFound then + self.RightChatWindowID = id + else + self.RightChatWindowID = nil + end + + for i=1, CreatedFrames do + local BASE_OFFSET = 60 + if E.PixelMode then + BASE_OFFSET = BASE_OFFSET - 3 + end + chat = _G[format("ChatFrame%d", i)] + chatbg = format("ChatFrame%dBackground", i) + button = _G[format("ButtonCF%d", i)] + id = chat:GetID() + tab = _G[format("ChatFrame%sTab", i)] + point = GetChatWindowSavedPosition(id) + isDocked = chat.isDocked + tab.isDocked = chat.isDocked + tab.owner = chat + if id > NUM_CHAT_WINDOWS then + point = point or select(1, chat:GetPoint()); + if select(2, tab:GetPoint()):GetName() ~= bg then + isDocked = true + else + isDocked = false + end + end + + + if point == "BOTTOMRIGHT" and chat:IsShown() and not (id > NUM_CHAT_WINDOWS) and id == self.RightChatWindowID then + chat:ClearAllPoints() + if E.db.sle.datatext.chathandle then + if E.db.datatexts.rightChatPanel then + chat:Point("BOTTOMRIGHT", RightChatDataPanel, "TOPRIGHT", 10, 3) -- <<< Changed + else + BASE_OFFSET = BASE_OFFSET - 24 + chat:Point("BOTTOMLEFT", RightChatPanel, "BOTTOMLEFT", 4, 4) + end + if id ~= 2 then + chat:SetSize(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - PixelOff)) -- <<< Changed + else + chat:Size(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - PixelOff) - CombatLogQuickButtonFrame_Custom:GetHeight()) + end + else + if E.db.datatexts.rightChatPanel then + chat:SetPoint("BOTTOMLEFT", RightChatDataPanel, "TOPLEFT", 1, 3) + else + BASE_OFFSET = BASE_OFFSET - 24 + chat:SetPoint("BOTTOMLEFT", RightChatDataPanel, "BOTTOMLEFT", 1, 1) + end + if id ~= 2 then + chat:SetSize(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - BASE_OFFSET)) + else + chat:SetSize(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - BASE_OFFSET) - CombatLogQuickButtonFrame_Custom:GetHeight()) + end + end + + + + FCF_SavePositionAndDimensions(chat) + + tab:SetParent(RightChatPanel) + chat:SetParent(RightChatPanel) + + if chat:IsMovable() then + chat:SetUserPlaced(true) + end + if E.db.chat.panelBackdrop == 'HIDEBOTH' or E.db.chat.panelBackdrop == 'LEFT' then + CH:SetupChatTabs(tab, true) + else + CH:SetupChatTabs(tab, false) + end + elseif not isDocked and chat:IsShown() then + tab:SetParent(UIParent) + chat:SetParent(UIParent) + + CH:SetupChatTabs(tab, true) + else + if E.db.sle.datatext.chathandle then + if id ~= 2 and not (id > NUM_CHAT_WINDOWS) then + chat:ClearAllPoints() + if E.db.datatexts.leftChatPanel then + chat:Point("BOTTOMLEFT", LeftChatToggleButton, "TOPLEFT", 5, 3) + else + BASE_OFFSET = BASE_OFFSET - 24 + chat:Point("BOTTOMLEFT", LeftChatToggleButton, "TOPLEFT", 5, 3) + end + chat:Size(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - PixelOff)) -- <<< Changed + FCF_SavePositionAndDimensions(chat) + end + else + if id ~= 2 and not (id > NUM_CHAT_WINDOWS) then + chat:ClearAllPoints() + if E.db.datatexts.leftChatPanel then + chat:SetPoint("BOTTOMLEFT", LeftChatToggleButton, "TOPLEFT", 1, 3) + else + BASE_OFFSET = BASE_OFFSET - 24 + chat:SetPoint("BOTTOMLEFT", LeftChatToggleButton, "BOTTOMLEFT", 1, 1) + end + chat:SetSize(E.db.chat.panelWidth - 11, (E.db.chat.panelHeight - BASE_OFFSET)) + FCF_SavePositionAndDimensions(chat) + end + end + chat:SetParent(LeftChatPanel) + if i > 2 then + tab:SetParent(GeneralDockManagerScrollFrameChild) + else + tab:SetParent(GeneralDockManager) + end + if chat:IsMovable() then + chat:SetUserPlaced(true) + end + + if E.db.chat.panelBackdrop == 'HIDEBOTH' or E.db.chat.panelBackdrop == 'RIGHT' then + CH:SetupChatTabs(tab, true) + else + CH:SetupChatTabs(tab, false) + end + end + end + + self.initialMove = true; +end + +local function GetBNFriendColor(name, id) + local _, _, game, _, _, _, _, class = BNGetToonInfo(id) + + if game ~= BNET_CLIENT_WOW or not class then + return name + else + for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end + for k,v in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do if class == v then class = k end end + + if RAID_CLASS_COLORS[class] then + return "|c"..RAID_CLASS_COLORS[class].colorStr..name.."|r" + else + return name + end + end +end + +E.NameReplacements = {} +function CH:ChatFrame_MessageEventHandler(event, ...) + if ( strsub(event, 1, 8) == "CHAT_MSG" ) then + local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 = ...; + local type = strsub(event, 10); + local info = ChatTypeInfo[type]; + + local filter = false; + if ( chatFilters[event] ) then + local newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12, newarg13, newarg14; + for _, filterFunc in next, chatFilters[event] do + filter, newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12, newarg13, newarg14 = filterFunc(self, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + if ( filter ) then + return true; + elseif ( newarg1 ) then + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 = newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12, newarg13, newarg14; + end + end + end + + arg2 = E.NameReplacements[arg2] or arg2 + local coloredName = GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + + local channelLength = strlen(arg4); + local infoType = type; + if ( (strsub(type, 1, 7) == "CHANNEL") and (type ~= "CHANNEL_LIST") and ((arg1 ~= "INVITE") or (type ~= "CHANNEL_NOTICE_USER")) ) then + if ( arg1 == "WRONG_PASSWORD" ) then + local staticPopup = _G[StaticPopup_Visible("CHAT_CHANNEL_PASSWORD") or ""]; + if ( staticPopup and strupper(staticPopup.data) == strupper(arg9) ) then + -- Don't display invalid password messages if we're going to prompt for a password (bug 102312) + return; + end + end + + local found = 0; + for index, value in pairs(self.channelList) do + if ( channelLength > strlen(value) ) then + -- arg9 is the channel name without the number in front... + if ( ((arg7 > 0) and (self.zoneChannelList[index] == arg7)) or (strupper(value) == strupper(arg9)) ) then + found = 1; + infoType = "CHANNEL"..arg8; + info = ChatTypeInfo[infoType]; + if ( (type == "CHANNEL_NOTICE") and (arg1 == "YOU_LEFT") ) then + self.channelList[index] = nil; + self.zoneChannelList[index] = nil; + end + break; + end + end + end + if ( (found == 0) or not info ) then + return true; + end + end + + local chatGroup = Chat_GetChatCategory(type); + local chatTarget; + if ( chatGroup == "CHANNEL" or chatGroup == "BN_CONVERSATION" ) then + chatTarget = tostring(arg8); + elseif ( chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" ) then + if(not(strsub(arg2, 1, 2) == "|K")) then + chatTarget = strupper(arg2); + else + chatTarget = arg2; + end + end + + if ( FCFManager_ShouldSuppressMessage(self, chatGroup, chatTarget) ) then + return true; + end + + if ( chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" ) then + if ( self.privateMessageList and not self.privateMessageList[strlower(arg2)] ) then + return true; + elseif ( self.excludePrivateMessageList and self.excludePrivateMessageList[strlower(arg2)] + and ( (chatGroup == "WHISPER" and GetCVar("whisperMode") ~= "popout_and_inline") or (chatGroup == "BN_WHISPER" and GetCVar("bnWhisperMode") ~= "popout_and_inline") ) ) then + return true; + end + elseif ( chatGroup == "BN_CONVERSATION" ) then + if ( self.bnConversationList and not self.bnConversationList[arg8] ) then + return true; + elseif ( self.excludeBNConversationList and self.excludeBNConversationList[arg8] and GetCVar("conversationMode") ~= "popout_and_inline") then + return true; + end + end + + if (self.privateMessageList) then + -- Dedicated BN whisper windows need online/offline messages for only that player + if ( (chatGroup == "BN_INLINE_TOAST_ALERT" or chatGroup == "BN_WHISPER_PLAYER_OFFLINE") and not self.privateMessageList[strlower(arg2)] ) then + return true; + end + + -- HACK to put certain system messages into dedicated whisper windows + if ( chatGroup == "SYSTEM") then + local matchFound = false; + local message = strlower(arg1); + for playerName, _ in pairs(self.privateMessageList) do + local playerNotFoundMsg = strlower(format(ERR_CHAT_PLAYER_NOT_FOUND_S, playerName)); + local charOnlineMsg = strlower(format(ERR_FRIEND_ONLINE_SS, playerName, playerName)); + local charOfflineMsg = strlower(format(ERR_FRIEND_OFFLINE_S, playerName)); + if ( message == playerNotFoundMsg or message == charOnlineMsg or message == charOfflineMsg) then + matchFound = true; + break; + end + end + + if (not matchFound) then + return true; + end + end + end + + if ( type == "SYSTEM" or type == "SKILL" or type == "LOOT" or type == "CURRENCY" or type == "MONEY" or + type == "OPENING" or type == "TRADESKILLS" or type == "PET_INFO" or type == "TARGETICONS" or type == "BN_WHISPER_PLAYER_OFFLINE") then + self:AddMessage(CH:ConcatenateTimeStamp(arg1), info.r, info.g, info.b, info.id); + elseif ( strsub(type,1,7) == "COMBAT_" ) then + self:AddMessage(CH:ConcatenateTimeStamp(arg1), info.r, info.g, info.b, info.id); + elseif ( strsub(type,1,6) == "SPELL_" ) then + self:AddMessage(CH:ConcatenateTimeStamp(arg1), info.r, info.g, info.b, info.id); + elseif ( strsub(type,1,10) == "BG_SYSTEM_" ) then + self:AddMessage(CH:ConcatenateTimeStamp(arg1), info.r, info.g, info.b, info.id); + elseif ( strsub(type,1,11) == "ACHIEVEMENT" ) then + self:AddMessage(format(CH:ConcatenateTimeStamp(arg1), "|Hplayer:"..arg2.."|h".."["..coloredName.."]".."|h"), info.r, info.g, info.b, info.id); + elseif ( strsub(type,1,18) == "GUILD_ACHIEVEMENT" ) then + self:AddMessage(format(CH:ConcatenateTimeStamp(arg1), "|Hplayer:"..arg2.."|h".."["..coloredName.."]".."|h"), info.r, info.g, info.b, info.id); + elseif ( type == "IGNORED" ) then + self:AddMessage(format(CH:ConcatenateTimeStamp(CHAT_IGNORED), arg2), info.r, info.g, info.b, info.id); + elseif ( type == "FILTERED" ) then + self:AddMessage(format(CH:ConcatenateTimeStamp(CHAT_FILTERED), arg2), info.r, info.g, info.b, info.id); + elseif ( type == "RESTRICTED" ) then + self:AddMessage(CH:ConcatenateTimeStamp(CHAT_RESTRICTED), info.r, info.g, info.b, info.id); + elseif ( type == "CHANNEL_LIST") then + if(channelLength > 0) then + self:AddMessage(format(CH:ConcatenateTimeStamp(_G["CHAT_"..type.."_GET"]..arg1), tonumber(arg8), arg4), info.r, info.g, info.b, info.id); + else + self:AddMessage(CH:ConcatenateTimeStamp(arg1), info.r, info.g, info.b, info.id); + end + elseif (type == "CHANNEL_NOTICE_USER") then + local globalstring = _G["CHAT_"..arg1.."_NOTICE_BN"]; + if ( not globalstring ) then + globalstring = _G["CHAT_"..arg1.."_NOTICE"]; + end + + globalString = CH:ConcatenateTimeStamp(globalstring); + + if(strlen(arg5) > 0) then + -- TWO users in this notice (E.G. x kicked y) + self:AddMessage(format(globalstring, arg8, arg4, arg2, arg5), info.r, info.g, info.b, info.id); + elseif ( arg1 == "INVITE" ) then + self:AddMessage(format(globalstring, arg4, arg2), info.r, info.g, info.b, info.id); + else + self:AddMessage(format(globalstring, arg8, arg4, arg2), info.r, info.g, info.b, info.id); + end + elseif (type == "CHANNEL_NOTICE") then + local globalstring = _G["CHAT_"..arg1.."_NOTICE_BN"]; + if ( not globalstring ) then + globalstring = _G["CHAT_"..arg1.."_NOTICE"]; + end + if ( arg10 > 0 ) then + arg4 = arg4.." "..arg10; + end + + globalString = CH:ConcatenateTimeStamp(globalstring); + + local accessID = ChatHistory_GetAccessID(Chat_GetChatCategory(type), arg8); + local typeID = ChatHistory_GetAccessID(infoType, arg8, arg12); + self:AddMessage(format(globalstring, arg8, arg4), info.r, info.g, info.b, info.id, false, accessID, typeID); + elseif ( type == "BN_CONVERSATION_NOTICE" ) then + local channelLink = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8); + local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), arg8, arg2); + local message = format(_G["CHAT_CONVERSATION_"..arg1.."_NOTICE"], channelLink, playerLink) + + local accessID = ChatHistory_GetAccessID(Chat_GetChatCategory(type), arg8); + local typeID = ChatHistory_GetAccessID(infoType, arg8, arg12); + self:AddMessage(CH:ConcatenateTimeStamp(message), info.r, info.g, info.b, info.id, false, accessID, typeID); + elseif ( type == "BN_CONVERSATION_LIST" ) then + local channelLink = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8); + local message = format(CHAT_BN_CONVERSATION_LIST, channelLink, arg1); + self:AddMessage(CH:ConcatenateTimeStamp(message), info.r, info.g, info.b, info.id, false, accessID, typeID); + elseif ( type == "BN_INLINE_TOAST_ALERT" ) then + if ( arg1 == "FRIEND_OFFLINE" and not BNet_ShouldProcessOfflineEvents() ) then + return true; + end + local globalstring = _G["BN_INLINE_TOAST_"..arg1]; + local message; + if ( arg1 == "FRIEND_REQUEST" ) then + message = globalstring; + elseif ( arg1 == "FRIEND_PENDING" ) then + message = format(BN_INLINE_TOAST_FRIEND_PENDING, BNGetNumFriendInvites()); + elseif ( arg1 == "FRIEND_REMOVED" or arg1 == "BATTLETAG_FRIEND_REMOVED" ) then + message = format(globalstring, arg2); + elseif ( arg1 == "FRIEND_ONLINE" or arg1 == "FRIEND_OFFLINE") then + local hasFocus, toonName, client, realmName, realmID, faction, race, class, guild, zoneName, level, gameText = BNGetToonInfo(arg13); + if (toonName and toonName ~= "" and client and client ~= "") then + local toonNameText = BNet_GetClientEmbeddedTexture(client, 14)..toonName; + local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s] (%s)|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2, toonNameText); + message = format(globalstring, playerLink); + else + local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2); + message = format(globalstring, playerLink); + end + else + local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2); + message = format(globalstring, playerLink); + end + self:AddMessage(CH:ConcatenateTimeStamp(message), info.r, info.g, info.b, info.id); + elseif ( type == "BN_INLINE_TOAST_BROADCAST" ) then + if ( arg1 ~= "" ) then + arg1 = RemoveExtraSpaces(arg1); + local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2); + self:AddMessage(format(CH:ConcatenateTimeStamp(BN_INLINE_TOAST_BROADCAST), playerLink, arg1), info.r, info.g, info.b, info.id); + end + elseif ( type == "BN_INLINE_TOAST_BROADCAST_INFORM" ) then + if ( arg1 ~= "" ) then + arg1 = RemoveExtraSpaces(arg1); + self:AddMessage(CH:ConcatenateTimeStamp(BN_INLINE_TOAST_BROADCAST_INFORM), info.r, info.g, info.b, info.id); + end + elseif ( type == "BN_INLINE_TOAST_CONVERSATION" ) then + self:AddMessage(format(CH:ConcatenateTimeStamp(BN_INLINE_TOAST_CONVERSATION), arg1), info.r, info.g, info.b, info.id); + else + local body; + + local _, fontHeight = FCF_GetChatWindowInfo(self:GetID()); + + if ( fontHeight == 0 ) then + --fontHeight will be 0 if it's still at the default (14) + fontHeight = 14; + end + + -- Add AFK/DND flags + local pflag = ""; + if(strlen(arg6) > 0) then + if ( arg6 == "GM" ) then + --If it was a whisper, dispatch it to the GMChat addon. + if ( type == "WHISPER" ) then + return; + end + --Add Blizzard Icon, this was sent by a GM + pflag = "|TInterface\\ChatFrame\\UI-ChatIcon-Blizz:12:20:0:0:32:16:4:28:0:16|t "; + elseif ( arg6 == "DEV" ) then + --Add Blizzard Icon, this was sent by a Dev + pflag = "|TInterface\\ChatFrame\\UI-ChatIcon-Blizz:12:20:0:0:32:16:4:28:0:16|t "; + elseif ( arg6 == "DND" or arg6 == "AFK") then + pflag = SLE:GetChatIcon(arg2).._G["CHAT_FLAG_"..arg6] + else + pflag = _G["CHAT_FLAG_"..arg6]; + end + else + pflag = SLE:GetChatIcon(arg2) + + if(pflag == true) then + pflag = "" + end + + if(lfgRoles[arg2] and SLE:SimpleTable(lfgChannels, type)) then + pflag = lfgRoles[arg2]..pflag + end + + pflag = pflag or "" + end + + if ( type == "WHISPER_INFORM" and GMChatFrame_IsGM and GMChatFrame_IsGM(arg2) ) then + return; + end + + local showLink = 1; + if ( strsub(type, 1, 7) == "MONSTER" or strsub(type, 1, 9) == "RAID_BOSS") then + showLink = nil; + else + arg1 = gsub(arg1, "%%", "%%%%"); + end + + -- Search for icon links and replace them with texture links. + for tag in gmatch(arg1, "%b{}") do + local term = strlower(gsub(tag, "[{}]", "")); + if ( ICON_TAG_LIST[term] and ICON_LIST[ICON_TAG_LIST[term]] ) then + arg1 = gsub(arg1, tag, ICON_LIST[ICON_TAG_LIST[term]] .. "0|t"); + elseif ( GROUP_TAG_LIST[term] ) then + local groupIndex = GROUP_TAG_LIST[term]; + local groupList = "["; + for i=1, GetNumGroupMembers() do + local name, rank, subgroup, level, class, classFileName = GetRaidRosterInfo(i); + if ( name and subgroup == groupIndex ) then + local classColorTable = RAID_CLASS_COLORS[classFileName]; + if ( classColorTable ) then + name = format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, name); + end + groupList = groupList..(groupList == "[" and "" or PLAYER_LIST_DELIMITER)..name; + end + end + groupList = groupList.."]"; + arg1 = gsub(arg1, tag, groupList); + end + end + + --Remove groups of many spaces + arg1 = RemoveExtraSpaces(arg1); + + local playerLink; + + if ( type ~= "BN_WHISPER" and type ~= "BN_WHISPER_INFORM" and type ~= "BN_CONVERSATION" ) then + playerLink = "|Hplayer:"..arg2..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"; + else + coloredName = GetBNFriendColor(arg2, arg13) + playerLink = "|HBNplayer:"..arg2..":"..arg13..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"; + end + + local message = arg1; + if ( arg14 ) then --isMobile + message = ChatFrame_GetMobileEmbeddedTexture(info.r, info.g, info.b)..message; + end + + if ( (strlen(arg3) > 0) and (arg3 ~= self.defaultLanguage) ) then + local languageHeader = "["..arg3.."] "; + if ( showLink and (strlen(arg2) > 0) ) then + body = format(_G["CHAT_"..type.."_GET"]..languageHeader..message, pflag..playerLink.."["..coloredName.."]".."|h"); + else + body = format(_G["CHAT_"..type.."_GET"]..languageHeader..message, pflag..arg2); + end + else + if ( not showLink or strlen(arg2) == 0 ) then + if ( type == "TEXT_EMOTE" ) then + body = message; + else + body = format(_G["CHAT_"..type.."_GET"]..message, pflag..arg2, arg2); + end + else + if ( type == "EMOTE" ) then + body = format(_G["CHAT_"..type.."_GET"]..message, pflag..playerLink..coloredName.."|h"); + elseif ( type == "TEXT_EMOTE") then + body = gsub(message, arg2, pflag..playerLink..coloredName.."|h", 1); + else + body = format(_G["CHAT_"..type.."_GET"]..message, pflag..playerLink.."["..coloredName.."]".."|h"); + end + end + end + + -- Add Channel + arg4 = gsub(arg4, "%s%-%s.*", ""); + if( chatGroup == "BN_CONVERSATION" ) then + body = format(CHAT_BN_CONVERSATION_GET_LINK, MAX_WOW_CHAT_CHANNELS + arg8, MAX_WOW_CHAT_CHANNELS + arg8)..body; + elseif(channelLength > 0) then + body = "|Hchannel:channel:"..arg8.."|h["..arg4.."]|h "..body; + end + + local accessID = ChatHistory_GetAccessID(chatGroup, chatTarget); + local typeID = ChatHistory_GetAccessID(infoType, chatTarget, arg12 == "" and arg13 or arg12); + if CH.db.shortChannels then + body = body:gsub("|Hchannel:(.-)|h%[(.-)%]|h", CH.ShortChannel) + body = body:gsub('CHANNEL:', '') + body = body:gsub("^(.-|h) "..L['whispers'], "%1") + body = body:gsub("^(.-|h) "..L['says'], "%1") + body = body:gsub("^(.-|h) "..L['yells'], "%1") + body = body:gsub("<"..AFK..">", "[|cffFF0000"..L['AFK'].."|r] ") + body = body:gsub("<"..DND..">", "[|cffE7E716"..L['DND'].."|r] ") + body = body:gsub("%[BN_CONVERSATION:", '%['.."") + body = body:gsub("^%["..RAID_WARNING.."%]", '['..L['RW']..']') + end + self:AddMessage(CH:ConcatenateTimeStamp(body), info.r, info.g, info.b, info.id, false, accessID, typeID); + end + + if ( type == "WHISPER" or type == "BN_WHISPER" ) then + --BN_WHISPER FIXME + ChatEdit_SetLastTellTarget(arg2, type); + if ( self.tellTimer and (GetTime() > self.tellTimer) ) then + PlaySound("TellMessage"); + end + self.tellTimer = GetTime() + CHAT_TELL_ALERT_TIME; + --FCF_FlashTab(self); + end + + if ( not self:IsShown() ) then + if ( (self == DEFAULT_CHAT_FRAME and info.flashTabOnGeneral) or (self ~= DEFAULT_CHAT_FRAME and info.flashTab) ) then + if ( not CHAT_OPTIONS.HIDE_FRAME_ALERTS or type == "WHISPER" or type == "BN_WHISPER" ) then --BN_WHISPER FIXME + if (not (type == "BN_CONVERSATION" and BNIsSelf(arg13))) then + if (not FCFManager_ShouldSuppressMessageFlash(self, chatGroup, chatTarget) ) then + --FCF_StartAlertFlash(self); THIS TAINTS<<<<<<< + _G[self:GetName().."Tab"].glow:Show() + _G[self:GetName().."Tab"]:SetScript("OnUpdate", CH.ChatTab_OnUpdate) + end + end + end + end + end + return true; + end +end + +function CH:ChatEdit_AddHistory(editBox, line) + if line:find("/rl") then return; end + + if ( strlen(line) > 0 ) then + for i, text in pairs(ElvCharacterDB.ChatEditHistory) do + if text == line then + return + end + end + + tinsert(ElvCharacterDB.ChatEditHistory, #ElvCharacterDB.ChatEditHistory + 1, line) + if #ElvCharacterDB.ChatEditHistory > E.db.chat.editboxhistory then + for i=1,(#ElvCharacterDB.ChatEditHistory - E.db.chat.editboxhistory) do + tremove(ElvCharacterDB.ChatEditHistory, 1) + end + end + end +end + +function SLE:GetChatIcon(sender) + local senderName, senderRealm + if sender then + senderName, senderRealm = string.split('-', sender) + else + senderName = Myname + end + senderRealm = senderRealm or PLAYER_REALM + senderRealm = senderRealm:gsub(' ', '') + + --Disabling ALL special icons. IDK why Elv use that and why would we want to have that but whatever + if(specialChatIcons[PLAYER_REALM] == nil or (specialChatIcons[PLAYER_REALM] and specialChatIcons[PLAYER_REALM][Myname] ~= true)) then + if specialChatIcons[senderRealm] and specialChatIcons[senderRealm][senderName] then + return specialChatIcons[senderRealm][senderName] + end + end + + if not IsInGuild() then return "" end + if not E.private.sle.guildmaster then return "" end + if senderName == GMName and senderRealm == GMRealm then + return leader + end + + return "" +end + +function CH:ChatFrame_AddMessageEventFilter (event, filter) + assert(event and filter); + + if ( chatFilters[event] ) then + -- Only allow a filter to be added once + for index, filterFunc in next, chatFilters[event] do + if ( filterFunc == filter ) then + return; + end + end + else + chatFilters[event] = {}; + end + + tinsert(chatFilters[event], filter); +end + +function CH:ChatFrame_RemoveMessageEventFilter (event, filter) + assert(event and filter); + + if ( chatFilters[event] ) then + for index, filterFunc in next, chatFilters[event] do + if ( filterFunc == filter ) then + tremove(chatFilters[event], index); + end + end + + if ( #chatFilters[event] == 0 ) then + chatFilters[event] = nil; + end + end +end + +function CH:CheckLFGRoles() + local isInGroup, isInRaid = IsInGroup(), IsInRaid() + local unit = isInRaid and "raid" or "party" + local name, realm + twipe(lfgRoles) + + if(not isInGroup or not self.db.lfgIcons) then return end + + local role = UnitGroupRolesAssigned("player") + if(role) then + lfgRoles[PLAYER_NAME] = rolePaths[role] + end + + for i=1, GetNumGroupMembers() do + if(UnitExists(unit..i) and not UnitIsUnit(unit..i, "player")) then + role = UnitGroupRolesAssigned(unit..i) + local name, realm = UnitName(unit..i) + + if(role and name) then + name = realm and name..'-'..realm or name..'-'..PLAYER_REALM; + lfgRoles[name] = rolePaths[role] + end + end + end +end + +function CH:GMCheck() + local name, rank + if GetNumGuildMembers() == 0 and IsInGuild() then E:Delay(2, CH.GMCheck); return end + if not IsInGuild() then GuildMaster = ""; GMName = ''; GMRealm = ''; return end + for i = 1, GetNumGuildMembers() do + name, _, rank = GetGuildRosterInfo(i) + if rank == 0 then + break + end + end + + GuildMaster = name + if GuildMaster then + GMName, GMRealm = string.split('-', GuildMaster) + end + GMRealm = GMRealm or PLAYER_REALM + GMRealm = GMRealm:gsub(' ', '') +end + +function CH:GMIconUpdate() + if E.private.chat.enable ~= true then return end + if E.private.sle.guildmaster then + self:RegisterEvent('GUILD_ROSTER_UPDATE', 'Roster') + CH:GMCheck() + else + self:UnregisterEvent('GUILD_ROSTER_UPDATE') + GuildMaster = "" + GMName = '' + GMRealm = '' + end +end + +function CH:Roster(event, update) + if update then CH:GMCheck() end +end + +function CH:Initialize() + if ElvCharacterDB.ChatHistory then + ElvCharacterDB.ChatHistory = nil --Depreciated + end + + self.db = E.db.chat + + if E.private.chat.enable ~= true then + stopScript = true + DEFAULT_CHAT_FRAME:RegisterEvent("GUILD_MOTD") + + local msg = GetGuildRosterMOTD() + if msg == "" then msg = nil end + if msg then + ChatFrame_SystemEventHandler(DEFAULT_CHAT_FRAME, "GUILD_MOTD", msg) + end + + return + end + + + if not ElvCharacterDB.ChatEditHistory then + ElvCharacterDB.ChatEditHistory = {}; + end + + if not ElvCharacterDB.ChatLog or not self.db.chatHistory then + ElvCharacterDB.ChatLog = {}; + end + + self:UpdateChatKeywords() + + self:UpdateFading() + E.Chat = self + self:SecureHook('ChatEdit_OnEnterPressed') + FriendsMicroButton:Kill() + ChatFrameMenuButton:Kill() + + + if WIM then + WIM.RegisterWidgetTrigger("chat_display", "whisper,chat,w2w,demo", "OnHyperlinkClick", function(self) CH.clickedframe = self end); + WIM.RegisterItemRefHandler('url', WIM_URLLink) + end + + self:SecureHook('FCF_SetChatWindowFontSize', 'SetChatFont') + self:RegisterEvent('PLAYER_ENTERING_WORLD', 'DelayGMOTD') + self:RegisterEvent('UPDATE_CHAT_WINDOWS', 'SetupChat') + self:RegisterEvent('UPDATE_FLOATING_CHAT_WINDOWS', 'SetupChat') + self:RegisterEvent('PET_BATTLE_CLOSE') + if E.private.sle.guildmaster then + self:RegisterEvent('GUILD_ROSTER_UPDATE', 'Roster') + CH:GMCheck() + end + + self:SetupChat() + self:UpdateAnchors() + + self:RegisterEvent("GROUP_ROSTER_UPDATE", "CheckLFGRoles") + + self:RegisterEvent('CHAT_MSG_INSTANCE_CHAT', 'SaveChatHistory') + self:RegisterEvent('CHAT_MSG_INSTANCE_CHAT_LEADER', 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_BN_WHISPER", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_BN_WHISPER_INFORM", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_CHANNEL", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_EMOTE", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_GUILD", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_GUILD_ACHIEVEMENT", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_OFFICER", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_PARTY", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_PARTY_LEADER", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_RAID", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_RAID_LEADER", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_RAID_WARNING", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_SAY", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_WHISPER", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_WHISPER_INFORM", 'SaveChatHistory') + self:RegisterEvent("CHAT_MSG_YELL", 'SaveChatHistory') + + --First get all pre-existing filters and copy them to our version of chatFilters using ChatFrame_GetMessageEventFilters + for name, _ in pairs(ChatTypeGroup) do + for i=1, #ChatTypeGroup[name] do + local filterFuncTable = ChatFrame_GetMessageEventFilters(ChatTypeGroup[name][i]) + if filterFuncTable then + chatFilters[ChatTypeGroup[name][i]] = {}; + + for j=1, #filterFuncTable do + local filterFunc = filterFuncTable[j] + tinsert(chatFilters[ChatTypeGroup[name][i]], filterFunc); + end + end + end + end + + --CHAT_MSG_CHANNEL isn't located inside ChatTypeGroup + local filterFuncTable = ChatFrame_GetMessageEventFilters("CHAT_MSG_CHANNEL") + if filterFuncTable then + chatFilters["CHAT_MSG_CHANNEL"] = {}; + + for j=1, #filterFuncTable do + local filterFunc = filterFuncTable[j] + tinsert(chatFilters["CHAT_MSG_CHANNEL"], filterFunc); + end + end + + --Now hook onto Blizzards functions for other addons + self:SecureHook("ChatFrame_AddMessageEventFilter"); + self:SecureHook("ChatFrame_RemoveMessageEventFilter"); + + self:SecureHook("FCF_SetWindowAlpha") + + + ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", CH.CHAT_MSG_CHANNEL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_YELL", CH.CHAT_MSG_YELL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY", CH.CHAT_MSG_SAY) + ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_GUILD", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_OFFICER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_LEADER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_INSTANCE_CHAT", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_INSTANCE_CHAT_LEADER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_CONVERSATION", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER_INFORM", CH.FindURL) + ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_INLINE_TOAST_BROADCAST", CH.FindURL) + + + GeneralDockManagerOverflowButton:ClearAllPoints() + GeneralDockManagerOverflowButton:Point('BOTTOMRIGHT', LeftChatTab, 'BOTTOMRIGHT', -2, 2) + GeneralDockManagerOverflowButtonList:SetTemplate('Transparent') + hooksecurefunc(GeneralDockManagerScrollFrame, 'SetPoint', function(self, point, anchor, attachTo, x, y) + if anchor == GeneralDockManagerOverflowButton and x == 0 and y == 0 then + self:SetPoint(point, anchor, attachTo, -2, -6) + end + end) + + if self.db.chatHistory then + self.SoundPlayed = true; + self:DisplayChatHistory() + self.SoundPlayed = nil; + end + + + local S = E:GetModule('Skins') + S:HandleNextPrevButton(CombatLogQuickButtonFrame_CustomAdditionalFilterButton, true) + local frame = CreateFrame("Frame", "CopyChatFrame", E.UIParent) + tinsert(UISpecialFrames, "CopyChatFrame") + frame:SetTemplate('Transparent') + frame:Size(700, 200) + frame:Point('BOTTOM', E.UIParent, 'BOTTOM', 0, 3) + frame:Hide() + frame:EnableMouse(true) + frame:SetFrameStrata("DIALOG") + + + local scrollArea = CreateFrame("ScrollFrame", "CopyChatScrollFrame", frame, "UIPanelScrollFrameTemplate") + scrollArea:Point("TOPLEFT", frame, "TOPLEFT", 8, -30) + scrollArea:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 8) + S:HandleScrollBar(CopyChatScrollFrameScrollBar) + + local editBox = CreateFrame("EditBox", "CopyChatFrameEditBox", frame) + editBox:SetMultiLine(true) + editBox:SetMaxLetters(99999) + editBox:EnableMouse(true) + editBox:SetAutoFocus(false) + editBox:SetFontObject(ChatFontNormal) + editBox:Width(scrollArea:GetWidth()) + editBox:Height(200) + editBox:SetScript("OnEscapePressed", function() CopyChatFrame:Hide() end) + scrollArea:SetScrollChild(editBox) + CopyChatFrameEditBox:SetScript("OnTextChanged", function(self, userInput) + if userInput then return end + local _, max = CopyChatScrollFrameScrollBar:GetMinMaxValues() + for i=1, max do + ScrollFrameTemplate_OnMouseWheel(CopyChatScrollFrame, -1) + end + end) + + local close = CreateFrame("Button", "CopyChatFrameCloseButton", frame, "UIPanelCloseButton") + close:SetPoint("TOPRIGHT") + close:SetFrameLevel(close:GetFrameLevel() + 1) + close:EnableMouse(true) + + S:HandleCloseButton(close) + + --Disable Blizzard + InterfaceOptionsSocialPanelTimestampsButton:SetAlpha(0) + InterfaceOptionsSocialPanelTimestampsButton:SetScale(0.000001) + InterfaceOptionsSocialPanelTimestamps:SetAlpha(0) + InterfaceOptionsSocialPanelTimestamps:SetScale(0.000001) + + InterfaceOptionsSocialPanelChatStyle:EnableMouse(false) + InterfaceOptionsSocialPanelChatStyleButton:Hide() + InterfaceOptionsSocialPanelChatStyle:SetAlpha(0) + + CombatLogQuickButtonFrame_CustomAdditionalFilterButton:Size(20, 22) + CombatLogQuickButtonFrame_CustomAdditionalFilterButton:Point("TOPRIGHT", CombatLogQuickButtonFrame_Custom, "TOPRIGHT", 0, -1) +end + +--Previously layout.lua +local LO = E:GetModule('Layout'); +local PANEL_HEIGHT = 22; +local SIDE_BUTTON_WIDTH = 16; + +LO.ToggleChatPanelsSLE = LO.ToggleChatPanels +function LO:ToggleChatPanels() + LO.ToggleChatPanelsSLE(self) + + if not E.db.sle.datatext.chathandle then return end + + if not E:HasMoverBeenMoved("LeftChatMover") and E.db.datatexts.leftChatPanel then + if not E.db.movers then E.db.movers = {}; end + if E.PixelMode then + E.db.movers.LeftChatMover = "BOTTOMLEFTUIParentBOTTOMLEFT019" + else + E.db.movers.LeftChatMover = "BOTTOMLEFTUIParentBOTTOMLEFT021" + end + E:SetMoversPositions() + end + + if not E:HasMoverBeenMoved("RightChatMover") and E.db.datatexts.rightChatPanel then + if not E.db.movers then E.db.movers = {}; end + if E.PixelMode then + E.db.movers.RightChatMover = "BOTTOMRIGHTUIParentBOTTOMRIGHT019" + else + E.db.movers.RightChatMover = "BOTTOMRIGHTUIParentBOTTOMRIGHT021" + end + E:SetMoversPositions() + end + + if E.db.chat.panelBackdrop == 'SHOWBOTH' then + LeftChatPanel.backdrop:Show() + RightChatPanel.backdrop:Show() + + LeftChatDataPanel:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', SIDE_BUTTON_WIDTH, (E.PixelMode and -19 or -21)) --lower line of datapanel + LeftChatDataPanel:Point('TOPRIGHT', LeftChatPanel, 'BOTTOMLEFT', 16 + E.db.sle.datatext.chatleft.width, (E.PixelMode and 1 or -1)) --upper line of datapanel + RightChatDataPanel:Point('BOTTOMLEFT', RightChatPanel, 'BOTTOMRIGHT', - (E.db.sle.datatext.chatright.width + 16), (E.PixelMode and -19 or -21)) --lower-left corner of right datapanel + RightChatDataPanel:Point('TOPRIGHT', RightChatPanel, 'BOTTOMRIGHT', -SIDE_BUTTON_WIDTH, (E.PixelMode and 1 or -1)) --upper-right corner of right datapanel + LeftChatToggleButton:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', 0, (E.PixelMode and -19 or -21)) + RightChatToggleButton:Point('BOTTOMRIGHT', RightChatPanel, 'BOTTOMRIGHT', 0, (E.PixelMode and -19 or -21)) + LO:ToggleChatTabPanels() + elseif E.db.chat.panelBackdrop == 'HIDEBOTH' then + LeftChatPanel.backdrop:Hide() + RightChatPanel.backdrop:Hide() + + LeftChatDataPanel:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', SIDE_BUTTON_WIDTH, (E.PixelMode and -19 or -21)) --lower line of datapanel + LeftChatDataPanel:Point('TOPRIGHT', LeftChatPanel, 'BOTTOMLEFT', 16 + E.db.sle.datatext.chatleft.width, (E.PixelMode and 1 or -1)) --upper line of datapanel + RightChatDataPanel:Point('BOTTOMLEFT', RightChatPanel, 'BOTTOMRIGHT', - (E.db.sle.datatext.chatright.width + 16), (E.PixelMode and -19 or -21)) --lower-left corner of right datapanel + RightChatDataPanel:Point('TOPRIGHT', RightChatPanel, 'BOTTOMRIGHT', -SIDE_BUTTON_WIDTH, (E.PixelMode and 1 or -1)) --upper-right corner of right datapanel + LeftChatToggleButton:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', 0, (E.PixelMode and -19 or -21)) + RightChatToggleButton:Point('BOTTOMRIGHT', RightChatPanel, 'BOTTOMRIGHT', 0, (E.PixelMode and -19 or -21)) + LO:ToggleChatTabPanels(true, true) + elseif E.db.chat.panelBackdrop == 'LEFT' then + LeftChatPanel.backdrop:Show() + RightChatPanel.backdrop:Hide() + + LeftChatDataPanel:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', SIDE_BUTTON_WIDTH, (E.PixelMode and -19 or -21)) --lower line of datapanel + LeftChatDataPanel:Point('TOPRIGHT', LeftChatPanel, 'BOTTOMLEFT', 16 + E.db.sle.datatext.chatleft.width, (E.PixelMode and 1 or -1)) --upper line of datapanel + RightChatDataPanel:Point('BOTTOMLEFT', RightChatPanel, 'BOTTOMRIGHT', - (E.db.sle.datatext.chatright.width + 16), (E.PixelMode and -19 or -21)) --lower-left corner of right datapanel + RightChatDataPanel:Point('TOPRIGHT', RightChatPanel, 'BOTTOMRIGHT', -SIDE_BUTTON_WIDTH, (E.PixelMode and 1 or -1)) --upper-right corner of right datapanel + LeftChatToggleButton:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', 0, (E.PixelMode and -19 or -21)) + RightChatToggleButton:Point('BOTTOMRIGHT', RightChatPanel, 'BOTTOMRIGHT', 0, (E.PixelMode and -19 or -21)) + LO:ToggleChatTabPanels(true) + else + LeftChatPanel.backdrop:Hide() + RightChatPanel.backdrop:Show() + + LeftChatDataPanel:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', SIDE_BUTTON_WIDTH, (E.PixelMode and -19 or -21)) --lower line of datapanel + LeftChatDataPanel:Point('TOPRIGHT', LeftChatPanel, 'BOTTOMLEFT', 16 + E.db.sle.datatext.chatleft.width, (E.PixelMode and 1 or -1)) --upper line of datapanel + RightChatDataPanel:Point('BOTTOMLEFT', RightChatPanel, 'BOTTOMRIGHT', - (E.db.sle.datatext.chatright.width + 16), (E.PixelMode and -19 or -21)) --lower-left corner of right datapanel + RightChatDataPanel:Point('TOPRIGHT', RightChatPanel, 'BOTTOMRIGHT', -SIDE_BUTTON_WIDTH, (E.PixelMode and 1 or -1)) --upper-right corner of right datapanel + LeftChatToggleButton:Point('BOTTOMLEFT', LeftChatPanel, 'BOTTOMLEFT', 0, (E.PixelMode and -19 or -21)) + RightChatToggleButton:Point('BOTTOMRIGHT', RightChatPanel, 'BOTTOMRIGHT', 0, (E.PixelMode and -19 or -21)) + LO:ToggleChatTabPanels(nil, true) + end +end + +LO.CreateChatPanelsSLE = LO.CreateChatPanels +function LO:CreateChatPanels() + LO.CreateChatPanelsSLE(self) + + --Left Chat Tab + LeftChatTab:Point('TOPLEFT', LeftChatPanel, 'TOPLEFT', 2, -2) + LeftChatTab:Point('BOTTOMRIGHT', LeftChatPanel, 'TOPRIGHT', -2, -PANEL_HEIGHT) + + --Preventing left chat datapanel fading + ChatFrame1EditBox:Hide() + + --Right Chat Tab + RightChatTab:Point('TOPRIGHT', RightChatPanel, 'TOPRIGHT', -2, -2) + RightChatTab:Point('BOTTOMLEFT', RightChatPanel, 'TOPLEFT', 2, -PANEL_HEIGHT) +end +