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