I think the lua errors occur when the game updates the BG status/score text (the one that resides at the top-middle of the screen during BG). I also think that it happens when the user is in combat at the time of the update.
This is core.lua code (about 1000 lines). Since it's my first addon, I'm pretty sure it doesn't meet with the coding standards of all experts here, but it was the best I could do with my little experience and knowledge. I would appreciate any help pointing me to the problem in my addon.
Code:
----------------------------------------
-- Libs
----------------------------------------
hebChat = LibStub("AceAddon-3.0"):NewAddon("hebChat", "AceEvent-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
--------------------------------------
-- General variables and Declarations
--------------------------------------
local addonName = ...
local origChatEdit_OnTextChanged = ChatEdit_OnTextChanged
local origChatEdit_OnTabPressed = ChatEdit_OnTabPressed
local origChatEdit_UpdateHeader = ChatEdit_UpdateHeader
local origFCF_OpenTemporaryWindow = FCF_OpenTemporaryWindow
local origSendChatMessage = SendChatMessage
local origBNSendWhisper = BNSendWhisper
local _G = _G
BINDING_HEADER_HEBCHAT = "Animor's hebChat"
hebChat.wimLoaded = false
hebChat.guildMemberMobile = {}
hebChat.guildMemberMobileInform = {}
-- Fonts table
hebChat.fontsName = {
["Default Font"] = "Default Font",
["Arial"] = "Arial",
["Tahoma"] = "Tahoma",
["Times New Roman"] = "Times New Roman",
["Sans Serif"] = "Sans Serif",
["Miriam"] = "Miriam",
["Courier"] = "Courier",
["David"] = "David",
["David Bold"] = "David Bold",
["FrankRuehl"] = "FrankRuehl",
["Levenim"] = "Levenim",
["Narkisim"] = "Narkisim",
["Gisha"] = "Gisha",
}
hebChat.fonts = {
["Default Font"] = "Fonts\\ARIALN.TTF",
["Arial"] = "Interface\\AddOns\\hebChat\\Fonts\\arial.ttf",
["Tahoma"] = "Interface\\AddOns\\hebChat\\Fonts\\tahoma.ttf",
["Times New Roman"] = "Interface\\AddOns\\hebChat\\Fonts\\times.ttf",
["Sans Serif"] = "Interface\\AddOns\\hebChat\\Fonts\\micross.ttf",
["Miriam"] = "Interface\\AddOns\\hebChat\\Fonts\\mriam.ttf",
["Courier"] = "Interface\\AddOns\\hebChat\\Fonts\\courbd.ttf",
["David"] = "Interface\\AddOns\\hebChat\\Fonts\\david.ttf",
["David Bold"] = "Interface\\AddOns\\hebChat\\Fonts\\davidbd.ttf",
["FrankRuehl"] = "Interface\\AddOns\\hebChat\\Fonts\\frank.ttf",
["Levenim"] = "Interface\\AddOns\\hebChat\\Fonts\\lvnm.ttf",
["Narkisim"] = "Interface\\AddOns\\hebChat\\Fonts\\nrkis.ttf",
["Gisha"] = "Interface\\AddOns\\hebChat\\Fonts\\gisha.ttf",
}
-- Font Objects table
hebChat.fObjects = {}
-- Save number of chars to identify delete
hebChat.lastText = ""
---------------
-- Delay Frame
---------------
if not hebChatDelayFrame then
hebChatDelayFrame = CreateFrame("Frame")
hebChatDelayFrame:Hide()
end
hebChatDelayFrame:SetScript("OnUpdate", function(self, elapsed)
self.delaySec = self.delaySec - elapsed
if self.delaySec <= 0 then
self:Hide()
self.func()
end
end)
function hebChatDelayFrame:delay(delaySec, func)
hebChatDelayFrame.func = func
hebChatDelayFrame.delaySec = delaySec
hebChatDelayFrame:Show()
end
-----------
-- Loading
-----------
-- Open configuration panel via slash commands
local function hebChatOpenConfig()
InterfaceOptionsFrame_OpenToCategory(hebChat.configPanel)
end
-- Show/Hide graphic button and make it movable
function hebChat:hebChatLangButton_OnLoad(frame)
frame:RegisterForDrag("LeftButton")
end
-- -- Even handling
-- hebChat:SetScript("OnEvent",
-- function(self, event, ...)
-- if self[event] then
-- return self[event](...)
-- end
-- end
-- )
-- ADDON_LOADED event
function hebChat:OnInitialize()
-- Init saved variables
self.defaults = {
globalEn = true,
graphicButtonEN = true,
currentLang = "EN",
currentFont = "Arial",
hebFont = "Arial",
defaultFont = "Default Font",
currentFontSize = 13,
hebFontSize = 13,
defaultFontSize = 14,
showWarning = true,
langButtonSize = 30,
}
if not hebChatDB then
hebChatDB = {}
end
for k, v in pairs(self.defaults) do
if type(hebChatDB[k]) ~= type(v) then
hebChatDB[k] = v
end
end
-- Register to PLAYER_ENTERING_WORLD
hebChat:RegisterEvent("PLAYER_ENTERING_WORLD")
-- Set chat frame fonts according to configuration
hebChat:setChatFont()
-- Hook ChatEdit_OnTextChanged
ChatEdit_OnTextChanged = hebChat.ChatEdit_OnTextChanged
-- Hook SendChatMessage
SendChatMessage = hebChat.SendChatMessage
-- Hook BNSendWhisper
BNSendWhisper = hebChat.BNSendWhisper
-- Hook ChatEdit_OnTabPressed
ChatEdit_OnTabPressed = hebChat.ChatEdit_OnTabPressed
-- Hook ChatEdit_UpdateHeader
ChatEdit_UpdateHeader = hebChat.ChatEdit_UpdateHeader
-- Hook FCF_OpenTemporaryWindow
FCF_OpenTemporaryWindow = hebChat.FCF_OpenTemporaryWindow
-- Init font Dropdown list
hebChat:createFontObjects()
-- Graphic button enable button
hebChatLangButton:SetSize(hebChatDB.langButtonSize, hebChatDB.langButtonSize)
hebChat:langButtonSetFont()
hebChatLangButton:SetText(hebChatDB.currentLang)
if (hebChatDB.globalEn and hebChatDB.graphicButtonEN) then
hebChatLangButton:Show()
else
hebChatLangButton:Hide()
end
-- Slash commands
SLASH_HEBCHAT1 = "/heb"
SLASH_HEBCHAT2 = "/hebchat"
SlashCmdList["HEBCHAT"] = hebChatOpenConfig
-- Fix wrapping
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER_INFORM", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_CONVERSATION", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_LEADER", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_GUILD", hebChat.hebChatFixWrap)
ChatFrame_AddMessageEventFilter("CHAT_MSG_OFFICER", hebChat.hebChatFixWrap)
-- Fontstring to measure string width
hebChat.textWidthFrame = CreateFrame("Frame", nil, UIParent)
hebChat.textWidthFrame:Hide()
hebChat.textWidthFrame.text = hebChat.textWidthFrame:CreateFontString()
hebChat.textWidthFrame.text:SetAllPoints(hebChat.textWidthFrame)
hebChat.textWidthFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont], hebChatDB.currentFontSize)
-- String table to fix wrapping
hebChat.newStringTable = {}
-- Save number of chars to identify delete
hebChat.lastText = ""
-- Welcome message
local enableString = (hebChatDB.globalEn and " enabled") or (not hebChatDB.globalEn and " disabled")
DEFAULT_CHAT_FRAME:AddMessage ("Animor's hebChat v"..GetAddOnMetadata(addonName, "Version")..enableString..": type /heb or /hebchat for configuration.", 1, 0, 1)
-- Config Panel
LibStub("AceConfig-3.0"):RegisterOptionsTable("hebChat", self.options)
hebChat.configPanel = AceConfigDialog:AddToBlizOptions("hebChat", "hebChat")
end
-- PLAYER_ENTERING_WORLD event
function hebChat.PLAYER_ENTERING_WORLD(...)
-- Set chat frame fonts according to configuration
hebChat:setChatFont()
-- Set Fonts again after 0.5[s] to bypass other addons fonts.
hebChatDelayFrame:delay(0.5, hebChat.setChatFont)
-- Display warning if Prat/Chatter and Misspelled are loaded
if ((Prat3DB or ChatterDB) and Misspelled_DB and hebChatDB.showWarning) then
StaticPopupDialogs["hebChat Warning"] = {
text = "Warning: Animor's hebChat will not work properly when either Prat3/Chatter and Misspelled are loaded.",
button1 = OKAY,
button2 = "Don't show again",
OnCancel = function()
hebChatDB.showWarning = false
end,
timeout = 0,
whileDead = true,
hideOnEscape = false,
}
StaticPopup_Show ("hebChat Warning")
end
-- WIM support
if (WIM3_Data) then
-- Hook WIM history viewer
if (not hebChat.wimLoaded) then
origWIMShowHistoryViewer = WIM.ShowHistoryViewer
WIM.ShowHistoryViewer = hebChat.ShowHistoryViewer
hebChat.wimLoaded = true
end
if (hebChatDB.globalEn) then
-- Convert WIM msg_box input to Hebrew
WIM.RegisterWidgetTrigger("msg_box", "whisper,chat,w2w", "OnTextChanged", hebChat.text2Heb)
-- Toggle language on ctrl-tab while typing
WIM.RegisterWidgetTrigger("msg_box", "whisper,chat,w2w", "OnTabPressed",
function()
if IsControlKeyDown() then
hebChat:toggleLanguage();
end
end)
-- Handle text leftovers when switching WIM windows
WIM.RegisterWidgetTrigger("msg_box", "whisper,chat,w2w", "OnEditFocusGained",
function(self)
if (self) then
hebChat.lastText = self:GetText()
else
hebChat.lastText = ""
end
end)
end
end
end
------------------------
-- Global enable button
------------------------
function hebChat:globalEn_OnClick(value)
if value then
hebChatDB.globalEn = true
hebChatDB.currentFontSize = hebChatDB.hebFontSize
hebChatDB.currentFont = hebChatDB.hebFont
if (hebChatDB.graphicButtonEN) then
hebChatLangButton:Show()
end
else
hebChatDB.globalEn = false
hebChatDB.currentFontSize = hebChatDB.defaultFontSize
hebChatDB.currentFont = hebChatDB.defaultFont
hebChatLangButton:Hide()
end
self:setChatFont()
end
-- Check legit chat type
function hebChat:checkLegitChatType (chatType)
if (chatType == "GUILD" or chatType == "OFFICER" or
chatType == "PARTY" or chatType == "RAID" or
chatType == "WHISPER" or chatType == "BN_CONVERSATION" or
chatType == "BN_WHISPER") then
return true
else
return false
end
end
-------------------
-- Graphic button
-------------------
function hebChat:graphicButtonEN_OnClick(value)
if value then
hebChatDB.graphicButtonEN = true
if (hebChatDB.globalEn) then
hebChatLangButton:Show()
end
else
hebChatDB.graphicButtonEN = false
hebChatLangButton:Hide()
end
end
function hebChat:toggleLanguage()
if (hebChatDB.currentLang == "EN") then
hebChatDB.currentLang = "HE"
else
hebChatDB.currentLang = "EN"
end
hebChatLangButton:SetText(hebChatDB.currentLang)
end
-----------------------
-- Fonts
-----------------------
-- Create font objects
function hebChat:createFontObjects()
local fObject = nil
for k, v in pairs(self.fonts) do
fObject = CreateFont(k)
fObject:SetFont(v, 13)
self.fObjects[k] = fObject
end
end
function hebChat:langButtonSetFont()
local langButtonFontObject = CreateFont("langButtonFont")
langButtonFontObject:SetFont("Fonts\\FRIZQT__.TTF", hebChatDB.langButtonSize*0.4)
hebChatLangButton:SetNormalFontObject(langButtonFontObject)
hebChatLangButton:SetHighlightFontObject(langButtonFontObject)
end
local function hebChatIsCurrentFont(fontName)
if (fontName == hebChatDB.currentFont) then
return true
else
return false
end
end
-- Selecting a font from dropdown list
function hebChat:hebChatDropDownList_OnClick(arg1)
hebChatDB.currentFont = arg1
if (hebChatDB.globalEn) then
hebChatDB.hebFont = arg1
else
hebChatDB.defaultFont = arg1
end
hebChat:setChatFont()
end
--------------------
-- Font Size slider
--------------------
function hebChat:hebChatFontSizeSlider_OnValueChanged(value)
if (hebChatDB.globalEn) then
hebChatDB.hebFontSize = value
hebChatDB.currentFontSize = value
else
hebChatDB.defaultFontSize = value
hebChatDB.currentFontSize = value
end
hebChat:setChatFont()
end
---------------------------------------------------
-- Set chat frames font according to configuration
---------------------------------------------------
function hebChat:setChatFont()
local newFont = ""
local frame = nil
if (hebChat.fonts[hebChatDB.currentFont]) then
newFont = hebChat.fonts[hebChatDB.currentFont]
else
newFont = hebChat.fonts["Default Font"]
end
for i = 1, 30 do
frame = _G["ChatFrame"..i]
if frame then
frame:SetFont(newFont, hebChatDB.currentFontSize)
_G["ChatFrame"..i.."EditBox"]:SetFont(newFont, hebChatDB.currentFontSize)
end
end
if (WIM3_Data) then
-- Set WIM chatFrame default font
WIM3_Data.fontSize = hebChatDB.currentFontSize - 2
if (hebChat.fObjects[hebChatDB.currentFont]) then
_G[WIM3_Data.skin.font] = hebChat.fObjects[hebChatDB.currentFont]
if (WIM3_HistoryFrame) then
WIM3_HistoryFrame.content.chatFrame:SetFontObject(hebChat.fObjects[hebChatDB.currentFont])
WIM3_HistoryFrame.content.textFrame.text:SetFontObject(hebChat.fObjects[hebChatDB.currentFont])
end
end
-- Set WIM msg_box default font
local SelectedSkin = WIM:GetSelectedSkin()
if (SelectedSkin) then
SelectedSkin.message_window.widgets.msg_box.font_height = hebChatDB.currentFontSize
end
-- Set WIM current chatFrames and msg_boxes fonts
local WindowSoupBowl = WIM:GetWindowSoupBowl()
local window_objects = WindowSoupBowl.windows
for i=1, table.getn(window_objects) do
local chat_display = window_objects[i].obj.widgets.chat_display;
local msg_box = window_objects[i].obj.widgets.msg_box;
chat_display:SetFont(newFont, hebChatDB.currentFontSize)
msg_box:SetFont(newFont, hebChatDB.currentFontSize)
end
end
end
---------------------------
-- Text handling functions
---------------------------
-- Check if string contains hebrew char
local function isHeb(str)
local byteArray = {}
local hebCharfound = false
local i = 1
byteArray = {string.byte(str, 1, strlenutf8(str))}
while (i <= #byteArray and hebCharfound == false) do
if (byteArray[i] == 215) then
hebCharfound = true
end
i = i + 1
end
return hebCharfound
end
-- Deal with utf8 chars
local function chsize(char)
-- UTF-8 Reference:
-- 0xxxxxxx - 1 byte UTF-8 codepoint (ASCII character)
-- 110yyyxx - First byte of a 2 byte UTF-8 codepoint
-- 1110yyyy - First byte of a 3 byte UTF-8 codepoint
-- 11110zzz - First byte of a 4 byte UTF-8 codepoint
-- 10xxxxxx - Inner byte of a multi-byte UTF-8 codepoint
if not char then
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
else
return 1
end
end
-- This function can return a substring of a UTF-8 string, properly handling
-- UTF-8 codepoints. Rather than taking a start index and optionally an end
-- index, it takes the string, the starting character, and the number of
-- characters to select from the string.
local function utf8sub(str, startChar, numChars, verbose)
local char = ""
local startIndex = 1
local currentIndex = 0
-- if verbose then print ("startChar: "..startChar) end
-- if verbose then print ("numChars: "..numChars) end
while startChar > 1 do
char = string.byte(str, startIndex)
startIndex = startIndex + chsize(char)
startChar = startChar - 1
end
currentIndex = startIndex
while numChars > 0 and currentIndex <= #str do
char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
numChars = numChars -1
end
-- if verbose then print ("startIndex: "..startIndex) end
-- if verbose then print ("currentIndex: "..currentIndex) end
-- if verbose then print (str:sub(startIndex, currentIndex - 1)) end
return str:sub(startIndex, currentIndex - 1)
end
-- identical to string.reverse except that it supports UTF-8
local function utf8reverse (str)
local bytes = str:len()
local pos = bytes
local charbytes
local newstr = ""
while pos > 0 do
c = str:byte(pos)
while c >= 128 and c <= 191 do
pos = pos - 1
c = str:byte(pos)
end
charbytes = chsize(c)
newstr = newstr .. str:sub(pos, pos + charbytes - 1)
pos = pos - 1
end
return newstr
end
-- Convert char to hebrew
local function charHebConvert(origString, cursorPosition)
local char = ""
local charHeb = ""
local charByte1 = 0
local charByte2 = 0
local charIsHebrew = false
local charIsLatin = false
-- Get current chat
if (cursorPosition > 1) then
char = origString:sub(cursorPosition-1, cursorPosition)
charByte1, charByte2 = char:byte(1, #char)
if (charByte1 == 195 and charByte2) then
charIsLatin = true
else
char = origString:sub(cursorPosition, cursorPosition)
charIsLatin = false
end
elseif (cursorPosition == 1) then
char = origString:sub(cursorPosition, cursorPosition)
charIsLatin = false
else
-- cursorPosition == 0 (should not happen)
char = ""
charIsLatin = false
end
-- If required, convert char to Hebrew
if (charIsLatin and not hebChatDB.graphicButtonEN) then
-- Convert according to alt-shift hebrew mode
charHeb = string.char(215, charByte2 - 16)
charIsHebrew = true
elseif (hebChatDB.graphicButtonEN and hebChatDB.currentLang == "HE") then
-- Convert according to keymap
if (hebChat.hebSet[char]) then
charHeb = hebChat.hebSet[char]
charIsHebrew = true
else
charHeb = char
charIsHebrew = false
end
else
-- Do not Convert
charHeb = char
charIsHebrew = false
end
return charIsHebrew, charHeb
end
-- Convert editBox to hebrew
function hebChat.text2Heb (editBox)
local numOfChars = 0
local prevNumOfChars = 0
local cursorPosition = 0
local editBoxMaxLetters = 0
local typedCharHeb = ""
local preString = ""
local postString = ""
local origString = ""
local newString = ""
local stringPreEn = ""
local stringEn = ""
local stringPostEn = ""
local punc1 = ""
local digit = ""
local digit1 = ""
local digit2 = ""
local punc2 = ""
local restPostString = ""
local typedCharIsHebrew = nil
local preStringFind = nil
editBoxMaxLetters = editBox:GetMaxLetters()
if (editBoxMaxLetters == 0) then
-- WIM fix
editBoxMaxLetters = 255
end
origString = editBox:GetText()
numOfChars = strlenutf8(origString)
prevNumOfChars = strlenutf8(hebChat.lastText)
newString = origString -- init value
cursorPosition = editBox:GetCursorPosition()
if ( (#origString > editBoxMaxLetters - 2) and (#origString > #hebChat.lastText) and isHeb(origString) ) then
-- editBox reached max letters limit - restore last string
newString = hebChat.lastText
editBox:SetText(newString)
editBox:SetCursorPosition(0)
elseif (numOfChars ~= prevNumOfChars - 1 and numOfChars ~= prevNumOfChars and numOfChars < prevNumOfChars + 2) then
-- Do not convert for delete/backspace or links
-- Typed char in string
typedCharIsHebrew, typedCharHeb = charHebConvert(origString, cursorPosition)
-- Extract the string after type char
if (cursorPosition < #origString) then
postString = origString:sub(cursorPosition + 1, #origString)
else
postString = ""
end
if (typedCharIsHebrew) then
-- Hebrew char in Hebrew or mixed-Hebrew string
-- Extract the string before typed char
if (hebChatDB.graphicButtonEN) then
-- 1 byte char typed
if (cursorPosition > 1) then
preString = string.sub(origString, 1, cursorPosition - 1)
else
preString = ""
end
else
-- 2 byte latin char typed
if (cursorPosition > 2) then
preString = string.sub(origString, 1, cursorPosition - 2)
else
preString = ""
end
end
stringPreEn, preStringFind, stringEn, stringPostEn = preString:match("(.-)(([%w%s%p]*[%w]+)([%p%s]+))$")
if (origString:match("^/[%a -_]*$")) then
-- do not convert slash commands
elseif (preStringFind) then
-- last chars before Hebrew char are white space or punctuation char, then English char.
newString = stringPreEn..typedCharHeb..string.reverse(stringPostEn)..stringEn..postString
editBox:SetText(newString)
editBox:SetCursorPosition(#stringPreEn)
elseif (preString:find("^[%p%s]+$")) then
-- Only chars before Hebrew char are white spaces or punctuation chars.
newString = typedCharHeb..string.reverse(preString)..postString
editBox:SetText(newString)
editBox:SetCursorPosition(0)
elseif (preString:find("^[%p%s%d]+$")) then
-- Hebrew Char after a number
punc1, digit, punc2 = preString:match("^([%s%p]*)([%d%s]-)([%s%p]*)$")
newString = typedCharHeb..string.reverse(punc2)..digit..punc1..postString
editBox:SetText(newString)
editBox:SetCursorPosition(0)
elseif (typedCharHeb:find("[%p]") and postString:find("[%s%p%d]*[א-ת]+") and preString:find("^[%a]+[%a%d%s]*$")) then
-- Punctuation char after Hebrew and before English
newString = typedCharHeb..preString..postString
editBox:SetText(newString)
editBox:SetCursorPosition(0)
else
-- Normal typing of Hebrew Char
newString = preString..typedCharHeb..postString
editBox:SetText(newString)
if (hebChatDB.graphicButtonEN) then
-- 1 byte char typed
editBox:SetCursorPosition(cursorPosition - 1)
else
-- 2 byte latin char typed
editBox:SetCursorPosition(cursorPosition - 2)
end
end
elseif (typedCharHeb ~= "") then
-- Non-Hebrew char
-- Extract the string before typed char
if (cursorPosition > 1) then
preString = string.sub(origString, 1, cursorPosition - 1)
else
preString = ""
end
if (typedCharHeb:find("[%d]") and postString:find("^[%p]*[%d%p]+[%s%d%p]*[א-ת]+.*")) then
-- Number (i.e. several digits) after Hebrew chars.
punc1, digit, restPostString = postString:match("^([%p]*)([%d%p]+)([%s%d%p]*[א-ת]+.*)")
if digit:find("%p+$") then
-- Punctuation char just after hebrew and before digit
digit1, digit2 = digit:match("(.-)(%p+)$")
newString = preString..digit1..punc1..typedCharHeb..digit2..restPostString
else
-- No punctuation char just after hebrew
newString = preString..digit..punc1..typedCharHeb..restPostString
end
editBox:SetText(newString)
editBox:SetCursorPosition(cursorPosition - 1)
elseif (typedCharHeb:find("[%p]") and postString:find("[%s%p%d]*[א-ת]+") and preString:find("^[%a]+$")) then
-- Punctuation char after Hebrew and before English
newString = typedCharHeb..preString..postString
editBox:SetText(newString)
editBox:SetCursorPosition(0)
elseif (typedCharHeb:find("[%p%s%d]") and postString:find("[%s%p%d]*[א-ת]+")) then
-- White space, digit or punctuation char after hebrew char
newString = preString..typedCharHeb..postString
editBox:SetText(newString)
if (not preString:find("[%w]+[%s]?$")) then
-- Move cursor back if there is no non-Hebrew on the left.
editBox:SetCursorPosition(cursorPosition - 1)
end
elseif (postString:find("^%p+%a+") and preString == "") then
punc1, stringEn, restPostString = postString:match("^(%p+)([%a%p]+)(.*)")
newString = stringEn..punc1..typedCharHeb..restPostString
editBox:SetText(newString)
editBox:SetCursorPosition(#(stringEn..punc1..typedCharHeb))
else
-- Other non-Hebrew char
end -- if (typedCharIsHebrew)
else
-- No char.
end
end
hebChat.lastText = newString;
end -- function text2Heb (editBox)
-- Fix chat frame text wrapping for Hebrew text
function hebChat.hebChatFixWrap(chatFrame, event, msg, author, ...)
local _, _, _, _, _, _, _, _, _, _, _, isMobile = ...
local remainingString = ""
wipe (hebChat.newStringTable)
local newString = ""
local lineString = ""
local lineStringBkp = ""
local remainingStringBkp = ""
local chatFrameWidth = chatFrame:GetWidth()
local effectiveChatFrameWidth = 0
local header = ""
local header1 = ""
local header2 = ""
local headerWidth1 = 0
local headerWidth2 = 0
local currentChar = ""
local inLink = false
local _
-- WIM unkown width bypass
if (chatFrameWidth == 0) then
chatFrameWidth = 330
end
-- Populate mobile guild members array
if isMobile then
hebChat.guildMemberMobile[author] = true
elseif hebChat.guildMemberMobile[author] then
hebChat.guildMemberMobile[author] = false
hebChat.guildMemberMobileInform[author] = false
end
-- In case of hebrew char
if isHeb(msg) and hebChatDB.globalEn then
-- Remove addon prefix
if msg:find("^%*hebChat addon%* ") then
_, msg = msg:match("^(%*hebChat addon%* )(.*)")
end
-- Remote guild chat (mobile appliaction)
-- Do not reverse INFORM whispers text if the author was not recognized as isMobile by the time the message was sent. Do not reverse links.
if isMobile and (hebChat.guildMemberMobileInform[author] or (event ~= "CHAT_MSG_WHISPER_INFORM" and event ~= "CHAT_MSG_BN_WHISPER_INFORM")) and not msg:find("|H.+|h") then
msg = utf8reverse(msg)
end
-- Calculate header widths
if (event == "CHAT_MSG_WHISPER" or event == "CHAT_MSG_BN_WHISPER") then
header1 = "["..author.."] whispers: "
header2 = "[55:55] [W From] ["..author.."]: "
elseif (event == "CHAT_MSG_WHISPER_INFORM" or event == "CHAT_MSG_BN_WHISPER_INFORM") then
header1 = "To ["..author.."]: "
header2 = "[55:55] [W To] ["..author.."]: "
elseif (event == "CHAT_MSG_GUILD") then
header1 = "[Guild] ["..author.."]: "
header2 = "[55:55] [G] ["..author.."]: "
elseif (event == "CHAT_MSG_OFFICER") then
header1 = "[Officer] ["..author.."]: "
header2 = "[55:55] [O] ["..author.."]: "
elseif (event == "CHAT_MSG_RAID") then
header1 = "[Raid] ["..author.."]: "
header2 = "[55:55] [R] ["..author.."]: "
elseif (event == "CHAT_MSG_RAID_LEADER") then
header1 = "[Raid Leader] ["..author.."]: "
header2 = "[55:55] [RL] ["..author.."]: "
elseif (event == "CHAT_MSG_PARTY") then
header1 = "[Party] ["..author.."]: "
header2 = "[55:55] [P] ["..author.."]: "
elseif (event == "CHAT_MSG_PARTY_LEADER") then
header1 = "[Party Leader] ["..author.."]: "
header2 = "[55:55] [PL] ["..author.."]: "
elseif (event == "CHAT_MSG_BN_CONVERSATION") then
header1 = "11. [Conversation] ["..author.."]: "
header2 = "[55:55] [Conversation] ["..author.."]: "
else
header1 = ""
header2 = ""
end
if Prat3DB or ChatterDB then
header = header2.."55:88:"
elseif ElvData then
header = header2
else
-- Default UI timestamps are enabled.
if CHAT_TIMESTAMP_FORMAT then
header1 = "55:55 "..header1
end
header = header1
end
-- hebChat.textWidthFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont][2], hebChatDB.currentFontSize)
hebChat.textWidthFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont], hebChatDB.currentFontSize)
hebChat.textWidthFrame.text:SetText(header)
headerWidth1 = hebChat.textWidthFrame.text:GetStringWidth()
hebChat.textWidthFrame.text:SetText("[2")
headerWidth2 = hebChat.textWidthFrame.text:GetStringWidth()
-- first line effective width
effectiveChatFrameWidth = chatFrameWidth - headerWidth1 - 10
-- Prepare for outer while loop
remainingString = msg
hebChat.textWidthFrame.text:SetText(remainingString)
while (hebChat.textWidthFrame.text:GetStringWidth() > effectiveChatFrameWidth) do
-- Prepare for inner while loop
hebChat.textWidthFrame.text:SetText(lineString)
while (hebChat.textWidthFrame.text:GetStringWidth() <= effectiveChatFrameWidth) or inLink do
-- Extract last char
currentChar = (utf8sub(remainingString, strlenutf8(remainingString), 1))
-- Check if inside link
if (currentChar == "|" and utf8sub(lineString, 1, 1) == "r" and not inLink) then
inLink = true
elseif (inLink and currentChar == "|" and utf8sub(lineString, 1, 1) == "c") then
inLink = false
end
-- Add current chat to line string
lineString = currentChar..lineString
remainingString = utf8sub(remainingString, 1, strlenutf8(remainingString) - 1)
-- Store current lineString between words and not in link and move last space to end of line
if (lineString:find("^%s") and not inLink) then
lineStringBkp = utf8sub(lineString, 2, strlenutf8(lineString) - 1)..utf8sub(lineString, 1, 1)
remainingStringBkp = remainingString
end
-- Prepare for next while loop check
hebChat.textWidthFrame.text:SetText(lineString)
end -- Inner while loop
-- out of inner while loop: lineString is wider than frame width
if (#lineStringBkp ~= 0) then
-- Add the bkp line, at word boundary
remainingString = remainingStringBkp
table.insert(hebChat.newStringTable, lineStringBkp.."\n")
else
-- Single word longer than width - just add the word
table.insert(hebChat.newStringTable, lineString)
end
-- Prepare for outer while loop
hebChat.textWidthFrame.text:SetText(remainingString)
-- non-first line effective width
effectiveChatFrameWidth = chatFrameWidth - headerWidth2 - 10
-- reset strings
lineStringBkp = ""
lineString = ""
end -- Outer while loop
table.insert (hebChat.newStringTable, remainingString)
newString = table.concat(hebChat.newStringTable)
return false, newString, author, ...
else
return false
end -- if (isHeb(msg))
end -- function hebChat.hebChatFixWrap
-----------
-- Hooking
-----------
-- Hook ChatEdit_OnTextChanged - convert to Hebrew when text in changed in chat editBox.
function hebChat:ChatEdit_OnTextChanged(userInput, ...)
if (ACTIVE_CHAT_EDIT_BOX and userInput and hebChat:checkLegitChatType(ACTIVE_CHAT_EDIT_BOX:GetAttribute("chatType")) and hebChatDB.globalEn) then
hebChat.text2Heb(ACTIVE_CHAT_EDIT_BOX)
end
return origChatEdit_OnTextChanged(self, userInput, ...)
end
-- Hook SendChatMessage - Post process text: add prefix, reverse Hebrew when whispering to mobile client
function hebChat.SendChatMessage(msg, chatType, lang, channel, ...)
if hebChatDB.globalEn and hebChat:checkLegitChatType(chatType) and isHeb(msg) then
-- Reverse message sent in whisper to mobile user.
if chatType == "WHISPER" and hebChat.guildMemberMobile[channel] then
-- Do not convert links
if not msg:find("|c.+|r") then
msg = utf8reverse(msg)
end
hebChat.guildMemberMobileInform[channel] = true
-- if target is not mobile whisper, and chat is whisper or guild, add prefix with info about the addon (for users that don't have it).
elseif (chatType == "WHISPER" or chatType == "GUILD") and msg:len() < 240 then
msg = "*hebChat addon* "..msg
end
end
return origSendChatMessage(msg, chatType, lang, channel, ...)
end
-- Hook BNSendWhisper - Post process text: add prefix
function hebChat.BNSendWhisper(presenceID, msg, ...)
if hebChatDB.globalEn and isHeb(msg) then
msg = "*hebChat addon* "..msg
end
return origBNSendWhisper(presenceID, msg, ...)
end
-- Hook ChatEdit_OnTabPressed - toggle language when ctrl-tab is hit
function hebChat:ChatEdit_OnTabPressed(...)
if IsControlKeyDown() then
hebChat:toggleLanguage();
else -- Switch whisper targets only if ctrl is not held down.
return origChatEdit_OnTabPressed(self, ...)
end
end
-- Hook ChatEdit_UpdateHeader - update bkp text when switching chat windows.
function hebChat:ChatEdit_UpdateHeader(...)
if (ACTIVE_CHAT_EDIT_BOX) then
hebChat.lastText = ACTIVE_CHAT_EDIT_BOX:GetText()
else
hebChat.lastText = ""
end
return origChatEdit_UpdateHeader(self, ...)
end
-- Hook FCF_OpenTemporaryWindow - set chat font when new chat window is created.
function hebChat.FCF_OpenTemporaryWindow(...)
hebChatDelayFrame:delay(0.1, hebChat.setChatFont)
return origFCF_OpenTemporaryWindow(...)
end
-- Hook WIM history viewer
function hebChat:ShowHistoryViewer(...)
origWIMShowHistoryViewer(...)
if (hebChat.fObjects[hebChatDB.currentFont]) then
WIM3_HistoryFrame.content.chatFrame:SetFontObject(hebChat.fObjects[hebChatDB.currentFont])
WIM3_HistoryFrame.content.textFrame.text:SetFontObject(hebChat.fObjects[hebChatDB.currentFont])
end
end