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