vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: AceConsole-2.0
3 Revision: $Rev: 14196 $
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
6 Website: http://www.wowace.com/
7 Documentation: http://www.wowace.com/index.php/AceConsole-2.0
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceConsole-2.0
9 Description: Mixin to allow for input/output capabilities. This uses the
10 AceOptions data table format to determine input.
11 http://wiki.wowace.com/index.php/AceOptions_data_table
12 Dependencies: AceLibrary, AceOO-2.0
13 ]]
14  
15 local MAJOR_VERSION = "AceConsole-2.0"
16 local MINOR_VERSION = "$Revision: 14196 $"
17  
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
20  
21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
22  
23 local MAP_ONOFF, USAGE, IS_CURRENTLY_SET_TO, IS_NOW_SET_TO, IS_NOT_A_VALID_OPTION_FOR, IS_NOT_A_VALID_VALUE_FOR, NO_OPTIONS_AVAILABLE, OPTION_HANDLER_NOT_FOUND, OPTION_HANDLER_NOT_VALID, OPTION_IS_DISABLED
24 if GetLocale() == "deDE" then
25 MAP_ONOFF = { [false] = "|cffff0000Aus|r", [true] = "|cff00ff00An|r" }
26 USAGE = "Benutzung"
27 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r steht momentan auf |cffffff7f[|r%s|cffffff7f]|r"
28 IS_NOW_SET_TO = "|cffffff7f%s|r ist nun auf |cffffff7f[|r%s|cffffff7f]|r gesetzt"
29 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] ist keine g\195\188ltige Option f\195\188r |cffffff7f%s|r"
30 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] ist kein g\195\188ltiger Wert f\195\188r |cffffff7f%s|r"
31 NO_OPTIONS_AVAILABLE = "Keine Optionen verfόgbar"
32 OPTION_HANDLER_NOT_FOUND = "Optionen handler |cffffff7f%q|r nicht gefunden."
33 OPTION_HANDLER_NOT_VALID = "Optionen handler nicht g\195\188ltig."
34 OPTION_IS_DISABLED = "Option |cffffff7f%s|r deaktiviert."
35 elseif GetLocale() == "frFR" then
36 MAP_ONOFF = { [false] = "|cffff0000Inactif|r", [true] = "|cff00ff00Actif|r" }
37 USAGE = "Utilisation"
38 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est actuellement positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
39 IS_NOW_SET_TO = "|cffffff7f%s|r est maintenant positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
40 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] n'est pas une option valide pour |cffffff7f%s|r"
41 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] n'est pas une valeur valide pour |cffffff7f%s|r"
42 NO_OPTIONS_AVAILABLE = "Pas d'options disponibles"
43 OPTION_HANDLER_NOT_FOUND = "Le gestionnaire d'option |cffffff7f%q|r n'a pas \195\169t\195\169 trouv\195\169."
44 OPTION_HANDLER_NOT_VALID = "Le gestionnaire d'option n'est pas valide."
45 OPTION_IS_DISABLED = "L'option |cffffff7f%s|r est d\195\169sactiv\195\169e."
46 elseif GetLocale() == "koKR" then
47 MAP_ONOFF = { [false] = "|cffff0000끔|r", [true] = "|cff00ff00μΌ¬|r" }
48 USAGE = "μ‚¬μš©λ²•"
49 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r|1은;λŠ”; ν˜„μž¬ μƒνƒœλŠ” |cffffff7f[|r%s|cffffff7f]|r|1으둜;둜; μ„€μ •λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€"
50 IS_NOW_SET_TO = "|cffffff7f%s|r|1을;λ₯Ό; |cffffff7f[|r%s|cffffff7f]|r μƒνƒœλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€"
51 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r]|1은;λŠ”; |cffffff7f%s|rμ—μ„œ μ‚¬μš©λΆˆκ°€λŠ₯ν•œ μ„€μ •μž…λ‹ˆλ‹€"
52 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r]|1은;λŠ”; |cffffff7f%s|rμ—μ„œ μ‚¬μš©λΆˆκ°€λŠ₯ν•œ μ„€μ •κ°’μž…λ‹ˆλ‹€"
53 NO_OPTIONS_AVAILABLE = "κ°€λŠ₯ν•œ 섀정이 μ—†μŠ΅λ‹ˆλ‹€"
54 OPTION_HANDLER_NOT_FOUND = "μ„€μ • 쑰정값인 |cffffff7f%q|r|1을;λ₯Ό; 찾지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€."
55 OPTION_HANDLER_NOT_VALID = "μ„€μ • 쑰정값이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."
56 OPTION_IS_DISABLED = "|cffffff7f%s|r 섀정은 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€."
57 else -- enUS
58 MAP_ONOFF = { [false] = "|cffff0000Off|r", [true] = "|cff00ff00On|r" }
59 USAGE = "Usage"
60 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r is currently set to |cffffff7f[|r%s|cffffff7f]|r"
61 IS_NOW_SET_TO = "|cffffff7f%s|r is now set to |cffffff7f[|r%s|cffffff7f]|r"
62 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] is not a valid option for |cffffff7f%s|r"
63 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] is not a valid value for |cffffff7f%s|r"
64 NO_OPTIONS_AVAILABLE = "No options available"
65 OPTION_HANDLER_NOT_FOUND = "Option handler |cffffff7f%q|r not found."
66 OPTION_HANDLER_NOT_VALID = "Option handler not valid."
67 OPTION_IS_DISABLED = "Option |cffffff7f%s|r is disabled."
68 end
69  
70 local NONE = NONE or "None"
71  
72 local AceOO = AceLibrary("AceOO-2.0")
73 local AceEvent
74  
75 local AceConsole = AceOO.Mixin { "Print", "PrintComma", "CustomPrint", "RegisterChatCommand" }
76 local Dewdrop
77  
78 local _G = getfenv(0)
79  
80 local table_setn
81 do
82 local version = GetBuildInfo()
83 if string.find(version, "^2%.") then
84 -- 2.0.0
85 table_setn = function() end
86 else
87 table_setn = table.setn
88 end
89 end
90  
91 local function print(text, name, r, g, b, frame, delay)
92 if not text or string.len(text) == 0 then
93 text = " "
94 end
95 if not name or name == AceConsole then
96 (frame or DEFAULT_CHAT_FRAME):AddMessage(text, r, g, b, nil, delay or 5)
97 else
98 (frame or DEFAULT_CHAT_FRAME):AddMessage("|cffffff78" .. tostring(name) .. ":|r " .. text, r, g, b, nil, delay or 5)
99 end
100 end
101  
102 local tmp
103 function AceConsole:CustomPrint(r, g, b, frame, delay, connector, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
104 a1 = tostring(a1)
105 if string.find(a1, "%%") then
106 print(string.format(a1, tostring(a2), tostring(a3), tostring(a4), tostring(a5), tostring(a6), tostring(a7), tostring(a8), tostring(a9), tostring(a10), tostring(a11), tostring(a12), tostring(a13), tostring(a14), tostring(a15), tostring(a16), tostring(a17), tostring(a18), tostring(a19), tostring(a20)), self, r, g, b, frame or self.printFrame, delay)
107 else
108 if not tmp then
109 tmp = {}
110 end
111 tmp[1] = a1
112 tmp[2] = a2
113 tmp[3] = a3
114 tmp[4] = a4
115 tmp[5] = a5
116 tmp[6] = a6
117 tmp[7] = a7
118 tmp[8] = a8
119 tmp[9] = a9
120 tmp[10] = a10
121 tmp[11] = a11
122 tmp[12] = a12
123 tmp[13] = a13
124 tmp[14] = a14
125 tmp[15] = a15
126 tmp[16] = a16
127 tmp[17] = a17
128 tmp[18] = a18
129 tmp[19] = a19
130 tmp[20] = a20
131 local n = 20
132 while tmp[n] == nil do
133 n = n - 1
134 end
135 table_setn(tmp, n)
136 for k = 1, n do
137 tmp[k] = tostring(tmp[k])
138 end
139 print(table.concat(tmp, connector or " "), self, r, g, b, frame or self.printFrame, delay)
140 for k,v in pairs(tmp) do
141 tmp[k] = nil
142 end
143 table_setn(tmp, 0)
144 end
145 end
146  
147 function AceConsole:Print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
148 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, " ", a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
149 end
150  
151 function AceConsole:PrintComma(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
152 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, ", ", a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
153 end
154  
155 local work
156 local argwork
157  
158 local string_gfind = string.gmatch or string.gfind
159  
160 local function findTableLevel(self, options, chat, text, index, passTable)
161 if not index then
162 index = 1
163 if work then
164 for k,v in pairs(work) do
165 work[k] = nil
166 end
167 table_setn(work, 0)
168 for k,v in pairs(argwork) do
169 argwork[k] = nil
170 end
171 table_setn(argwork, 0)
172 else
173 work = {}
174 argwork = {}
175 end
176 local len = string.len(text)
177 local count
178 repeat
179 text, count = string.gsub(text, "(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[[^%]]-) (.-%]|h|r)", "%1\001%2")
180 until count == 0
181 text = string.gsub(text, "(%]|h|r)(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[)", "%1 %2")
182 for token in string_gfind(text, "([^%s]+)") do
183 local token = token
184 local num = tonumber(token)
185 if num then
186 token = num
187 else
188 token = string.gsub(token, "\001", " ")
189 end
190 table.insert(work, token)
191 end
192 end
193  
194 local path = chat
195 for i = 1, index - 1 do
196 path = path .. " " .. tostring(work[i])
197 end
198  
199 if type(options.args) == "table" then
200 local disabled, hidden = options.disabled, options.cmdHidden or options.hidden
201 if hidden then
202 if type(hidden) == "function" then
203 hidden = hidden()
204 elseif type(hidden) == "string" then
205 local handler = options.handler or self
206 if type(handler[hidden]) ~= "function" then
207 AceConsole:error(OPTION_HANDLER_NOT_FOUND, hidden)
208 end
209 hidden = handler[hidden](handler)
210 end
211 end
212 if hidden then
213 disabled = true
214 elseif disabled then
215 if type(disabled) == "function" then
216 disabled = disabled()
217 elseif type(disabled) == "string" then
218 local handler = options.handler or self
219 if type(handler[disabled]) ~= "function" then
220 AceConsole:error(OPTION_HANDLER_NOT_FOUND, disabled)
221 end
222 disabled = handler[disabled](handler)
223 end
224 end
225 if not disabled then
226 local next = work[index] and string.lower(work[index])
227 if next then
228 for k,v in pairs(options.args) do
229 local good = false
230 if string.lower(k) == next then
231 good = true
232 elseif type(v.aliases) == "table" then
233 for _,alias in ipairs(v.aliases) do
234 if string.lower(alias) == next then
235 good = true
236 break
237 end
238 end
239 elseif type(v.aliases) == "string" and string.lower(v.aliases) == next then
240 good = true
241 end
242 if good then
243 return findTableLevel(options.handler or self, v, chat, text, index + 1, options.pass and options or nil)
244 end
245 end
246 end
247 end
248 end
249 for i = index, table.getn(work) do
250 table.insert(argwork, work[i])
251 end
252 return options, path, argwork, options.handler or self, passTable, passTable and work[index - 1]
253 end
254  
255 local function validateOptionsMethods(self, options, position)
256 if type(options) ~= "table" then
257 return "Options must be a table.", position
258 end
259 self = options.handler or self
260 if options.type == "execute" then
261 if options.func and type(options.func) ~= "string" and type(options.func) ~= "function" then
262 return "func must be a string or function", position
263 end
264 if options.func and type(options.func) == "string" and type(self[options.func]) ~= "function" then
265 return string.format("%q is not a proper function", options.func), position
266 end
267 else
268 if options.get then
269 if type(options.get) ~= "string" and type(options.get) ~= "function" then
270 return "get must be a string or function", position
271 end
272 if type(options.get) == "string" and type(self[options.get]) ~= "function" then
273 return string.format("%q is not a proper function", options.get), position
274 end
275 end
276 if options.set then
277 if type(options.set) ~= "string" and type(options.set) ~= "function" then
278 return "set must be a string or function", position
279 end
280 if type(options.set) == "string" and type(self[options.set]) ~= "function" then
281 return string.format("%q is not a proper function", options.set), position
282 end
283 end
284 if options.validate and type(options.validate) ~= "table" then
285 if type(options.validate) ~= "string" and type(options.validate) ~= "function" then
286 return "validate must be a string or function", position
287 end
288 if type(options.validate) == "string" and type(self[options.validate]) ~= "function" then
289 return string.format("%q is not a proper function", options.validate), position
290 end
291 end
292 end
293 if options.disabled and type(options.disabled) == "string" and type(self[options.disabled]) ~= "function" then
294 return string.format("%q is not a proper function", options.disabled), position
295 end
296 if options.cmdHidden and type(options.cmdHidden) == "string" and type(self[options.cmdHidden]) ~= "function" then
297 return string.format("%q is not a proper function", options.cmdHidden), position
298 end
299 if options.guiHidden and type(options.guiHidden) == "string" and type(self[options.guiHidden]) ~= "function" then
300 return string.format("%q is not a proper function", options.guiHidden), position
301 end
302 if options.hidden and type(options.hidden) == "string" and type(self[options.hidden]) ~= "function" then
303 return string.format("%q is not a proper function", options.hidden), position
304 end
305 if options.type == "group" and type(options.args) == "table" then
306 for k,v in pairs(options.args) do
307 if type(v) == "table" then
308 local newposition
309 if position then
310 newposition = position .. ".args." .. k
311 else
312 newposition = "args." .. k
313 end
314 local err, pos = validateOptionsMethods(self, v, newposition)
315 if err then
316 return err, pos
317 end
318 end
319 end
320 end
321 end
322  
323 local function validateOptions(options, position, baseOptions, fromPass)
324 if not baseOptions then
325 baseOptions = options
326 end
327 if type(options) ~= "table" then
328 return "Options must be a table.", position
329 end
330 local kind = options.type
331 if type(kind) ~= "string" then
332 return '"type" must be a string.', position
333 elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then
334 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position
335 end
336 if options.aliases then
337 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
338 return '"alias" must be a table or string', position
339 end
340 end
341 if not fromPass then
342 if kind == "execute" then
343 if type(options.func) ~= "string" and type(options.func) ~= "function" then
344 return '"func" must be a string or function', position
345 end
346 elseif kind == "range" or kind == "text" or kind == "toggle" then
347 if type(options.set) ~= "string" and type(options.set) ~= "function" then
348 return '"set" must be a string or function', position
349 end
350 if kind == "text" and options.get == false then
351 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then
352 return '"get" must be a string or function', position
353 end
354 elseif kind == "group" and options.pass then
355 if options.pass ~= true then
356 return '"pass" must be either nil, true, or false', position
357 end
358 if not options.func then
359 if type(options.set) ~= "string" and type(options.set) ~= "function" then
360 return '"set" must be a string or function', position
361 end
362 if type(options.get) ~= "string" and type(options.get) ~= "function" then
363 return '"get" must be a string or function', position
364 end
365 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then
366 return '"func" must be a string or function', position
367 end
368 end
369 else
370 if kind == "group" then
371 return 'cannot have "type" = "group" as a subgroup of a passing group', position
372 end
373 end
374 if options ~= baseOptions then
375 if kind == "header" then
376 elseif type(options.desc) ~= "string" then
377 return '"desc" must be a string', position
378 elseif string.len(options.desc) == 0 then
379 return '"desc" cannot be a 0-length string', position
380 end
381 end
382  
383 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then
384 if options.type == "header" and not options.cmdName and not options.name then
385 elseif options.cmdName then
386 if type(options.cmdName) ~= "string" then
387 return '"cmdName" must be a string or nil', position
388 elseif string.len(options.cmdName) == 0 then
389 return '"cmdName" cannot be a 0-length string', position
390 end
391 if type(options.guiName) ~= "string" then
392 if not options.guiNameIsMap then
393 return '"guiName" must be a string or nil', position
394 end
395 elseif string.len(options.guiName) == 0 then
396 return '"guiName" cannot be a 0-length string', position
397 end
398 else
399 if type(options.name) ~= "string" then
400 return '"name" must be a string', position
401 elseif string.len(options.name) == 0 then
402 return '"name" cannot be a 0-length string', position
403 end
404 end
405 end
406 if options.guiNameIsMap then
407 if type(options.guiNameIsMap) ~= "boolean" then
408 return '"guiNameIsMap" must be a boolean or nil', position
409 elseif options.type ~= "toggle" then
410 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position
411 elseif type(options.map) ~= "table" then
412 return '"map" must be a table', position
413 end
414 end
415 if options.message and type(options.message) ~= "string" then
416 return '"message" must be a string or nil', position
417 end
418 if options.error and type(options.error) ~= "string" then
419 return '"error" must be a string or nil', position
420 end
421 if options.current and type(options.current) ~= "string" then
422 return '"current" must be a string or nil', position
423 end
424 if options.order then
425 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then
426 return '"order" must be a non-zero number or nil', position
427 end
428 end
429 if options.disabled then
430 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then
431 return '"disabled" must be a function, string, or boolean', position
432 end
433 end
434 if options.cmdHidden then
435 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then
436 return '"cmdHidden" must be a function, string, or boolean', position
437 end
438 end
439 if options.guiHidden then
440 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then
441 return '"guiHidden" must be a function, string, or boolean', position
442 end
443 end
444 if options.hidden then
445 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then
446 return '"hidden" must be a function, string, or boolean', position
447 end
448 end
449 if kind == "text" then
450 if type(options.validate) == "table" then
451 local t = options.validate
452 local iTable = nil
453 for k,v in pairs(t) do
454 if type(k) == "number" then
455 if iTable == nil then
456 iTable = true
457 elseif not iTable then
458 return '"validate" must either have all keys be indexed numbers or strings', position
459 elseif k < 1 or k > table.getn(t) then
460 return '"validate" numeric keys must be indexed properly. >= 1 and <= table.getn', position
461 end
462 else
463 if iTable == nil then
464 iTable = false
465 elseif iTable then
466 return '"validate" must either have all keys be indexed numbers or strings', position
467 end
468 end
469 if type(v) ~= "string" then
470 return '"validate" values must all be strings', position
471 end
472 end
473 else
474 if type(options.usage) ~= "string" then
475 return '"usage" must be a string', position
476 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then
477 return '"validate" must be a string, function, or table', position
478 end
479 end
480 elseif kind == "range" then
481 if options.min or options.max then
482 if type(options.min) ~= "number" then
483 return '"min" must be a number', position
484 elseif type(options.max) ~= "number" then
485 return '"max" must be a number', position
486 elseif options.min >= options.max then
487 return '"min" must be less than "max"', position
488 end
489 end
490 if options.step then
491 if type(options.step) ~= "number" then
492 return '"step" must be a number', position
493 elseif options.step < 0 then
494 return '"step" must be nonnegative', position
495 end
496 end
497 if options.isPercent and options.isPercent ~= true then
498 return '"isPercent" must either be nil, true, or false', position
499 end
500 elseif kind == "toggle" then
501 if options.map then
502 if type(options.map) ~= "table" then
503 return '"map" must be a table', position
504 elseif type(options.map[true]) ~= "string" then
505 return '"map[true]" must be a string', position
506 elseif type(options.map[false]) ~= "string" then
507 return '"map[false]" must be a string', position
508 end
509 end
510 elseif kind == "color" then
511 if options.hasAlpha and options.hasAlpha ~= true then
512 return '"hasAlpha" must be nil, true, or false', position
513 end
514 elseif kind == "group" then
515 if options.pass and options.pass ~= true then
516 return '"pass" must be nil, true, or false', position
517 end
518 if type(options.args) ~= "table" then
519 return '"args" must be a table', position
520 end
521 for k,v in pairs(options.args) do
522 if type(k) ~= "string" then
523 return '"args" keys must be strings', position
524 elseif string.find(k, "%s") then
525 return string.format('"args" keys must not include spaces. %q is not appropriate.', k), position
526 elseif string.len(k) == 0 then
527 return '"args" keys must not be 0-length strings.', position
528 end
529 if type(v) ~= "table" then
530 return '"args" values must be tables', position and position .. "." .. k or k
531 end
532 local newposition
533 if position then
534 newposition = position .. ".args." .. k
535 else
536 newposition = "args." .. k
537 end
538 local err, pos = validateOptions(v, newposition, baseOptions, options.pass)
539 if err then
540 return err, pos
541 end
542 end
543 end
544 end
545  
546 local colorTable
547 local colorFunc
548 local colorCancelFunc
549  
550 local order
551  
552 local mysort_args
553 local mysort
554  
555 local function printUsage(self, handler, realOptions, options, path, args, quiet, filter)
556 if filter then
557 filter = "^" .. string.gsub(filter, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
558 end
559 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
560 if hidden then
561 if type(hidden) == "function" then
562 hidden = hidden()
563 elseif type(hidden) == "string" then
564 if type(handler[handler]) ~= "function" then
565 AceConsole:error(OPTION_HANDLER_NOT_FOUND, handler)
566 end
567 hidden = handler[hidden](handler)
568 end
569 end
570 if hidden then
571 disabled = true
572 elseif disabled then
573 if type(disabled) == "function" then
574 disabled = disabled()
575 elseif type(disabled) == "string" then
576 if type(handler[disabled]) ~= "function" then
577 AceConsole:error(OPTION_HANDLER_NOT_FOUND, disabled)
578 end
579 disabled = handler[disabled](handler)
580 end
581 end
582 local kind = string.lower(options.type or "group")
583 if disabled then
584 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self)
585 elseif kind == "text" then
586 local var
587 if passTable then
588 if not passTable.get then
589 elseif type(passTable.get) == "function" then
590 var = passTable.get(passValue)
591 else
592 local handler = passTable.handler or handler
593 if type(handler[passTable.get]) ~= "function" then
594 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
595 end
596 var = handler[passTable.get](handler, passValue)
597 end
598 else
599 if not options.get then
600 elseif type(options.get) == "function" then
601 var = options.get()
602 else
603 local handler = options.handler or handler
604 if type(handler[options.get]) ~= "function" then
605 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
606 end
607 var = handler[options.get](handler)
608 end
609 end
610  
611 local usage
612 if type(options.validate) == "table" then
613 if filter then
614 if not order then
615 order = {}
616 end
617 for k,v in pairs(options.validate) do
618 if string.find(v, filter) then
619 table.insert(order, v)
620 end
621 end
622 usage = "{" .. table.concat(order, " || ") .. "}"
623 for k in pairs(order) do
624 order[k] = nil
625 end
626 table_setn(order, 0)
627 else
628 if not order then
629 order = {}
630 end
631 for k,v in pairs(options.validate) do
632 table.insert(order, v)
633 end
634 usage = "{" .. table.concat(order, " || ") .. "}"
635 for k in pairs(order) do
636 order[k] = nil
637 end
638 table_setn(order, 0)
639 end
640 var = options.validate[var] or var
641 else
642 usage = options.usage or "<value>"
643 end
644 if not quiet then
645 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
646 end
647 if (passTable and passTable.get) or options.get then
648 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)))
649 end
650 elseif kind == "range" then
651 local var
652 if passTable then
653 if type(passTable.get) == "function" then
654 var = passTable.get(passValue)
655 else
656 local handler = passTable.handler or handler
657 if type(handler[passTable.get]) ~= "function" then
658 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
659 end
660 var = handler[passTable.get](handler, passValue)
661 end
662 else
663 if type(options.get) == "function" then
664 var = options.get()
665 else
666 local handler = options.handler or handler
667 if type(handler[options.get]) ~= "function" then
668 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
669 end
670 var = handler[options.get](handler)
671 end
672 end
673  
674 local usage
675 local min = options.min or 0
676 local max = options.max or 1
677 if options.isPercent then
678 min, max = min * 100, max * 100
679 var = tostring(var * 100) .. "%"
680 end
681 local bit = "-"
682 if min < 0 or max < 0 then
683 bit = " - "
684 end
685 usage = string.format("(%s%s%s)", min, bit, max)
686 if not quiet then
687 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
688 end
689 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)))
690 elseif kind == "group" then
691 local usage
692 if next(options.args) then
693 if not order then
694 order = {}
695 end
696 for k,v in pairs(options.args) do
697 if v.type ~= "header" then
698 local hidden = v.cmdHidden or v.hidden
699 if hidden then
700 if type(hidden) == "function" then
701 hidden = hidden()
702 elseif type(hidden) == "string" then
703 local handler = v.handler or handler
704 if type(handler[hidden]) ~= "function" then
705 AceConsole:error(OPTION_HANDLER_NOT_FOUND, hidden)
706 end
707 hidden = handler[hidden](handler)
708 end
709 end
710 if not hidden then
711 if filter then
712 if string.find(k, filter) then
713 table.insert(order, k)
714 elseif type(v.aliases) == "table" then
715 for _,bit in ipairs(v.aliases) do
716 if string.find(v.aliases, filter) then
717 table.insert(order, k)
718 break
719 end
720 end
721 elseif type(v.aliases) == "string" then
722 if string.find(v.aliases, filter) then
723 table.insert(order, k)
724 end
725 end
726 else
727 table.insert(order, k)
728 end
729 end
730 end
731 end
732 if not mysort then
733 mysort = function(a, b)
734 local alpha, bravo = mysort_args[a], mysort_args[b]
735 local alpha_order = alpha and alpha.order or 100
736 local bravo_order = bravo and bravo.order or 100
737 if alpha_order == bravo_order then
738 return tostring(a) < tostring(b)
739 else
740 if alpha_order < 0 then
741 if bravo_order > 0 then
742 return false
743 end
744 else
745 if bravo_order < 0 then
746 return true
747 end
748 end
749 if alpha_order > 0 and bravo_order > 0 then
750 return tostring(a) < tostring(b)
751 end
752 return alpha_order < bravo_order
753 end
754 end
755 end
756 mysort_args = options.args
757 table.sort(order, mysort)
758 mysort_args = nil
759 if not quiet then
760 if options == realOptions then
761 if options.desc then
762 print(tostring(options.desc), realOptions.cmdName or realOptions.name or self)
763 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
764 elseif self.description or self.notes then
765 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
766 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
767 else
768 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
769 end
770 else
771 if options.desc then
772 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
773 print(tostring(options.desc))
774 else
775 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
776 end
777 end
778 end
779 for _,k in ipairs(order) do
780 local v = options.args[k]
781 if v then
782 local disabled = v.disabled
783 if disabled then
784 if type(disabled) == "function" then
785 disabled = disabled()
786 elseif type(disabled) == "string" then
787 local handler = v.handler or handler
788 if type(handler[disabled]) ~= "function" then
789 AceConsole:error(OPTION_HANDLER_NOT_FOUND, disabled)
790 end
791 disabled = handler[disabled](handler)
792 end
793 end
794 if type(v.aliases) == "table" then
795 k = k .. " || " .. table.concat(v.aliases, " || ")
796 elseif type(v.aliases) == "string" then
797 k = k .. " || " .. v.aliases
798 end
799 if v.get then
800 local a1,a2,a3,a4
801 if type(v.get) == "function" then
802 if options.pass then
803 a1,a2,a3,a4 = v.get(k)
804 else
805 a1,a2,a3,a4 = v.get()
806 end
807 else
808 local handler = v.handler or handler
809 if type(handler[v.get]) ~= "function" then
810 AceConsole:error(OPTION_HANDLER_NOT_FOUND, v.get)
811 end
812 if options.pass then
813 a1,a2,a3,a4 = handler[v.get](handler, k)
814 else
815 a1,a2,a3,a4 = handler[v.get](handler)
816 end
817 end
818 if v.type == "color" then
819 if v.hasAlpha then
820 if not a1 or not a2 or not a3 or not a4 then
821 s = NONE
822 else
823 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a4*255, a1*255, a2*255, a3*255, a4*255, a1*255, a2*255, a3*255)
824 end
825 else
826 if not a1 or not a2 or not a3 then
827 s = NONE
828 else
829 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", a1*255, a2*255, a3*255, a1*255, a2*255, a3*255)
830 end
831 end
832 elseif v.type == "toggle" then
833 if v.map then
834 s = tostring(v.map[a1 or false] or NONE)
835 else
836 s = tostring(MAP_ONOFF[a1 or false] or NONE)
837 end
838 elseif v.type == "range" then
839 if v.isPercent then
840 s = tostring(a1 * 100) .. "%"
841 else
842 s = tostring(a1)
843 end
844 elseif v.type == "text" and type(v.validate) == "table" then
845 s = tostring(v.validate[a1] or a1)
846 else
847 s = tostring(a1 or NONE)
848 end
849 if disabled then
850 local s = string.gsub(s, "|cff%x%x%x%x%x%x(.-)|r", "%1")
851 local desc = string.gsub(v.desc or NONE, "|cff%x%x%x%x%x%x(.-)|r", "%1")
852 print(string.format("|cffcfcfcf - %s: [%s] %s|r", k, s, desc))
853 else
854 print(string.format(" - |cffffff7f%s: [|r%s|cffffff7f]|r %s", k, s, v.desc or NONE))
855 end
856 else
857 if disabled then
858 local desc = string.gsub(v.desc or NONE, "|cff%x%x%x%x%x%x(.-)|r", "%1")
859 print(string.format("|cffcfcfcf - %s: %s", k, desc))
860 else
861 print(string.format(" - |cffffff7f%s:|r %s", k, v.desc or NONE))
862 end
863 end
864 end
865 end
866 for k in pairs(order) do
867 order[k] = nil
868 end
869 table_setn(order, 0)
870 else
871 if options.desc then
872 desc = options.desc
873 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self)
874 print(tostring(options.desc))
875 elseif options == realOptions and (self.description or self.notes) then
876 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
877 print(string.format("|cffffff7f%s:|r %s", USAGE, path))
878 else
879 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self)
880 end
881 print(self, NO_OPTIONS_AVAILABLE)
882 end
883 end
884 end
885  
886 local function handlerFunc(self, chat, msg, options)
887 if not msg then
888 msg = ""
889 else
890 msg = string.gsub(msg, "^%s*(.-)%s*$", "%1")
891 msg = string.gsub(msg, "%s+", " ")
892 end
893  
894 local realOptions = options
895 local options, path, args, handler, passTable, passValue = findTableLevel(self, options, chat, msg)
896  
897 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
898 if hidden then
899 if type(hidden) == "function" then
900 hidden = hidden()
901 elseif type(hidden) == "string" then
902 if type(handler[hidden]) ~= "function" then
903 AceConsole:error(OPTION_HANDLER_NOT_FOUND, hidden)
904 end
905 hidden = handler[hidden](handler)
906 end
907 end
908 if hidden then
909 disabled = true
910 elseif disabled then
911 if type(disabled) == "function" then
912 disabled = disabled()
913 elseif type(disabled) == "string" then
914 if type(handler[disabled]) ~= "function" then
915 AceConsole:error(OPTION_HANDLER_NOT_FOUND, disabled)
916 end
917 disabled = handler[disabled](handler)
918 end
919 end
920 local _G_this = this
921 local kind = string.lower(options.type or "group")
922 if disabled then
923 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self)
924 elseif kind == "text" then
925 if table.getn(args) > 0 then
926 if (type(options.validate) == "table" and table.getn(args) > 1) or (type(options.validate) ~= "table" and not options.input) then
927 local arg = table.concat(args, " ")
928 for k,v in pairs(args) do
929 args[k] = nil
930 end
931 table_setn(args, 0)
932 table.insert(args, arg)
933 end
934 if options.validate then
935 local good
936 if type(options.validate) == "function" then
937 good = options.validate(unpack(args))
938 elseif type(options.validate) == "table" then
939 local arg = args[1]
940 arg = string.lower(tostring(arg))
941 for k,v in pairs(options.validate) do
942 if string.lower(v) == arg then
943 args[1] = type(k) == "string" and k or v
944 good = true
945 break
946 end
947 end
948 if not good and type((next(options.validate))) == "string" then
949 for k,v in pairs(options.validate) do
950 if type(k) == "string" and string.lower(k) == arg then
951 args[1] = k
952 good = true
953 break
954 end
955 end
956 end
957 else
958 if type(handler[options.validate]) ~= "function" then
959 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.validate)
960 end
961 good = handler[options.validate](handler, unpack(args))
962 end
963 if not good then
964 local usage
965 if type(options.validate) == "table" then
966 if not order then
967 order = {}
968 end
969 for k,v in pairs(options.validate) do
970 table.insert(order, v)
971 end
972 usage = "{" .. table.concat(order, " || ") .. "}"
973 for k in pairs(order) do
974 order[k] = nil
975 end
976 table_setn(order, 0)
977 else
978 usage = options.usage or "<value>"
979 end
980 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, tostring(table.concat(args, " ")), path), realOptions.cmdName or realOptions.name or self)
981 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage))
982 return
983 end
984 end
985  
986 local var
987 if passTable then
988 if not passTable.get then
989 elseif type(passTable.get) == "function" then
990 var = passTable.get(passValue)
991 else
992 if type(handler[passTable.get]) ~= "function" then
993 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
994 end
995 var = handler[passTable.get](handler, passValue)
996 end
997 else
998 if not options.get then
999 elseif type(options.get) == "function" then
1000 var = options.get()
1001 else
1002 if type(handler[options.get]) ~= "function" then
1003 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1004 end
1005 var = handler[options.get](handler)
1006 end
1007 end
1008  
1009 if var ~= args[1] then
1010 if passTable then
1011 if type(passTable.set) == "function" then
1012 passTable.set(passValue, unpack(args))
1013 else
1014 if type(handler[passTable.set]) ~= "function" then
1015 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.set)
1016 end
1017 handler[passTable.set](handler, passTable.set, unpack(args))
1018 end
1019 else
1020 if type(options.set) == "function" then
1021 options.set(unpack(args))
1022 else
1023 if type(handler[options.set]) ~= "function" then
1024 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.set)
1025 end
1026 handler[options.set](handler, unpack(args))
1027 end
1028 end
1029 end
1030 end
1031  
1032 if table.getn(args) > 0 then
1033 local var
1034 if passTable then
1035 if not passTable.get then
1036 elseif type(passTable.get) == "function" then
1037 var = passTable.get(passValue)
1038 else
1039 if type(handler[passTable.get]) ~= "function" then
1040 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1041 end
1042 var = handler[passTable.get](handler, passValue)
1043 end
1044 else
1045 if not options.get then
1046 elseif type(options.get) == "function" then
1047 var = options.get()
1048 else
1049 if type(handler[options.get]) ~= "function" then
1050 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1051 end
1052 var = handler[options.get](handler)
1053 end
1054 end
1055 if type(options.validate) == "table" then
1056 var = options.validate[var] or var
1057 end
1058 if (passTable and passTable.get) or options.get then
1059 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self)
1060 end
1061 if var == args[1] then
1062 return
1063 end
1064 else
1065 printUsage(self, handler, realOptions, options, path, args)
1066 return
1067 end
1068 elseif kind == "execute" then
1069 if passTable then
1070 if type(passFunc) == "function" then
1071 set(passValue)
1072 else
1073 if type(handler[passFunc]) ~= "function" then
1074 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passFunc)
1075 end
1076 handler[passFunc](handler, passValue)
1077 end
1078 else
1079 local ret, msg
1080 if type(options.func) == "function" then
1081 options.func()
1082 else
1083 local handler = options.handler or self
1084 if type(handler[options.func]) ~= "function" then
1085 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.func)
1086 end
1087 handler[options.func](handler)
1088 end
1089 end
1090 elseif kind == "toggle" then
1091 local var
1092 if passTable then
1093 if type(passTable.get) == "function" then
1094 var = passTable.get(passValue)
1095 else
1096 if type(handler[passTable.get]) ~= "function" then
1097 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1098 end
1099 var = handler[passTable.get](handler, passValue)
1100 end
1101 if type(passTable.set) == "function" then
1102 passTable.set(passValue, not var)
1103 else
1104 if type(handler[passTable.set]) ~= "function" then
1105 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.set)
1106 end
1107 handler[passTable.set](handler, passValue, not var)
1108 end
1109 if type(passTable.get) == "function" then
1110 var = passTable.get(passValue)
1111 else
1112 var = handler[passTable.get](handler, passValue)
1113 end
1114 else
1115 local handler = options.handler or self
1116 if type(options.get) == "function" then
1117 var = options.get()
1118 else
1119 if type(handler[options.get]) ~= "function" then
1120 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1121 end
1122 var = handler[options.get](handler)
1123 end
1124 if type(options.set) == "function" then
1125 options.set(not var)
1126 else
1127 if type(handler[options.set]) ~= "function" then
1128 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.set)
1129 end
1130 handler[options.set](handler, not var)
1131 end
1132 if type(options.get) == "function" then
1133 var = options.get()
1134 else
1135 var = handler[options.get](handler)
1136 end
1137 end
1138  
1139 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), (options.map or MAP_ONOFF)[var or false] or NONE), realOptions.cmdName or realOptions.name or self)
1140 elseif kind == "range" then
1141 local arg
1142 if table.getn(args) <= 1 then
1143 arg = args[1]
1144 else
1145 arg = table.concat(args, " ")
1146 end
1147  
1148 if arg then
1149 local min = options.min or 0
1150 local max = options.max or 1
1151 local good = false
1152 if type(arg) == "number" then
1153 if options.isPercent then
1154 arg = arg / 100
1155 end
1156  
1157 if arg >= min and arg <= max then
1158 good = true
1159 end
1160  
1161 if good and type(options.step) == "number" and options.step > 0 then
1162 local step = options.step
1163 arg = math.floor((arg - min) / step + 0.5) * step + min
1164 if arg > max then
1165 arg = max
1166 elseif arg < min then
1167 arg = min
1168 end
1169 end
1170 end
1171 if not good then
1172 local usage
1173 local min = options.min or 0
1174 local max = options.max or 1
1175 if options.isPercent then
1176 min, max = min * 100, max * 100
1177 end
1178 local bit = "-"
1179 if min < 0 or max < 0 then
1180 bit = " - "
1181 end
1182 usage = string.format("(%s%s%s)", min, bit, max)
1183 print(string.format(options.error or IS_NOT_A_VALID_VALUE_FOR, tostring(arg), path), realOptions.cmdName or realOptions.name or self)
1184 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage))
1185 return
1186 end
1187  
1188 local var
1189 if passTable then
1190 if type(passTable.get) == "function" then
1191 var = passTable.get(passValue)
1192 else
1193 if type(handler[passTable.get]) ~= "function" then
1194 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1195 end
1196 var = handler[passTable.get](handler, passValue)
1197 end
1198 else
1199 if type(options.get) == "function" then
1200 var = options.get()
1201 else
1202 local handler = options.handler or self
1203 if type(handler[options.get]) ~= "function" then
1204 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1205 end
1206 var = handler[options.get](handler)
1207 end
1208 end
1209  
1210 if var ~= arg then
1211 if passTable then
1212 if type(passTable.set) == "function" then
1213 passTable.set(passValue, arg)
1214 else
1215 if type(handler[passTable.set]) ~= "function" then
1216 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.set)
1217 end
1218 handler[passTable.set](handler, passValue, arg)
1219 end
1220 else
1221 if type(options.set) == "function" then
1222 options.set(arg)
1223 else
1224 local handler = options.handler or self
1225 if type(handler[options.set]) ~= "function" then
1226 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.set)
1227 end
1228 handler[options.set](handler, arg)
1229 end
1230 end
1231 end
1232 end
1233  
1234 if arg then
1235 local var
1236 if passTable then
1237 if type(passTable.get) == "function" then
1238 var = passTable.get(passValue)
1239 else
1240 if type(handler[passTable.get]) ~= "function" then
1241 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1242 end
1243 var = handler[passTable.get](handler, passValue)
1244 end
1245 else
1246 if type(options.get) == "function" then
1247 var = options.get()
1248 else
1249 local handler = options.handler or self
1250 if type(handler[options.get]) ~= "function" then
1251 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1252 end
1253 var = handler[options.get](handler)
1254 end
1255 end
1256  
1257 if var and options.isPercent then
1258 var = tostring(var * 100) .. "%"
1259 end
1260 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self)
1261 if var == arg then
1262 return
1263 end
1264 else
1265 printUsage(self, handler, realOptions, options, path, args)
1266 return
1267 end
1268 elseif kind == "color" then
1269 if table.getn(args) > 0 then
1270 local r,g,b,a
1271 if table.getn(args) == 1 then
1272 local arg = tostring(args[1])
1273 if options.hasAlpha then
1274 if string.len(arg) == 8 and string.find(arg, "^%x*$") then
1275 r,g,b,a = tonumber(string.sub(arg, 1, 2), 16) / 255, tonumber(string.sub(arg, 3, 4), 16) / 255, tonumber(string.sub(arg, 5, 6), 16) / 255, tonumber(string.sub(arg, 7, 8), 16) / 255
1276 end
1277 else
1278 if string.len(arg) == 6 and string.find(arg, "^%x*$") then
1279 r,g,b = tonumber(string.sub(arg, 1, 2), 16) / 255, tonumber(string.sub(arg, 3, 4), 16) / 255, tonumber(string.sub(arg, 5, 6), 16) / 255
1280 end
1281 end
1282 elseif table.getn(args) == 4 and options.hasAlpha then
1283 local a1,a2,a3,a4 = args[1], args[2], args[3], args[4]
1284 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and type(a4) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 and a4 <= 1 then
1285 r,g,b,a = a1,a2,a3,a4
1286 elseif (type(a1) == "number" or string.len(a1) == 2) and string.find(a1, "^%x*$") and (type(a2) == "number" or string.len(a2) == 2) and string.find(a2, "^%x*$") and (type(a3) == "number" or string.len(a3) == 2) and string.find(a3, "^%x*$") and (type(a4) == "number" or string.len(a4) == 2) and string.find(a4, "^%x*$") then
1287 r,g,b,a = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255, tonumber(a4, 16) / 255
1288 end
1289 elseif table.getn(args) == 3 and not options.hasAlpha then
1290 local a1,a2,a3 = args[1], args[2], args[3]
1291 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 then
1292 r,g,b = a1,a2,a3
1293 elseif (type(a1) == "number" or string.len(a1) == 2) and string.find(a1, "^%x*$") and (type(a2) == "number" or string.len(a2) == 2) and string.find(a2, "^%x*$") and (type(a3) == "number" or string.len(a3) == 2) and string.find(a3, "^%x*$") then
1294 r,g,b = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255
1295 end
1296 end
1297 if not r then
1298 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, table.concat(args, ' '), path), realOptions.cmdName or realOptions.name or self)
1299 print(string.format("|cffffff7f%s:|r %s {0-1} {0-1} {0-1}%s", USAGE, path, options.hasAlpha and " {0-1}" or ""))
1300 return
1301 end
1302 if passTable then
1303 if type(passTable.set) == "function" then
1304 passTable.set(passValue, r,g,b,a)
1305 else
1306 if type(handler[passTable.set]) ~= "function" then
1307 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.set)
1308 end
1309 handler[passTable.set](handler, passValue, r,g,b,a)
1310 end
1311 else
1312 if type(options.set) == "function" then
1313 options.set(r,g,b,a)
1314 else
1315 if type(handler[options.set]) ~= "function" then
1316 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.set)
1317 end
1318 handler[options.set](handler, r,g,b,a)
1319 end
1320 end
1321  
1322 local r,g,b,a
1323 if passTable then
1324 if type(passTable.get) == "function" then
1325 r,g,b,a = passTable.get(passValue)
1326 else
1327 if type(handler[passTable.get]) ~= "function" then
1328 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1329 end
1330 r,g,b,a = handler[passTable.get](handler, passValue)
1331 end
1332 else
1333 if type(options.get) == "function" then
1334 r,g,b,a = options.get()
1335 else
1336 if type(handler[options.get]) ~= "function" then
1337 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1338 end
1339 r,g,b,a = handler[options.get](handler)
1340 end
1341 end
1342  
1343 local s
1344 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
1345 if options.hasAlpha and type(a) == "number" then
1346 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255)
1347 else
1348 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255)
1349 end
1350 else
1351 s = NONE
1352 end
1353 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), s), realOptions.cmdName or realOptions.name or self)
1354 else
1355 local r,g,b,a
1356 if passTable then
1357 if type(passTable.get) == "function" then
1358 r,g,b,a = passTable.get(passValue)
1359 else
1360 if type(handler[passTable.get]) ~= "function" then
1361 AceConsole:error(OPTION_HANDLER_NOT_FOUND, passTable.get)
1362 end
1363 r,g,b,a = handler[passTable.get](handler, passValue)
1364 end
1365 else
1366 if type(options.get) == "function" then
1367 r,g,b,a = options.get()
1368 else
1369 if type(handler[options.get]) ~= "function" then
1370 AceConsole:error(OPTION_HANDLER_NOT_FOUND, options.get)
1371 end
1372 r,g,b,a = handler[options.get](handler)
1373 end
1374 end
1375  
1376 if not colorTable then
1377 colorTable = {}
1378 local t = colorTable
1379  
1380 if ColorPickerOkayButton then
1381 local ColorPickerOkayButton_OnClick = ColorPickerOkayButton:GetScript("OnClick")
1382 ColorPickerOkayButton:SetScript("OnClick", function()
1383 if ColorPickerOkayButton_OnClick then
1384 ColorPickerOkayButton_OnClick()
1385 end
1386 if t.active then
1387 ColorPickerFrame.cancelFunc = nil
1388 ColorPickerFrame.func = nil
1389 ColorPickerFrame.opacityFunc = nil
1390 local r,g,b,a
1391 if t.passValue then
1392 if type(t.get) == "function" then
1393 r,g,b,a = t.get(t.passValue)
1394 else
1395 if type(t.handler[t.get]) ~= "function" then
1396 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.get)
1397 end
1398 r,g,b,a = t.handler[t.get](t.handler, t.passValue)
1399 end
1400 else
1401 if type(t.get) == "function" then
1402 r,g,b,a = t.get()
1403 else
1404 if type(t.handler[t.get]) ~= "function" then
1405 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.get)
1406 end
1407 r,g,b,a = t.handler[t.get](t.handler)
1408 end
1409 end
1410 if r ~= t.r or g ~= t.g or b ~= t.b or (t.hasAlpha and a ~= t.a) then
1411 local s
1412 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
1413 if t.hasAlpha and type(a) == "number" then
1414 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255)
1415 else
1416 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255)
1417 end
1418 else
1419 s = NONE
1420 end
1421 print(string.format(t.message, tostring(t.name), s), t.realOptions.cmdName or t.realOptions.name or self)
1422 end
1423 for k,v in pairs(t) do
1424 t[k] = nil
1425 end
1426 end
1427 end)
1428 end
1429 else
1430 for k,v in pairs(colorTable) do
1431 colorTable[k] = nil
1432 end
1433 end
1434  
1435 if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then
1436 r,g,b = 1, 1, 1
1437 end
1438 if type(a) ~= "number" then
1439 a = 1
1440 end
1441 local t = colorTable
1442 t.r = r
1443 t.g = g
1444 t.b = b
1445 if hasAlpha then
1446 t.a = a
1447 end
1448 t.realOptions = realOptions
1449 t.hasAlpha = options.hasAlpha
1450 t.handler = handler
1451 t.set = passTable and passTable.set or options.set
1452 t.get = passTable and passTable.get or options.get
1453 t.name = options.cmdName or options.name
1454 t.message = options.message or IS_NOW_SET_TO
1455 t.passValue = passValue
1456 t.active = true
1457  
1458 if not colorFunc then
1459 colorFunc = function()
1460 local r,g,b = ColorPickerFrame:GetColorRGB()
1461 if t.hasAlpha then
1462 local a = 1 - OpacitySliderFrame:GetValue()
1463 if type(t.set) == "function" then
1464 if t.passValue then
1465 t.set(t.passValue, r,g,b,a)
1466 else
1467 t.set(r,g,b,a)
1468 end
1469 else
1470 if type(t.handler[t.set]) ~= "function" then
1471 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.set)
1472 end
1473 if t.passValue then
1474 t.handler[t.set](t.handler, t.passValue, r,g,b,a)
1475 else
1476 t.handler[t.set](t.handler, r,g,b,a)
1477 end
1478 end
1479 else
1480 if type(t.set) == "function" then
1481 if t.passValue then
1482 t.set(t.passValue, r,g,b)
1483 else
1484 t.set(r,g,b)
1485 end
1486 else
1487 if type(t.handler[t.set]) ~= "function" then
1488 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.set)
1489 end
1490 if t.passValue then
1491 t.handler[t.set](t.handler, t.passValue, r,g,b)
1492 else
1493 t.handler[t.set](t.handler, r,g,b)
1494 end
1495 end
1496 end
1497 end
1498 end
1499  
1500 ColorPickerFrame.func = colorFunc
1501 ColorPickerFrame.hasOpacity = options.hasAlpha
1502 if options.hasAlpha then
1503 ColorPickerFrame.opacityFunc = ColorPickerFrame.func
1504 ColorPickerFrame.opacity = 1 - a
1505 end
1506 ColorPickerFrame:SetColorRGB(r,g,b)
1507  
1508 if not colorCancelFunc then
1509 colorCancelFunc = function()
1510 if t.hasAlpha then
1511 if type(t.set) == "function" then
1512 if t.passValue then
1513 t.set(t.passValue, t.r,t.g,t.b,t.a)
1514 else
1515 t.set(t.r,t.g,t.b,t.a)
1516 end
1517 else
1518 if type(t.handler[t.get]) ~= "function" then
1519 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.get)
1520 end
1521 if t.passValue then
1522 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b,t.a)
1523 else
1524 t.handler[t.set](t.handler, t.r,t.g,t.b,t.a)
1525 end
1526 end
1527 else
1528 if type(t.set) == "function" then
1529 if t.passValue then
1530 t.set(t.passValue, t.r,t.g,t.b)
1531 else
1532 t.set(t.r,t.g,t.b)
1533 end
1534 else
1535 if type(t.handler[t.set]) ~= "function" then
1536 AceConsole:error(OPTION_HANDLER_NOT_FOUND, t.set)
1537 end
1538 if t.passValue then
1539 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b)
1540 else
1541 t.handler[t.set](t.handler, t.r,t.g,t.b)
1542 end
1543 end
1544 end
1545 for k,v in pairs(t) do
1546 t[k] = nil
1547 end
1548 ColorPickerFrame.cancelFunc = nil
1549 ColorPickerFrame.func = nil
1550 ColorPickerFrame.opacityFunc = nil
1551 end
1552 end
1553  
1554 ColorPickerFrame.cancelFunc = colorCancelFunc
1555  
1556 ShowUIPanel(ColorPickerFrame)
1557 end
1558 return
1559 elseif kind == "group" then
1560 if table.getn(args) == 0 then
1561 printUsage(self, handler, realOptions, options, path, args)
1562 else
1563 -- invalid argument
1564 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, args[1], path), realOptions.cmdName or realOptions.name or self)
1565 end
1566 return
1567 end
1568 this = _G_this
1569 if Dewdrop then
1570 Dewdrop:Refresh(1)
1571 Dewdrop:Refresh(2)
1572 Dewdrop:Refresh(3)
1573 Dewdrop:Refresh(4)
1574 Dewdrop:Refresh(5)
1575 end
1576 end
1577  
1578 local external
1579 function AceConsole:RegisterChatCommand(slashCommands, options, name)
1580 if type(slashCommands) ~= "table" and slashCommands ~= false then
1581 AceConsole:error("Bad argument #2 to `RegisterChatCommand' (expected table, got %s)", type(slashCommands))
1582 end
1583 if not slashCommands and type(name) ~= "string" then
1584 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string, got %s)", type(name))
1585 end
1586 if type(options) ~= "table" and type(options) ~= "function" and options ~= nil then
1587 AceConsole:error("Bad argument #3 to `RegisterChatCommand' (expected table, function, or nil, got %s)", type(options))
1588 end
1589 if name then
1590 if type(name) ~= "string" then
1591 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string or nil, got %s)", type(name))
1592 elseif not string.find(name, "^%w+$") or string.upper(name) ~= name or string.len(name) == 0 then
1593 AceConsole:error("Argument #4 must be an uppercase, letters-only string with at least 1 character")
1594 end
1595 end
1596 if slashCommands then
1597 if table.getn(slashCommands) == 0 then
1598 AceConsole:error("Argument #2 to `RegisterChatCommand' must include at least one string")
1599 end
1600  
1601 for k,v in pairs(slashCommands) do
1602 if type(k) ~= "number" then
1603 AceConsole:error("All keys in argument #2 to `RegisterChatCommand' must be numbers")
1604 end
1605 if type(v) ~= "string" then
1606 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be strings")
1607 elseif not string.find(v, "^/[A-Za-z][A-Za-z0-9_]*$") then
1608 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be in the form of \"/word\"")
1609 end
1610 end
1611 end
1612  
1613 if not options then
1614 options = {
1615 type = 'group',
1616 args = {},
1617 handler = self
1618 }
1619 end
1620  
1621 if type(options) == "table" then
1622 local err, position = validateOptions(options)
1623 if err then
1624 if position then
1625 AceConsole:error(position .. ": " .. err)
1626 else
1627 AceConsole:error(err)
1628 end
1629 end
1630  
1631 if not options.handler then
1632 options.handler = self
1633 end
1634  
1635 if options.handler == self and string.lower(options.type) == "group" and self.class then
1636 AceConsole:InjectAceOptionsTable(self, options)
1637 end
1638 end
1639  
1640 local chat
1641 if slashCommands then
1642 chat = slashCommands[1]
1643 else
1644 chat = _G["SLASH_"..name..1]
1645 end
1646  
1647 local handler
1648 if type(options) == "function" then
1649 handler = options
1650 for k,v in pairs(_G) do
1651 if handler == v then
1652 local k = k
1653 handler = function(msg)
1654 return _G[k](msg)
1655 end
1656 end
1657 end
1658 else
1659 function handler(msg)
1660 handlerFunc(self, chat, msg, options)
1661 end
1662 end
1663  
1664 if not _G.SlashCmdList then
1665 _G.SlashCmdList = {}
1666 end
1667  
1668 if not name then
1669 repeat
1670 name = string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1) .. string.char(math.random(26) + string.byte('A') - 1)
1671 until not _G.SlashCmdList[name]
1672 end
1673  
1674 if slashCommands then
1675 if _G.SlashCmdList[name] then
1676 local i = 0
1677 while true do
1678 i = i + 1
1679 if _G["SLASH_"..name..i] then
1680 _G["SLASH_"..name..i] = nil
1681 else
1682 break
1683 end
1684 end
1685 end
1686  
1687 local i = 0
1688 for _,command in ipairs(slashCommands) do
1689 i = i + 1
1690 _G["SLASH_"..name..i] = command
1691 if string.lower(command) ~= command then
1692 i = i + 1
1693 _G["SLASH_"..name..i] = string.lower(command)
1694 end
1695 end
1696 end
1697 _G.SlashCmdList[name] = handler
1698 if self ~= AceConsole and self.slashCommand == nil then
1699 self.slashCommand = chat
1700 end
1701  
1702 if not AceEvent and AceLibrary:HasInstance("AceEvent-2.0") then
1703 external(AceConsole, "AceEvent-2.0", AceLibrary("AceEvent-2.0"))
1704 end
1705 if AceEvent then
1706 if not AceConsole.nextAddon then
1707 AceConsole.nextAddon = {}
1708 end
1709 if type(options) == "table" then
1710 AceConsole.nextAddon[self] = options
1711 if not self.playerLogin then
1712 AceConsole:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
1713 end
1714 end
1715 end
1716  
1717 AceConsole.registry[name] = options
1718 end
1719  
1720 function AceConsole:InjectAceOptionsTable(handler, options)
1721 self:argCheck(handler, 2, "table")
1722 self:argCheck(options, 3, "table")
1723 if string.lower(options.type) ~= "group" then
1724 self:error('Cannot inject into options table argument #3 if its type is not "group"')
1725 end
1726 if options.handler ~= nil and options.handler ~= handler then
1727 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2")
1728 end
1729 options.handler = handler
1730 local class = handler.class
1731 if not class then
1732 self:error("Cannot retrieve AceOptions tables from a non-object argument #2")
1733 end
1734 while class and class ~= AceOO.Class do
1735 if type(class.GetAceOptionsDataTable) == "function" then
1736 local t = class:GetAceOptionsDataTable(handler)
1737 for k,v in pairs(t) do
1738 if type(options.args) ~= "table" then
1739 options.args = {}
1740 end
1741 if options.args[k] == nil then
1742 options.args[k] = v
1743 end
1744 end
1745 end
1746 local mixins = class.mixins
1747 if mixins then
1748 for mixin in pairs(mixins) do
1749 if type(mixin.GetAceOptionsDataTable) == "function" then
1750 local t = mixin:GetAceOptionsDataTable(handler)
1751 for k,v in pairs(t) do
1752 if type(options.args) ~= "table" then
1753 options.args = {}
1754 end
1755 if options.args[k] == nil then
1756 options.args[k] = v
1757 end
1758 end
1759 end
1760 end
1761 end
1762 class = class.super
1763 end
1764 return options
1765 end
1766  
1767 function AceConsole:PLAYER_LOGIN()
1768 self.playerLogin = true
1769 for addon, options in pairs(self.nextAddon) do
1770 local err, position = validateOptionsMethods(addon, options)
1771 if err then
1772 if position then
1773 error(tostring(addon) .. ": AceConsole: " .. position .. ": " .. err)
1774 else
1775 error(tostring(addon) .. ": AceConsole: " .. err)
1776 end
1777 end
1778 self.nextAddon[addon] = nil
1779 end
1780  
1781 self:RegisterChatCommand({ "/reload", "/rl", "/reloadui" }, ReloadUI, "RELOAD")
1782  
1783 local version = GetBuildInfo()
1784 if string.find(version, "^2%.") then
1785 -- 2.0.0
1786 self:RegisterChatCommand({ "/print" }, function(text)
1787 RunScript("local function func(...) local arg = {...}; for k = 1,select('#', ...) do arg[k] = tostring(arg[k]) end DEFAULT_CHAT_FRAME:AddMessage(table.concat(arg, ' ')) end func(" .. text .. ")")
1788 end, "PRINT")
1789 else
1790 self:RegisterChatCommand({ "/print" }, function(text)
1791 RunScript("local function func(...) for k = 1,table.getn(arg) do arg[k] = tostring(arg[k]) end DEFAULT_CHAT_FRAME:AddMessage(table.concat(arg, ' ')) end func(" .. text .. ")")
1792 end, "PRINT")
1793 end
1794 end
1795  
1796 function AceConsole:TabCompleteInfo(cmdpath)
1797 local _, _, cmd = string.find(cmdpath, "(/%S+)")
1798 if not cmd then
1799 return
1800 end
1801 local path = string.sub(cmdpath, string.len(cmd) + 2)
1802 for name in pairs(SlashCmdList) do --global
1803 if AceConsole.registry[name] then
1804 local i = 0
1805 while true do
1806 i = i + 1
1807 local scmd = _G["SLASH_"..name..i]
1808 if not scmd then break end
1809 if cmd == scmd then
1810 return name, cmd, path
1811 end
1812 end
1813 end
1814 end
1815 end
1816  
1817 function external(self, major, instance)
1818 if major == "AceEvent-2.0" then
1819 if not AceEvent then
1820 AceEvent = instance
1821  
1822 AceEvent:embed(self)
1823 end
1824 elseif major == "AceTab-2.0" then
1825 instance:RegisterTabCompletion("AceConsole", "%/.*", function(t, cmdpath, pos)
1826 local ac = AceLibrary("AceConsole-2.0")
1827 local name, cmd, path = ac:TabCompleteInfo(string.sub(cmdpath, 1, pos))
1828  
1829 if not ac.registry[name] then
1830 return false
1831 else
1832 local validArgs = findTableLevel(ac, ac.registry[name], cmd, path or "")
1833 if validArgs.args then
1834 for arg in pairs(validArgs.args) do
1835 table.insert(t, arg)
1836 end
1837 end
1838 end
1839 end, function(u, matches, gcs, cmdpath)
1840 local ac = AceLibrary("AceConsole-2.0")
1841 local name, cmd, path = ac:TabCompleteInfo(cmdpath)
1842 if ac.registry[name] then
1843 local validArgs, path2, argwork = findTableLevel(ac, ac.registry[name], cmd, path)
1844 printUsage(ac, validArgs.handler, ac.registry[name], validArgs, path2, argwork, not gcs or gcs ~= "", gcs)
1845 end
1846 end)
1847 elseif major == "Dewdrop-2.0" then
1848 Dewdrop = instance
1849 end
1850 end
1851  
1852 local function activate(self, oldLib, oldDeactivate)
1853 AceConsole = self
1854  
1855 self.super.activate(self, oldLib, oldDeactivate)
1856  
1857 if oldLib then
1858 self.registry = oldLib.registry
1859 self.nextAddon = oldLib.nextAddon
1860 end
1861 if not self.registry then
1862 self.registry = {}
1863 else
1864 for name,options in pairs(self.registry) do
1865 self:RegisterChatCommand(false, options, name)
1866 end
1867 end
1868  
1869 if oldDeactivate then
1870 oldDeactivate(oldLib)
1871 end
1872 end
1873  
1874 AceLibrary:Register(AceConsole, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
1875 AceConsole = AceLibrary(MAJOR_VERSION)