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