Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!

BlackBook.lua RecentList fixed RC4

By: flow0284 on Dec 25th, 2013  |  syntax: Lua  |  size: 27.07 KB  |  views: 44  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. local Postal = LibStub("AceAddon-3.0"):GetAddon("Postal")
  2. local Postal_BlackBook = Postal:NewModule("BlackBook", "AceEvent-3.0", "AceHook-3.0")
  3. local L = LibStub("AceLocale-3.0"):GetLocale("Postal")
  4. Postal_BlackBook.description = L["Adds a contact list next to the To: field."]
  5. Postal_BlackBook.description2 = L[ [[|cFFFFCC00*|r This module will list your contacts, friends, guild mates, alts and track the last 10 people you mailed.
  6. |cFFFFCC00*|r It will also autocomplete all names in your BlackBook.]] ]
  7.  
  8. local Postal_BlackBookButton
  9. local numFriendsOnList = 0
  10. local sorttable = {}
  11. local ignoresortlocale = {
  12.         ["koKR"] = true,
  13.         ["zhCN"] = true,
  14.         ["zhTW"] = true,
  15. }
  16. local enableAltsMenu = true
  17. local Postal_BlackBook_Autocomplete_Flags = {
  18.         include = AUTOCOMPLETE_FLAG_ALL,
  19.         exclude = AUTOCOMPLETE_FLAG_BNET,
  20. }
  21.  
  22. function Postal_BlackBook:OnEnable()
  23.         if not Postal_BlackBookButton then
  24.                 -- Create the Menu Button
  25.                 Postal_BlackBookButton = CreateFrame("Button", "Postal_BlackBookButton", SendMailFrame)
  26.                 Postal_BlackBookButton:SetWidth(25)
  27.                 Postal_BlackBookButton:SetHeight(25)
  28.                 Postal_BlackBookButton:SetPoint("LEFT", SendMailNameEditBox, "RIGHT", -2, 2)
  29.                 Postal_BlackBookButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up")
  30.                 Postal_BlackBookButton:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Round")
  31.                 Postal_BlackBookButton:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled")
  32.                 Postal_BlackBookButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down")
  33.                 Postal_BlackBookButton:SetScript("OnClick", function(self, button, down)
  34.                         if Postal_DropDownMenu.initialize ~= Postal_BlackBook.BlackBookMenu then
  35.                                 CloseDropDownMenus()
  36.                                 Postal_DropDownMenu.initialize = Postal_BlackBook.BlackBookMenu
  37.                         end
  38.                         ToggleDropDownMenu(1, nil, Postal_DropDownMenu, self:GetName(), 0, 0)
  39.                 end)
  40.                 Postal_BlackBookButton:SetScript("OnHide", Postal_DropDownMenu.HideMenu)
  41.         end
  42.  
  43.         local db = Postal.db.profile.BlackBook
  44.  
  45.         SendMailNameEditBox:SetHistoryLines(15)
  46.         self:RawHook("SendMailFrame_Reset", true)
  47.         self:RawHook("MailFrameTab_OnClick", true)
  48.         if db.UseAutoComplete then
  49.                 self:RawHookScript(SendMailNameEditBox, "OnChar")
  50.         end
  51.         self:HookScript(SendMailNameEditBox, "OnEditFocusGained")
  52.         self:RawHook("AutoComplete_Update", true)
  53.         self:RegisterEvent("MAIL_SHOW")
  54.         self:RegisterEvent("PLAYER_ENTERING_WORLD", "AddAlt")
  55.  
  56.         local exclude = bit.bor(db.AutoCompleteFriends and AUTOCOMPLETE_FLAG_NONE or AUTOCOMPLETE_FLAG_FRIEND,
  57.                 db.AutoCompleteGuild and AUTOCOMPLETE_FLAG_NONE or AUTOCOMPLETE_FLAG_IN_GUILD)
  58.         Postal_BlackBook_Autocomplete_Flags.include = bit.bxor(
  59.                 db.ExcludeRandoms and (bit.bor(AUTOCOMPLETE_FLAG_FRIEND, AUTOCOMPLETE_FLAG_IN_GUILD)) or AUTOCOMPLETE_FLAG_ALL, exclude)
  60.         SendMailNameEditBox.autoCompleteParams = Postal_BlackBook_Autocomplete_Flags
  61.  
  62.         -- Delete Real ID database. Patch 4.0.1 onwards no longer allows addons to obtain Real ID information.
  63.         Postal.db.global.BlackBook.realID = nil
  64.         db.AutoCompleteRealIDFriends = nil
  65.  
  66.         -- Delete old recent data without faction and realm data
  67.         for i = #Postal.db.profile.BlackBook.recent, 1, -1 do
  68.                 local p, f = strsplit("|", Postal.db.profile.BlackBook.recent[i])
  69.                 local r = strsplit("-", Postal.db.profile.BlackBook.recent[i])
  70.                 if (not r) and (not f) then
  71.                         tremove(Postal.db.profile.BlackBook.recent, i)
  72.                 end
  73.         end
  74.  
  75.         -- Update old alts
  76.         for i = #Postal.db.global.BlackBook.alts, 1, -1 do
  77.                 local p, r, f, l, c = strsplit("|", Postal.db.global.BlackBook.alts[i])
  78.                
  79.                 if c then
  80.                 local namestring = ("%s-%s|%s|%s|%s"):format(p, r, f, l, c)
  81.                         tremove(Postal.db.global.BlackBook.alts, i)
  82.                         tinsert(Postal.db.global.BlackBook.alts, namestring)
  83.                 end
  84.                 --print(#Postal.db.global.BlackBook.alts)
  85.         end
  86.        
  87.         -- For enabling after a disable
  88.         Postal_BlackBookButton:Show()
  89. end
  90.  
  91. function Postal_BlackBook:OnDisable()
  92.         -- Disabling modules unregisters all events/hook automatically
  93.         SendMailNameEditBox:SetHistoryLines(1)
  94.         Postal_BlackBookButton:Hide()
  95.         SendMailNameEditBox.autoCompleteParams = AUTOCOMPLETE_LIST.MAIL
  96. end
  97.  
  98. function Postal_BlackBook:MAIL_SHOW()
  99.         self:RegisterEvent("MAIL_CLOSED", "Reset")
  100.         self:RegisterEvent("PLAYER_LEAVING_WORLD", "Reset")
  101.         if self.AddAlt then self:AddAlt() end
  102. end
  103.  
  104. function Postal_BlackBook:Reset(event)
  105.         self:UnregisterEvent("MAIL_CLOSED")
  106.         self:UnregisterEvent("PLAYER_LEAVING_WORLD")
  107. end
  108.  
  109. -- We do this once on MAIL_SHOW because UnitFactionGroup() is only valid after
  110. -- PLAYER_ENTERING_WORLD and because Postal might be LoD due to AddOnLoader
  111. -- and PLAYER_ENTERING_WORLD won't fire in that scenerio.
  112. function Postal_BlackBook:AddAlt()
  113.         local realm = GetRealmName()
  114.         local faction = UnitFactionGroup("player")
  115.         local player = UnitName("player")
  116.         local level = UnitLevel("player")
  117.         local _, class = UnitClass("player")
  118.         if not realm or not faction or not player or not level or not class then return end
  119.         local namestring = ("%s-%s|%s|%s|%s"):format(player, realm, faction, level, class)
  120.         local db = Postal.db.global.BlackBook.alts
  121.         enableAltsMenu = false
  122.         for i = #db, 1, -1 do
  123.                 local p, l, c = strsplit("|", db[i])
  124.                 if p == player.."-"..realm then
  125.                         tremove(db, i)
  126.                 end
  127.                 if p ~= player.."-"..realm then
  128.                         enableAltsMenu = true
  129.                 end
  130.         end
  131.         tinsert(db, namestring)
  132.         table.sort(db)
  133.         self:UnregisterEvent("PLAYER_ENTERING_WORLD")
  134.         self.AddAlt = nil -- Kill ourselves so we only run it once
  135. end
  136.  
  137. function Postal_BlackBook.DeleteAlt(dropdownbutton, arg1, arg2, checked)
  138.         local realm = GetRealmName()
  139.         local faction = UnitFactionGroup("player")
  140.         local player = UnitName("player")
  141.         local db = Postal.db.global.BlackBook.alts
  142.         enableAltsMenu = false
  143.         for i = #db, 1, -1 do
  144.                 if arg1 == db[i] then
  145.                         tremove(db, i)
  146.                 else
  147.                         local p, f = strsplit("|", db[i])
  148.                         if p ~= player.."-"..realm then
  149.                                 enableAltsMenu = true
  150.                         end
  151.                 end
  152.         end
  153.         CloseDropDownMenus()
  154. end
  155.  
  156. -- Only called on a mail that is sent successfully
  157. function Postal_BlackBook:SendMailFrame_Reset()
  158.         local name, rlm = strsplit("-", strtrim(SendMailNameEditBox:GetText()))
  159.         if name == "" then return self.hooks["SendMailFrame_Reset"]() end
  160.         --SendMailNameEditBox:AddHistoryLine(name)     
  161.        
  162.         if rlm == "" or rlm == nil then
  163.                 SendMailNameEditBox:AddHistoryLine(name)
  164.                 local realm = GetRealmName()
  165.                 local faction = UnitFactionGroup("player")
  166.                 if not realm or not faction then return self.hooks["SendMailFrame_Reset"]() end
  167.                 local namestring = ("%s-%s|%s"):format(name, realm, faction)
  168.                 local db = Postal.db.profile.BlackBook.recent
  169.                 for k = 1, #db do
  170.                         if namestring == db[k] then tremove(db, k) break end
  171.                 end
  172.                 tinsert(db, 1, namestring)
  173.                 for k = #db, 21, -1 do
  174.                         tremove(db, k)
  175.                 end
  176.                 local a, b, c = self.hooks["SendMailFrame_Reset"]()
  177.                 if Postal.db.profile.BlackBook.AutoFill then
  178.                         SendMailNameEditBox:SetText(name.."-"..realm)
  179.                         SendMailNameEditBox:HighlightText()
  180.                 end
  181.                 return a, b, c
  182.         else
  183.                 SendMailNameEditBox:AddHistoryLine(name.."-"..rlm)
  184.                 local faction = UnitFactionGroup("player")
  185.                 if not rlm or not faction then return self.hooks["SendMailFrame_Reset"]() end
  186.                 local namestring = ("%s-%s|%s"):format(name, rlm, faction)
  187.                 local db = Postal.db.profile.BlackBook.recent
  188.                 for k = 1, #db do
  189.                         if namestring == db[k] then tremove(db, k) break end
  190.                 end
  191.                 tinsert(db, 1, namestring)
  192.                 for k = #db, 21, -1 do
  193.                         tremove(db, k)
  194.                 end
  195.                 local a, b, c = self.hooks["SendMailFrame_Reset"]()
  196.                 if Postal.db.profile.BlackBook.AutoFill then
  197.                         SendMailNameEditBox:SetText(name.."-"..rlm)
  198.                         SendMailNameEditBox:HighlightText()
  199.                 end
  200.                 return a, b, c
  201.         end
  202. end
  203.  
  204. function Postal_BlackBook.ClearRecent(dropdownbutton, arg1, arg2, checked)
  205.         wipe(Postal.db.profile.BlackBook.recent)
  206.         CloseDropDownMenus()
  207. end
  208.  
  209. function Postal_BlackBook:MailFrameTab_OnClick(button, tab)
  210.         self.hooks["MailFrameTab_OnClick"](button, tab)
  211.         if Postal.db.profile.BlackBook.AutoFill and tab == 2 then
  212.                 local realm = GetRealmName()
  213.                 local faction = UnitFactionGroup("player")
  214.                 local player = UnitName("player")
  215.                
  216.                 -- Find the first eligible recently mailed
  217.                 for i = 1, #Postal.db.profile.BlackBook.recent do
  218.                         local p, f = strsplit("|", Postal.db.profile.BlackBook.recent[i])
  219.                         if p ~= player.."-"..realm then
  220.                                 if p and SendMailNameEditBox:GetText() == "" then
  221.                                         SendMailNameEditBox:SetText(p)
  222.                                         SendMailNameEditBox:HighlightText()
  223.                                         break
  224.                                 end
  225.                         end
  226.                 end
  227.         end
  228. end
  229.  
  230. function Postal_BlackBook:OnEditFocusGained(editbox, ...)
  231.         -- Most other addons aren't hooking properly and do not pass in editbox at all.
  232.         SendMailNameEditBox:HighlightText()
  233. end
  234.  
  235. function Postal_BlackBook:AutoComplete_Update(editBox, editBoxText, utf8Position)
  236.         if editBox ~= SendMailNameEditBox or not Postal.db.profile.BlackBook.DisableBlizzardAutoComplete then
  237.                 self.hooks["AutoComplete_Update"](editBox, editBoxText, utf8Position)
  238.         end
  239. end
  240.  
  241. -- OnChar fires before OnTextChanged
  242. -- OnChar does not fire for Backspace, Delete keys that shorten the text
  243. -- Hook player name autocomplete to look in our dbs first
  244. function Postal_BlackBook:OnChar(editbox, ...)
  245.         if editbox:GetUTF8CursorPosition() ~= strlenutf8(editbox:GetText()) then return end
  246.  
  247.         local db = Postal.db.profile.BlackBook
  248.         local text = strupper(editbox:GetText())
  249.         local textlen = strlen(text)
  250.         local realm = GetRealmName()
  251.         local faction = UnitFactionGroup("player")
  252.         local player = UnitName("player")
  253.         local newname
  254.  
  255.         -- Check recent list
  256.         if db.AutoCompleteRecent then
  257.                 local db2 = db.recent
  258.                 for j = 1, #db2 do
  259.                         local p, f = strsplit("|", db2[j])
  260.                         if p ~= player.."-"..realm then
  261.                                 if strfind(strupper(p), text, 1, 1) == 1 then
  262.                                         newname = p
  263.                                         break
  264.                                 end
  265.                         end
  266.                 end
  267.         end
  268.  
  269.                 -- Check alt list
  270.         if not newname and db.AutoCompleteAlts then
  271.                 local db = Postal.db.global.BlackBook.alts
  272.                 for i = 1, #db do
  273.                         local p, f = strsplit("|", db[i])
  274.                         if p ~= player.."-"..realm then
  275.                                 if strfind(strupper(p), text, 1, 1) == 1 then
  276.                                         newname = p
  277.                                         break
  278.                                 end
  279.                         end
  280.                 end
  281.         end
  282.        
  283.         -- Check contacts list
  284.         if not newname and db.AutoCompleteContacts then
  285.                 local db2 = db.contacts
  286.                 for j = 1, #db2 do
  287.                         local name = db2[j]
  288.                         if strfind(strupper(name), text, 1, 1) == 1 then
  289.                                 newname = name
  290.                                 break
  291.                         end
  292.                 end
  293.         end
  294.  
  295.         -- Check RealID friends that are online
  296.         if not newname and db.AutoCompleteFriends then
  297.                 local numBNetTotal, numBNetOnline = BNGetNumFriends()
  298.                 for i = 1, numBNetOnline do
  299.                         local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(i)
  300.                         if (toonName and client == BNET_CLIENT_WOW and CanCooperateWithToon(toonID, false)) then
  301.                                 if strfind(strupper(toonName), text, 1, 1) == 1 then
  302.                                         newname = toonName
  303.                                         break
  304.                                 end
  305.                         end
  306.                 end
  307.         end
  308.  
  309.         -- The Blizzard autocomplete is borked for guild. So we implement our own for guild autocomplete
  310.         if not newname and db.AutoCompleteGuild and IsInGuild() then
  311.                 local numMembers, numOnline = GetNumGuildMembers(true)
  312.                 for i = 1, numMembers do
  313.                         local name, rank, rankIndex, level, class, zone, note, officernote, online, status, classFileName, achievementPoints, achievementRank, isMobile, canSoR = GetGuildRosterInfo(i)
  314.                         if strfind(strupper(name), text, 1, 1) == 1 then
  315.                                 newname = name
  316.                                 break
  317.                         end
  318.                 end
  319.         end
  320.  
  321.         -- Call the original Blizzard function to autocomplete and for its popup
  322.         self.hooks[SendMailNameEditBox].OnChar(editbox, ...)
  323.  
  324.         -- Set our match if we found one (overriding Blizzard's match if there's one)
  325.         if newname then
  326.                 editbox:SetText(newname)
  327.                 editbox:HighlightText(textlen, -1)
  328.                 editbox:SetCursorPosition(textlen)
  329.         end
  330. end
  331.  
  332. function Postal_BlackBook.SetSendMailName(dropdownbutton, arg1, arg2, checked)
  333.         SendMailNameEditBox:SetText(arg1)
  334.         if SendMailNameEditBox:HasFocus() then SendMailSubjectEditBox:SetFocus() end
  335.         CloseDropDownMenus()
  336. end
  337.  
  338. function Postal_BlackBook.AddContact(dropdownbutton, arg1, arg2, checked)
  339.         local name = strtrim(SendMailNameEditBox:GetText())
  340.         if name == "" then return end
  341.         local db = Postal.db.profile.BlackBook.contacts
  342.         for k = 1, #db do
  343.                 if name == db[k] then return end
  344.         end
  345.         tinsert(db, name)
  346.         table.sort(db)
  347. end
  348.  
  349. function Postal_BlackBook.RemoveContact(dropdownbutton, arg1, arg2, checked)
  350.         local name = strtrim(SendMailNameEditBox:GetText())
  351.         if name == "" then return end
  352.         local db = Postal.db.profile.BlackBook.contacts
  353.         for k = 1, #db do
  354.                 if name == db[k] then tremove(db, k) return end
  355.         end
  356. end
  357.  
  358. function Postal_BlackBook:SortAndCountNumFriends()
  359.         wipe(sorttable)
  360.         local numFriends = GetNumFriends()
  361.         for i = 1, numFriends do
  362.                 sorttable[i] = GetFriendInfo(i)
  363.         end
  364.  
  365.         -- Battle.net friends
  366.         if BNGetNumFriends then -- For pre 3.3.5 backwards compat
  367.                 local numBNetTotal, numBNetOnline = BNGetNumFriends()
  368.                 for i= 1, numBNetOnline do
  369.                         local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(i)
  370.                         if (toonName and client == BNET_CLIENT_WOW and CanCooperateWithToon(toonID, false)) then
  371.                                 -- Check if already on friends list
  372.                                 local alreadyOnList = false
  373.                                 for j = 1, numFriends do
  374.                                         if sorttable[j] == toonName then
  375.                                                 alreadyOnList = true
  376.                                                 break
  377.                                         end
  378.                                 end                    
  379.                                 if not alreadyOnList then
  380.                                         numFriends = numFriends + 1
  381.                                         sorttable[numFriends] = toonName
  382.                                 end
  383.                         end
  384.                 end
  385.         end
  386.  
  387.         -- Sort the list
  388.         if numFriends > 0 and not ignoresortlocale[GetLocale()] then table.sort(sorttable) end
  389.  
  390.         -- Store upvalue
  391.         numFriendsOnList = numFriends
  392.         return numFriends
  393. end
  394.  
  395. function Postal_BlackBook.BlackBookMenu(self, level)
  396.         if not level then return end
  397.         local info = self.info
  398.         wipe(info)
  399.         if level == 1 then
  400.                 info.isTitle = 1
  401.                 info.text = L["Contacts"]
  402.                 info.notCheckable = 1
  403.                 UIDropDownMenu_AddButton(info, level)
  404.  
  405.                 info.disabled = nil
  406.                 info.isTitle = nil
  407.  
  408.                 local db = Postal.db.profile.BlackBook.contacts
  409.                 for i = 1, #db do
  410.                         info.text = db[i]
  411.                         info.func = Postal_BlackBook.SetSendMailName
  412.                         info.arg1 = db[i]
  413.                         UIDropDownMenu_AddButton(info, level)
  414.                 end
  415.  
  416.                 info.arg1 = nil
  417.                 if #db > 0 then
  418.                         info.disabled = 1
  419.                         info.text = nil
  420.                         info.func = nil
  421.                         UIDropDownMenu_AddButton(info, level)
  422.                         info.disabled = nil
  423.                 end
  424.  
  425.                 info.text = L["Add Contact"]
  426.                 info.func = Postal_BlackBook.AddContact
  427.                 UIDropDownMenu_AddButton(info, level)
  428.  
  429.                 info.text = L["Remove Contact"]
  430.                 info.func = Postal_BlackBook.RemoveContact
  431.                 UIDropDownMenu_AddButton(info, level)
  432.  
  433.                 info.disabled = 1
  434.                 info.text = nil
  435.                 info.func = nil
  436.                 UIDropDownMenu_AddButton(info, level)
  437.  
  438.                 info.hasArrow = 1
  439.                 info.keepShownOnClick = 1
  440.                 info.func = self.UncheckHack
  441.  
  442.                 info.disabled = #Postal.db.profile.BlackBook.recent == 0
  443.                 info.text = L["Recently Mailed"]
  444.                 info.value = "recent"
  445.                 UIDropDownMenu_AddButton(info, level)
  446.  
  447.                 info.disabled = not enableAltsMenu
  448.                 info.text = L["Alts"]
  449.                 info.value = "alt"
  450.                 UIDropDownMenu_AddButton(info, level)
  451.  
  452.                 info.disabled = Postal_BlackBook:SortAndCountNumFriends() == 0
  453.                 info.text = L["Friends"]
  454.                 info.value = "friend"
  455.                 UIDropDownMenu_AddButton(info, level)
  456.  
  457.                 info.disabled = not IsInGuild()
  458.                 info.text = L["Guild"]
  459.                 info.value = "guild"
  460.                 UIDropDownMenu_AddButton(info, level)
  461.  
  462.                 wipe(info)
  463.                 info.disabled = 1
  464.                 info.notCheckable = 1
  465.                 UIDropDownMenu_AddButton(info, level)
  466.                 info.disabled = nil
  467.  
  468.                 info.text = CLOSE
  469.                 info.func = self.HideMenu
  470.                 UIDropDownMenu_AddButton(info, level)
  471.  
  472.         elseif level == 2 then
  473.                 info.notCheckable = 1
  474.                 if UIDROPDOWNMENU_MENU_VALUE == "recent" then
  475.                         local realm = GetRealmName()
  476.                         local faction = UnitFactionGroup("player")
  477.                         local player = UnitName("player")
  478.                         local db = Postal.db.profile.BlackBook.recent
  479.                         if #db == 0 then return end
  480.                         for i = 1, #db do
  481.                                 local p, f = strsplit("|", db[i])
  482.                                 if p ~= player.."-"..realm then
  483.                                         info.text = p
  484.                                         info.func = Postal_BlackBook.SetSendMailName
  485.                                         info.arg1 = p
  486.                                         UIDropDownMenu_AddButton(info, level)
  487.                                 end
  488.                         end
  489.  
  490.                         info.disabled = 1
  491.                         info.text = nil
  492.                         info.func = nil
  493.                         info.arg1 = nil
  494.                         UIDropDownMenu_AddButton(info, level)
  495.                         info.disabled = nil
  496.  
  497.                         info.text = L["Clear list"]
  498.                         info.func = Postal_BlackBook.ClearRecent
  499.                         info.arg1 = nil
  500.                         UIDropDownMenu_AddButton(info, level)
  501.  
  502.                 elseif UIDROPDOWNMENU_MENU_VALUE == "alt" then
  503.                         if not enableAltsMenu then return end
  504.                         local db = Postal.db.global.BlackBook.alts
  505.                         local realm = GetRealmName()
  506.                         local faction = UnitFactionGroup("player")
  507.                         local player = UnitName("player")
  508.                         info.notCheckable = 1
  509.                         for i = 1, #db do
  510.                                 local p, f, l, c = strsplit("|", Postal.db.global.BlackBook.alts[i])
  511.                                 if p == player.."-"..realm or p ~= player.."-"..realm then
  512.                                         if l and c then
  513.                                                 local clr = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[c] or RAID_CLASS_COLORS[c]
  514.                                                 sorttable[i] = format("%s |cffffd200(%s)|r |cff%.2x%.2x%.2x(%d %s)|r", p, f, clr.r*255, clr.g*255, clr.b*255, l, LOCALIZED_CLASS_NAMES_MALE[c])
  515.                                         end
  516.                                 end
  517.                         end
  518.                         for i = #sorttable, #db+1, -1 do
  519.                                 sorttable[i] = nil
  520.                         end
  521.                         if not ignoresortlocale[GetLocale()] then table.sort(sorttable) end
  522.                         if #db > 0 and #db <= 25 then
  523.                                 for i = 1, #db do
  524.                                         info.text = sorttable[i]
  525.                                         info.func = Postal_BlackBook.SetSendMailName
  526.                                         info.arg1 = strmatch(sorttable[i], "(.*) |cffffd200")
  527.                                         UIDropDownMenu_AddButton(info, level)
  528.                                 end
  529.                         elseif #db > 25 then
  530.                         -- More than 25 alts, split the list into multiple sublists of 25
  531.                                 info.hasArrow = 1
  532.                                 info.keepShownOnClick = 1
  533.                                 info.func = self.UncheckHack
  534.                                 for i = 1, math.ceil((#db)/25) do
  535.                                         info.text  = L["Part %d"]:format(i)
  536.                                         info.value = "altspart"..i
  537.                                         UIDropDownMenu_AddButton(info, level)
  538.                                 end    
  539.                         end
  540.                                
  541.                         wipe(info)
  542.                         info.disabled = 1
  543.                         info.notCheckable = 1
  544.                         UIDropDownMenu_AddButton(info, level)
  545.                         info.disabled = nil
  546.        
  547.                         info.text = L["Delete"]
  548.                         info.hasArrow = 1
  549.                         info.keepShownOnClick = 1
  550.                         info.func = self.UncheckHack
  551.                         info.value = "deletealt"
  552.                         UIDropDownMenu_AddButton(info, level)
  553.  
  554.                 elseif UIDROPDOWNMENU_MENU_VALUE == "friend" then
  555.                         -- Friends list
  556.                         local numFriends = Postal_BlackBook:SortAndCountNumFriends()
  557.  
  558.                         -- 25 or less, don't need multi level menus
  559.                         if numFriends > 0 and numFriends <= 25 then
  560.                                 for i = 1, numFriends do
  561.                                         local name = sorttable[i]
  562.                                         info.text = name
  563.                                         info.func = Postal_BlackBook.SetSendMailName
  564.                                         info.arg1 = name
  565.                                         UIDropDownMenu_AddButton(info, level)
  566.                                 end
  567.                         elseif numFriends > 25 then
  568.                                 -- More than 25 people, split the list into multiple sublists of 25
  569.                                 info.hasArrow = 1
  570.                                 info.keepShownOnClick = 1
  571.                                 info.func = self.UncheckHack
  572.                                 for i = 1, math.ceil(numFriends/25) do
  573.                                         info.text  = L["Part %d"]:format(i)
  574.                                         info.value = "fpart"..i
  575.                                         UIDropDownMenu_AddButton(info, level)
  576.                                 end
  577.                         end
  578.  
  579.                 elseif UIDROPDOWNMENU_MENU_VALUE == "guild" then
  580.                         if not IsInGuild() then return end
  581.                         local numFriends = GetNumGuildMembers(true)
  582.                         for i = 1, numFriends do
  583.                                 local name, rank, rankIndex, level, class, zone, note, officernote, online, status, classFileName, achievementPoints, achievementRank, isMobile, canSoR = GetGuildRosterInfo(i)
  584.                                 local c = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[classFileName] or RAID_CLASS_COLORS[classFileName]
  585.                                 sorttable[i] = format("%s |cffffd200(%s)|r |cff%.2x%.2x%.2x(%d %s)|r", name, rank, c.r*255, c.g*255, c.b*255, level, class)
  586.                         end
  587.                         for i = #sorttable, numFriends+1, -1 do
  588.                                 sorttable[i] = nil
  589.                         end
  590.                         if not ignoresortlocale[GetLocale()] then table.sort(sorttable) end
  591.                         if numFriends > 0 and numFriends <= 25 then
  592.                                 for i = 1, numFriends do
  593.                                         info.text = sorttable[i]
  594.                                         info.func = Postal_BlackBook.SetSendMailName
  595.                                         info.arg1 = strmatch(sorttable[i], "(.*) |cffffd200")
  596.                                         UIDropDownMenu_AddButton(info, level)
  597.                                 end
  598.                         elseif numFriends > 25 then
  599.                                 -- More than 25 people, split the list into multiple sublists of 25
  600.                                 info.hasArrow = 1
  601.                                 info.keepShownOnClick = 1
  602.                                 info.func = self.UncheckHack
  603.                                 for i = 1, math.ceil(numFriends/25) do
  604.                                         info.text  = L["Part %d"]:format(i)
  605.                                         info.value = "gpart"..i
  606.                                         UIDropDownMenu_AddButton(info, level)
  607.                                 end
  608.                         end
  609.                 end
  610.  
  611.         elseif level >= 3 then
  612.                 info.notCheckable = 1
  613.                 if UIDROPDOWNMENU_MENU_VALUE == "deletealt" then
  614.                         local db = Postal.db.global.BlackBook.alts
  615.                         local realm = GetRealmName()
  616.                         local faction = UnitFactionGroup("player")
  617.                         local player = UnitName("player")
  618.                         for i = 1, #db do
  619.                                 local p, f, l, c = strsplit("|", Postal.db.global.BlackBook.alts[i])
  620.                                 if p == player.."-"..realm or p ~= player.."-"..realm then
  621.                                         if l and c then
  622.                                                 local clr = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[c] or RAID_CLASS_COLORS[c]
  623.                                                 sorttable[i] = format("%s |cffffd200(%s)|r |cff%.2x%.2x%.2x(%d %s)|r", p, f, clr.r*255, clr.g*255, clr.b*255, l, LOCALIZED_CLASS_NAMES_MALE[c])
  624.                                         end
  625.                                 end
  626.                         end
  627.                         for i = #sorttable, #db+1, -1 do
  628.                                 sorttable[i] = nil
  629.                         end
  630.                         if not ignoresortlocale[GetLocale()] then table.sort(sorttable) end
  631.                         if #db > 0 and #db <= 25 then
  632.                                 for i = 1, #db do
  633.                                         info.text = sorttable[i]
  634.                                         info.func = Postal_BlackBook.DeleteAlt
  635.                                         info.arg1 = db[i]
  636.                                         --info.arg1 = strmatch(sorttable[i], "(.*) |cffffd200")
  637.                                         UIDropDownMenu_AddButton(info, level)
  638.                                 end
  639.                         elseif #db > 25 then
  640.                         -- More than 25 alts, split the list into multiple sublists of 25
  641.                                 info.hasArrow = 1
  642.                                 info.keepShownOnClick = 1
  643.                                 info.func = self.UncheckHack
  644.                                 for i = 1, math.ceil((#db)/25) do
  645.                                         info.text  = L["Part %d"]:format(i)
  646.                                         info.value = "delpart"..i
  647.                                         UIDropDownMenu_AddButton(info, level)
  648.                                 end    
  649.                         end
  650.  
  651.                 elseif strfind(UIDROPDOWNMENU_MENU_VALUE, "fpart") then
  652.                         local startIndex = tonumber(strmatch(UIDROPDOWNMENU_MENU_VALUE, "fpart(%d+)")) * 25 - 24
  653.                         local endIndex = math.min(startIndex+24, numFriendsOnList)
  654.                         for i = startIndex, endIndex do
  655.                                 local name = sorttable[i]
  656.                                 info.text = name
  657.                                 info.func = Postal_BlackBook.SetSendMailName
  658.                                 info.arg1 = name
  659.                                 UIDropDownMenu_AddButton(info, level)
  660.                         end
  661.  
  662.                 elseif strfind(UIDROPDOWNMENU_MENU_VALUE, "altspart") then
  663.                         local startIndex = tonumber(strmatch(UIDROPDOWNMENU_MENU_VALUE, "altspart(%d+)")) * 25 - 24
  664.                         local endIndex = math.min(startIndex+24, (#Postal.db.global.BlackBook.alts))
  665.                         for i = startIndex, endIndex do
  666.                                 local name = sorttable[i]
  667.                                 info.text = sorttable[i]
  668.                                 info.func = Postal_BlackBook.SetSendMailName
  669.                                 info.arg1 = strmatch(sorttable[i], "(.*) |cffffd200")
  670.                                 UIDropDownMenu_AddButton(info, level)
  671.                         end
  672.                        
  673.                 elseif strfind(UIDROPDOWNMENU_MENU_VALUE, "delpart") then
  674.                         local startIndex = tonumber(strmatch(UIDROPDOWNMENU_MENU_VALUE, "delpart(%d+)")) * 25 - 24
  675.                         local endIndex = math.min(startIndex+24, (#Postal.db.global.BlackBook.alts))
  676.                         for i = startIndex, endIndex do
  677.                                 local name = sorttable[i]
  678.                                 info.text = sorttable[i]
  679.                                 info.func = Postal_BlackBook.DeleteAlt
  680.                                 info.arg1 = Postal.db.global.BlackBook.alts[i]
  681.                                 UIDropDownMenu_AddButton(info, level)
  682.                         end
  683.                
  684.                 elseif strfind(UIDROPDOWNMENU_MENU_VALUE, "gpart") then
  685.                         local startIndex = tonumber(strmatch(UIDROPDOWNMENU_MENU_VALUE, "gpart(%d+)")) * 25 - 24
  686.                         local endIndex = math.min(startIndex+24, (GetNumGuildMembers(true)))
  687.                         for i = startIndex, endIndex do
  688.                                 local name = sorttable[i]
  689.                                 info.text = sorttable[i]
  690.                                 info.func = Postal_BlackBook.SetSendMailName
  691.                                 info.arg1 = strmatch(sorttable[i], "(.*) |cffffd200")
  692.                                 UIDropDownMenu_AddButton(info, level)
  693.                         end
  694.                 end
  695.  
  696.         end
  697. end
  698.  
  699. function Postal_BlackBook.SaveFriendGuildOption(dropdownbutton, arg1, arg2, checked)
  700.         Postal.SaveOption(dropdownbutton, arg1, arg2, checked)
  701.         local db = Postal.db.profile.BlackBook
  702.         local exclude = bit.bor(db.AutoCompleteFriends and AUTOCOMPLETE_FLAG_NONE or AUTOCOMPLETE_FLAG_FRIEND,
  703.                 db.AutoCompleteGuild and AUTOCOMPLETE_FLAG_NONE or AUTOCOMPLETE_FLAG_IN_GUILD)
  704.         Postal_BlackBook_Autocomplete_Flags.include = bit.bxor(
  705.                 db.ExcludeRandoms and (bit.bor(AUTOCOMPLETE_FLAG_FRIEND, AUTOCOMPLETE_FLAG_IN_GUILD)) or AUTOCOMPLETE_FLAG_ALL, exclude)
  706. end
  707.  
  708. function Postal_BlackBook.SetAutoComplete(dropdownbutton, arg1, arg2, checked)
  709.         local self = Postal_BlackBook
  710.         Postal.db.profile.BlackBook.UseAutoComplete = not checked
  711.         if checked then
  712.                 if self:IsHooked(SendMailNameEditBox, "OnChar") then
  713.                         self:Unhook(SendMailNameEditBox, "OnChar")
  714.                 end
  715.         else
  716.                 if not self:IsHooked(SendMailNameEditBox, "OnChar") then
  717.                         self:RawHookScript(SendMailNameEditBox, "OnChar")
  718.                 end
  719.         end
  720. end
  721.  
  722. function Postal_BlackBook.ModuleMenu(self, level)
  723.         if not level then return end
  724.         local info = self.info
  725.         wipe(info)
  726.         info.isNotRadio = 1
  727.         if level == 1 + self.levelAdjust then
  728.                 info.keepShownOnClick = 1
  729.                 info.text = L["Autofill last person mailed"]
  730.                 info.func = Postal.SaveOption
  731.                 info.arg1 = "BlackBook"
  732.                 info.arg2 = "AutoFill"
  733.                 info.checked = Postal.db.profile.BlackBook.AutoFill
  734.                 UIDropDownMenu_AddButton(info, level)
  735.  
  736.                 info.hasArrow = 1
  737.                 info.keepShownOnClick = 1
  738.                 info.func = self.UncheckHack
  739.                 info.checked = nil
  740.                 info.arg1 = nil
  741.                 info.arg2 = nil
  742.                 info.text = L["Name auto-completion options"]
  743.                 info.value = "AutoComplete"
  744.                 UIDropDownMenu_AddButton(info, level)
  745.                 local listFrame = _G["DropDownList"..level]
  746.                 self.UncheckHack(_G[listFrame:GetName().."Button"..listFrame.numButtons])
  747.  
  748.         elseif level == 2 + self.levelAdjust then
  749.                 local db = Postal.db.profile.BlackBook
  750.                 info.arg1 = "BlackBook"
  751.  
  752.                 if UIDROPDOWNMENU_MENU_VALUE == "AutoComplete" then
  753.                         info.text = L["Use Postal's auto-complete"]
  754.                         info.arg2 = "UseAutoComplete"
  755.                         info.checked = db.UseAutoComplete
  756.                         info.func = Postal_BlackBook.SetAutoComplete
  757.                         UIDropDownMenu_AddButton(info, level)
  758.  
  759.                         info.func = Postal.SaveOption
  760.                         info.disabled = not db.UseAutoComplete
  761.                         info.keepShownOnClick = 1
  762.  
  763.                         info.text = L["Alts"]
  764.                         info.arg2 = "AutoCompleteAlts"
  765.                         info.checked = db.AutoCompleteAlts
  766.                         UIDropDownMenu_AddButton(info, level)
  767.  
  768.                         info.text = L["Recently Mailed"]
  769.                         info.arg2 = "AutoCompleteRecent"
  770.                         info.checked = db.AutoCompleteRecent
  771.                         UIDropDownMenu_AddButton(info, level)
  772.  
  773.                         info.text = L["Contacts"]
  774.                         info.arg2 = "AutoCompleteContacts"
  775.                         info.checked = db.AutoCompleteContacts
  776.                         UIDropDownMenu_AddButton(info, level)
  777.  
  778.                         info.disabled = nil
  779.  
  780.                         info.text = L["Friends"]
  781.                         info.arg2 = "AutoCompleteFriends"
  782.                         info.checked = db.AutoCompleteFriends
  783.                         info.func = Postal_BlackBook.SaveFriendGuildOption
  784.                         UIDropDownMenu_AddButton(info, level)
  785.  
  786.                         info.text = L["Guild"]
  787.                         info.arg2 = "AutoCompleteGuild"
  788.                         info.checked = db.AutoCompleteGuild
  789.                         UIDropDownMenu_AddButton(info, level)
  790.  
  791.                         info.text = L["Exclude randoms you interacted with"]
  792.                         info.arg2 = "ExcludeRandoms"
  793.                         info.checked = db.ExcludeRandoms
  794.                         UIDropDownMenu_AddButton(info, level)
  795.  
  796.                         info.text = L["Disable Blizzard's auto-completion popup menu"]
  797.                         info.arg2 = "DisableBlizzardAutoComplete"
  798.                         info.checked = db.DisableBlizzardAutoComplete
  799.                         info.func = Postal.SaveOption
  800.                         UIDropDownMenu_AddButton(info, level)
  801.                 end
  802.         end
  803. end