comparison main.lua @ 15:3a2beea01a28

Use a paged window instead of a huge one. Make LoD. Show flag #14 rather than trying to skip it, but override the column header.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Fri, 03 Aug 2012 03:16:07 -0400
parents e6382ba088c3
children
comparison
equal deleted inserted replaced
14:efa948aae82f 15:3a2beea01a28
40 }, 40 },
41 guildcontrol = { 41 guildcontrol = {
42 name = L["Guild Control for non-GMs"], 42 name = L["Guild Control for non-GMs"],
43 desc = L["Make the grayed-out Guild Control button activate this addon instead."], 43 desc = L["Make the grayed-out Guild Control button activate this addon instead."],
44 type = 'toggle', 44 type = 'toggle',
45 width = 'double', -- else it gets cut off
45 order = 10, 46 order = 10,
46 }, 47 },
47 break1 = { 48 break1 = {
48 name = '', 49 name = '',
49 type = 'description', 50 type = 'description',
72 ----------------------------------------------------------------------------- 73 -----------------------------------------------------------------------------
73 -- other locals 74 -- other locals
74 local AceGUI = LibStub("AceGUI-3.0") 75 local AceGUI = LibStub("AceGUI-3.0")
75 local st_rowheight = 25 76 local st_rowheight = 25
76 local st_displayed_rows = 15 --math.floor(366/st_rowheight) 77 local st_displayed_rows = 15 --math.floor(366/st_rowheight)
77 local st_colwidth = 65 78 local st_colwidth = 80 --65
79 local cols_per_group = 6
80 local num_flagsets
78 local sidetabs 81 local sidetabs
79 local incomplete 82 local incomplete
80 83 local flagmap
81 -- Remove children ST widgets without explicitly Release()'ing them. 84
85 -- Remove children ST widgets without explicitly Release()'ing them. As there
86 -- are no children other than STs, no "normal" widget resources are leaked.
82 local function DisownChildren (container) 87 local function DisownChildren (container)
83 for i,v in ipairs(container.children) do 88 for i,v in ipairs(container.children) do
84 container.children[i] = nil 89 container.children[i] = nil
85 v.frame:Hide() 90 v.frame:Hide()
86 v.frame:ClearAllPoints() 91 v.frame:ClearAllPoints()
87 end 92 end
93 end
94
95 local function setstatus(txt)
96 addon.display:SetStatusText(txt)
97 addon.tooltip = #txt > 40 and txt or nil
88 end 98 end
89 99
90 100
91 ----------------------------------------------------------------------------- 101 -----------------------------------------------------------------------------
92 addon = LibStub("AceAddon-3.0"):NewAddon(addon, nametag, 102 addon = LibStub("AceAddon-3.0"):NewAddon(addon, nametag,
138 local function onenter(this) GameTooltip_AddNewbieTip(this, GUILDCONTROL, 1.0, 1.0, 1.0, "/wrdw", 1) end 148 local function onenter(this) GameTooltip_AddNewbieTip(this, GUILDCONTROL, 1.0, 1.0, 1.0, "/wrdw", 1) end
139 GuildFrame_LoadUI() 149 GuildFrame_LoadUI()
140 if not NUM_RANK_FLAGS then 150 if not NUM_RANK_FLAGS then
141 UIParentLoadAddOn("Blizzard_GuildControlUI") 151 UIParentLoadAddOn("Blizzard_GuildControlUI")
142 end 152 end
143 hooksecurefunc("GuildFrame_CheckPermissions", function() 153 local function noreallyitsokay()
144 GuildControlButton:Enable() 154 GuildControlButton:Enable()
145 GuildControlButton:SetScript("OnClick", onclick) 155 GuildControlButton:SetScript("OnClick", onclick)
146 GuildControlButton:SetScript("OnEnter", onenter) 156 GuildControlButton:SetScript("OnEnter", onenter)
147 end) 157 end
158 hooksecurefunc("GuildInfoFrame_UpdatePermissions", noreallyitsokay)
159 -- This doesn't seem to be used anymore...?
160 hooksecurefunc("GuildFrame_CheckPermissions", noreallyitsokay)
148 end 161 end
149 end 162 end
150 163
151 function addon:OnDisable() 164 function addon:OnDisable()
152 self:Print(L["You will need to relog or /reload to fully disable this addon."]) 165 self:Print(L["You will need to relog or /reload to fully disable this addon."])
178 end 191 end
179 192
180 193
181 -- Something somewhere has changed, redo the cache 194 -- Something somewhere has changed, redo the cache
182 do 195 do
183 local text = '|cffff1010' .. L["Guild flags have changed!"] .. '|r' .. 196 local text = '|cffff1010' .. L["Guild flags have changed!"] .. '|r ' ..
184 L["You must close and reopen this window to display the changes."] 197 L["You must close and reopen this window to display the changes."]
185 function addon:GUILD_RANKS_UPDATE() 198 function addon:GUILD_RANKS_UPDATE()
186 self.perms = nil 199 self.perms = nil
187 if (not incomplete) and self.display and self.display:IsVisible() then 200 if (not incomplete) and self.display and self.display:IsVisible() then
188 self.display:SetStatusText(text) 201 setstatus(text)
189 end 202 end
190 end 203 end
191 end 204 end
192 205
193 206
195 assert(UIParentLoadAddOn("Blizzard_GuildControlUI")) 208 assert(UIParentLoadAddOn("Blizzard_GuildControlUI"))
196 local check = "|TInterface\\Buttons\\UI-CheckBox-Check:"..(st_rowheight+5).."|t" 209 local check = "|TInterface\\Buttons\\UI-CheckBox-Check:"..(st_rowheight+5).."|t"
197 210
198 -- http://www.wowace.com/addons/lib-st/pages/set-data/minimal-dataset-format/ 211 -- http://www.wowace.com/addons/lib-st/pages/set-data/minimal-dataset-format/
199 local p,v = {}, {} 212 local p,v = {}, {}
213 flagmap = {}
214 num_flagsets = math.floor(NUM_RANK_FLAGS/cols_per_group + 1)
215 for flagset = 1, num_flagsets do
216 p[flagset] = {}
217 end
218
200 for r = 1, GuildControlGetNumRanks() do 219 for r = 1, GuildControlGetNumRanks() do
201 GuildControlSetRank(r) 220 GuildControlSetRank(r)
202 221
203 -- permissions 222 -- permissions (most special handling goes here)
223 -- flag 14 is no longer used
224 -- flags 15 and 16 may have numeric values not just a boolean
225 -- flag 21 is... not included yet, apparently
204 local flags = { GuildControlGetRankFlags() } 226 local flags = { GuildControlGetRankFlags() }
205 local row = { GuildControlGetRankName(r) } 227 for flagset = 1, num_flagsets do
206 for c = 1, NUM_RANK_FLAGS do if c ~= 14 then 228 local row = { GuildControlGetRankName(r) }
207 local newcol = #row + 1 229 for c_offset = 1, cols_per_group do while true do
208 if c == 15 or c == 16 then 230 local c = (flagset-1) * cols_per_group + c_offset
209 local val = GetGuildBankWithdrawGoldLimit() 231 --if c == 14 or c > NUM_RANK_FLAGS then break end
210 row[newcol] = flags[c] and ((val == -1) and check or val) or "" 232 if c > NUM_RANK_FLAGS then break end
211 else 233 local newcol = #row + 1
212 row[newcol] = flags[c] and check or "" 234 flagmap[flagset..'x'..newcol] = c
213 end 235 if c == 15 or c == 16 then
214 end end 236 local val = GetGuildBankWithdrawGoldLimit()
215 p[r] = row 237 row[newcol] = flags[c] and ((val == -1) and check or val) or ""
238 elseif c == 14 then
239 row[newcol] = ""
240 else
241 row[newcol] = flags[c] and check or ""
242 end
243 break
244 end end
245 p[flagset][r] = row
246 end
216 247
217 -- guild vault 248 -- guild vault
218 local banktabs = {} 249 local banktabs = {}
219 for t = 1, GetNumGuildBankTabs() do 250 for t = 1, GetNumGuildBankTabs() do
220 -- isViewable, canDeposit, editText, numWithdrawals 251 -- isViewable, canDeposit, editText, numWithdrawals
221 banktabs[t] = { row[1], GetGuildBankTabPermissions(t) } 252 banktabs[t] = { GuildControlGetRankName(r), GetGuildBankTabPermissions(t) }
222 banktabs[t][2] = banktabs[t][2] and check or "" 253 banktabs[t][2] = banktabs[t][2] and check or ""
223 banktabs[t][3] = banktabs[t][3] and check or "" 254 banktabs[t][3] = banktabs[t][3] and check or ""
224 banktabs[t][4] = banktabs[t][4] and check or "" 255 banktabs[t][4] = banktabs[t][4] and check or ""
225 local withdraw = banktabs[t][5] 256 local withdraw = banktabs[t][5]
226 banktabs[t][5] = (withdraw == -1) and check or (withdraw == 0) and "" or withdraw 257 banktabs[t][5] = (withdraw == -1) and check or (withdraw == 0) and "" or withdraw
236 self.vault[t][r] = v[r][t] 267 self.vault[t][r] = v[r][t]
237 end 268 end
238 end 269 end
239 end 270 end
240 271
241
242 local function setstatus(txt) addon.display:SetStatusText(txt) end
243 272
244 local make_sidetab 273 local make_sidetab
245 do 274 do
246 local lastclicked 275 local lastclicked
247 local function OnClick (thistab) 276 local function OnClick (thistab)
284 incomplete = nil 313 incomplete = nil
285 local offset = 1 -- number of tabs already made 314 local offset = 1 -- number of tabs already made
286 local function pick_a_tab (tab, id) 315 local function pick_a_tab (tab, id)
287 DisownChildren(self.display) 316 DisownChildren(self.display)
288 self.display:AddChild(self.vault_sts[id-offset]) 317 self.display:AddChild(self.vault_sts[id-offset])
318 local buttons = self.display:GetUserData("extra buttons")
319 buttons['prev']:Disable()
320 buttons['next']:Disable()
289 end 321 end
290 for t = 1, GetNumGuildBankTabs() do 322 for t = 1, GetNumGuildBankTabs() do
291 local name, icon = GetGuildBankTabInfo(t) 323 local name, icon = GetGuildBankTabInfo(t)
292 incomplete = incomplete or icon == [[Interface\Icons\INV_Misc_QuestionMark]] 324 incomplete = incomplete or icon == [[Interface\Icons\INV_Misc_QuestionMark]]
293 local tab = make_sidetab(t+offset, pick_a_tab) 325 local tab = make_sidetab(t+offset, pick_a_tab)
299 end 331 end
300 end 332 end
301 end 333 end
302 334
303 335
336 -- The "closebutton" variable isn't accessible through the widget. I should
337 -- probably just constuct an entire Frame-equse thing by hand instead... gah.
338 local function FIXFRAME (container, ...)
339 for i = 1, select('#',...) do
340 local child = select(i,...)
341 if child:GetObjectType() == "Button" and child:GetText() == CLOSE then
342 container:SetUserData("close button", child)
343 return
344 end
345 end
346 end
347
348 local function adjust_flagset (button)
349 local key = button.button_key
350 assert (key == 'prev' or key == 'next')
351 local flagset = addon.current_main_st
352 if key == 'prev' then
353 flagset = flagset - 1
354 else
355 flagset = flagset + 1
356 end
357 return flagset
358 end
359
360 local function AddedButton_OnEnter (button)
361 -- not very generic, that's okay until we need to be
362 local high = adjust_flagset(button) * cols_per_group
363 local low = high - cols_per_group + 1
364 if high > NUM_RANK_FLAGS then high = NUM_RANK_FLAGS end
365 setstatus(L["Show flag columns %d - %d"]:format(low,high))
366 end
367 local function AddedButton_OnLeave (button)
368 setstatus("")
369 end
370 local function AddedButton_OnClick (button)
371 addon:DoMainST(adjust_flagset(button))
372 -- the buttons may have changed state, adjust their status text
373 if button:IsEnabled() then
374 AddedButton_OnEnter (button)
375 else
376 AddedButton_OnLeave (button)
377 end
378 end
379
380 local function AddButton (container, key, label)
381 assert(not tonumber(key))
382 local all = container:GetUserData("extra buttons") or {}
383 container:SetUserData("extra buttons", all)
384 local n = #all
385 local closebutton = assert(container:GetUserData("close button"), "something horrible")
386 local b = CreateFrame("Button", nil, container.frame, "UIPanelButtonTemplate")
387 b.button_key = key
388 b.obj = self
389 b:SetScript("OnClick", AddedButton_OnClick)
390 b:SetScript("OnEnter", AddedButton_OnEnter)
391 b:SetScript("OnLeave", AddedButton_OnLeave)
392 b:SetText(label)
393 b:SetHeight(20)
394 b:SetWidth(50) -- "Close" is 100
395 b:SetPoint("BOTTOMRIGHT", closebutton, "BOTTOMLEFT", -5, 0)
396 b:Show()
397 all[n+1] = b
398 all[key] = b
399
400 for i = n, 1, -1 do
401 local ob = all[i]
402 ob:ClearAllPoints()
403 ob:SetPoint("BOTTOMRIGHT", all[i+1], "BOTTOMLEFT", -5, 0)
404 end
405 -- The Frame's statusbar is not accessible via the Frame widget itself.
406 -- Which is nice and properly encapsulated and all, but also inconvenient.
407 -- We'll take the long route there.
408 local sb = container.statustext:GetParent()
409 assert (sb.obj == container)
410 sb:ClearAllPoints()
411 sb:SetPoint("BOTTOMLEFT", 15, 15) -- default
412 sb:SetPoint("BOTTOMRIGHT", all[1], "BOTTOMLEFT", -5, 0)
413 end
414
415
304 local function st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...) 416 local function st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...)
305 if (row == nil) or (realrow == nil) then -- mouseover column header 417 if (row == nil) or (realrow == nil) then -- mouseover column header
306 setstatus(cellFrame:GetText():gsub('\n',' ')) 418 setstatus(cellFrame:GetText():gsub('\n',' '))
307 return true 419 return true
308 end 420 end
317 -- more here? 429 -- more here?
318 return true -- do not do anything further 430 return true -- do not do anything further
319 end 431 end
320 432
321 433
322 function addon:BuildMainST (permissions, parent_frame) 434 local function OnEnterStatusBar (container)
435 if not addon.tooltip then return end
436 GameTooltip:SetOwner (container.frame, "ANCHOR_RIGHT")
437 GameTooltip:ClearLines()
438 GameTooltip:AddLine (nametag)
439 GameTooltip:AddLine (addon.tooltip, 0.8, 0.8, 0.8, 1)
440 GameTooltip:Show()
441 end
442
443
444 function addon:BuildMainSTs (permissions, parent_frame)
445 local errtxt = "flagset %d, column %d, failed to map to a flag number"
323 -- if this language uses a trailing colon, strip it 446 -- if this language uses a trailing colon, strip it
324 local tmp = GUILDCONTROL_RANKLABEL:gsub(":$","") 447 local ranklabel = GUILDCONTROL_RANKLABEL:gsub(":$","")
325 local cols = {{ 448 self.main_sts = {}
326 name = tmp, 449
327 width = 10 * #tmp, 450 for flagset = 1, #permissions do
328 }} 451 local cols = {{
329 for i = 1, NUM_RANK_FLAGS do if i ~= 14 then 452 name = ranklabel,
330 table.insert(cols,{ 453 width = 10 * #ranklabel,
331 name = _G['GUILDCONTROL_OPTION'..i], 454 }}
332 width = st_colwidth, 455 for c = #cols+1, #permissions[flagset][1] do -- all ranks work here
333 }) 456 local f = flagmap[flagset..'x'..c]
334 end end 457 if not f then error(errtxt:format(flagset, c)) end
335 458 table.insert(cols,{
336 local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) 459 -- the only special handling outside BuildPerms
337 ST:Hide() 460 name = _G[f == 14 and 'UNUSED' or 'GUILDCONTROL_OPTION'..f],
338 461 width = st_colwidth,
339 ST:SetData(permissions, --[[minimal format=]]true) 462 })
340 ST:RegisterEvents{ 463 end
341 OnEnter = st_OnEnter, 464
342 OnLeave = st_OnLeave, 465 local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, --[[highlight=]]nil, parent_frame)
343 OnClick = st_OnClick, 466 ST:Hide()
344 OnDoubleClick = st_OnClick, 467
345 } 468 ST:SetData(permissions[flagset], --[[minimal format=]]true)
346 469 ST:RegisterEvents{
347 return ST 470 OnEnter = st_OnEnter,
471 OnLeave = st_OnLeave,
472 OnClick = st_OnClick,
473 OnDoubleClick = st_OnClick,
474 }
475 self.main_sts[flagset] = ST
476 end
348 end 477 end
349 478
350 function addon:BuildVaultSTs (permissions, parent_frame) 479 function addon:BuildVaultSTs (permissions, parent_frame)
351 self.vault_sts = {} 480 self.vault_sts = {}
352 local cols = { 481 local cols = {
353 self.main_st.st.cols[1], 482 self.main_sts[1].st.cols[1],
354 { name = GUILDCONTROL_VIEW_TAB, width = 80 }, 483 { name = GUILDCONTROL_VIEW_TAB, width = 80 },
355 { name = GUILDCONTROL_DEPOSIT_ITEMS, width = 80 }, 484 { name = GUILDCONTROL_DEPOSIT_ITEMS, width = 80 },
356 { name = GUILDCONTROL_UPDATE_TEXT, width = 80 }, 485 { name = GUILDCONTROL_UPDATE_TEXT, width = 80 },
357 { name = GUILDCONTROL_WITHDRAW_ITEMS, width = 150 }, 486 { name = GUILDCONTROL_WITHDRAW_ITEMS, width = 150 },
358 } 487 }
359 488
360 for tab = 1, #permissions do 489 for tab = 1, #permissions do
361 local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) 490 local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, --[[highlight=]]nil, parent_frame)
362 ST:Hide() 491 ST:Hide()
363 ST:SetData(permissions[tab], --[[minimal format=]]true) 492 ST:SetData(permissions[tab], --[[minimal format=]]true)
364 ST:RegisterEvents{ 493 ST:RegisterEvents{
365 OnEnter = st_OnEnter, 494 OnEnter = st_OnEnter,
366 OnLeave = st_OnLeave, 495 OnLeave = st_OnLeave,
367 OnClick = st_OnClick, 496 OnClick = st_OnClick,
368 OnDoubleClick = st_OnClick, 497 OnDoubleClick = st_OnClick,
369 } 498 }
370 self.vault_sts[tab] = ST 499 self.vault_sts[tab] = ST
371 end 500 end
501 end
502
503
504 function addon:DoMainST (index)
505 self.current_main_st = index
506 DisownChildren(self.display)
507 self.display:AddChild(self.main_sts[index])
508 local buttons = self.display:GetUserData("extra buttons")
509 buttons['prev'][index <= 1 and 'Disable' or 'Enable'](buttons['prev'])
510 buttons['next'][index >= num_flagsets and 'Disable' or 'Enable'](buttons['next'])
372 end 511 end
373 512
374 513
375 -- Under normal conditions, this massive wodge is built once, and then merely 514 -- Under normal conditions, this massive wodge is built once, and then merely
376 -- :Show'n and :Hide'n. Only if info gets out of date do we release/destroy 515 -- :Show'n and :Hide'n. Only if info gets out of date do we release/destroy
383 self.display = AceGUI:Create("Frame") 522 self.display = AceGUI:Create("Frame")
384 self.display:SetTitle("Which Rank Does What") 523 self.display:SetTitle("Which Rank Does What")
385 self.display:SetLayout("Fill") 524 self.display:SetLayout("Fill")
386 self.display:EnableResize(false) 525 self.display:EnableResize(false)
387 self.display:SetStatusTable{ 526 self.display:SetStatusTable{
388 width = (st_colwidth+4) * (NUM_RANK_FLAGS-1) -- flag columns 527 width = (st_colwidth+4) * cols_per_group -- flag columns
389 + 105, -- rank label column 528 + 105, -- rank label column
390 height = 500, 529 height = 500,
391 } 530 }
392 self.display:ApplyStatus() 531 self.display:ApplyStatus()
532 FIXFRAME (self.display, self.display.frame:GetChildren())
533 AddButton (self.display, 'prev', "<<")
534 AddButton (self.display, 'next', ">>")
535 self.display:SetCallback("OnEnterStatusBar", OnEnterStatusBar)
536 self.display:SetCallback("OnLeaveStatusBar", GameTooltip_Hide)
393 self.display:SetCallback("OnClose", function(_d) 537 self.display:SetCallback("OnClose", function(_d)
394 if incomplete or (not self.perms) then 538 if incomplete or (not self.perms) then
395 -- stuff changed while open 539 -- stuff changed while open
396 self.perms = nil 540 self.perms = nil
397 self.display = nil 541 self.display = nil
399 s:Hide() 543 s:Hide()
400 s:ClearAllPoints() 544 s:ClearAllPoints()
401 s:SetParent(nil) -- Blizzard does this too. Huh. 545 s:SetParent(nil) -- Blizzard does this too. Huh.
402 end end 546 end end
403 sidetabs = nil 547 sidetabs = nil
548 for i,b in ipairs(_d:GetUserData("extra buttons")) do
549 b.obj = nil
550 b:Hide()
551 b:ClearAllPoints()
552 b:SetParent(nil)
553 end
404 AceGUI:Release(_d) 554 AceGUI:Release(_d)
405 end 555 end
406 end) 556 end)
407 need_tabs = true 557 need_tabs = true
408 end 558 end
416 if sidetabs then for i,s in ipairs(sidetabs) do 566 if sidetabs then for i,s in ipairs(sidetabs) do
417 s:Hide() 567 s:Hide()
418 s:ClearAllPoints() 568 s:ClearAllPoints()
419 s:SetParent(nil) -- Blizzard does this too. Huh. 569 s:SetParent(nil) -- Blizzard does this too. Huh.
420 end end 570 end end
421 if self.main_st and self.main_st.st then 571 if self.main_sts then for i = 1, #self.main_sts do
422 self.main_st:Release() 572 if self.main_sts[i] and self.main_sts[i].st then
423 end 573 self.main_sts[i]:Release()
574 end
575 end end
424 if self.vault_sts then for i = 1, #self.vault_sts do 576 if self.vault_sts then for i = 1, #self.vault_sts do
425 if self.vault_sts[i] and self.vault_sts[i].st then 577 if self.vault_sts[i] and self.vault_sts[i].st then
426 self.vault_sts[i]:Release() 578 self.vault_sts[i]:Release()
427 end 579 end
428 end end 580 end end
429 self.main_st = nil 581 self.main_sts = nil
430 self.vault_sts = nil 582 self.vault_sts = nil
431 end 583 end
432 if not self.main_st then 584 if not self.main_sts then
433 local st = self:BuildMainST (self.perms, self.display.content) 585 self:BuildMainSTs (self.perms, self.display.content)
434 self.main_st = AceGUI:Create("lib-st"):WrapST(st) 586 for i,st in ipairs(self.main_sts) do
435 self.main_st.head_offset = 20 587 self.main_sts[i] = AceGUI:Create("lib-st"):WrapST(st)
436 --st_widget.tail_offset = 5 588 self.main_sts[i].head_offset = 20
437 self.display:AddChild(self.main_st) 589 end
590 self:DoMainST(1)
438 591
439 self:BuildVaultSTs (self.vault, self.display.content) 592 self:BuildVaultSTs (self.vault, self.display.content)
440 for i,st in ipairs(self.vault_sts) do 593 for i,st in ipairs(self.vault_sts) do
441 self.vault_sts[i] = AceGUI:Create("lib-st"):WrapST(st) 594 self.vault_sts[i] = AceGUI:Create("lib-st"):WrapST(st)
442 self.vault_sts[i].head_offset = 20 595 self.vault_sts[i].head_offset = 20
443 end 596 end
444 end 597 end
445 598
446 if need_tabs or incomplete then 599 if need_tabs or incomplete then
447 local maintab = make_sidetab(1, function (this, id) 600 local maintab = make_sidetab(1, function (this, id)
448 DisownChildren(self.display) 601 self:DoMainST(self.current_main_st)
449 self.display:AddChild(self.main_st)
450 end) 602 end)
451 maintab.tooltip = [[Rank permissions]] 603 maintab.tooltip = [[Rank permissions]]
452 maintab:SetChecked(true) 604 maintab:SetChecked(true)
453 self:BuildVaultTabs() 605 self:BuildVaultTabs()
454 end 606 end