Version 0.2
- handle SendChatMessage ordering if addon Misspelled is also installed - break long texts in chunks of 255 length - debug flag and messages
This commit is contained in:
parent
6ff629284a
commit
418e6cf446
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,2 +1,23 @@
|
|||||||
# Grichelde
|
# Grichelde Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased] Version 1.0 - 2020-05-27
|
||||||
|
First version to be released
|
||||||
|
### Added
|
||||||
|
- slash commands
|
||||||
|
- Options GUI
|
||||||
|
- store settings globally or per character
|
||||||
|
- added translations
|
||||||
|
|
||||||
|
## Version 0.2 - 2020-05-25
|
||||||
|
### Added
|
||||||
|
- added debug flag and messages
|
||||||
|
### Fixed
|
||||||
|
- handle SendChatMessage ordering if addon Misspelled is also installed
|
||||||
|
- break long texts in chunks of 255 length
|
||||||
|
|
||||||
|
## Version 0.1 - 2020-05-24
|
||||||
|
### Added
|
||||||
|
- bootstrap addon with Ace3 from [Misspelled](https://www.curseforge.com/wow/addons/misspelled)
|
515
Grichelde.lua
515
Grichelde.lua
@ -1,13 +1,11 @@
|
|||||||
--[[--------------------------------------------------------------------------
|
--[[---------------------------------------------------------------------------
|
||||||
Grichelde
|
Grichelde
|
||||||
Copyright 2020 Teilzeit-Jedi <tj@teilzeit-jedi.de>
|
Copyright 2020 Teilzeit-Jedi <tj@teilzeit-jedi.de>
|
||||||
|
|
||||||
based on Misspelled developed by Nathan Pieper - nrpieper (@) gmail (dot) com
|
based on Misspelled developed by Nathan Pieper - nrpieper (@) gmail (dot) com
|
||||||
|
|
||||||
This code freely distributed for your use in any GPL compliant project.
|
This code freely distributed for your use in any GPL compliant project.
|
||||||
You may obtain a copy of the License at
|
See conditions in the LICENSE file attached.
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@ -17,107 +15,141 @@
|
|||||||
|
|
||||||
--------------------------------------------------------------------------]] --
|
--------------------------------------------------------------------------]] --
|
||||||
|
|
||||||
local Grichelde = {}
|
local AddonName, AddonTable = ...
|
||||||
Grichelde = LibStub("AceAddon-3.0"):NewAddon("Grichelde", "AceEvent-3.0", "AceHook-3.0")
|
|
||||||
Grichelde.Version = "0.1.0"
|
local Grichelde = LibStub("AceAddon-3.0"):NewAddon("Grichelde", "AceEvent-3.0", "AceHook-3.0")
|
||||||
|
Grichelde.version = GetAddOnMetadata(AddonName, "Version")
|
||||||
|
Grichelde.build = GetAddOnMetadata(AddonName, "X-Build") or "UNKNOWN"
|
||||||
|
|
||||||
local AceGUI = LibStub("AceGUI-3.0")
|
|
||||||
local L = LibStub("AceLocale-3.0"):GetLocale("Grichelde", true)
|
local L = LibStub("AceLocale-3.0"):GetLocale("Grichelde", true)
|
||||||
|
|
||||||
|
local Grichelde_Debug = false
|
||||||
|
|
||||||
-- faster function lookups by mapping to local refs
|
-- faster function lookups by mapping to local refs
|
||||||
local string_find = string.find
|
local string_find = string.find
|
||||||
local string_gsub = string.gsub
|
local string_gsub = string.gsub
|
||||||
local string_len = string.len
|
local string_len = string.len
|
||||||
local string_rep = string.rep
|
local string_rep = string.rep
|
||||||
local string_sub = string.sub
|
local string_sub = string.sub
|
||||||
local tostring = string.tostring
|
|
||||||
local tContains = tContains
|
|
||||||
local strtrim = strtrim
|
local strtrim = strtrim
|
||||||
local pairs = table.pairs
|
local strmatch = strmatch
|
||||||
local ipairs = table.ipairs
|
local tostring = tostring
|
||||||
|
local tInsert = table.insert
|
||||||
|
local tContains = tContains
|
||||||
|
local pairs = pairs
|
||||||
|
local ipairs = ipairs
|
||||||
|
|
||||||
local Grichelde_Saved_CTL_SendChatMessage
|
local Grichelde_Hooks = {}
|
||||||
local Grichelde_CTL_hookedversion = 0
|
|
||||||
|
|
||||||
local Grichelde_ChatTypes = { "SAY", "EMOTE", "YELL", "PARTY", "GUILD", "OFFICER", "RAID", "RAID_WARNING", "INSTANCE_CHAT", "BATTLEGROUND", "WHISPER" }
|
--local Grichelde_ChatTypes = { "SAY", "EMOTE", "YELL", "PARTY", "GUILD", "OFFICER", "RAID", "RAID_WARNING", "INSTANCE_CHAT", "BATTLEGROUND", "WHISPER" }
|
||||||
|
local Grichelde_ChatTypes = { "SAY", "EMOTE", "YELL", "PARTY", "GUILD" }
|
||||||
local Grichelde_ChatCommands = { "/s", "/e", "/me", "/y", "/p", "/pl", "/g", "/o", "/raid", "/rl", "/rw", "/i", "bg", "/w", "/r", "/tt" }
|
local Grichelde_ChatCommands = { "/s", "/e", "/me", "/y", "/p", "/pl", "/g", "/o", "/raid", "/rl", "/rw", "/i", "bg", "/w", "/r", "/tt" }
|
||||||
|
|
||||||
-- do not replace these patterns
|
-- do not replace these patterns
|
||||||
local Grichelde_IgnorePatterns = {
|
local Grichelde_IgnorePatterns = {
|
||||||
"|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links)
|
"|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links)
|
||||||
"|H.-|h", -- item links (http://www.wowwiki.com/ItemLink)
|
"|H.-|h", -- item links (http://www.wowwiki.com/ItemLink)
|
||||||
"|T.-|t", -- textures
|
"|T.-|t", -- textures
|
||||||
"|n", -- newline
|
"|n", -- newline
|
||||||
"{rt[1-8]}", -- rumbered raid target icons
|
"{rt[1-8]}", -- rumbered raid target icons
|
||||||
"{Star}", -- named raid target icon 1
|
"{Star}", -- named raid target icon 1
|
||||||
"{Circle}", -- named raid target icon 2
|
"{Circle}", -- named raid target icon 2
|
||||||
"{Coin}", -- named raid target icon 2
|
"{Coin}", -- named raid target icon 2
|
||||||
"{Diamond}", -- named raid target icon 3
|
"{Diamond}", -- named raid target icon 3
|
||||||
"{Triangle}", -- named raid target icon 4
|
"{Triangle}", -- named raid target icon 4
|
||||||
"{Moon}", -- named raid target icon 5
|
"{Moon}", -- named raid target icon 5
|
||||||
"{Square}", -- named raid target icon 6
|
"{Square}", -- named raid target icon 6
|
||||||
"{Cross}", -- named raid target icon 7
|
"{Cross}", -- named raid target icon 7
|
||||||
"{X}", -- named raid target icon 7
|
"{X}", -- named raid target icon 7
|
||||||
"{Skull}" -- named raid target icon 8
|
"{Skull}" -- named raid target icon 8
|
||||||
}
|
}
|
||||||
|
|
||||||
function Grichelde:OnInitialize()
|
function Grichelde:OnInitialize()
|
||||||
-- print("Grichelde was loaded")
|
|
||||||
|
|
||||||
-- Build Interface Options window
|
-- Build Interface Options window
|
||||||
self:CreateInterfaceOptions()
|
--self:CreateInterfaceOptions()
|
||||||
|
|
||||||
-- Watch for WIM and Prat to Load, then integrate
|
-- Watch for WIM and Prat to Load, then integrate
|
||||||
Grichelde:RegisterEvent("ADDON_LOADED")
|
self:RegisterEvent("ADDON_LOADED", "HookIntoForOtherChatAddons")
|
||||||
|
end
|
||||||
|
|
||||||
-- hooks for removing any misspelled word highlighting in the text before the chat message is sent
|
function Grichelde:OnEnable()
|
||||||
-- The WoW client will disconnect if you attempt to send a color tags in a chat message.
|
-- Hook in before message is sent to replace all character occurrences where replacements have been defined in the options
|
||||||
Grichelde:RawHook("SendChatMessage", true)
|
self:RawHook("SendChatMessage", true)
|
||||||
|
|
||||||
|
if (Misspelled) then
|
||||||
|
print("Misspelled detected, Grichelde will have any messsage being cleansed")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- tell the world we are listening
|
||||||
|
print(L.AddonLoaded)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grichelde:OnDisable()
|
||||||
|
self:Unhook("SendChatMessage")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param event string
|
--- @param event string
|
||||||
--- @param addonName string
|
--- @param addonName string
|
||||||
function Grichelde:ADDON_LOADED(event, addonName)
|
function Grichelde:HookIntoForOtherChatAddons(event, addonName)
|
||||||
if event == "ADDON_LOADED" and addonName == "WIM" then
|
if event == "ADDON_LOADED" then
|
||||||
WIM.RegisterWidgetTrigger("msg_box", "whisper,chat,w2w", "OnEnterPressed", Grichelde.EditBox_OnEnterPressed)
|
if addonName == "WIM" then
|
||||||
|
WIM.RegisterWidgetTrigger("msg_box", "whisper,chat,w2w", "OnEnterPressed", Grichelde.EditBox_OnEnterPressed)
|
||||||
|
|
||||||
-- WIM sends its chat messages via the API ChatThrottleLib, which itself hooks the default SendChatMessage api
|
-- If available use the WIM API
|
||||||
-- many times before Grichelde will. ChatThrottleLib might potentially load before Grichelde, so we just hook
|
if (WIM.RegisterPreSendFilterText) then -- avoid error if WIM not up to date.
|
||||||
-- into ChatThrottleLib to be on the safe side.
|
WIM.RegisterPreSendFilterText(function(text)
|
||||||
|
return Grichelde:CheckAndReplace(text)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
-- WIM sends its chat messages via the API ChatThrottleLib, which itself hooks the default SendChatMessage api
|
||||||
|
-- many times before Grichelde will. ChatThrottleLib might potentially load before Grichelde, so we just hook
|
||||||
|
-- into ChatThrottleLib to be on the safe side.
|
||||||
|
|
||||||
if (WIM.RegisterPreSendFilterText) then -- avoid error if WIM not up to date.
|
if (ChatThrottleLib) then
|
||||||
WIM.RegisterPreSendFilterText(function(text)
|
Grichelde_Hooks["ChatThrottleLib"] = ChatThrottleLib.SendChatMessage
|
||||||
return Grichelde:ReplaceText(text)
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
if (ChatThrottleLib and Grichelde_CTL_hookedversion < ChatThrottleLib.version) then
|
|
||||||
Grichelde_Saved_CTL_SendChatMessage = ChatThrottleLib.SendChatMessage
|
|
||||||
|
|
||||||
function ChatThrottleLib:SendChatMessage(prio, prefix, text, ...)
|
function ChatThrottleLib:SendChatMessage(prio, prefix, text, ...)
|
||||||
text = Grichelde:ReplaceText(text)
|
Grichelde:DebugPrint("ChatThrottleLib:SendChatMessage : Hook called")
|
||||||
-- print("Grichelde Hooked ChatThrottleLib_SendChatMessaged called")
|
local replacedText = Grichelde:CheckAndReplace(text)
|
||||||
return Grichelde_Saved_CTL_SendChatMessage(ChatThrottleLib, prio, prefix, text, ...)
|
return Grichelde_Hooks["ChatThrottleLib"](ChatThrottleLib, prio, prefix, replacedText, ...)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Grichelde_CTL_hookedversion = ChatThrottleLib.version
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Before a chat message is sent, check if replacement is required and replace the text accordingly.
|
--- Before af chat message is sent, check if replacement is required and replace the text accordingly.
|
||||||
--- @param message string
|
--- @param message string
|
||||||
--- @param type string
|
--- @param type string
|
||||||
--- @param language string
|
--- @param language string
|
||||||
--- @param channel string
|
--- @param channel string
|
||||||
function Grichelde:SendChatMessage(message, type, language, channel, ...)
|
function Grichelde:SendChatMessage(message, type, language, channel, ...)
|
||||||
local text = strtrim(message)
|
local replacedText = self:CheckAndReplace(message, type)
|
||||||
|
|
||||||
if (Grichelde:CheckReplacement(message, type)) then
|
self:DebugPrint("SendChatMessage : replacedText: " .. replacedText)
|
||||||
text = Grichelde:ReplaceText(text)
|
|
||||||
|
-- Send text in chunks if length exceeds 255 bytes after replacement
|
||||||
|
local chunks = self:SplitText(replacedText)
|
||||||
|
self:DebugPrint("SendChatMessage : #chunks: " .. #chunks)
|
||||||
|
|
||||||
|
for _, chunk in ipairs(chunks) do
|
||||||
|
self.hooks["SendChatMessage"](chunk, type, language, channel, ...);
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self.hooks["SendChatMessage"](text, type, language, channel, ...);
|
function Grichelde:CheckAndReplace(message, type)
|
||||||
|
local text = message
|
||||||
|
if (Misspelled) then
|
||||||
|
self:DebugPrint("Misspelled detected: cleansing message")
|
||||||
|
text = Misspelled:RemoveHighlighting(text)
|
||||||
|
end
|
||||||
|
text = strtrim(text)
|
||||||
|
|
||||||
|
if (self:CheckReplacement(text, type)) then
|
||||||
|
text = self:ReplaceText(text)
|
||||||
|
end
|
||||||
|
return text
|
||||||
end
|
end
|
||||||
|
|
||||||
function Grichelde:CheckReplacement(text, type)
|
function Grichelde:CheckReplacement(text, type)
|
||||||
@ -125,20 +157,41 @@ function Grichelde:CheckReplacement(text, type)
|
|||||||
|
|
||||||
-- check type
|
-- check type
|
||||||
if (not tContains(Grichelde_ChatTypes, type)) then
|
if (not tContains(Grichelde_ChatTypes, type)) then
|
||||||
|
self:DebugPrint("CheckReplacement : skip channel type")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- don't replace slash commands except chat related commands
|
-- don't replace slash commands except chat related commands
|
||||||
if string_sub(text, 1, 1) == "/" then
|
if string_sub(text, 1, 1) == "/" then
|
||||||
local firstWord, _ = Grichelde:GetNextWord(text)
|
local firstWord, _ = self:SplitOnFirstMatch(text)
|
||||||
if (firstWord == nil or not tContains(Grichelde_ChatCommands, firstWord)) then
|
if (firstWord == nil or not tContains(Grichelde_ChatCommands, firstWord)) then
|
||||||
|
self:DebugPrint("CheckReplacement : ignore slash command")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- in any other case
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures or raid target icons
|
||||||
|
--- and returns the end location of the match, or 0 if no pattern was found
|
||||||
|
--- @param text string
|
||||||
|
--- @return number
|
||||||
|
function Grichelde:CheckForPreversableText(text)
|
||||||
|
self:DebugPrint("CheckForPreversableText : text is " .. text)
|
||||||
|
-- Calling find on ever pattern might be inefficient but its way less code.
|
||||||
|
for _, pattern in ipairs(Grichelde_IgnorePatterns) do
|
||||||
|
local pos1, pos2 = string_find(text, pattern)
|
||||||
|
if pos1 == 1 and pos2 ~= nil then
|
||||||
|
self:DebugPrint("CheckForPreversableText : Found ignore pattern " .. pattern .. " at (" .. pos1 .. "," .. pos2 .. ")")
|
||||||
|
return pos2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:DebugPrint("CheckForPreversableText : no ignore pattern found")
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
--- Replaces all character occurrences for which replacements have been defined in the options,
|
--- Replaces all character occurrences for which replacements have been defined in the options,
|
||||||
--- while preserving any itemLinks or textures. (http://www.wowwiki.com/ItemLink)
|
--- while preserving any itemLinks or textures. (http://www.wowwiki.com/ItemLink)
|
||||||
--- @param text string
|
--- @param text string
|
||||||
@ -148,8 +201,9 @@ function Grichelde:ReplaceText(text)
|
|||||||
local newText = text
|
local newText = text
|
||||||
|
|
||||||
-- don't replace non-chat related slash commands
|
-- don't replace non-chat related slash commands
|
||||||
local firstWord, line = Grichelde:GetNextWord(text)
|
local firstWord, line = self:SplitOnFirstMatch(text)
|
||||||
if (tContains(Grichelde_ChatCommands, firstWord)) then
|
if (firstWord ~= nil and tContains(Grichelde_ChatCommands, firstWord)) then
|
||||||
|
self:DebugPrint("ReplaceText : Found slash command " .. (firstWord + "") )
|
||||||
-- skip chat slash command
|
-- skip chat slash command
|
||||||
finalText = finalText .. firstWord .. ' '
|
finalText = finalText .. firstWord .. ' '
|
||||||
newText = line
|
newText = line
|
||||||
@ -158,22 +212,28 @@ function Grichelde:ReplaceText(text)
|
|||||||
local current = 1
|
local current = 1
|
||||||
local lastStart = 1
|
local lastStart = 1
|
||||||
|
|
||||||
while current < string_len(newText) do
|
while current <= string_len(newText) do
|
||||||
local currentChar = string_sub(newText, current, current)
|
local currentChar = string_sub(newText, current, current)
|
||||||
|
self:DebugPrint("current/char : " .. current .. "," .. currentChar)
|
||||||
|
|
||||||
if currentChar ~= '|' and currentChar ~= '{' then
|
if currentChar ~= '|' and currentChar ~= '{' then
|
||||||
current = current + 1
|
current = current + 1
|
||||||
else
|
else
|
||||||
|
|
||||||
-- lookahead-check for itemLinks, textures and raid target icons
|
-- lookahead-check for itemLinks, textures and raid target icons
|
||||||
local textAhead = string_sub(newText, current)
|
local textAhead = string_sub(newText, current)
|
||||||
local posEnd = Grichelde:CheckForPreversableText(textAhead)
|
local posEnd = self:CheckForPreversableText(textAhead)
|
||||||
if posEnd > 0 then
|
if posEnd > 0 then
|
||||||
|
self:DebugPrint("ReplaceText : Found an ignore pattern")
|
||||||
|
|
||||||
local textBehind = string_sub(newText, lastStart, current - 1)
|
local textBehind = string_sub(newText, lastStart, current - 1)
|
||||||
local replacement = Grichelde:ReplaceCharacters(textBehind)
|
local replacement = self:ReplaceCharacters(textBehind)
|
||||||
local preservedText = string_sub(textAhead, 1, posEnd)
|
local preservedText = string_sub(textAhead, 1, posEnd)
|
||||||
|
|
||||||
finalText = finalText .. replacement .. preservedText
|
finalText = finalText .. replacement .. preservedText
|
||||||
current = current + posEnd
|
current = current + posEnd
|
||||||
lastStart = current
|
lastStart = current
|
||||||
|
self:DebugPrint("ReplaceText : restarting at " .. lastStart)
|
||||||
else
|
else
|
||||||
-- no corresponding end was found to start pattern, continue loop with next char
|
-- no corresponding end was found to start pattern, continue loop with next char
|
||||||
current = current + 1
|
current = current + 1
|
||||||
@ -181,29 +241,14 @@ function Grichelde:ReplaceText(text)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- cleanup to the end
|
-- cleanup remaining text to the end
|
||||||
local remainingText = newText
|
local remainingText = string_sub(newText, lastStart)
|
||||||
if lastStart ~= 1 then
|
local replacement = self:ReplaceCharacters(remainingText)
|
||||||
remainingText = string_sub(newText, lastStart)
|
|
||||||
end
|
|
||||||
|
|
||||||
local replacement = Grichelde:ReplaceCharacters(remainingText)
|
|
||||||
finalText = finalText .. replacement
|
finalText = finalText .. replacement
|
||||||
return finalText
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures or raid target icons
|
self:DebugPrint("ReplaceText : replaced \"" .. text .. "\"")
|
||||||
--- @param text string
|
self:DebugPrint("ReplaceText : with \"" .. finalText .. "\"")
|
||||||
--- @return number
|
return finalText
|
||||||
function Grichelde:CheckForPreversableText(text)
|
|
||||||
-- Calling find on ever pattern might be inefficient but its way less code.
|
|
||||||
for _, pattern in ipairs(Grichelde_IgnorePatterns) do
|
|
||||||
local pos1, pos2 = string_find(text, pattern)
|
|
||||||
if pos1 == 1 and pos2 ~= nil then
|
|
||||||
return pos2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Replaces all character occurrences for which replacements have been defined in the options
|
--- Replaces all character occurrences for which replacements have been defined in the options
|
||||||
@ -217,258 +262,82 @@ function Grichelde:ReplaceCharacters(text)
|
|||||||
replacement = string_gsub(replacement, "S", "Ch")
|
replacement = string_gsub(replacement, "S", "Ch")
|
||||||
replacement = string_gsub(replacement, "t", "k")
|
replacement = string_gsub(replacement, "t", "k")
|
||||||
replacement = string_gsub(replacement, "T", "K")
|
replacement = string_gsub(replacement, "T", "K")
|
||||||
|
self:DebugPrint("ReplaceCharacters : replaced \"" .. text .. "\" with \"" .. replacement .. "\"")
|
||||||
return replacement
|
return replacement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Splits a long text in longest possible chunks of <= 255 length, split at last available space
|
||||||
|
--- @param text string
|
||||||
|
--- @return table
|
||||||
|
function Grichelde:SplitText(text)
|
||||||
|
local chunks = {}
|
||||||
|
local splitText = text
|
||||||
|
local textSize = string_len(splitText)
|
||||||
|
|
||||||
--[[ Interface Options Window ]] --
|
while textSize > 255 do
|
||||||
function Grichelde:CreateInterfaceOptions()
|
local chunk = string_sub(splitText, 1, 255)
|
||||||
local cfgFrame = CreateFrame("FRAME", nil, UIParent)
|
local remaining = ""
|
||||||
cfgFrame.name = "Grichelde"
|
|
||||||
|
|
||||||
local cfgFrameHeader = cfgFrame:CreateFontString("OVERLAY", nil, "GameFontNormalLarge")
|
-- special case: if space is the start of the next chunk, don't split this chunk
|
||||||
cfgFrameHeader:SetPoint("TOPLEFT", 15, -15)
|
if string_sub(splitText, 256, 256) ~= ' ' then
|
||||||
cfgFrameHeader:SetText(self.Version)
|
-- split at last space, don't assign directly as nil might be returned
|
||||||
|
local left, right = self:SplitOnLastMatch(chunk)
|
||||||
local cfgAutoSelectDict = CreateFrame("CHECKBUTTON", "Misspelled_cfgAutoSelectDict", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
if left ~= nil then
|
||||||
Misspelled_cfgAutoSelectDict:SetPoint("TOPLEFT", 20, -40)
|
chunk = left
|
||||||
Misspelled_cfgAutoSelectDictText:SetText(L["Auto Select Dictionary to Load"])
|
end
|
||||||
Misspelled_cfgAutoSelectDict:SetChecked(Misspelled_DB.AutoSelectDictionary)
|
if right ~= nil then
|
||||||
Misspelled_cfgAutoSelectDict:SetScript("OnClick", function(self)
|
remaining = right
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
Misspelled_DB.AutoSelectDictionary = not Misspelled_DB.AutoSelectDictionary
|
|
||||||
--Toggle the sub options
|
|
||||||
if Misspelled_DB.AutoSelectDictionary == true then
|
|
||||||
Misspelled_cfgDictdeDE:Disable()
|
|
||||||
Misspelled_cfgDictenGB:Disable()
|
|
||||||
Misspelled_cfgDictenUS:Disable()
|
|
||||||
Misspelled_cfgDictesES:Disable()
|
|
||||||
Misspelled_cfgDictfrFR:Disable()
|
|
||||||
Misspelled_cfgDictruRU:Disable()
|
|
||||||
Misspelled_cfgDictitIT:Disable()
|
|
||||||
else
|
|
||||||
Misspelled_cfgDictdeDE:Enable()
|
|
||||||
Misspelled_cfgDictenGB:Enable()
|
|
||||||
Misspelled_cfgDictenUS:Enable()
|
|
||||||
Misspelled_cfgDictesES:Enable()
|
|
||||||
Misspelled_cfgDictfrFR:Enable()
|
|
||||||
Misspelled_cfgDictruRU:Enable()
|
|
||||||
Misspelled_cfgDictitIT:Enable()
|
|
||||||
if Misspelled_DB.LoadDictionary == nil or #Misspelled_DB.LoadDictionary == 0 then
|
|
||||||
Misspelled_DB.LoadDictionary = "enUS"
|
|
||||||
Misspelled_cfgDictenUS:setChecked(true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictdeDE = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictdeDE", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
self:DebugPrint("SplitText : chunk: " .. chunk )
|
||||||
Misspelled_cfgDictdeDE:SetPoint("TOPLEFT", 40, -64)
|
|
||||||
Misspelled_cfgDictdeDEText:SetText("deDE")
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(Misspelled_DB.LoadDictionary == "deDE")
|
|
||||||
Misspelled_cfgDictdeDE:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "deDE"
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictenGB = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictenGB", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
tInsert(chunks, chunk)
|
||||||
Misspelled_cfgDictenGB:SetPoint("TOPLEFT", 40, -88)
|
splitText = remaining .. string_sub(splitText, 256)
|
||||||
Misspelled_cfgDictenGBText:SetText("enGB")
|
textSize = string_len(splitText)
|
||||||
Misspelled_cfgDictenGB:SetChecked(Misspelled_DB.LoadDictionary == "enGB")
|
|
||||||
Misspelled_cfgDictenGB:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "enGB"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictenUS = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictenUS", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
|
||||||
Misspelled_cfgDictenUS:SetPoint("TOPLEFT", 40, -112)
|
|
||||||
Misspelled_cfgDictenUSText:SetText("enUS")
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(Misspelled_DB.LoadDictionary == "enUS")
|
|
||||||
Misspelled_cfgDictenUS:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "enUS"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictesES = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictesES", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
|
||||||
Misspelled_cfgDictesES:SetPoint("TOPLEFT", 40, -136)
|
|
||||||
Misspelled_cfgDictesESText:SetText("esES")
|
|
||||||
Misspelled_cfgDictesES:SetChecked(Misspelled_DB.LoadDictionary == "esES")
|
|
||||||
Misspelled_cfgDictesES:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "esES"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictfrFR = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictfrFR", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
|
||||||
Misspelled_cfgDictfrFR:SetPoint("TOPLEFT", 40, -160)
|
|
||||||
Misspelled_cfgDictfrFRText:SetText("frFR")
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(Misspelled_DB.LoadDictionary == "frFR")
|
|
||||||
Misspelled_cfgDictfrFR:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "frFR"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictruRU = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictruRU", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
|
||||||
Misspelled_cfgDictruRU:SetPoint("TOPLEFT", 40, -184)
|
|
||||||
Misspelled_cfgDictruRUText:SetText("ruRU")
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(Misspelled_DB.LoadDictionary == "ruRU")
|
|
||||||
Misspelled_cfgDictruRU:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "ruRU"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local cfgDictitIT = CreateFrame("CHECKBUTTON", "Misspelled_cfgDictitIT", cfgFrame, "InterfaceOptionsCheckButtonTemplate")
|
|
||||||
Misspelled_cfgDictitIT:SetPoint("TOPLEFT", 40, -208)
|
|
||||||
Misspelled_cfgDictitITText:SetText("itIT")
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(Misspelled_DB.LoadDictionary == "itIT")
|
|
||||||
Misspelled_cfgDictitIT:SetScript("OnClick", function(self)
|
|
||||||
if self:GetChecked() then
|
|
||||||
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
|
|
||||||
Misspelled_DB.LoadDictionary = "itIT"
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
else
|
|
||||||
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--Edit User Dictionary Button
|
|
||||||
local cfgEditUserDict = CreateFrame("Button", "EdutUserDictButton", cfgFrame, "UIPanelButtonTemplate")
|
|
||||||
cfgEditUserDict:SetPoint("TOPLEFT", 20, -287)
|
|
||||||
cfgEditUserDict:SetText(L["Edit User Dictionary..."])
|
|
||||||
cfgEditUserDict:SetWidth(200)
|
|
||||||
cfgEditUserDict:SetHeight(24)
|
|
||||||
cfgEditUserDict:SetScript("OnClick", function(self)
|
|
||||||
--PlaySound("igMainMenuOptionCheckBoxOn")
|
|
||||||
Misspelled:EditUserDict()
|
|
||||||
end)
|
|
||||||
|
|
||||||
--set options on startup
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(false)
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(false)
|
|
||||||
Misspelled_cfgDictesES:SetChecked(false)
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(false)
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(false)
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(false)
|
|
||||||
|
|
||||||
if Misspelled_DB.LoadDictionary == "deDE" then
|
|
||||||
Misspelled_cfgDictdeDE:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "enGB" then
|
|
||||||
Misspelled_cfgDictenGB:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "enUS" then
|
|
||||||
Misspelled_cfgDictenUS:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "esES" then
|
|
||||||
Misspelled_cfgDictesES:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "frFR" then
|
|
||||||
Misspelled_cfgDictfrFR:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "ruRU" then
|
|
||||||
Misspelled_cfgDictruRU:SetChecked(true)
|
|
||||||
elseif Misspelled_DB.LoadDictionary == "itIT" then
|
|
||||||
Misspelled_cfgDictitIT:SetChecked(true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if Misspelled_DB.AutoSelectDictionary == true then
|
-- pickup remaining text < 255
|
||||||
Misspelled_cfgDictdeDE:Disable()
|
self:DebugPrint("SplitText : last chunk: " .. splitText)
|
||||||
Misspelled_cfgDictenGB:Disable()
|
tInsert(chunks, splitText)
|
||||||
Misspelled_cfgDictenUS:Disable()
|
|
||||||
Misspelled_cfgDictesES:Disable()
|
|
||||||
Misspelled_cfgDictfrFR:Disable()
|
|
||||||
Misspelled_cfgDictruRU:Disable()
|
|
||||||
Misspelled_cfgDictitIT:Disable()
|
|
||||||
else
|
|
||||||
Misspelled_cfgDictdeDE:Enable()
|
|
||||||
Misspelled_cfgDictenGB:Enable()
|
|
||||||
Misspelled_cfgDictenUS:Enable()
|
|
||||||
Misspelled_cfgDictesES:Enable()
|
|
||||||
Misspelled_cfgDictfrFR:Enable()
|
|
||||||
Misspelled_cfgDictruRU:Enable()
|
|
||||||
Misspelled_cfgDictitIT:Enable()
|
|
||||||
end
|
|
||||||
|
|
||||||
InterfaceOptions_AddCategory(cfgFrame)
|
return chunks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- split first word of a text line
|
-- split first word of a text line
|
||||||
function Grichelde:GetNextWord(line)
|
function Grichelde:SplitOnFirstMatch(text, start)
|
||||||
-- need to add a trailing separator to catch the last value.
|
self:DebugPrint("SplitOnFirstMatch : text: " .. text .. ", start: " .. self:EmptyIfNil(start))
|
||||||
local wordPattern = "[%s%c]*(%w+)[%s%c]*"
|
local pos = 1
|
||||||
local s, e = string_find(line, wordPattern)
|
if start ~= nil then pos = start end
|
||||||
local word = string_sub(line, s, e)
|
local left, right = strmatch(text, "^.- .+", pos)
|
||||||
local rest = string_sub(line, e)
|
self:DebugPrint("SplitOnFirstMatch : left: " .. self:EmptyIfNil(left) .. ", right: " .. self:EmptyIfNil(right))
|
||||||
return word, rest
|
return left, right
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grichelde:SplitOnLastMatch(text, start)
|
||||||
|
self:DebugPrint("SplitOnLastMatch : text: " .. text .. ", start: " .. self:EmptyIfNil(start))
|
||||||
|
local pos = 1
|
||||||
|
if start ~= nil then pos = start end
|
||||||
|
local left, right = strmatch(text, ".+ .-$", pos)
|
||||||
|
self:DebugPrint("SplitOnLastMatch : left: " .. self:EmptyIfNil(left) .. ", right: " .. self:EmptyIfNil(right))
|
||||||
|
return left, right
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grichelde:DebugPrint(message)
|
||||||
|
if (Grichelde_Debug) then
|
||||||
|
print(GRAY_FONT_COLOR_CODE .. "Grichelde:" .. FONT_COLOR_CODE_CLOSE .. " " .. message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grichelde:EmptyIfNil(value)
|
||||||
|
if value == nil then return "" end
|
||||||
|
return tostring(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Grichelde:tprint(t, indent, done)
|
function Grichelde:tprint(t, indent, done)
|
||||||
-- in case we run it standalone
|
-- in case we run it standalone
|
||||||
local Note = Note or print
|
local Note = Note or print
|
||||||
|
-- local Tell = Tell or io.write
|
||||||
|
|
||||||
-- show strings differently to distinguish them from numbers
|
-- show strings differently to distinguish them from numbers
|
||||||
local function show(val)
|
local function show(val)
|
||||||
@ -487,14 +356,10 @@ function Grichelde:tprint(t, indent, done)
|
|||||||
if type(value) == "table" and not done[value] then
|
if type(value) == "table" and not done[value] then
|
||||||
done[value] = true
|
done[value] = true
|
||||||
Note(show(key), ":");
|
Note(show(key), ":");
|
||||||
Grichelde:tprint(value, indent + 2, done)
|
self:tprint(value, indent + 2, done)
|
||||||
else
|
else
|
||||||
print(show(key), "=")
|
print(show(key), "=")
|
||||||
print(show(value))
|
print(show(value))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Grichelde:print(...)
|
|
||||||
SELECTED_DOCK_FRAME:AddMessage(...)
|
|
||||||
end
|
|
@ -11,7 +11,9 @@
|
|||||||
## X-Curse-Project-ID: 385480
|
## X-Curse-Project-ID: 385480
|
||||||
## X-Category: Chat/Communication
|
## X-Category: Chat/Communication
|
||||||
## X-Credits: Teilzeit-Jedi, Nathan Pieper
|
## X-Credits: Teilzeit-Jedi, Nathan Pieper
|
||||||
|
## X-Embeds: Ace3
|
||||||
|
|
||||||
|
## OptionalDeps: Ace3
|
||||||
## SavedVariables: GrichseldeOptions
|
## SavedVariables: GrichseldeOptions
|
||||||
## SavedVariablesPerCharacter: GrichseldeCharOptions
|
## SavedVariablesPerCharacter: GrichseldeCharOptions
|
||||||
|
|
||||||
|
11
README.md
11
README.md
@ -1,2 +1,11 @@
|
|||||||
# Grichelde
|
# Grichelde - Text replacer
|
||||||
|
|
||||||
|
Grichelde replaces characters you entered in a chatbox with any replacment text you specified in the addon options.
|
||||||
|
|
||||||
|
Intentionally started as a helper addon for a roleplaying friend, Grichelde can be used for much more, like
|
||||||
|
* fixing your common spelling errors :)
|
||||||
|
* replacing toon names with their nick names
|
||||||
|
* write out abbreviations for you
|
||||||
|
* create hilarious moments during roleplay
|
||||||
|
|
||||||
|
<!-- Did you ever had an Undead without a jaw and wondered how it might sound like if s/he'd actually speak? -->
|
||||||
|
1
libs.xml
1
libs.xml
@ -4,6 +4,7 @@
|
|||||||
<Script file="libs\LibStub\LibStub.lua"/>
|
<Script file="libs\LibStub\LibStub.lua"/>
|
||||||
<Include file="libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
|
<Include file="libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
|
||||||
<Include file="libs\AceAddon-3.0\AceAddon-3.0.xml"/>
|
<Include file="libs\AceAddon-3.0\AceAddon-3.0.xml"/>
|
||||||
|
<Include file="libs\AceConsole-3.0\AceConsole-3.0.xml"/>
|
||||||
<Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/>
|
<Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/>
|
||||||
<Include file="libs\AceEvent-3.0\AceEvent-3.0.xml" />
|
<Include file="libs\AceEvent-3.0\AceEvent-3.0.xml" />
|
||||||
<Include file="libs\AceLocale-3.0\AceLocale-3.0.xml" />
|
<Include file="libs\AceLocale-3.0\AceLocale-3.0.xml" />
|
||||||
|
250
libs/AceConsole-3.0/AceConsole-3.0.lua
Normal file
250
libs/AceConsole-3.0/AceConsole-3.0.lua
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
--- **AceConsole-3.0** provides registration facilities for slash commands.
|
||||||
|
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
|
||||||
|
-- to your addons individual needs.
|
||||||
|
--
|
||||||
|
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
|
||||||
|
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||||
|
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
|
||||||
|
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
|
||||||
|
-- make into AceConsole.
|
||||||
|
-- @class file
|
||||||
|
-- @name AceConsole-3.0
|
||||||
|
-- @release $Id: AceConsole-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
|
||||||
|
local MAJOR,MINOR = "AceConsole-3.0", 7
|
||||||
|
|
||||||
|
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
|
if not AceConsole then return end -- No upgrade needed
|
||||||
|
|
||||||
|
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
|
||||||
|
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
|
||||||
|
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
|
||||||
|
|
||||||
|
-- Lua APIs
|
||||||
|
local tconcat, tostring, select = table.concat, tostring, select
|
||||||
|
local type, pairs, error = type, pairs, error
|
||||||
|
local format, strfind, strsub = string.format, string.find, string.sub
|
||||||
|
local max = math.max
|
||||||
|
|
||||||
|
-- WoW APIs
|
||||||
|
local _G = _G
|
||||||
|
|
||||||
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
|
-- List them here for Mikk's FindGlobals script
|
||||||
|
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
|
||||||
|
|
||||||
|
local tmp={}
|
||||||
|
local function Print(self,frame,...)
|
||||||
|
local n=0
|
||||||
|
if self ~= AceConsole then
|
||||||
|
n=n+1
|
||||||
|
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
|
||||||
|
end
|
||||||
|
for i=1, select("#", ...) do
|
||||||
|
n=n+1
|
||||||
|
tmp[n] = tostring(select(i, ...))
|
||||||
|
end
|
||||||
|
frame:AddMessage( tconcat(tmp," ",1,n) )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||||
|
-- @paramsig [chatframe ,] ...
|
||||||
|
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
||||||
|
-- @param ... List of any values to be printed
|
||||||
|
function AceConsole:Print(...)
|
||||||
|
local frame = ...
|
||||||
|
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||||
|
return Print(self, frame, select(2,...))
|
||||||
|
else
|
||||||
|
return Print(self, DEFAULT_CHAT_FRAME, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||||
|
-- @paramsig [chatframe ,] "format"[, ...]
|
||||||
|
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
||||||
|
-- @param format Format string - same syntax as standard Lua format()
|
||||||
|
-- @param ... Arguments to the format string
|
||||||
|
function AceConsole:Printf(...)
|
||||||
|
local frame = ...
|
||||||
|
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||||
|
return Print(self, frame, format(select(2,...)))
|
||||||
|
else
|
||||||
|
return Print(self, DEFAULT_CHAT_FRAME, format(...))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Register a simple chat command
|
||||||
|
-- @param command Chat command to be registered WITHOUT leading "/"
|
||||||
|
-- @param func Function to call when the slash command is being used (funcref or methodname)
|
||||||
|
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
|
||||||
|
function AceConsole:RegisterChatCommand( command, func, persist )
|
||||||
|
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
|
||||||
|
|
||||||
|
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
|
||||||
|
|
||||||
|
local name = "ACECONSOLE_"..command:upper()
|
||||||
|
|
||||||
|
if type( func ) == "string" then
|
||||||
|
SlashCmdList[name] = function(input, editBox)
|
||||||
|
self[func](self, input, editBox)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
SlashCmdList[name] = func
|
||||||
|
end
|
||||||
|
_G["SLASH_"..name.."1"] = "/"..command:lower()
|
||||||
|
AceConsole.commands[command] = name
|
||||||
|
-- non-persisting commands are registered for enabling disabling
|
||||||
|
if not persist then
|
||||||
|
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
|
||||||
|
AceConsole.weakcommands[self][command] = func
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Unregister a chatcommand
|
||||||
|
-- @param command Chat command to be unregistered WITHOUT leading "/"
|
||||||
|
function AceConsole:UnregisterChatCommand( command )
|
||||||
|
local name = AceConsole.commands[command]
|
||||||
|
if name then
|
||||||
|
SlashCmdList[name] = nil
|
||||||
|
_G["SLASH_" .. name .. "1"] = nil
|
||||||
|
hash_SlashCmdList["/" .. command:upper()] = nil
|
||||||
|
AceConsole.commands[command] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get an iterator over all Chat Commands registered with AceConsole
|
||||||
|
-- @return Iterator (pairs) over all commands
|
||||||
|
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
|
||||||
|
|
||||||
|
|
||||||
|
local function nils(n, ...)
|
||||||
|
if n>1 then
|
||||||
|
return nil, nils(n-1, ...)
|
||||||
|
elseif n==1 then
|
||||||
|
return nil, ...
|
||||||
|
else
|
||||||
|
return ...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Retreive one or more space-separated arguments from a string.
|
||||||
|
-- Treats quoted strings and itemlinks as non-spaced.
|
||||||
|
-- @param str The raw argument string
|
||||||
|
-- @param numargs How many arguments to get (default 1)
|
||||||
|
-- @param startpos Where in the string to start scanning (default 1)
|
||||||
|
-- @return Returns arg1, arg2, ..., nextposition\\
|
||||||
|
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
|
||||||
|
function AceConsole:GetArgs(str, numargs, startpos)
|
||||||
|
numargs = numargs or 1
|
||||||
|
startpos = max(startpos or 1, 1)
|
||||||
|
|
||||||
|
local pos=startpos
|
||||||
|
|
||||||
|
-- find start of new arg
|
||||||
|
pos = strfind(str, "[^ ]", pos)
|
||||||
|
if not pos then -- whoops, end of string
|
||||||
|
return nils(numargs, 1e9)
|
||||||
|
end
|
||||||
|
|
||||||
|
if numargs<1 then
|
||||||
|
return pos
|
||||||
|
end
|
||||||
|
|
||||||
|
-- quoted or space separated? find out which pattern to use
|
||||||
|
local delim_or_pipe
|
||||||
|
local ch = strsub(str, pos, pos)
|
||||||
|
if ch=='"' then
|
||||||
|
pos = pos + 1
|
||||||
|
delim_or_pipe='([|"])'
|
||||||
|
elseif ch=="'" then
|
||||||
|
pos = pos + 1
|
||||||
|
delim_or_pipe="([|'])"
|
||||||
|
else
|
||||||
|
delim_or_pipe="([| ])"
|
||||||
|
end
|
||||||
|
|
||||||
|
startpos = pos
|
||||||
|
|
||||||
|
while true do
|
||||||
|
-- find delimiter or hyperlink
|
||||||
|
local ch,_
|
||||||
|
pos,_,ch = strfind(str, delim_or_pipe, pos)
|
||||||
|
|
||||||
|
if not pos then break end
|
||||||
|
|
||||||
|
if ch=="|" then
|
||||||
|
-- some kind of escape
|
||||||
|
|
||||||
|
if strsub(str,pos,pos+1)=="|H" then
|
||||||
|
-- It's a |H....|hhyper link!|h
|
||||||
|
pos=strfind(str, "|h", pos+2) -- first |h
|
||||||
|
if not pos then break end
|
||||||
|
|
||||||
|
pos=strfind(str, "|h", pos+2) -- second |h
|
||||||
|
if not pos then break end
|
||||||
|
elseif strsub(str,pos, pos+1) == "|T" then
|
||||||
|
-- It's a |T....|t texture
|
||||||
|
pos=strfind(str, "|t", pos+2)
|
||||||
|
if not pos then break end
|
||||||
|
end
|
||||||
|
|
||||||
|
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
|
||||||
|
|
||||||
|
else
|
||||||
|
-- found delimiter, done with this arg
|
||||||
|
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
|
||||||
|
return strsub(str, startpos), nils(numargs-1, 1e9)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- embedding and embed handling
|
||||||
|
|
||||||
|
local mixins = {
|
||||||
|
"Print",
|
||||||
|
"Printf",
|
||||||
|
"RegisterChatCommand",
|
||||||
|
"UnregisterChatCommand",
|
||||||
|
"GetArgs",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
|
||||||
|
-- @param target target object to embed AceBucket in
|
||||||
|
function AceConsole:Embed( target )
|
||||||
|
for k, v in pairs( mixins ) do
|
||||||
|
target[v] = self[v]
|
||||||
|
end
|
||||||
|
self.embeds[target] = true
|
||||||
|
return target
|
||||||
|
end
|
||||||
|
|
||||||
|
function AceConsole:OnEmbedEnable( target )
|
||||||
|
if AceConsole.weakcommands[target] then
|
||||||
|
for command, func in pairs( AceConsole.weakcommands[target] ) do
|
||||||
|
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function AceConsole:OnEmbedDisable( target )
|
||||||
|
if AceConsole.weakcommands[target] then
|
||||||
|
for command, func in pairs( AceConsole.weakcommands[target] ) do
|
||||||
|
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for addon in pairs(AceConsole.embeds) do
|
||||||
|
AceConsole:Embed(addon)
|
||||||
|
end
|
4
libs/AceConsole-3.0/AceConsole-3.0.xml
Normal file
4
libs/AceConsole-3.0/AceConsole-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||||
|
..\FrameXML\UI.xsd">
|
||||||
|
<Script file="AceConsole-3.0.lua"/>
|
||||||
|
</Ui>
|
@ -1,5 +1,5 @@
|
|||||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||||
..\FrameXML\UI.xsd">
|
..\FrameXML\UI.xsd">
|
||||||
<Script file="localization\localisation.lua"/>
|
<Script file="localisation\enUS.lua"/>
|
||||||
<Script file="localization\localisation-de.lua"/>
|
<Script file="localisation\deDE.lua"/>
|
||||||
</Ui>
|
</Ui>
|
||||||
|
14
localisation/deDE.lua
Normal file
14
localisation/deDE.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
local L = LibStub('AceLocale-3.0'):NewLocale('Grichelde', 'deDE')
|
||||||
|
if not L then return end
|
||||||
|
|
||||||
|
-- system messages
|
||||||
|
L.AddonLoaded = 'Grichelde hilft Euch jetzt bei euren Sprachschwierigkeiten.'
|
||||||
|
|
||||||
|
-- profiles
|
||||||
|
--L.ProfileCreated = 'Neues Profil "%s" erstellt'
|
||||||
|
--L.ProfileLoaded = 'Profil auf "%s" festgelegt'
|
||||||
|
--L.ProfileDeleted = 'Profil "%s" gel\195\182scht'
|
||||||
|
--L.ProfileCopied = 'Einstellungen von "%s" kopiert'
|
||||||
|
--L.ProfileReset = 'Profil "%s" zur\195\188ckgesetzt'
|
||||||
|
--L.CantDeleteCurrentProfile = 'Das aktuelle Profil kann nicht gel\195\182scht werden'
|
||||||
|
--L.InvalidProfile = 'Ung\195\188ltiges Profil "%s"'
|
5
localisation/enUS.lua
Normal file
5
localisation/enUS.lua
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
local L = LibStub('AceLocale-3.0'):NewLocale('Grichelde', 'enUS', true)
|
||||||
|
if not L then return end
|
||||||
|
|
||||||
|
-- system messages
|
||||||
|
L.AddonLoaded = 'Grichelde now helps you with your spelling disabilities.'
|
@ -1,22 +0,0 @@
|
|||||||
--[[
|
|
||||||
Localization.lua
|
|
||||||
Translations for Dominos
|
|
||||||
|
|
||||||
German language
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local L = LibStub('AceLocale-3.0'):NewLocale('Grichelde', 'deDE')
|
|
||||||
if not L then return end
|
|
||||||
|
|
||||||
--system messages
|
|
||||||
L.NewPlayer = 'Neues Profil f\195\188r %s erstellt'
|
|
||||||
L.Updated = 'Aktualisiert auf v%s'
|
|
||||||
|
|
||||||
--profiles
|
|
||||||
L.ProfileCreated = 'Neues Profil "%s" erstellt'
|
|
||||||
L.ProfileLoaded = 'Profil auf "%s" festgelegt'
|
|
||||||
L.ProfileDeleted = 'Profil "%s" gel\195\182scht'
|
|
||||||
L.ProfileCopied = 'Einstellungen von "%s" kopiert'
|
|
||||||
L.ProfileReset = 'Profil "%s" zur\195\188ckgesetzt'
|
|
||||||
L.CantDeleteCurrentProfile = 'Das aktuelle Profil kann nicht gel\195\182scht werden'
|
|
||||||
L.InvalidProfile = 'Ung\195\188ltiges Profil "%s"'
|
|
Loading…
x
Reference in New Issue
Block a user