vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 if AceChatCmd then
2 PerfectRaid.AceChatCmd = AceChatCmd
3 else
4 local AceChatCmd = {}
5 PerfectRaid.AceChatCmd = AceChatCmd
6  
7 local Ace = {}
8  
9 function Ace:print(...)
10 local r,g,b,frame,delay
11 if( type(arg[1]) == "table" ) then
12 r,g,b,frame,delay = unpack(tremove(arg,1))
13 end
14 (frame or DEFAULT_CHAT_FRAME):AddMessage(self.concat(arg),r,g,b,1,delay or 5)
15 end
16  
17 function Ace.ParseWords(str, pat)
18 if( Ace.tostr(str) == "" ) then return {} end
19 local list = {}
20 for word in gfind(str, pat or "%S+") do
21 tinsert(list, word)
22 end
23 return list
24 end
25  
26 local ACE_CMD = {}
27 ACE_CMD.OPT_HELP = "?"
28 ACE_CMD.OPT_HELP_DESC = "Display extra information about this addon."
29 ACE_CMD.OPT_STANDBY = "standby"
30 ACE_CMD.OPT_STANDBY_DESC = "Toggle the addon's standby mode."
31 ACE_CMD.OPT_REPORT = "report"
32 ACE_CMD.OPT_REPORT_DESC = "Display the status of all settings."
33 ACE_CMD.OPT_INVALID = "Invalid option '%s' entered."
34 ACE_CMD.OPT_LIST_ADDONS = "Addon List"
35 ACE_CMD.OPT_LOAD_IS_LOADED = "%s is already loaded."
36 ACE_CMD.OPT_LOAD_ERROR = "%s could not be loaded because it is %s."
37 ACE_CMD.OPT_LOAD_LOADED = "%s is now loaded."
38 ACE_CMD.OPT_AUTO_OFF_MSG = "%s will no longer be loaded on demand at game start."
39 ACE_CMD.ERROR = "|cffff6060[error]|r"
40  
41 ACE_CMD.ADDON_NOTFOUND = "No addon named '%s' was found."
42 ACE_CMD.ADDON_ENABLED = "%s has been enabled. You must reload the game to load this addon."
43 ACE_CMD.ADDON_ENABLED_ALL = "All addons have been enabled. You must reload the game to load "..
44 "previously unloaded addons."
45 ACE_CMD.ADDON_DISABLED = "%s has been disabled but will remain loaded until you reload the game."
46 ACE_CMD.ADDON_DISABLED_ALL = "All addons except Ace itself have been disabled but will remain loaded "..
47 "until you reload the game."
48  
49 ACE_CMD.PROFILE_ADDON_ADDED = "%s has been added. Active profile: %s."
50 ACE_CMD.PROFILE_ALL_ADDED = "All addons have been added. Active profile: %s."
51 ACE_CMD.PROFILE_ALL = "all"
52 ACE_CMD.PROFILE_NO_PROFILE = "%s has no profiling options available."
53  
54 ACE_CMD.USAGE_ADDON_DESC = "|cffffff78[%s v%s]|r : %s"
55 ACE_CMD.USAGE_HEADER = "|cffffff78Usage:|r |cffd8c7ff%s|r %s"
56 ACE_CMD.USAGE_OPT_DESC = " - |cffffff78%s:|r %s"
57 ACE_CMD.USAGE_OPT_SEP = " | "
58 ACE_CMD.USAGE_OPT_OPEN = "["
59 ACE_CMD.USAGE_OPT_CLOSE = "]"
60 ACE_CMD.USAGE_OPTION = "|cffd8c7ff%s %s|r %s"
61 ACE_CMD.USAGE_NOINFO = "No further information"
62  
63 ACE_CMD.RESULT = "|cffffff78%s:|r %s"
64  
65 ACE_CMD.REPORT_STATUS = "Status"
66 ACE_CMD.REPORT_LINE = "%s [|cfff5f530%s|r]"
67 ACE_CMD.REPORT_LINE_PRE = " - "
68 ACE_CMD.REPORT_LINE_INDENT = " "
69  
70 ACE_CMD.REPORT_NO_VAL = "|cffc7c7c7no value|r"
71  
72  
73 -- Recursively iterate through the table and sub-tables until the entire table
74 -- structure is copied over. Note: I used to check whether the table was numerically
75 -- indexed and use two different for() loops, one with ipairs() and one without. I
76 -- did this because there seemed to be problems otherwise, but in rewriting this, I
77 -- haven't encountered any problems.
78 function Ace.CopyTable(into, from)
79 for key, val in from do
80 if( type(val) == "table" ) then
81 if( not into[key] ) then into[key] = {} end
82 Ace.CopyTable(into[key], val)
83 else
84 into[key] = val
85 end
86 end
87  
88 if (getn(from)) then
89 table.setn(into, getn(from))
90 end
91  
92 return into
93 end
94  
95 function Ace.GetTableKeys(tbl)
96 local t = {}
97 for key, val in pairs(tbl) do
98 tinsert(t, key)
99 end
100 return(t)
101 end
102  
103 function Ace.TableFindKeyCaseless(tbl, key)
104 key = strlower(key)
105 for i, val in tbl do
106 if( strlower(i) == key ) then return i, val end
107 end
108 end
109  
110 function Ace.TableFindByKeyValue(tbl, key, val, caseless)
111 if( not tbl ) then error("No table supplied to TableFindByKeyValue.", 2) end
112 for i, t in ipairs(tbl) do
113 if( (caseless and (strlower(t[key]) == strlower(val))) or (t[key] == val) ) then
114 return i, t
115 end
116 end
117 end
118  
119 function Ace.concat(t,sep)
120 local msg = ""
121 if( getn(t) > 0 ) then
122 for key, val in ipairs(t) do
123 if( msg ~= "" and sep ) then msg = msg..sep end
124 msg = msg..Ace.tostr(val)
125 end
126 else
127 for key, val in t do
128 if( msg ~= "" and sep ) then msg = msg..sep end
129 msg = msg..key.."="..Ace.tostr(val)
130 end
131 end
132 return msg
133 end
134  
135 function Ace.round(num)
136 return floor(Ace.tonum(num)+.5)
137 end
138  
139 function Ace.sort(tbl, comp)
140 sort(tbl, comp)
141 return tbl
142 end
143  
144 function Ace.strlen(str)
145 return strlen(str or "")
146 end
147  
148 function Ace.tonum(val, base)
149 return tonumber((val or 0), base) or 0
150 end
151  
152 function Ace.tostr(val)
153 return tostring(val or "")
154 end
155  
156 function Ace.toggle(val)
157 if( val ) then return FALSE end
158 return TRUE
159 end
160  
161 function Ace.trim(str, opt)
162 if( (not opt) or (opt=="left" ) ) then str = gsub(str, "^%s*", "") end
163 if( (not opt) or (opt=="right") ) then str = gsub(str, "%s*$", "") end
164 return str
165 end
166  
167 -- Object constructor
168 function AceChatCmd:new(commands,options)
169 self.__index = self
170 return setmetatable({_cmdList=commands,options=options}, self)
171 end
172  
173 --[[---------------------------------------------------------------------------------
174 Reporting Methods
175 ------------------------------------------------------------------------------------]]
176  
177 function AceChatCmd:result(...)
178 Ace:print(self.app.disabled and ACE_ADDON_STANDBY.." " or "",
179 format(ACE_CMD.RESULT, self.app.name, Ace.concat(arg))
180 )
181 end
182  
183 function AceChatCmd:msg(...) self:result(format(unpack(arg))) end
184 function AceChatCmd:error(...) self:result(ACE_CMD.ERROR.." ", format(unpack(arg))) end
185 function AceChatCmd:status(text, val, map)
186 if( map ) then val = map[val or 0] or val end
187 self:result(text, " ", ACE_TEXT_NOW_SET_TO, " ",
188 format(ACE_DISPLAY_OPTION, val or ACE_CMD.REPORT_NO_VAL)
189 )
190 end
191  
192 function AceChatCmd:report(hdr, def)
193 if( not def ) then def = hdr; hdr = nil end
194 Ace:print(hdr or format(ACE_CMD.RESULT,
195 self.app.name.." "..ACE_CMD.REPORT_STATUS,
196 self.app.disabled and ACE_ADDON_STANDBY or ""
197 )
198 )
199 for _, ref in ipairs(def) do
200 local val
201 if( ref.map ) then val = ref.map[ref.val or 0]
202 else val = ref.val
203 end
204 Ace:print(
205 (ref.indent
206 and (strrep(" ", strlen(ACE_CMD.REPORT_LINE_PRE))..
207 strrep(ACE_CMD.REPORT_LINE_INDENT, ref.indent))
208 or ACE_CMD.REPORT_LINE_PRE
209 ),
210 format(ACE_CMD.REPORT_LINE, ref.text, val or ACE_CMD.REPORT_NO_VAL)
211 )
212 end
213 end
214  
215  
216 --[[---------------------------------------------------------------------------------
217 Command Handling Methods
218 ------------------------------------------------------------------------------------]]
219  
220 function AceChatCmd:FindCommand(cmd)
221 cmd = strlower(cmd)
222 for index in SlashCmdList do
223 local i, cmdString = 0
224 repeat
225 i = i + 1
226 cmdString = getglobal("SLASH_"..index..i)
227 if( strlower(cmdString or "") == cmd ) then return TRUE end
228 until( not cmdString )
229 end
230 end
231  
232 function AceChatCmd:Register(handler)
233 if( not self._cmdList ) then
234 error("Attempt to register command handler without defining commands.", 2)
235 end
236 if( self.registered ) then return end
237  
238 local slashID = strupper(self.app.name).."_CMD"
239  
240 SlashCmdList[slashID] = function(msg) self:ProcessCommand(msg) end
241 local i = 0
242 for index, cmd in self._cmdList do
243 if( not self:FindCommand(cmd) ) then
244 if( not self.commands ) then self.commands = {} end
245 i = i + 1
246 tinsert(self.commands, cmd)
247 setglobal("SLASH_"..slashID..i, cmd)
248 end
249 end
250  
251 self.handler = handler or self
252  
253 if( not self.options ) then self.options = {} end
254  
255 if( self.handler.Report ) then
256 tinsert(self.options, 1, {
257 option = ACE_CMD.OPT_REPORT,
258 desc = ACE_CMD.OPT_REPORT_DESC,
259 method = "Report"
260 }
261 )
262 end
263  
264 if( self.app.Enable ) then
265 tinsert(self.options, 1, {
266 option = ACE_CMD.OPT_STANDBY,
267 desc = format(ACE_CMD.OPT_STANDBY_DESC, self.app.name),
268 method = "ToggleStandBy"
269 }
270 )
271 end
272  
273 tinsert(self.options, 1, {option = ACE_CMD.OPT_HELP, desc = ACE_CMD.OPT_HELP_DESC})
274  
275 -- Create a closure for printing option lines, since it's done so much
276 self.printOpt = function(l,t) Ace:print(format(ACE_CMD.USAGE_OPT_DESC,l,t)) end
277 self.registered = TRUE
278 end
279  
280 function AceChatCmd:ProcessCommand(msg)
281 msg = Ace.trim(msg or "")
282  
283 if( strfind(strlower(msg), ACE_CMD.OPT_HELP) == 1 ) then
284 self:DisplayAddonInfo(self.options)
285 return
286 elseif( msg ~= "" ) then
287 return self:ProcessOptions(self.options, msg, self.handler, self.handler.CommandHandler)
288 elseif( self.handler.CommandHandler ) then
289 self.handler.CommandHandler(self.handler, msg)
290 return
291 end
292  
293 self:DisplayUsage()
294 end
295  
296 function AceChatCmd:ProcessOptions(list, msg, handler, method, opttext)
297 local _, _, cmd = strfind(strlower(msg), "(%S+)")
298 local args = gsub(msg, cmd.."%s*", "")
299  
300 local i = Ace.TableFindByKeyValue(list, "option", cmd, TRUE)
301 if( i ) then
302 local opt = list[i]
303 if( opt.args and (args ~= "") and
304 self:ProcessOptions(opt.args,
305 args,
306 opt.handler or handler,
307 opt.method or method,
308 opttext and opttext.." "..opt.option or opt.option
309 )
310 ) then
311 return TRUE
312 elseif( opt.method and ((args ~= "") or (not opt.input)) and
313 (strlower(args) ~= ACE_CMD.OPT_HELP)
314 ) then
315 handler = opt.handler or handler
316 handler[opt.method](handler, args)
317 return TRUE
318 elseif( opt.input and (args == "") or (opt.args and (not method)) or
319 (strlower(args) == ACE_CMD.OPT_HELP)
320 ) then
321 self:OptionHeader(opt, opttext)
322 self:DisplayArgUsage(opt)
323 return TRUE
324 end
325 elseif( ((cmd or "") ~= "") and (cmd ~= ACE_CMD.OPT_HELP) and (not method) ) then
326 self:result(format(ACE_CMD.OPT_INVALID, cmd))
327 return TRUE
328 end
329 end
330  
331  
332 --[[---------------------------------------------------------------------------------
333 Usage Display Methods
334 ------------------------------------------------------------------------------------]]
335  
336 function AceChatCmd:DisplayAddonInfo()
337 self:CommandHeader()
338 if( self.commands ) then
339 self.printOpt(ACE_TEXT_COMMANDS, Ace.concat(self.commands, " | "))
340 end
341 if( self.app.author ) then self.printOpt(ACE_TEXT_AUTHOR, self.app.author) end
342 if( self.app.releaseDate ) then self.printOpt(ACE_TEXT_RELEASED, self.app.releaseDate) end
343 if( self.app.email ) then self.printOpt(ACE_TEXT_EMAIL, self.app.email) end
344 if( self.app.website ) then self.printOpt(ACE_TEXT_WEBSITE, self.app.website) end
345 end
346  
347 function AceChatCmd:OptionHeader(option, opttext)
348 local args
349 if( option.args ) then
350 args = self:ConcatOptions(option.args, ACE_CMD.USAGE_OPT_SEP)
351 end
352 if( not args ) then
353 args = "- "..(option.desc or ACE_CMD.USAGE_NOINFO)
354 end
355 Ace:print(format(ACE_CMD.USAGE_OPTION,
356 self.commands[1],
357 opttext and opttext.." "..option.option or option.option,
358 args
359 )
360 )
361 end
362  
363 function AceChatCmd:DisplayArgUsage(option)
364 if( not option.args ) then return end
365 for _, arg in ipairs(option.args) do
366 self.printOpt(arg.option, arg.desc)
367 end
368 end
369  
370 function AceChatCmd:DisplayUsage()
371 self:CommandHeader()
372  
373 if( getn(self.options) < 1 ) then return end
374  
375 Ace:print(format(ACE_CMD.USAGE_HEADER,
376 self.commands[1],
377 self:ConcatOptions(self.options, ACE_CMD.USAGE_OPT_SEP)
378 )
379 )
380  
381 -- Have to print the lines one at a time or risk it getting too large for the
382 -- print buffer.
383 for _, opt in ipairs(self.options) do
384 self.printOpt(opt.option, opt.desc)
385 end
386 end
387  
388 function AceChatCmd:CommandHeader()
389 Ace:print(self.app.disabled and ACE_ADDON_STANDBY.." " or "",
390 format(ACE_CMD.USAGE_ADDON_DESC,
391 self.app.name,
392 self.app.version,
393 self.app.description
394 )
395 )
396 end
397  
398 function AceChatCmd:ConcatOptions(options, sep)
399 local str = ""
400 for _, opt in options do
401 if( (str ~= "") and sep ) then str = str..sep end
402 str = str..opt.option
403 end
404 return str
405 end
406 end