Mercurial > wow > guild-delta
comparison gd.lua @ 3:7b31138c3c8e
- Add option to print message even on no changes.
- Split up options panel into tabs.
- Make localization (such as it is) table accessible through addon table.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Mon, 29 Nov 2010 01:52:48 +0000 |
parents | fb9a91642a60 |
children | 9527583a842b |
comparison
equal
deleted
inserted
replaced
2:fb9a91642a60 | 3:7b31138c3c8e |
---|---|
2 local addon = CreateFrame("Frame") --select(2,...) | 2 local addon = CreateFrame("Frame") --select(2,...) |
3 local SV | 3 local SV |
4 | 4 |
5 local DEFAULT_CHAT = 2 -- combat log (no constant predefined for that) | 5 local DEFAULT_CHAT = 2 -- combat log (no constant predefined for that) |
6 | 6 |
7 local l10n | |
8 --if GetLocale() == "enUS" then | 7 --if GetLocale() == "enUS" then |
9 l10n= { | 8 addon.l10n= { |
10 ["LEFT"] = "Players who have left the guild: ", | 9 ["LEFT"] = "Players who have left the guild: ", |
11 ["JOINED"] = "Players who have joined the guild: ", | 10 ["JOINED"] = "Players who have joined the guild: ", |
12 ["RANK"] = "Players whose rank has changed:", | 11 ["RANK"] = "Players whose rank has changed:", |
13 ["LEVEL"] = "Players whose level has changed:", | 12 ["LEVEL"] = "Players whose level has changed:", |
14 ["NOTES"] = "Players whose notes have changed:", | 13 ["NOTES"] = "Players whose notes have changed:", |
15 | 14 |
16 ["Oabbrev"] = "O", -- abbreviation for "Officer", specifically the non-public note | 15 ["Oabbrev"] = "O", -- abbreviation for "Officer", specifically the non-public note |
17 ["FIELD_rank"] = "Rank", | 16 ["FIELD_rank"] = "Rank", |
18 ["FIELD_level"] = "Level", | 17 ["FIELD_level"] = "Level", |
19 ["FIELD_notes"] = "Player/Officer notes", | 18 ["FIELD_notes"] = "Player/Officer notes", |
20 | 19 |
21 -- Something needs to be done about the walls of description text below. | 20 ["NOCHANGE"] = "No changes to tracked fields have been detected.", |
22 } | 21 |
22 -- Something needs to be done about the walls of description text below. | |
23 } | |
23 --elseif .... end | 24 --elseif .... end |
24 | 25 |
25 local guild_selection, log_ever_shown | 26 local guild_selection, log_ever_shown |
26 addon.options = { | 27 addon.options = { |
27 name = "Guild Delta", | 28 name = "Guild Delta", |
28 type = 'group', | 29 type = 'group', |
30 childGroups = 'tab', | |
29 handler = addon, -- functions listed as strings called as addon:func | 31 handler = addon, -- functions listed as strings called as addon:func |
30 args = { | 32 args = { |
31 version = { | 33 version = { |
32 --name = filled in during OnEnable | 34 --name = filled in during OnEnable |
33 type = 'description', | 35 type = 'description', |
41 type = 'description', | 43 type = 'description', |
42 cmdHidden = true, | 44 cmdHidden = true, |
43 width = 'full', | 45 width = 'full', |
44 order = 2, | 46 order = 2, |
45 }, | 47 }, |
46 reset = { | 48 general = { |
47 name = "Reset Output", | 49 name = "General", |
48 desc = "Restores default output settings", | 50 desc = "Tracking options", |
49 type = 'execute', | 51 type = 'group', |
50 order = 5, | 52 order = 10, |
51 func = "SetChat", | 53 args = { |
52 arg = DEFAULT_CHAT, | 54 fields = { |
55 name = "Fields", | |
56 desc = "Track changes to these player fields", | |
57 type = 'multiselect', | |
58 order = 10, | |
59 -- these need to be of function type rather than string keys of members | |
60 values = function(info) return addon:MakeFieldList() end, | |
61 get = function(info,x) return SV.fields[x] end, | |
62 set = function(info,x,val) SV.fields[x] = val end, | |
63 }, | |
64 nochange = { | |
65 name = "No Change", | |
66 desc = "Print a message even when no changes are detected", | |
67 type = 'toggle', | |
68 order = 15, | |
69 get = function() return not not SV.notify_nochange end, | |
70 set = function(info,val) SV.notify_nochange = val end, | |
71 }, | |
72 spacer2 = { | |
73 name = '', | |
74 type = 'description', | |
75 cmdHidden = true, | |
76 width = 'full', | |
77 order = 19, | |
78 }, | |
79 guilds = { | |
80 name = "Guilds", | |
81 desc = "Guilds for which a roster is known", | |
82 type = 'select', | |
83 order = 20, | |
84 width = 'double', | |
85 values = function(info) return addon:MakeGuildList() end, | |
86 get = function(info) return guild_selection end, | |
87 set = function(info,val) guild_selection = val end, | |
88 }, | |
89 clearguild = { | |
90 name = "Reset Guild", | |
91 desc = "Erase stored data for selected guild; information will be scanned from scratch on next login.", | |
92 type = 'execute', | |
93 order = 22, | |
94 disabled = function() return not guild_selection end, | |
95 func = function() | |
96 assert(type(guild_selection)=='string') | |
97 local g,r = guild_selection:match("<([^>]+)> %- (.*)") | |
98 local m = SV.members[r] | |
99 if m then | |
100 m[g] = nil | |
101 else | |
102 addon:Print("Hm, error.", r, "can't be matched as a realm name. Please report this as a bug, including the name of the realm and guild.") | |
103 end | |
104 end, | |
105 }, | |
106 }, | |
53 }, | 107 }, |
54 spacer2 = { | 108 output = { |
55 name = '', | 109 name = "Output", |
56 type = 'description', | 110 desc = "What and where to print", |
57 cmdHidden = true, | 111 type = 'group', |
58 width = 'full', | |
59 order = 6, | |
60 }, | |
61 print_chatframes = { | |
62 name = "Print Chatframe Numbers", | |
63 desc = "Print each chat window number in its frame, for easy reference in the next slider option", | |
64 type = 'execute', | |
65 --func = print_chatframes filled in below | |
66 order = 10, | |
67 }, | |
68 chatframe_num = { | |
69 name = "Output Chatframe", | |
70 desc = "Which chat window to prefer for printing all the output during login", | |
71 type = 'range', | |
72 min = 1, | |
73 max = NUM_CHAT_WINDOWS, | |
74 step = 1, | |
75 get = function() return tonumber(SV.chatframe) or --[[in case of custom name]]DEFAULT_CHAT end, | |
76 set = "SetChat", | |
77 order = 15, | |
78 }, | |
79 chatframe_name = { | |
80 name = "Chatframe Override", | |
81 desc = "<Advanced> If blank, uses the numerical slider. If set, it is the NAME of a frame with AddMessage capability to use for output.", | |
82 type = 'input', | |
83 get = function() | |
84 return type(SV.chatframe) == 'string' and SV.chatframe or nil | |
85 end, | |
86 set = "SetChat", | |
87 order = 16, | |
88 }, | |
89 fields = { | |
90 name = "Fields", | |
91 desc = "Track changes to these player fields", | |
92 type = 'multiselect', | |
93 order = 20, | 112 order = 20, |
94 -- these need to be of function type rather than string keys of members | 113 args = { |
95 values = function(info) return addon:MakeFieldList() end, | 114 reset = { |
96 get = function(info,x) return SV.fields[x] end, | 115 name = "Reset Output", |
97 set = function(info,x,val) SV.fields[x] = val end, | 116 desc = "Restores default output settings", |
98 }, | 117 type = 'execute', |
99 spacer1 = { | 118 order = 10, |
100 name = '', | 119 func = "SetChat", |
101 type = 'description', | 120 arg = DEFAULT_CHAT, |
102 cmdHidden = true, | 121 }, |
103 width = 'full', | 122 spacer1 = { |
104 order = 29, | 123 name = '', |
105 }, | 124 type = 'description', |
106 guilds = { | 125 cmdHidden = true, |
107 name = "Guilds", | 126 width = 'full', |
108 desc = "Guilds for which a roster is known", | 127 order = 11, |
109 type = 'select', | 128 }, |
110 order = 30, | 129 print_chatframes = { |
111 width = 'double', | 130 name = "Print Chatframe Numbers", |
112 values = function(info) return addon:MakeGuildList() end, | 131 desc = "Print each chat window number in its frame, for easy reference in the next slider option", |
113 get = function(info) return guild_selection end, | 132 type = 'execute', |
114 set = function(info,val) guild_selection = val end, | 133 --func = print_chatframes filled in below |
115 }, | 134 order = 20, |
116 clearguild = { | 135 }, |
117 name = "Reset Guild", | 136 chatframe_num = { |
118 desc = "Erase stored data for selected guild; information will be scanned from scratch on next login.", | 137 name = "Output Chatframe", |
119 type = 'execute', | 138 desc = "Which chat window to prefer for printing all the output during login", |
120 order = 32, | 139 type = 'range', |
121 disabled = function() return not guild_selection end, | 140 min = 1, |
122 func = function() | 141 max = NUM_CHAT_WINDOWS, |
123 assert(type(guild_selection)=='string') | 142 step = 1, |
124 local g,r = guild_selection:match("<([^>]+)> %- (.*)") | 143 get = function() return tonumber(SV.chatframe) or --[[in case of custom name]]DEFAULT_CHAT end, |
125 local m = SV.members[r] | 144 set = "SetChat", |
126 if m then | 145 order = 25, |
127 m[g] = nil | 146 }, |
128 else | 147 chatframe_name = { |
129 addon:Print("Hm, error.", r, "can't be matched as a realm name. Please report this as a bug, including the name of the realm and guild.") | 148 name = "Chatframe Override", |
130 end | 149 desc = "<Advanced> If blank, uses the numerical slider. If set, it is the NAME of a frame with AddMessage capability to use for output.", |
131 end, | 150 type = 'input', |
151 get = function() | |
152 return type(SV.chatframe) == 'string' and SV.chatframe or nil | |
153 end, | |
154 set = "SetChat", | |
155 order = 26, | |
156 }, | |
157 }, | |
132 }, | 158 }, |
133 persist = { | 159 persist = { |
134 name = "Logging", | 160 name = "Logging", |
161 desc = "Storing changes for later review", | |
135 type = 'group', | 162 type = 'group', |
136 inline = true, | 163 order = 30, |
137 order = 60, | |
138 args = { | 164 args = { |
139 note = { | 165 note = { |
140 --name = filled in locals section | 166 --name = filled in locals section |
141 type = 'description', | 167 type = 'description', |
142 cmdHidden = true, | 168 cmdHidden = true, |
143 width = 'full', | 169 width = 'full', |
144 order = 1, | 170 order = 10, |
145 }, | 171 }, |
146 enable = { | 172 enable = { |
147 name = "Enable Logging", | 173 name = "Enable Logging", |
148 desc = [[Accumulate all deltas, including a timestamp. |cffFF0000WARNING|r: if logging was enabled and you turn it off, the log itself will not be saved when exiting the game.]], | 174 desc = [[Accumulate all deltas, including a timestamp. |cffFF0000WARNING|r: if logging was enabled and you turn it off, the log itself will not be saved when exiting the game.]], |
149 type = 'toggle', | 175 type = 'toggle', |
150 order = 2, | 176 order = 15, |
151 get = function() return SV.logging end, | 177 get = function() return SV.logging end, |
152 set = function(i,v) | 178 set = function(i,v) |
153 SV.logging = v | 179 SV.logging = v |
154 log_ever_shown = SV.logging or log_ever_shown | 180 log_ever_shown = SV.logging or log_ever_shown |
155 end, | 181 end, |
156 }, | 182 }, |
157 clearlog = { | 183 clearlog = { |
158 name = "Reset Log", | 184 name = "Reset Log", |
159 desc = "Erase accumulated deltas.", | 185 desc = "Erase accumulated deltas.", |
160 type = 'execute', | 186 type = 'execute', |
161 order = 3, | 187 order = 20, |
162 hidden = function() return not (SV.logging or log_ever_shown) end, | 188 hidden = function() return not (SV.logging or log_ever_shown) end, |
163 disabled = function() return not SV.logging end, | 189 disabled = function() return not SV.logging end, |
164 func = function() | 190 func = function() |
165 SV.logtext = nil | 191 SV.logtext = nil |
166 end, | 192 end, |
167 }, | 193 }, |
168 log = { | 194 log = { |
169 name = "Log", | 195 name = "Log", |
170 desc = "If you make changes, don't forget to click 'Accept' to save them.", | 196 desc = "If you make changes, don't forget to click 'Accept' to save them. Scroll down if needed.", |
171 type = 'input', | 197 type = 'input', |
172 order = 10, | 198 order = 25, |
173 multiline = 15, | 199 multiline = 15, |
174 width = 'full', | 200 width = 'full', |
175 hidden = function() return not (SV.logging or log_ever_shown) end, | 201 hidden = function() return not (SV.logging or log_ever_shown) end, |
176 disabled = function() return not SV.logging end, | 202 disabled = function() return not SV.logging end, |
177 get = function() return SV.logtext end, | 203 get = function() return SV.logtext end, |
216 end | 242 end |
217 table.sort(ret, function (l,r) return l.name < r.name end) | 243 table.sort(ret, function (l,r) return l.name < r.name end) |
218 return ret | 244 return ret |
219 end | 245 end |
220 | 246 |
221 function addon.options.args.print_chatframes.func() | 247 function addon.options.args.output.args.print_chatframes.func() |
222 for i = 1, NUM_CHAT_WINDOWS do | 248 for i = 1, NUM_CHAT_WINDOWS do |
223 local cf = _G['ChatFrame'..i] | 249 local cf = _G['ChatFrame'..i] |
224 if not cf then break end | 250 if not cf then break end |
225 addon:Print(cf, "This is frame number", i) | 251 addon:Print(cf, "This is frame number", i) |
226 end | 252 end |
229 addon.options.args.note.name = | 255 addon.options.args.note.name = |
230 "You can use the '/guilddelta' command to open the options window.\n\n".. | 256 "You can use the '/guilddelta' command to open the options window.\n\n".. |
231 "The guild roster has already been scanned by the time you see this. Therefore, ".. | 257 "The guild roster has already been scanned by the time you see this. Therefore, ".. |
232 "if you make any changes to the Fields section below, you should probably relog ".. | 258 "if you make any changes to the Fields section below, you should probably relog ".. |
233 "immediately to begin tracking the changed fields. Changes to the contents *OF* ".. | 259 "immediately to begin tracking the changed fields. Changes to the contents *OF* ".. |
234 "those fields will not be noticed until the first login after *that*.\n\n" | 260 "those fields will not be noticed until the first login after *that*.\n" |
235 | 261 |
236 addon.options.args.persist.args.note.name = | 262 addon.options.args.persist.args.note.name = |
237 "Enabling logging will accumulate the text of the 'deltas' as you see them. ".. | 263 "Enabling logging will accumulate the text of the 'deltas' as you see them. ".. |
238 "This can grow large over time, depending on the activity of your guilds, so you ".. | 264 "This can grow large over time, depending on the activity of your guilds, so you ".. |
239 "should use the Reset Log button below from time to time.\n\n".. | 265 "should use the Reset Log button below from time to time.\n\n".. |
243 "changes, add reminders to yourself, and so forth.)\n\n" | 269 "changes, add reminders to yourself, and so forth.)\n\n" |
244 | 270 |
245 | 271 |
246 ----------------------------------------------------------------------------- | 272 ----------------------------------------------------------------------------- |
247 addon = LibStub("AceAddon-3.0"):NewAddon(addon, "GuildDelta", | 273 addon = LibStub("AceAddon-3.0"):NewAddon(addon, "GuildDelta", |
248 "AceConsole-3.0") | 274 "AceConsole-3.0") |
249 | 275 |
250 function addon:OnInitialize() | 276 function addon:OnInitialize() |
251 if _G.GuildDeltaSV == nil then | 277 if _G.GuildDeltaSV == nil then |
252 -- Defaults need to transition from potential older savedvars | 278 -- Defaults need to transition from potential older savedvars |
253 _G.GuildDeltaSV = { | 279 _G.GuildDeltaSV = { |
254 chatframe = _G.GuildDelta_chatframe or DEFAULT_CHAT, | 280 chatframe = _G.GuildDelta_chatframe or DEFAULT_CHAT, |
255 fields = _G.GuildDelta_fields or { rank = true, level = false, notes = true }, | 281 fields = _G.GuildDelta_fields or { rank = true, level = false, notes = true }, |
256 members = _G.GuildDelta_memberdata or {} | 282 members = _G.GuildDelta_memberdata or {}, |
283 --notify_nochange = nil by default | |
284 --logging = nil by default | |
257 } | 285 } |
258 end | 286 end |
259 SV = _G.GuildDeltaSV | 287 SV = _G.GuildDeltaSV |
260 end | 288 end |
261 | 289 |
271 end | 299 end |
272 -- Remove everything. | 300 -- Remove everything. |
273 function addon:unload() | 301 function addon:unload() |
274 self:cleanup() | 302 self:cleanup() |
275 LibStub("AceAddon-3.0").addons["GuildDelta"] = nil | 303 LibStub("AceAddon-3.0").addons["GuildDelta"] = nil |
276 l10n = nil; addon = nil; | 304 addon = nil; |
277 -- put the userdata back so it counts as a Frame object again | 305 -- put the userdata back so it counts as a Frame object again |
278 local ud = self[0] | 306 local ud = self[0] |
279 table.wipe(self) | 307 table.wipe(self) |
280 self[0] = ud | 308 self[0] = ud |
281 end | 309 end |
284 if not IsInGuild() then | 312 if not IsInGuild() then |
285 self:Print("You are not in a guild, not loading.") | 313 self:Print("You are not in a guild, not loading.") |
286 return self:unload() | 314 return self:unload() |
287 end | 315 end |
288 | 316 |
289 AutoCompleteInfoDelayer:HookScript("OnFinished", | 317 self:RegisterEvent("GUILD_ROSTER_UPDATE") |
290 function() self:RegisterEvent("GUILD_ROSTER_UPDATE") end) | |
291 self:SetScript("OnEvent", self.GuildUpdate) | 318 self:SetScript("OnEvent", self.GuildUpdate) |
292 | 319 |
293 self.options.args.version.name = | 320 self.options.args.version.name = |
294 "|cff30adffVersion " .. (GetAddOnMetadata("GuildDelta", "Version") or "?") .. "|r" | 321 "|cff30adffVersion " .. (GetAddOnMetadata("GuildDelta", "Version") or "?") .. "|r" |
295 LibStub("AceConfig-3.0"):RegisterOptionsTable("GuildDelta", self.options) | 322 LibStub("AceConfig-3.0"):RegisterOptionsTable("GuildDelta", self.options) |
377 self:Print("Your accumulated logfile has grown rather large; you should consider copying it out and clearing it.") | 404 self:Print("Your accumulated logfile has grown rather large; you should consider copying it out and clearing it.") |
378 end | 405 end |
379 | 406 |
380 local guild, realm = (GetGuildInfo("player")), GetRealmName() | 407 local guild, realm = (GetGuildInfo("player")), GetRealmName() |
381 local members = SV.members | 408 local members = SV.members |
409 local l10n = self.l10n | |
382 if members[realm] | 410 if members[realm] |
383 and members[realm][guild] | 411 and members[realm][guild] |
384 and #(members[realm][guild]) > 0 | 412 and #(members[realm][guild]) > 0 |
385 then | 413 then |
386 -- moved the normal case below | 414 -- moved the normal case below |
391 members[realm][guild] = self:current_guild_info(current_n) | 419 members[realm][guild] = self:current_guild_info(current_n) |
392 return self:cleanup() | 420 return self:cleanup() |
393 end | 421 end |
394 | 422 |
395 -- table.insert with notes if available | 423 -- table.insert with notes if available |
396 -- concatentation of all strings faster than string.format | 424 -- concatentation of string-only args faster than string.format of same |
397 local function tins (t, x) | 425 local function tins (t, x) |
398 local s = x.name | 426 local s = x.name |
399 if x.onote and (x.onote ~= "") then | 427 if x.onote and (x.onote ~= "") then |
400 s = s .. "(" .. l10n.Oabbrev .. ": " .. x.onote .. ")" | 428 s = s .. "(" .. l10n.Oabbrev .. ": " .. x.onote .. ")" |
401 end | 429 end |
454 tins (joined, current[i]) | 482 tins (joined, current[i]) |
455 end | 483 end |
456 | 484 |
457 -- show results | 485 -- show results |
458 if SV.logging then self.logquay = {} end | 486 if SV.logging then self.logquay = {} end |
459 local m | 487 local m, changes |
460 if #left > 0 then | 488 if #left > 0 then |
489 changes = true | |
461 m = l10n.LEFT .. table.concat(left, ", ") | 490 m = l10n.LEFT .. table.concat(left, ", ") |
462 cprt(m) | 491 cprt(m) |
463 end | 492 end |
464 | 493 |
465 if #joined > 0 then | 494 if #joined > 0 then |
495 changes = true | |
466 m = l10n.JOINED .. table.concat(joined, ", ") | 496 m = l10n.JOINED .. table.concat(joined, ", ") |
467 cprt(m) | 497 cprt(m) |
468 end | 498 end |
469 | 499 |
470 if #rank > 0 then | 500 if #rank > 0 then |
501 changes = true | |
471 cprt(l10n.RANK) | 502 cprt(l10n.RANK) |
472 for i = 1, #rank do | 503 for i = 1, #rank do |
473 cprt(rank[i][1]..': '..rank[i][2]) | 504 cprt(rank[i][1]..': '..rank[i][2]) |
474 end | 505 end |
475 end | 506 end |
476 | 507 |
477 if #level > 0 then | 508 if #level > 0 then |
509 changes = true | |
478 cprt(l10n.LEVEL) | 510 cprt(l10n.LEVEL) |
479 for i = 1, #level do | 511 for i = 1, #level do |
480 cprt(level[i][1]..': '..level[i][2]) | 512 cprt(level[i][1]..': '..level[i][2]) |
481 end | 513 end |
482 end | 514 end |
483 | 515 |
484 if #notes > 0 then | 516 if #notes > 0 then |
517 changes = true | |
485 cprt(l10n.NOTES) | 518 cprt(l10n.NOTES) |
486 for i = 1, #notes do | 519 for i = 1, #notes do |
487 cprt(notes[i][1]..': "'..notes[i][2]..'"') | 520 cprt(notes[i][1]..': "'..notes[i][2]..'"') |
488 end | 521 end |
489 end | 522 end |
490 | 523 |
491 if SV.logging then self:FinishLog(guild,realm) end | 524 if SV.logging then self:FinishLog(guild,realm) end |
525 if SV.notify_nochange and (not changes) then cprt(l10n.NOCHANGE) end | |
492 members[realm][guild] = current | 526 members[realm][guild] = current |
493 self:cleanup() | 527 self:cleanup() |
494 end | 528 end |
495 | 529 |
496 | 530 |
497 function addon:MakeFieldList() | 531 function addon:MakeFieldList() |
498 if not fieldlist then | 532 if not fieldlist then |
499 fieldlist = {} | 533 fieldlist = {} |
500 for name in pairs(SV.fields) do | 534 for name in pairs(SV.fields) do |
501 fieldlist[name] = l10n["FIELD_"..name] | 535 fieldlist[name] = self.l10n["FIELD_"..name] |
502 end | 536 end |
503 end | 537 end |
504 return fieldlist | 538 return fieldlist |
505 end | 539 end |
506 | 540 |