Thread Tools Display Modes
10-19-12, 03:38 PM   #21
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Phanx View Post
You should probably post your code.
I'm getting really tired of telling people this, to the point where I don't even enjoy helping people around here anymore... I just want to yell at them instead. How does anyone imagine people can help them figure out what is wrong with their code if nobody can see their code?
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-19-12, 03:46 PM   #22
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
I'm sorry for that, but what code should I post? My addon is 1000 lines of code, if I knew which part is relevant I would have posted it.
I have already posted the xml button code, but I don't even know if that's the problem. I have replaced my config code with Ace3 to get rid of the dropdownlist.
I would be very happy to understand what is the problem, but I don't even know were to look right now.
Thanks.
  Reply With Quote
10-19-12, 03:50 PM   #23
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Just post the whole thing. It's not like posting it means that anyone who sees your post is forced to read through all 1000 lines of code if they don't want to, and often it's simpler for someone to just load your addon in-game than to read through the code, but again, if you don't post the whole thing, nobody can load it in-game.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-19-12, 06:21 PM   #24
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
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.

My addon can be found here: http://www.wowinterface.com/download...6-hebChat.html

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.

Thanks

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
  Reply With Quote
10-19-12, 07:33 PM   #25
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
I'll look at it more in-depth when I'm not at work, but why are you copying/pasting functions out of the UTF8 lib instead of just including the UTF8 lib in your addon?
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-20-12, 01:45 AM   #26
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Hi, i really appreciate it that you're (and others here as well) helping me with that.

Initially, I took a utf8 snippet from wowprogramming.com, and modified it for my needs. At that time I wasn't aware of the lib. Then, recently, I've added a utf8 reverse function I took from that lib, and didn't change the others.
  Reply With Quote
10-22-12, 05:05 AM   #27
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
After further investigations, I have found out that the ArenaEnemyFrames and ArenaPrepFrames taints are also related to new whispers on new tab.

The whispers on new tab also causes the glyph UI error, which is blamed on many addons (even DBM).

I really don't know what is the connection between new whisper tabs and all these taints and errors.

Last edited by Animor : 10-22-12 at 06:25 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » A replacement for UIPanelButtonTemplate

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off