This commit is contained in:
Andrew6810
2022-11-05 21:19:42 -07:00
parent b79f4bd588
commit f3e579cb57
386 changed files with 93729 additions and 2 deletions
@@ -0,0 +1,234 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local AutoMail = TSM:NewModule("AutoMail", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = {}
function AutoMail:OnEnable()
AutoMail:RegisterEvent("MAIL_CLOSED", private.StopSending)
end
function AutoMail:SendItems(items, target, callback, codPerItem)
if private.isSending or TSMAPI:IsPlayer(target) or not MailFrame:IsVisible() then return end
private.isSending = true
private.items = items
private.target = target
private.callback = callback
private.codPerItem = codPerItem
private.waitingLocations = {}
TSMAPI:CreateTimeDelay("mailingSendDelay", 0, private.SendNextMail, TSM.db.global.sendDelay)
return true
end
-- returns the number of items currently attached to the mail
function private:GetNumPendingAttachments()
local totalAttached = 0
for i=1, ATTACHMENTS_MAX_SEND do
if GetSendMailItem(i) then
totalAttached = totalAttached + 1
end
end
return totalAttached
end
function private:SendNextMail()
for _, info in ipairs(private.waitingLocations) do
if not GetContainerItemInfo(info.bag, info.slot) then
return
end
end
-- send off any pending items
private:SendOffMail()
-- fill the mail with the next batch of items
local bagsFull = private:FillMail()
if #private.waitingLocations > 0 then return end
-- check if anything was actually put in the mail to be sent
if private:GetNumPendingAttachments() == 0 then
-- we're done
if bagsFull then
TSM:Printf(L["Could not send mail due to not having free bag space available to split a stack of items."])
end
private:StopSending()
return
end
-- send off this mail
private:SendOffMail()
end
function private:SendOffMail()
local attachments = private:GetNumPendingAttachments()
if attachments == 0 or not private.target then return end
SendMailNameEditBox:SetText(private.target)
SetSendMailMoney(0)
if private.codPerItem then
local numItems = 0
for i=1, ATTACHMENTS_MAX_SEND do
local count = select(3, GetSendMailItem(i))
numItems = numItems + count
end
SetSendMailCOD(private.codPerItem*numItems)
else
SetSendMailCOD(0)
end
SendMail(private.target, SendMailSubjectEditBox:GetText() or "TSM_Mailing", "")
if TSM.db.global.sendMessages then
local items = {}
for i=1, attachments do
local num = select(3, GetSendMailItem(i))
local link = GetSendMailItemLink(i)
local itemString = TSMAPI:GetItemString(link)
if itemString then
items[itemString] = items[itemString] or {num=0, link=link}
items[itemString].num = items[itemString].num + num
end
end
local temp = {}
for itemString, info in pairs(items) do
tinsert(temp, format("%sx%d", info.link, info.num))
end
local msg = ""
local cod = GetSendMailCOD()
if cod and cod > 0 then
msg = format(L["Sent %s to %s with a COD of %s."], table.concat(temp, ", "), private.target, TSMAPI:FormatTextMoney(cod))
else
msg = format(L["Sent %s to %s."], table.concat(temp, ", "), private.target)
end
local function DoPrint()
if private:GetNumPendingAttachments() > 0 then return end
TSMAPI:CancelFrame("sendMailPrintDelay")
TSM:Printf(msg)
end
TSMAPI:CreateTimeDelay("sendMailPrintDelay", 0, DoPrint, 0.1)
end
end
-- fills the current mail with items to be sent to the target
function private:FillMail()
if private:GetNumPendingAttachments() ~= 0 then return end
local locationInfo = {}
for bag, slot, itemString, quantity, locked in TSMAPI:GetBagIterator(true) do
if not locked then
locationInfo[itemString] = locationInfo[itemString] or {}
tinsert(locationInfo[itemString], {bag=bag, slot=slot, quantity=quantity})
end
end
local emptySlots = {}
for bag=0, NUM_BAG_SLOTS do
for slot=1, GetContainerNumSlots(bag) do
if not GetContainerItemInfo(bag, slot) then
local family = bag == 0 and 0 or GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag)))
tinsert(emptySlots, {bag=bag, slot=slot, family=family})
end
end
end
private.waitingLocations = {}
for itemString, quantity in pairs(private.items) do
if locationInfo[itemString] and quantity > 0 then
-- use stack sizes which match exactly first, followed by the smallest stacks
local sameSize = {}
for i=#locationInfo[itemString], 1, -1 do
if locationInfo[itemString][i].quantity == quantity then
tinsert(sameSize, locationInfo[itemString][i])
tremove(locationInfo[itemString], i)
end
end
sort(locationInfo[itemString], function(a,b) return a.quantity < b.quantity end)
for _, info in ipairs(sameSize) do
tinsert(locationInfo[itemString], 1, info)
end
for _, info in ipairs(locationInfo[itemString]) do
if quantity == 0 then break end
if quantity >= info.quantity then
PickupContainerItem(info.bag, info.slot)
quantity = quantity - info.quantity
private.items[itemString] = quantity
ClickSendMailItemButton()
if private:GetNumPendingAttachments() == ATTACHMENTS_MAX_SEND then
return
end
else
-- sort the empty slots such that we'll use special bags first if possible
local family = GetItemFamily(itemString)
local splitTarget
if family > 0 then
local specialBags = {}
for bag=1, NUM_BAG_SLOTS do
local bagFamily = GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag)))
if bagFamily and bagFamily > 0 and bit.band(family, bagFamily) > 0 then
specialBags[bag] = true
end
end
sort(emptySlots, function(a, b)
if specialBags[a.bag] and specialBags[b.bag] then
if a.bag == b.bag then
return a.slot < b.slot
end
return a.bag < b.bag
end
if a.bag == b.bag then
return a.slot < b.slot
end
if specialBags[a.bag] then return true end
if specialBags[b.bag] then return false end
return a.bag < b.bag
end)
else
sort(emptySlots, function(a, b)
if a.bag == b.bag then
return a.slot < b.slot
end
return a.bag < b.bag
end)
end
for i=1, #emptySlots do
if emptySlots[i].family == 0 or bit.band(family, emptySlots[i].family) > 0 then
splitTarget = emptySlots[i]
tremove(emptySlots, i)
break
end
end
if not splitTarget then return true end
SplitContainerItem(info.bag, info.slot, quantity)
PickupContainerItem(splitTarget.bag, splitTarget.slot)
tinsert(private.waitingLocations, splitTarget)
break
end
end
-- check if we want to send only one type of item per mail
if TSM.db.global.sendItemsIndividually then
return
end
end
end
end
-- stops sending mail and calls the callback
function private:StopSending()
if not private.isSending then return end
TSMAPI:CancelFrame("mailingSendDelay")
private.isSending = nil
private.items = nil
private.target = nil
private.waitingLocations = {}
private.callback()
end
+147
View File
@@ -0,0 +1,147 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local Groups = TSM:NewModule("Groups", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = {}
function Groups:CreateTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:Hide()
frame:SetAllPoints()
frame:SetScript("OnHide", function()
TSMAPI:CancelFrame("mailingGroupsRepeat")
end)
local stContainer = CreateFrame("Frame", nil, frame)
stContainer:SetPoint("TOPLEFT", 5, -5)
stContainer:SetPoint("BOTTOMRIGHT", -5, 35)
TSMAPI.Design:SetFrameColor(stContainer)
frame.groupTree = TSMAPI:CreateGroupTree(stContainer, "Mailing", "Mailing_Send")
local function OnButtonClick(self)
if IsShiftKeyDown() then
TSMAPI:CreateTimeDelay("mailingResendDelay", 0.1, private.StartSending, TSM.db.global.resendDelay * 60)
else
private:StartSending()
end
end
Groups:RegisterEvent("MAIL_CLOSED", function() TSMAPI:CancelFrame("mailingResendDelay") end)
local button = TSMAPI.GUI:CreateButton(frame, 15)
button:SetPoint("BOTTOMLEFT", 5, 5)
button:SetPoint("BOTTOMRIGHT", -5, 5)
button:SetHeight(25)
button:SetText(L["Mail Selected Groups"])
button:SetScript("OnClick", OnButtonClick)
button.tooltip = L["Shift-Click to automatically re-send after the amount of time specified in the TSM_Mailing options."]
frame.button = button
private.frame = frame
return frame
end
local badOperations = {}
function private:ValidateOperation(operation, operationName)
if not operation then return end
if operation.target == "" then
-- operation is invalid (no target)
if not badOperations[operationName] then
TSM:Printf(L["Skipping operation '%s' because there is no target."], operationName)
badOperations[operationName] = true
end
return
end
return true
end
function private:StartSending()
if private.isSending then return end
-- get a table of how many of each item we have in our bags
local inventoryItems = {}
for bag, slot, itemString, quantity, locked in TSMAPI:GetBagIterator(true) do
inventoryItems[itemString] = (inventoryItems[itemString] or 0) + quantity
end
local badOperations = {}
local targets = {}
for _, data in pairs(private.frame.groupTree:GetSelectedGroupInfo()) do
for _, operationName in ipairs(data.operations) do
TSMAPI:UpdateOperation("Mailing", operationName)
local operation = TSM.operations[operationName]
if private:ValidateOperation(operation, operationName) then
-- operation is valid
for itemString in pairs(data.items) do
local numAvailable = (inventoryItems[itemString] or 0) - operation.keepQty
if numAvailable > 0 then
local quantity = 0
if operation.maxQtyEnabled then
if TSMAPI:IsPlayer(operation.target) or not operation.restock then
quantity = min(numAvailable, operation.maxQty)
else
local targetQty = private:GetTargetQuantity(operation.target, itemString, operation.restockGBank)
quantity = min(numAvailable, operation.maxQty - targetQty)
end
else
quantity = numAvailable
end
if quantity > 0 then
inventoryItems[itemString] = inventoryItems[itemString] - quantity
targets[operation.target] = targets[operation.target] or {}
targets[operation.target][itemString] = quantity
end
end
end
end
end
end
for target in pairs(targets) do
if TSMAPI:IsPlayer(target) then
targets[target] = nil
end
end
private.targets = targets
private:SendNextTarget()
end
function private:GetTargetQuantity(player, itemString, includeGBank)
local num = 0
num = num + ((TSMAPI:ModuleAPI("ItemTracker", "playerbags", player, true) or {})[itemString] or 0)
num = num + ((TSMAPI:ModuleAPI("ItemTracker", "playerbank", player, true) or {})[itemString] or 0)
num = num + ((TSMAPI:ModuleAPI("ItemTracker", "playermail", player, true) or {})[itemString] or 0)
num = num + ((TSMAPI:ModuleAPI("ItemTracker", "playerauctions", player, true) or {})[itemString] or 0)
if includeGBank then
num = num + (TSMAPI:ModuleAPI("ItemTracker", "playerguildtotal", itemString, player) or 0)
end
return num
end
function private:SendNextTarget()
local target, items = next(private.targets)
if not target then
private.frame.button:SetText(L["Mail Selected Groups"])
private.frame.button:Enable()
private.isSending = nil
TSM:Print(L["Done sending mail."])
return
end
private.isSending = true
private.targets[target] = nil
private.frame.button:SetText(L["Sending..."])
private.frame.button:Disable()
if not TSM.AutoMail:SendItems(items, target, private.SendNextTarget) then
private:SendNextTarget()
end
end
+715
View File
@@ -0,0 +1,715 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local Inbox = TSM:NewModule("Inbox", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = { recheckTime = 1, allowTimerStart = true, lootIndex = 1, freeSlots = true }
function Inbox:OnEnable()
Inbox:RegisterEvent("MAIL_SHOW")
TSMAPI:CreateEventBucket("MAIL_INBOX_UPDATE", private.InboxUpdate, 0.3)
Inbox:RegisterEvent("MAIL_CLOSED")
end
function Inbox:CreateTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:Hide()
frame:SetAllPoints()
frame:SetScript("OnHide", function() private:StopAutoLooting() end)
frame:SetScript("OnShow", private.InboxUpdate)
local label = TSMAPI.GUI:CreateLabel(frame, "small")
label:SetPoint("TOPLEFT", 5, -5)
label:SetPoint("TOPRIGHT", -5, -5)
label:SetHeight(15)
label:SetJustifyH("CENTER")
label:SetJustifyV("CENTER")
frame.topLabel = label
TSMAPI.GUI:CreateHorizontalLine(frame, -25)
local stContainer = CreateFrame("Frame", nil, frame)
stContainer:SetPoint("TOPLEFT", 5, -35)
stContainer:SetPoint("BOTTOMRIGHT", -5, 55)
TSMAPI.Design:SetFrameColor(stContainer)
local handlers = {
OnClick = function(_, data)
if IsShiftKeyDown() and select(6, GetInboxHeaderInfo(data.index)) <= 0 then
if private:CanLootMailIndex(data.index) then
private:LootMailItem(data.index)
else
TSM:Print(L["Could not loot item from mail because your bags are full."])
end
end
if InboxFrame.openMailID ~= data.index then
InboxFrame.openMailID = data.index
OpenMailFrame.updateButtonPositions = true
OpenMail_Update()
ShowUIPanel(OpenMailFrame)
OpenMailFrame:SetPoint("TOPLEFT", InboxFrame, "TOPRIGHT", 32, 0)
PlaySound("igSpellBookOpen")
else
InboxFrame.openMailID = 0
HideUIPanel(OpenMailFrame)
end
InboxFrame_Update()
end,
OnEnter = function(_, data, self)
end,
OnLeave = function()
end,
}
local st = TSMAPI:CreateScrollingTable(stContainer, nil, handlers)
st:SetData({})
frame.st = st
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", 5, 30)
btn:SetPoint("BOTTOMRIGHT", -5, 30)
btn:SetHeight(20)
btn:SetText(L["Open All Mail"])
btn:SetScript("OnClick", function() private:StartAutoLooting("all") end)
frame.allBtn = btn
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
label:SetPoint("BOTTOMLEFT", 5, 5)
label:SetHeight(20)
label:SetJustifyH("LEFT")
label:SetJustifyV("CENTER")
label:SetText(L["AH Mail:"])
local btnWidth = (frame:GetWidth() - label:GetWidth() - 25) / 5
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", label, "BOTTOMRIGHT", 5, 0)
btn:SetWidth(btnWidth)
btn:SetHeight(20)
btn:SetText(L["Sales"])
btn:SetScript("OnClick", function() private:StartAutoLooting("sales") end)
frame.salesBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", frame.salesBtn, "BOTTOMRIGHT", 5, 0)
btn:SetWidth(btnWidth)
btn:SetHeight(20)
btn:SetText(L["Buys"])
btn:SetScript("OnClick", function() private:StartAutoLooting("buys") end)
frame.buysBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", frame.buysBtn, "BOTTOMRIGHT", 5, 0)
btn:SetWidth(btnWidth)
btn:SetHeight(20)
btn:SetText(L["Cancels"])
btn:SetScript("OnClick", function() private:StartAutoLooting("cancels") end)
frame.cancelsBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", frame.cancelsBtn, "BOTTOMRIGHT", 5, 0)
btn:SetWidth(btnWidth)
btn:SetHeight(20)
btn:SetText(L["Expires"])
btn:SetScript("OnClick", function() private:StartAutoLooting("expires") end)
frame.expiresBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", frame.expiresBtn, "BOTTOMRIGHT", 5, 0)
btn:SetPoint("BOTTOMRIGHT", -5, 5)
btn:SetHeight(20)
btn:SetText("Pending")
btn:SetScript("OnClick", function() private:StartAutoLooting("pendings") end)
frame.expiresBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 16)
btn:SetFrameStrata("HIGH")
btn:SetPoint("CENTER")
btn:SetHeight(30)
btn:SetWidth(150)
btn:SetText(L["Reload UI"])
btn:SetScript("OnClick", ReloadUI)
btn:Hide()
frame.reloadBtn = btn
frame.EnableButtons = function(self)
self.allBtn:Enable()
self.salesBtn:Enable()
self.buysBtn:Enable()
self.cancelsBtn:Enable()
self.expiresBtn:Enable()
self.buttonsEnabled = true
end
frame.DisableButtons = function(self)
self.allBtn:Disable()
self.salesBtn:Disable()
self.buysBtn:Disable()
self.cancelsBtn:Disable()
self.expiresBtn:Disable()
self.buttonsEnabled = nil
end
frame.buttonsEnabled = true
private.frame = frame
return frame
end
local function CacheFrameOnUpdate(self, elapsed)
if not private.waitingForData then
local seconds = self.endTime - GetTime()
if seconds <= 0 then
-- Look for new mail
-- Sometimes it fails and isn't available at exactly 60-61 seconds, and more like 62-64, will keep rechecking every 1 second
-- until data becomes available
if TSM.db.global.autoCheck then
private.waitingForData = true
self.timeLeft = private.recheckTime
private.lootIndex = 1
private.resetIndex = nil
CheckInbox()
private.frame.reloadBtn:Hide()
else
self:Hide()
end
return
end
private:UpdateTopLabel()
else
self.timeLeft = self.timeLeft - elapsed
if self.timeLeft <= 0 then
self.timeLeft = private.recheckTime
private.lootIndex = 1
private.resetIndex = nil
CheckInbox()
private.frame.reloadBtn:Hide()
end
end
end
function Inbox:MAIL_SHOW()
if not private.cacheFrame then
-- Timer for mailbox cache updates
private.cacheFrame = CreateFrame("Frame", nil, MailFrame)
private.cacheFrame:Hide()
private.cacheFrame:SetScript("OnUpdate", CacheFrameOnUpdate)
end
end
local function FormatDaysLeft(daysLeft, index)
-- code taken from Blizzard MailFrame.lua code
if daysLeft >= 1 then
if InboxItemCanDelete(index) then
daysLeft = YELLOW_FONT_COLOR_CODE .. format(DAYS_ABBR, floor(daysLeft)) .. " " .. FONT_COLOR_CODE_CLOSE;
else
daysLeft = GREEN_FONT_COLOR_CODE .. format(DAYS_ABBR, floor(daysLeft)) .. " " .. FONT_COLOR_CODE_CLOSE;
end
else
daysLeft = RED_FONT_COLOR_CODE .. SecondsToTime(floor(daysLeft * 24 * 60 * 60)) .. FONT_COLOR_CODE_CLOSE;
end
return daysLeft
end
function private:UpdateTopLabel()
local parts = {}
local numMail, totalMail = GetInboxNumItems()
if totalMail == numMail then
tinsert(parts, format(L["Showing all %d mail."], numMail))
else
tinsert(parts, format(L["Showing %d of %d mail."], numMail, totalMail))
end
local collectGold = private.collectGold or 0
if collectGold > 0 then
tinsert(parts, format(L["%s to collect."], TSMAPI:FormatTextMoney(collectGold)))
end
local nextRefresh = private.cacheFrame:IsVisible() and private.cacheFrame.endTime
if nextRefresh then
if numMail == 0 and TSM.db.global.showReloadBtn then
private.frame.reloadBtn:Show()
end
tinsert(parts, format(L["Next inbox update in %d seconds."], max(ceil(nextRefresh - GetTime()), 0)))
end
private.frame.topLabel:SetText(table.concat(parts, " "))
end
function private:InboxUpdate()
if not private.frame or not private.frame:IsVisible() then return end
TSMAPI:CancelFrame("inboxLootTextDelay")
local numMail, totalMail = GetInboxNumItems()
local greenColor, redColor, yellowColor = "|cff00ff00", "|cffff0000", "|cffeeff00"
local mailInfo = {}
local collectGold = 0
for i = 1, numMail do
mailInfo[i] = ""
local isInvoice = select(4, GetInboxText(i))
--local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index)
local _, _, sender, subject, money, cod, daysLeft, hasItem, _, _, _, _, _, itemQuantity = GetInboxHeaderInfo(i)
if isInvoice then
local invoiceType, itemName, playerName, bid, buyout, deposit, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(i)
-- fix MoP difference
if (quantity == nil) then quantity = itemQuantity end
if invoiceType == "buyer" then
local itemLink = GetInboxItemLink(i, 1) or itemName
mailInfo[i] = format(L["Buy: %s (%d) | %s | %s"], itemLink, quantity or 0, TSMAPI:FormatTextMoney(bid, redColor), FormatDaysLeft(daysLeft, i))
elseif invoiceType == "seller" then
collectGold = collectGold + bid - ahcut
--mailInfo[i] = format(L["Sale: %s (%d) | %s | %s"], itemName, quantity, TSMAPI:FormatTextMoney(bid - ahcut, greenColor), FormatDaysLeft(daysLeft, i))
mailInfo[i] = format("Sale: %s | %s | %s", itemName, TSMAPI:FormatTextMoney(bid - ahcut, greenColor), FormatDaysLeft(daysLeft, i))
elseif invoiceType == "seller_temp_invoice" then
mailInfo[i] = format("Pending Sale: %s | %s | %s", itemName, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor), FormatDaysLeft(daysLeft, i))
end
elseif hasItem then
local itemLink
local quantity = 0
for j = 1, hasItem do
local link = GetInboxItemLink(i, j)
itemLink = itemLink or link
quantity = quantity + select(3, GetInboxItem(i, j))
if TSMAPI:GetItemString(itemLink) ~= TSMAPI:GetItemString(link) then
itemLink = L["Multiple Items"]
quantity = -1
break
end
end
local itemDesc = (quantity > 0 and format("%s (%d)", itemLink, quantity)) or (quantity == -1 and L["Multiple Items"]) or "---"
if hasItem == 1 and itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
mailInfo[i] = format(L["Expired: %s | %s"], itemDesc, FormatDaysLeft(daysLeft, i))
elseif cod > 0 then
mailInfo[i] = format(L["COD: %s | %s | %s | %s"], itemDesc, TSMAPI:FormatTextMoney(cod, redColor), sender or "---", FormatDaysLeft(daysLeft, i))
elseif money > 0 then
collectGold = collectGold + money
mailInfo[i] = format("%s + %s | %s | %s", itemDesc, TSMAPI:FormatTextMoney(money, greenColor), sender or "---", FormatDaysLeft(daysLeft, i))
else
mailInfo[i] = format("%s | %s | %s", itemDesc, sender or "---", FormatDaysLeft(daysLeft, i))
end
elseif money > 0 then
mailInfo[i] = format("%s | %s | %s | %s", subject, TSMAPI:FormatTextMoney(money, greenColor), sender or "---", FormatDaysLeft(daysLeft, i))
else
mailInfo[i] = format("%s | %s | %s", subject, sender or "---", FormatDaysLeft(daysLeft, i))
end
end
private.collectGold = collectGold
local stData = {}
for i, info in ipairs(mailInfo) do
tinsert(stData, { cols = { { value = info } }, index = i })
end
private.frame.st:SetData(stData)
private:UpdateTopLabel()
-- Yay nothing else to loot, so nothing else to update the cache for!
if private.cacheFrame.endTime and numMail == totalMail and private.lastTotal ~= totalMail then
private.cacheFrame.endTime = nil
private.cacheFrame:Hide()
-- Start a timer since we're over the limit of 50 items before waiting for it to recache
elseif (private.cacheFrame.endTime and numMail >= 50 and private.lastTotal ~= totalMail) or (numMail >= 50 and private.allowTimerStart) then
private.resetIndex = nil
private.allowTimerStart = nil
private.waitingForData = nil
private.lastTotal = totalMail
private.cacheFrame.endTime = GetTime() + 60
private.cacheFrame:Show()
end
-- The last item we setup to auto loot is finished, time for the next one
if not private.frame.buttonsEnabled then
if private.autoLootTotal ~= numMail then
private.autoLootTotal = GetInboxNumItems()
-- If we're auto checking mail when new data is available, will wait and continue auto looting, otherwise we just stop now
if numMail == 0 and (not TSM.db.global.autoCheck or totalMail == 0) then
private:StopAutoLooting()
else
private:AutoLoot()
end
else
TSMAPI:CreateTimeDelay("mailSkipDelay", 1, function()
local money, _, _, hasItem, _, _, _, canReply = select(5, GetInboxHeaderInfo(private.lootIndex))
if not hasItem and money == 0 then
private.lootIndex = private.lootIndex + 1
return private:AutoLoot()
end
end)
end
end
end
function private:ShouldOpenMail(index)
local shouldOpen
if private.mode == "all" then
return true
elseif private.mode == "sales" then
local money = select(5, GetInboxHeaderInfo(index))
if money > 0 and GetInboxInvoiceInfo(index) == "seller" then
return true
end
elseif private.mode == "buys" then
local hasItem = select(8, GetInboxHeaderInfo(index))
if hasItem and GetInboxInvoiceInfo(index) == "buyer" then
return true
end
elseif private.mode == "cancels" then
local isInvoice = select(4, GetInboxText(index))
local subject, _, _, _, hasItem = select(4, GetInboxHeaderInfo(index))
if not isInvoice and hasItem == 1 then
local itemLink = GetInboxItemLink(index, 1)
if itemLink then
local itemName = TSMAPI:GetSafeItemInfo(itemLink)
local quantity = select(3, GetInboxItem(index, 1))
if quantity and quantity > 0 and (subject == format(AUCTION_REMOVED_MAIL_SUBJECT.." (%d)", itemName, quantity) or subject == format(AUCTION_REMOVED_MAIL_SUBJECT, itemName)) then
return true
end
end
end
elseif private.mode == "pendings" then
local isInvoice = select(4, GetInboxText(index))
if isInvoice then
invoiceType = GetInboxInvoiceInfo(index)
if invoiceType == "seller_temp_invoice" then
return true
end
end
elseif private.mode == "expires" then
local isInvoice = select(4, GetInboxText(index))
local subject, _, _, _, hasItem = select(4, GetInboxHeaderInfo(index))
if not isInvoice and hasItem == 1 then
local itemLink = GetInboxItemLink(index, 1)
if itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
return true
end
end
end
end
-- Deals with auto looting of mail!
function private:StartAutoLooting(mode)
private.mode = mode
local canCollectMail
if private.mode == "all" then
local total
private.autoLootTotal, total = GetInboxNumItems()
canCollectMail = not (private.autoLootTotal == 0 and total == 0)
else
for i = 1, GetInboxNumItems() do
if private:ShouldOpenMail(i) then
canCollectMail = true
break
end
end
end
if not canCollectMail then
private.mode = nil
return
end
Inbox:RegisterEvent("UI_ERROR_MESSAGE")
private.frame:DisableButtons()
private.moneyCollected = 0
private.mode = mode
private.lootIndex = 1
private:AutoLoot()
end
function private:AutoLoot()
TSMAPI:CancelFrame("mailSkipDelay")
-- Already looted everything after the invalid indexes we had, so fail it
if private.lootIndex > 1 and private.lootIndex > GetInboxNumItems() then
if private.resetIndex then
private:StopAutoLooting()
else
private.resetIndex = true
private.lootIndex = 1
private:AutoLoot()
end
return
end
local money, cod, _, items, _, _, _, _, isGM = select(5, GetInboxHeaderInfo(private.lootIndex))
if not isGM and (not cod or cod <= 0) and ((money and money > 0) or (items and items > 0)) or GetInboxInvoiceInfo(private.lootIndex) == "seller_temp_invoice" then
TSMAPI:CancelFrame("mailWaitDelay")
if private.mode == "all" then
if money > 0 then
if TSM.db.global.openAllLeaveGold then
private.lootIndex = private.lootIndex + 1
return private:AutoLoot()
end
end
if private:CanLootMailIndex(private.lootIndex) then
if money > 0 then
private.moneyCollected = private.moneyCollected + money
end
private:LootMailItem(private.lootIndex)
else
private.lootIndex = private.lootIndex + 1
return private:AutoLoot()
end
else
if private:CanLootMailIndex(private.lootIndex) and private:ShouldOpenMail(private.lootIndex) then
if money > 0 then
private.moneyCollected = private.moneyCollected + money
end
private:LootMailItem(private.lootIndex)
else
private.lootIndex = private.lootIndex + 1
return private:AutoLoot()
end
end
-- Can't grab the first mail, so increase it and try again
elseif GetInboxNumItems() >= private.lootIndex then
private.lootIndex = private.lootIndex + 1
private:AutoLoot()
end
end
function private:LootMailItem(index)
if TSM.db.global.inboxMessages then
--local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index)
local _, _, sender, subject, money, cod, _, hasItem, _, _, _, _, _, itemQuantity = GetInboxHeaderInfo(index)
sender = sender or "?"
if select(4, GetInboxText(index)) then
-- it's an invoice
local invoiceType, itemName, playerName, bid, _, _, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(index)
-- fix MoP difference
if (quantity == nil) then quantity = itemQuantity end
local redColor = "|cffFF0000"
local greenColor = "|cff00FF00"
local yellowColor = "|cffFFFF00"
if invoiceType == "buyer" then
local itemLink = GetInboxItemLink(index, 1) or itemName
TSM:Printf(L["Collected purchase of %s (%d) for %s."], itemLink, quantity, TSMAPI:FormatTextMoney(bid, redColor))
elseif invoiceType == "seller" then
--TSM:Printf(L["Collected sale of %s (%d) for %s."], itemName, quantity, TSMAPI:FormatTextMoney(bid - ahcut, greenColor))
TSM:Printf("Collected sale of %s for %s.", itemName, TSMAPI:FormatTextMoney(bid - ahcut, greenColor))
elseif invoiceType == "seller_temp_invoice" then
TSM:Printf("Removing pending sale: %s (%s)", itemName, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor))
DeleteInboxItem(index)
return
end
elseif hasItem then
local itemLink
local quantity = 0
for i = 1, hasItem do
local link = GetInboxItemLink(index, i)
itemLink = itemLink or link
quantity = quantity + select(3, GetInboxItem(index, i))
if TSMAPI:GetItemString(itemLink) ~= TSMAPI:GetItemString(link) then
itemLink = L["Multiple Items"]
quantity = -1
break
end
end
local itemDesc = (quantity > 0 and format("%s (%d)", itemLink, quantity)) or (quantity == -1 and "Multiple Items") or "?"
if hasItem == 1 and itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
TSM:Printf(L["Collected expired auction of %s"], itemDesc)
elseif cod > 0 then
TSM:Printf(L["Collected COD of %s from %s for %s."], itemDesc, sender, TSMAPI:FormatTextMoney(cod, redColor))
elseif money > 0 then
TSM:Printf(L["Collected %s and %s from %s."], itemDesc, TSMAPI:FormatTextMoney(money, greenColor), sender)
else
TSM:Printf(L["Collected %s from %s."], itemDesc, sender)
end
elseif money > 0 then
TSM:Printf(L["Collected %s from %s."], TSMAPI:FormatTextMoney(money, greenColor), sender)
else
TSM:Printf(L["Collected mail from %s with a subject of '%s'."], sender, subject)
end
end
AutoLootMailItem(index)
end
function private:CanLootMailIndex(index)
local hasItem = select(8, GetInboxHeaderInfo(index))
if not hasItem or hasItem == 0 then return true end
if not TSM.db.global.keepMailSpace or TSM.db.global.keepMailSpace == 0 then
for j = 1, ATTACHMENTS_MAX_RECEIVE do
local itemString = TSMAPI:GetItemString(GetInboxItemLink(index, j))
local quantity = select(3, GetInboxItem(index, j))
local space = 0
if itemString then
for bag = 0, NUM_BAG_SLOTS do
if TSMAPI:ItemWillGoInBag(itemString, bag) then
for slot = 1, GetContainerNumSlots(bag) do
local iString = TSMAPI:GetItemString(GetContainerItemLink(bag, slot))
if iString == itemString then
local stackSize = select(2, GetContainerItemInfo(bag, slot))
local maxStackSize = select(8, TSMAPI:GetSafeItemInfo(itemString))
if (maxStackSize - stackSize) >= quantity then
return true
end
elseif not iString then
return true
end
end
end
end
end
end
else
-- get number of free slots per generic / special bags and partial slots by bag
local genericSpace, uniqueSpace, partSlots = private:GetBagSlots()
local usedSlots = {}
for j = 1, ATTACHMENTS_MAX_RECEIVE do
local itemString = TSMAPI:GetItemString(GetInboxItemLink(index, j))
local quantity = select(3, GetInboxItem(index, j))
local isDone = false
if itemString then
for bag = 0, NUM_BAG_SLOTS do
if TSMAPI:ItemWillGoInBag(itemString, bag) then
for slot = 1, GetContainerNumSlots(bag) do
local iString = TSMAPI:GetItemString(GetContainerItemLink(bag, slot))
if iString == itemString and (partSlots[bag] and partSlots[bag][slot]) then
local stackSize = select(2, GetContainerItemInfo(bag, slot))
local maxStackSize = select(8, TSMAPI:GetSafeItemInfo(itemString))
if (maxStackSize - stackSize - (usedSlots[bag] and usedSlots[bag][slot] or 0)) >= quantity then
if stackSize + quantity == maxStackSize then
if partSlots[bag] and partSlots[bag][slot] then
partSlots[bag][slot] = nil -- this partial slot would be filled so remove it from available part slots
end
else
if not usedSlots[bag] then
usedSlots[bag] = {}
end
usedSlots[bag][slot] = (usedSlots[bag][slot] or 0) + stackSize -- store the stacksize for this slot after adding this item
end
isDone = true
break
end
else
local itemFamily = GetItemFamily(itemString)
local bagFamily = GetItemFamily(GetBagName(bag)) or 0
if itemFamily and bagFamily and bagFamily > 0 and bit.band(itemFamily, bagFamily) > 0 and (uniqueSpace[bag] and uniqueSpace[bag] > 0) then
uniqueSpace[bag] = uniqueSpace[bag] - 1 -- remove one empty slot from the bag
isDone = true
break
else
if genericSpace[bag] and genericSpace[bag] > 0 then
genericSpace[bag] = genericSpace[bag] - 1 -- remove one empty slot from the bag
if genericSpace[bag] <= 0 then
genericSpace[bag] = nil
end
isDone = true
break
end
end
end
end
if isDone then break end
end
end
end
end
--calculate the total remaining empty slots in generic bags after looting this mail
local remainingSpace = 0
for bag, space in pairs(genericSpace) do
remainingSpace = remainingSpace + space
end
if remainingSpace >= TSM.db.global.keepMailSpace then
return true -- either not using keepMailSpace option or we can loot all of this mail
else
private.keepFreeSlots = true -- can't loot the whole of this mail and leave enough free slots so set the flag that displays the chat message
end
end
end
function private:StopAutoLooting(failed)
if failed and (not private.frame or not private.frame:IsVisible()) then
TSM:Print(L["Cannot finish auto looting, inventory is full or too many unique items."])
end
if private.keepFreeSlots then
TSM:Printf(L["Cannot finish auto looting, keeping %s slots free."], TSM.db.global.keepMailSpace)
private.keepFreeSlots = false
end
private.mode = nil
private.resetIndex = nil
private.autoLootTotal = nil
if not private.frame then return end
private.frame:EnableButtons()
--Tell user how much money has been collected if they don't have it turned off in TradeSkillMaster_Mailing options
if private.moneyCollected and private.moneyCollected > 0 and TSM.db.global.displayMoneyCollected then
TSM:Printf(L["%s total gold collected!"], TSMAPI:FormatTextMoney(private.moneyCollected))
private.moneyCollected = 0
end
end
function private:GetBagSlots()
local genericSpace, uniqueSpace, partSlots = {}, {}, {}
for bag = 0, NUM_BAG_SLOTS do
if (GetItemFamily(GetBagName(bag)) or 0) > 0 then
uniqueSpace[bag] = GetContainerNumFreeSlots(bag) or 0
else
genericSpace[bag] = GetContainerNumFreeSlots(bag) or 0
end
for slot = 1, GetContainerNumSlots(bag) do
local iLink = GetContainerItemLink(bag, slot)
if iLink then
if not partSlots[bag] then
partSlots[bag] = {}
end
table.insert(partSlots[bag], slot)
end
end
end
return genericSpace, uniqueSpace, partSlots
end
function Inbox:UI_ERROR_MESSAGE(event, msg)
if msg == ERR_MAIL_DATABASE_ERROR then
-- recover from internal mail error
TSMAPI:CreateTimeDelay("mailWaitDelay", 1, private.AutoLoot)
elseif msg == ERR_INV_FULL or msg == ERR_ITEM_MAX_COUNT then
-- Try the next index in case we can still loot more such as in the case of glyphs
private.lootIndex = private.lootIndex + 1
-- If we've exhausted all slots, but we still have <50 and more mail pending, wait until new data comes and keep looting it
local current, total = GetInboxNumItems()
if private.lootIndex > current then
if private.lootIndex > total and total <= 50 then
private:StopAutoLooting(true)
end
return
end
TSMAPI:CreateTimeDelay("mailWaitDelay", 0.3, private.AutoLoot)
end
end
function Inbox:MAIL_CLOSED()
private.resetIndex = nil
private.allowTimerStart = true
private.waitingForData = nil
private:StopAutoLooting()
TSMAPI:CancelFrame("inboxLootTextDelay")
TSMAPI:CancelFrame("mailSkipDelay")
Inbox:UnregisterEvent("UI_ERROR_MESSAGE") --sometimes shows error messages even when closed, so unregister that event.
end
@@ -0,0 +1,225 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local MailTab = TSM:NewModule("MailTab", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = {tabs = {}}
function MailTab:OnEnable()
MailTab:RegisterEvent("MAIL_SHOW", function() TSMAPI:CreateTimeDelay("mailShowDelay", 0, private.OnMailShow) end)
end
function private:OnMailShow()
private.frame = private.frame or private:CreateMailTab()
if TSM.db.global.defaultMailTab then
for i=1, MailFrame.numTabs do
if _G["MailFrameTab"..i].isTSMTab then
_G["MailFrameTab"..i]:Click()
break
end
end
end
-- make sure the second tab gets loaded so we can send mail
local currentTab = PanelTemplates_GetSelectedTab(MailFrame)
MailFrameTab2:Click()
_G["MailFrameTab"..currentTab]:Click()
end
function private:CreateMailTab()
local frame = CreateFrame("Frame", nil, MailFrame)
TSMAPI.Design:SetFrameBackdropColor(frame)
frame:Hide()
frame:SetPoint("TOPLEFT")
frame:SetPoint("BOTTOMRIGHT", 40, 0)
frame:EnableMouse(true)
local function OnTabClick(self)
PanelTemplates_SetTab(MailFrame, self:GetID())
--ButtonFrameTemplate_HideButtonBar(MailFrame)
InboxFrame:Hide()
OpenMailFrame:Hide()
StationeryPopupFrame:Hide()
SendMailFrame:Hide()
SetSendMailShowing(false)
MailFrameTab1:Hide()
MailFrameTab2:Hide()
MailFrameTab3:Hide()
InboxCloseButton:Hide()
private.frame:Show()
if TSM.db.global.defaultPage == 1 then
private.frame.inboxBtn:Click()
elseif TSM.db.global.defaultPage == 2 then
private.frame.groupsBtn:Click()
elseif TSM.db.global.defaultPage == 3 then
private.frame.quickSendBtn:Click()
elseif TSM.db.global.defaultPage == 4 then
private.frame.otherBtn:Click()
end
end
local function OnOtherTabClick()
if not private.frame then return end
private.frame:Hide()
InboxFrame:Show()
MailFrameTab1:Show()
MailFrameTab2:Show()
MailFrameTab3:Show()
InboxCloseButton:Show()
PanelTemplates_SetTab(MailFrame, 1)
end
--MailTab:Hook("MailFrameTab_OnClick", OnOtherTabClick, true)
local n = MailFrame.numTabs + 1
local tab = CreateFrame("Button", "MailFrameTab"..n, MailFrame, "FriendsFrameTabTemplate")
tab:Hide()
tab:SetID(n)
tab:SetText(TSMAPI.Design:GetInlineColor("link2").."TSM_Mailing|r")
tab:SetNormalFontObject(GameFontHighlightSmall)
tab.isTSMTab = true
tab:SetPoint("LEFT", _G["MailFrameTab"..n-1], "RIGHT", -8, 0)
tab:Show()
tab:SetScript("OnClick", OnTabClick)
PanelTemplates_SetNumTabs(MailFrame, n)
PanelTemplates_EnableTab(MailFrame, n)
frame.tab = tab
local iconFrame = CreateFrame("Frame", nil, frame)
iconFrame:SetPoint("CENTER", frame, "TOPLEFT", 25, -25)
iconFrame:SetHeight(80)
iconFrame:SetWidth(80)
local icon = iconFrame:CreateTexture(nil, "ARTWORK")
icon:SetAllPoints()
icon:SetTexture("Interface\\Addons\\TradeSkillMaster\\Media\\TSM_Icon_Big")
local ag = iconFrame:CreateAnimationGroup()
local spin = ag:CreateAnimation("Rotation")
spin:SetOrder(1)
spin:SetDuration(2)
spin:SetDegrees(90)
local spin = ag:CreateAnimation("Rotation")
spin:SetOrder(2)
spin:SetDuration(4)
spin:SetDegrees(-180)
local spin = ag:CreateAnimation("Rotation")
spin:SetOrder(3)
spin:SetDuration(2)
spin:SetDegrees(90)
ag:SetLooping("REPEAT")
iconFrame:SetScript("OnEnter", function() ag:Play() end)
iconFrame:SetScript("OnLeave", function() ag:Stop() end)
local title = TSMAPI.GUI:CreateLabel(frame)
title:SetPoint("TOPLEFT", 40, -5)
title:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -5, -25)
title:SetJustifyH("CENTER")
title:SetJustifyV("CENTER")
title:SetText("TSM_Mailing - "..TSM._version)
local closeBtn = TSMAPI.GUI:CreateButton(frame, 19)
closeBtn:SetPoint("TOPRIGHT", -5, -5)
closeBtn:SetWidth(20)
closeBtn:SetHeight(20)
closeBtn:SetText("X")
closeBtn:SetScript("OnClick", CloseMail)
local switchBtn = TSMAPI.GUI:CreateButton(frame, 15)
switchBtn:SetPoint("TOPRIGHT", closeBtn, "TOPLEFT", -4, 0)
switchBtn:SetHeight(20)
switchBtn:SetWidth(85)
switchBtn:SetText("Default UI")
switchBtn:SetScript("OnClick", OnOtherTabClick)
frame.switchBtn = switchBtn
local line = TSMAPI.GUI:CreateVerticalLine(frame, 0)
line:ClearAllPoints()
line:SetPoint("TOPRIGHT", -30, -1)
line:SetWidth(2)
line:SetHeight(30)
TSMAPI.GUI:CreateHorizontalLine(frame, -30)
private:CreateTabs(frame)
return frame
end
function private:CreateTabs(frame)
local function OnButtonClick(self)
frame.inboxTab:Hide()
frame.groupsTab:Hide()
frame.otherTab:Hide()
frame.quickSendTab:Hide()
frame.inboxBtn:UnlockHighlight()
frame.groupsBtn:UnlockHighlight()
frame.otherBtn:UnlockHighlight()
frame.quickSendBtn:UnlockHighlight()
self:LockHighlight()
if self == frame.inboxBtn then
frame.inboxTab:Show()
elseif self == frame.groupsBtn then
frame.groupsTab:Show()
elseif self == frame.otherBtn then
frame.otherTab:Show()
elseif self == frame.quickSendBtn then
frame.quickSendTab:Show()
end
end
local button = TSMAPI.GUI:CreateButton(frame, 15)
button:SetPoint("TOPLEFT", 70, -40)
button:SetHeight(20)
button:SetWidth(55)
button:SetText(L["Inbox"])
button:SetScript("OnClick", OnButtonClick)
frame.inboxBtn = button
local button = TSMAPI.GUI:CreateButton(frame, 15)
button:SetPoint("TOPLEFT", frame.inboxBtn, "TOPRIGHT", 5, 0)
button:SetHeight(20)
button:SetWidth(95)
button:SetText(L["TSM Groups"])
button:SetScript("OnClick", OnButtonClick)
frame.groupsBtn = button
local button = TSMAPI.GUI:CreateButton(frame, 15)
button:SetPoint("TOPLEFT", frame.groupsBtn, "TOPRIGHT", 5, 0)
button:SetHeight(20)
button:SetWidth(85)
button:SetText(L["Quick Send"])
button:SetScript("OnClick", OnButtonClick)
frame.quickSendBtn = button
local button = TSMAPI.GUI:CreateButton(frame, 15)
button:SetPoint("TOPLEFT", frame.quickSendBtn, "TOPRIGHT", 5, 0)
button:SetPoint("TOPRIGHT", -5, -40)
button:SetHeight(20)
button:SetText(L["Other"])
button:SetScript("OnClick", OnButtonClick)
frame.otherBtn = button
TSMAPI.GUI:CreateHorizontalLine(frame, -70)
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 0, -70)
content:SetPoint("BOTTOMRIGHT")
frame.inboxTab = TSM.Inbox:CreateTab(content)
frame.inboxTab:Hide()
frame.groupsTab = TSM.Groups:CreateTab(content)
frame.groupsTab:Hide()
frame.otherTab = TSM.Other:CreateTab(content)
frame.otherTab:Hide()
frame.quickSendTab = TSM.QuickSend:CreateTab(content)
frame.quickSendTab:Hide()
end
@@ -0,0 +1,352 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local Options = TSM:NewModule("Options", "AceEvent-3.0")
local AceGUI = LibStub("AceGUI-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
function Options:Load(parent, operation, group)
Options.treeGroup = AceGUI:Create("TSMTreeGroup")
Options.treeGroup:SetLayout("Fill")
Options.treeGroup:SetCallback("OnGroupSelected", function(...) Options:SelectTree(...) end)
Options.treeGroup:SetStatusTable(TSM.db.global.optionsTreeStatus)
parent:AddChild(Options.treeGroup)
Options:UpdateTree()
if operation then
if operation == "" then
Options.currentGroup = group
Options.treeGroup:SelectByPath(2)
Options.currentGroup = nil
else
Options.treeGroup:SelectByPath(2, operation)
end
else
Options.treeGroup:SelectByPath(1)
end
end
function Options:UpdateTree()
local operationTreeChildren = {}
for name in pairs(TSM.operations) do
tinsert(operationTreeChildren, { value = name, text = name })
end
sort(operationTreeChildren, function(a, b) return a.value < b.value end)
Options.treeGroup:SetTree({ { value = 1, text = L["Options"] }, { value = 2, text = L["Operations"], children = operationTreeChildren } })
end
function Options:SelectTree(treeGroup, _, selection)
treeGroup:ReleaseChildren()
local major, minor = ("\001"):split(selection)
major = tonumber(major)
if major == 1 then
Options:LoadGeneralSettings(treeGroup)
elseif minor then
Options:DrawOperationSettings(treeGroup, minor)
else
Options:DrawNewOperation(treeGroup)
end
end
function Options:DrawNewOperation(container)
local currentGroup = Options.currentGroup
local page = {
{
-- scroll frame to contain everything
type = "ScrollFrame",
layout = "List",
children = {
{
type = "InlineGroup",
layout = "flow",
title = L["New Operation"],
children = {
{
type = "Label",
text = L["Mailing operations contain settings for easy mailing of items to other characters."],
relativeWidth = 1,
},
{
type = "EditBox",
label = L["Operation Name"],
relativeWidth = 0.8,
callback = function(self, _, name)
name = (name or ""):trim()
if name == "" then return end
if TSM.operations[name] then
self:SetText("")
return TSM:Printf(L["Error creating operation. Operation with name '%s' already exists."], name)
end
TSM.operations[name] = CopyTable(TSM.operationDefaults)
Options:UpdateTree()
Options.treeGroup:SelectByPath(2, name)
TSMAPI:NewOperationCallback("Mailing", currentGroup, name)
end,
tooltip = L["Give the new operation a name. A descriptive name will help you find this operation later."],
},
},
},
},
},
}
TSMAPI:BuildPage(container, page)
end
function Options:DrawOperationSettings(container, operationName)
local tg = AceGUI:Create("TSMTabGroup")
tg:SetLayout("Fill")
tg:SetFullHeight(true)
tg:SetFullWidth(true)
tg:SetTabs({{value=1, text=L["General"]}, {value=2, text=L["Relationships"]}, {value=3, text=L["Management"]}})
tg:SetCallback("OnGroupSelected", function(self,_,value)
tg:ReleaseChildren()
TSMAPI:UpdateOperation("Mailing", operationName)
if value == 1 then
Options:DrawOperationGeneral(self, operationName)
elseif value == 2 then
Options:DrawOperationRelationships(self, operationName)
elseif value == 3 then
TSMAPI:DrawOperationManagement(TSM, self, operationName)
end
end)
container:AddChild(tg)
tg:SelectTab(1)
end
function Options:DrawOperationGeneral(container, operationName)
local operationSettings = TSM.operations[operationName]
local page = {
{
-- scroll frame to contain everything
type = "ScrollFrame",
layout = "List",
children = {
{
type = "InlineGroup",
layout = "flow",
title = L["Operation Settings"],
children = {
{
type = "EditBox",
label = L["Target Player"],
settingInfo = {operationSettings, "target"},
autoComplete = AUTOCOMPLETE_LIST.MAIL,
relativeWidth = 0.5,
disabled = operationSettings.relationships.target,
tooltip = L["The name of the player you want to mail items to."].."\n\n"..TSM.SPELLING_WARNING,
},
{
type = "Slider",
label = L["Keep Quantity"],
settingInfo = {operationSettings, "keepQty"},
relativeWidth = 0.5,
disabled = operationSettings.relationships.keepQty,
min = 0,
max = 500,
step = 1,
tooltip = L["Mailing will keep this number of items in the current player's bags and not mail them to the target."],
},
{
type = "HeadingLine"
},
{ -- first line of text
type = "CheckBox",
label = L["Set Max Quantity"],
settingInfo = {operationSettings, "maxQtyEnabled"},
disabled = operationSettings.relationships.maxQtyEnabled,
callback = function() Options.treeGroup:SelectByPath(2, operationName) end,
tooltip = L["If checked, a maximum quantity to send to the target can be set. Otherwise, Mailing will send as many as it can."],
},
{
type = "Slider",
label = L["Maximum Quantity"],
settingInfo = {operationSettings, "maxQty"},
disabled = not operationSettings.maxQtyEnabled or operationSettings.relationships.maxQty,
relativeWidth = 0.5,
min = 1,
max = 500,
step = 1,
tooltip = L["Sets the maximum quantity of each unique item to send to the target at a time."],
},
{
type = "CheckBox",
label = L["Restock Target to Max Quantity"],
settingInfo = {operationSettings, "restock"},
disabled = not operationSettings.maxQtyEnabled or operationSettings.relationships.restock,
callback = function() Options.treeGroup:SelectByPath(2, operationName) end,
tooltip = L["If checked, the target's current inventory will be taken into account when determing how many to send. For example, if the max quantity is set to 10, and the target already has 3, Mailing will send at most 7 items."],
},
{
type = "CheckBox",
label = L["Include Guild Bank in Restock"],
settingInfo = {operationSettings, "restockGBank"},
disabled = not operationSettings.restock or operationSettings.relationships.restockGBank,
tooltip = L["If checked, the target's guild bank will be included in their inventory for the 'Restock Target to Max Quantity' option."],
},
},
},
},
},
}
TSMAPI:BuildPage(container, page)
end
function Options:DrawOperationRelationships(container, operationName)
local settingInfo = {
{
label = L["General Settings"],
{key="target", label=L["Target Player"]},
{key="keepQty", label=L["Keep Quantity"]},
{key="maxQtyEnabled", label=L["Set Max Quantity"]},
{key="maxQty", label=L["Maximum Quantity"]},
{key="restock", label=L["Restock Target to Max Quantity"]},
{key="restockGBank", label=L["Include Guild Bank in Restock"]},
},
}
TSMAPI:ShowOperationRelationshipTab(TSM, container, TSM.operations[operationName], settingInfo)
end
function Options:LoadGeneralSettings(container)
local page = {
{
-- scroll frame to contain everything
type = "ScrollFrame",
layout = "List",
children = {
{
type = "InlineGroup",
layout = "flow",
title = L["General Settings"],
relativeWidth = 1,
children = {
{
type = "CheckBox",
label = L["Make Mailing Default Mail Tab"],
settingInfo = {TSM.db.global, "defaultMailTab"},
tooltip = L["If checked, the Mailing tab of the mailbox will be the default tab."],
},
{
type = "Dropdown",
label = L["Default Mailing Page"],
relativeWidth = 0.49,
list = {L["Inbox"], L["TSM Groups"], L["Quick Send"], L["Other"]},
settingInfo = {TSM.db.global, "defaultPage"},
tooltip = L["Specifies the default page that'll show when you select the TSM_Mailing tab."],
},
{
type = "CheckBox",
label = L["Auto Recheck Mail"],
settingInfo = {TSM.db.global, "autoCheck"},
tooltip = L["Automatically rechecks mail every 60 seconds when you have too much mail.\n\nIf you loot all mail with this enabled, it will wait and recheck then keep auto looting."],
},
{
type = "CheckBox",
label = L["Show Reload UI Button"],
settingInfo = {TSM.db.global, "showReloadBtn"},
tooltip = L["If checked, a 'Reload UI' button will be shown while waiting for the inbox to refresh. Reloading will cause the mailbox to refresh and may be faster than waiting for the next refresh."],
},
{
type = "CheckBox",
label = L["Leave Gold with Open All"],
settingInfo = {TSM.db.global, "openAllLeaveGold"},
tooltip = L["If checked, the 'Open All' button will leave any mail containing gold."],
},
{
type = "CheckBox",
label = L["Send Items Individually"],
settingInfo = {TSM.db.global, "sendItemsIndividually"},
tooltip = L["Sends each unique item in a seperate mail."],
},
{
type = "Slider",
value = TSM.db.global.sendDelay,
label = L["Mail Send Delay"],
min = 0.1,
max = 2,
step = 0.1,
relativeWidth = 0.49,
disabled = not TSM.db.global.sendDelay,
callback = function(self,_,value)
if value < 0.1 then value = 0.1 end
if value > 2 then value = 2 end
self:SetValue(value)
TSM.db.global.sendDelay = value
end,
tooltip = L["This slider controls how long the mail sending code waits between consecutive mails. If this is set too low, you will run into internal mailbox errors."],
},
{
type = "Slider",
value = TSM.db.global.resendDelay,
label = L["Restart Delay (minutes)"],
min = 0.5,
max = 10,
step = 0.5,
relativeWidth = 0.49,
disabled = not TSM.db.global.resendDelay,
callback = function(self,_,value)
if value < 0.5 then value = 0.5 end
if value > 10 then value = 10 end
self:SetValue(value)
TSM.db.global.resendDelay = value
end,
tooltip = L["When you shift-click a send mail button, after the initial send, it will check for new items to send at this interval."],
},
{
type = "Slider",
value = TSM.db.global.keepMailSpace,
label = L["Keep Free Bag Space"],
min = 0,
max = 20,
step = 1,
relativeWidth = 0.49,
callback = function(self,_,value)
TSM.db.global.keepMailSpace = value
end,
tooltip = L["This slider controls how much free space to keep in your bags when looting from the mailbox. This only applies to bags that any item can go in."],
},
},
},
{
type = "InlineGroup",
layout = "flow",
title = L["Chat Message Options"],
relativeWidth = 1,
children = {
{
type = "CheckBox",
label = L["Enable Inbox Chat Messages"],
settingInfo = {TSM.db.global, "inboxMessages"},
tooltip = L["If checked, information on mails collected by TSM_Mailing will be printed out to chat."],
},
{
type = "CheckBox",
label = L["Display Total Money Received"],
settingInfo = {TSM.db.global, "displayMoneyCollected"},
tooltip = L["If checked, the total amount of gold received will be shown at the end of automatically collecting mail."],
},
{
type = "CheckBox",
label = L["Enable Sending Chat Messages"],
settingInfo = {TSM.db.global, "sendMessages"},
tooltip = L["If checked, information on mails sent by TSM_Mailing will be printed out to chat."],
},
},
},
},
},
}
TSMAPI:BuildPage(container, page)
end
+198
View File
@@ -0,0 +1,198 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local Other = TSM:NewModule("Other", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = {}
function Other:CreateTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:Hide()
frame:SetAllPoints()
local deBox = CreateFrame("Frame", nil, frame)
TSMAPI.Design:SetFrameColor(deBox)
deBox:SetPoint("TOPLEFT", 5, -5)
deBox:SetPoint("TOPRIGHT", -5, -5)
deBox:SetHeight(80)
private:CreateDisenchantBox(deBox)
TSMAPI.GUI:CreateHorizontalLine(frame, -103)
local sendGoldBox = CreateFrame("Frame", nil, frame)
TSMAPI.Design:SetFrameColor(sendGoldBox)
sendGoldBox:SetPoint("TOPLEFT", deBox, "BOTTOMLEFT", 0, -50)
sendGoldBox:SetPoint("TOPRIGHT", deBox, "BOTTOMRIGHT", 0, -50)
sendGoldBox:SetHeight(80)
private:CreateSendGoldBox(sendGoldBox)
return frame
end
function private:CreateDisenchantBox(frame)
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
label:SetPoint("TOPLEFT", 5, -5)
label:SetPoint("TOPRIGHT", -5, -5)
label:SetHeight(20)
label:SetJustifyV("TOP")
label:SetJustifyH("LEFT")
label:SetText(L["Mail Disenchantables:"])
local targetBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
targetBoxLabel:SetPoint("TOPLEFT", 5, -30)
targetBoxLabel:SetHeight(20)
targetBoxLabel:SetJustifyV("CENTER")
targetBoxLabel:SetJustifyH("LEFT")
targetBoxLabel:SetText(L["Target Player:"])
local targetBox = TSMAPI.GUI:CreateInputBox(frame)
targetBox:SetPoint("TOPLEFT", targetBoxLabel, "TOPRIGHT", 5, 0)
targetBox:SetPoint("TOPRIGHT", -5, -30)
targetBox:SetHeight(20)
targetBox:SetText(TSM.db.factionrealm.deMailTarget)
targetBox:SetScript("OnEnterPressed", function(self)
TSM.db.factionrealm.deMailTarget = self:GetText():trim()
self:ClearFocus()
frame.btn:Update()
end)
targetBox.tooltip = L["Enter name of the character disenchantable greens should be sent to."].."\n\n"..TSM.SPELLING_WARNING
local function OnClick()
local target = TSM.db.factionrealm.deMailTarget
if target == "" then return end
local items = {}
local hasItems
for bag, slot, itemString, quantity in TSMAPI:GetBagIterator() do
if private:IsDisenchantable(itemString) and not TSMAPI:GetGroupPath(TSMAPI:GetBaseItemString(itemString, true)) and not TSMAPI:IsSoulbound(bag, slot) then
items[itemString] = (items[itemString] or 0) + quantity
hasItems = true
end
end
if hasItems then
local function callback()
TSM:Printf(L["Sent all disenchantable greens to %s."], target)
frame.btn:Update()
end
frame.btn:Disable()
frame.btn:SetText(L["Sending..."])
TSM.AutoMail:SendItems(items, target, callback)
end
end
local btn = TSMAPI.GUI:CreateButton(frame, 15)
btn:SetPoint("TOPLEFT", 5, -55)
btn:SetPoint("TOPRIGHT", -5, -55)
btn:SetHeight(20)
btn:SetScript("OnClick", OnClick)
btn.tooltip = L["Click this button to send all disenchantable greens in your bags to the specified character."]
btn.Update = function(self)
if TSM.db.factionrealm.deMailTarget ~= "" then
self:Enable()
self:SetText(format(L["Send Disenchantable Greens to %s"], TSM.db.factionrealm.deMailTarget))
else
self:Disable()
self:SetText(L["No Target Player"])
end
end
btn:Update()
frame.btn = btn
end
function private:CreateSendGoldBox(frame)
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
label:SetPoint("TOPLEFT", 5, -5)
label:SetPoint("TOPRIGHT", -5, -5)
label:SetHeight(20)
label:SetJustifyV("TOP")
label:SetJustifyH("LEFT")
label:SetText(L["Send Excess Gold to Banker:"])
local targetBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
targetBoxLabel:SetPoint("TOPLEFT", 5, -30)
targetBoxLabel:SetHeight(20)
targetBoxLabel:SetJustifyV("CENTER")
targetBoxLabel:SetJustifyH("LEFT")
targetBoxLabel:SetText(L["Target Player:"])
local targetBox = TSMAPI.GUI:CreateInputBox(frame)
targetBox:SetPoint("TOPLEFT", targetBoxLabel, "TOPRIGHT", 5, 0)
targetBox:SetWidth(80)
targetBox:SetHeight(20)
targetBox:SetText(TSM.db.char.goldMailTarget)
targetBox:SetScript("OnEnterPressed", function(self)
TSM.db.char.goldMailTarget = self:GetText():trim()
self:ClearFocus()
frame.btn:Update()
end)
targetBox.tooltip = L["Enter the name of the player you want to send excess gold to."].."\n\n"..TSM.SPELLING_WARNING
local goldBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
goldBoxLabel:SetPoint("TOPLEFT", targetBox, "TOPRIGHT", 15, 0)
goldBoxLabel:SetHeight(20)
goldBoxLabel:SetJustifyV("CENTER")
goldBoxLabel:SetJustifyH("LEFT")
goldBoxLabel:SetText(L["Limit (In Gold):"])
local goldBox = TSMAPI.GUI:CreateInputBox(frame)
goldBox:SetPoint("TOPLEFT", goldBoxLabel, "TOPRIGHT", 5, 0)
goldBox:SetPoint("TOPRIGHT", -5, -30)
goldBox:SetHeight(20)
goldBox:SetNumeric(true)
goldBox:SetNumber(TSM.db.char.goldKeepAmount)
goldBox:SetScript("OnTextChanged", function(self)
TSM.db.char.goldKeepAmount = self:GetNumber()
frame.btn:Update()
end)
goldBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end)
goldBox.tooltip = L["This is maximum amount of gold you want to keep on the current player. Any amount over this limit will be send to the specified character."]
local function OnClick()
local extra = (GetMoney() - 30) - (TSM.db.char.goldKeepAmount * COPPER_PER_GOLD)
if extra <= 0 then
TSM:Print(L["Not sending any gold as you have less than the specified limit."])
return
end
SetSendMailMoney(extra)
SendMail(TSM.db.char.goldMailTarget, L["TSM_Mailing Excess Gold"], "")
TSM:Printf(L["Sent %s to %s."], TSMAPI:FormatTextMoney(extra), TSM.db.char.goldMailTarget)
end
local btn = TSMAPI.GUI:CreateButton(frame, 15)
btn:SetPoint("TOPLEFT", 5, -55)
btn:SetPoint("TOPRIGHT", -5, -55)
btn:SetHeight(20)
btn:SetScript("OnClick", OnClick)
btn.tooltip = L["Click this button to send excess gold to the specified character."]
btn.Update = function(self)
if TSM.db.char.goldMailTarget == "" then
self:Disable()
self:SetText(L["Not Target Specified"])
elseif TSMAPI:IsPlayer(TSM.db.char.goldMailTarget) then
self:Disable()
self:SetText(L["Target is Current Player"])
else
self:Enable()
self:SetText(format(L["Send Excess Gold to %s"], TSM.db.char.goldMailTarget))
end
end
btn:Update()
frame.btn = btn
end
function private:IsDisenchantable(itemString)
local _, link, quality, _, _, iType = TSMAPI:GetSafeItemInfo(itemString)
local WEAPON, ARMOR = GetAuctionItemClasses()
if itemString and not TSMAPI.DisenchantingData.notDisenchantable[itemString] and (iType == ARMOR or iType == WEAPON) and quality == ITEM_QUALITY_UNCOMMON then
return true
end
end
@@ -0,0 +1,221 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Mailing --
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...)
local QuickSend = TSM:NewModule("QuickSend", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
local private = {itemLink=nil, quantity=0, target="", cod=0}
function QuickSend:CreateTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:Hide()
frame:SetPoint("TOPLEFT", 5, -5)
frame:SetPoint("BOTTOMRIGHT", -5, 5)
frame:SetAllPoints()
TSMAPI.Design:SetFrameColor(frame)
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
label:SetPoint("TOPLEFT", 5, -5)
label:SetPoint("TOPRIGHT", -5, -5)
label:SetHeight(50)
label:SetJustifyV("TOP")
label:SetJustifyH("LEFT")
label:SetText(L["This tab allows you to quickly send any quantity of an item to another character. You can also specify a COD to set on the mail (per item)."])
TSMAPI.GUI:CreateHorizontalLine(frame, -55)
local itemBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
itemBoxLabel:SetPoint("TOPLEFT", 5, -65)
itemBoxLabel:SetHeight(20)
itemBoxLabel:SetJustifyV("CENTER")
itemBoxLabel:SetJustifyH("LEFT")
itemBoxLabel:SetText(L["Item (Drag Into Box):"])
local function OnItemDrag(self)
local cType, _, link = GetCursorInfo()
if cType == "item" then
self:SetText(link)
private.itemLink = link
ClearCursor()
private.btn:Update()
end
end
local itemBox = TSMAPI.GUI:CreateInputBox(frame)
itemBox:SetPoint("TOPLEFT", itemBoxLabel, "TOPRIGHT", 5, 0)
itemBox:SetPoint("TOPRIGHT", -95, -65)
itemBox:SetHeight(20)
itemBox:SetText(private.itemLink or "")
itemBox:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
itemBox:SetScript("OnReceiveDrag", OnItemDrag)
itemBox:SetScript("OnMouseDown", OnItemDrag)
itemBox.tooltip = L["Drag (or place) the item that you want to send into this editbox."]
local itemClearBtn = TSMAPI.GUI:CreateButton(frame, 15)
itemClearBtn:SetPoint("TOPLEFT", itemBox, "TOPRIGHT", 5, 0)
itemClearBtn:SetPoint("TOPRIGHT", -5, -65)
itemClearBtn:SetHeight(20)
itemClearBtn:SetText(L["Clear"])
itemClearBtn:SetScript("OnClick", function()
private.itemLink = nil
itemBox:SetText("")
private.btn:Update()
end)
itemClearBtn.tooltip = L["Clears the item box."]
local targetBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
targetBoxLabel:SetPoint("TOPLEFT", 5, -95)
targetBoxLabel:SetHeight(20)
targetBoxLabel:SetJustifyV("CENTER")
targetBoxLabel:SetJustifyH("LEFT")
targetBoxLabel:SetText(L["Target:"])
local targetBox = TSMAPI.GUI:CreateInputBox(frame)
targetBox:SetPoint("TOPLEFT", targetBoxLabel, "TOPRIGHT", 5, 0)
targetBox:SetWidth(100)
targetBox:SetHeight(20)
targetBox:SetText(private.target)
targetBox:SetScript("OnEnterPressed", function(self)
self:ClearFocus()
end)
targetBox:SetScript("OnEditFocusLost", function(self)
self:HighlightText(0, 0)
private.target = self:GetText():trim()
private.btn:Update()
end)
targetBox:SetScript("OnTabPressed", function(self)
self:ClearFocus()
frame.qtyBox:SetFocus()
frame.qtyBox:HighlightText()
end)
TSMAPI.GUI:SetAutoComplete(targetBox, AUTOCOMPLETE_LIST.MAIL)
targetBox.tooltip = L["Enter the name of the player you want to send this item to."].."\n\n"..TSM.SPELLING_WARNING
local qtyBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
qtyBoxLabel:SetPoint("TOPLEFT", targetBox, "TOPRIGHT", 20, 0)
qtyBoxLabel:SetHeight(20)
qtyBoxLabel:SetJustifyV("CENTER")
qtyBoxLabel:SetJustifyH("LEFT")
qtyBoxLabel:SetText(L["Max Quantity:"])
local qtyBox = TSMAPI.GUI:CreateInputBox(frame)
qtyBox:SetPoint("TOPLEFT", qtyBoxLabel, "TOPRIGHT", 5, 0)
qtyBox:SetPoint("TOPRIGHT", -5, -95)
qtyBox:SetHeight(20)
qtyBox:SetNumeric(true)
qtyBox:SetNumber(private.quantity)
qtyBox:SetScript("OnEnterPressed", function(self)
self:ClearFocus()
end)
qtyBox:SetScript("OnEditFocusLost", function(self)
self:HighlightText(0, 0)
private.quantity = self:GetNumber()
private.btn:Update()
end)
qtyBox:SetScript("OnTabPressed", function(self)
self:ClearFocus()
frame.codBox:SetFocus()
frame.codBox:HighlightText()
end)
qtyBox.tooltip = L["This is the maximum number of the specified item to send when you click the button below. Setting this to 0 will send ALL items."]
frame.qtyBox = qtyBox
local codBoxLabel = TSMAPI.GUI:CreateLabel(frame, "small")
codBoxLabel:SetPoint("TOPLEFT", 5, -125)
codBoxLabel:SetHeight(20)
codBoxLabel:SetJustifyV("CENTER")
codBoxLabel:SetJustifyH("LEFT")
codBoxLabel:SetText(L["COD Amount (per Item):"])
local codBox = TSMAPI.GUI:CreateInputBox(frame)
codBox:SetPoint("TOPLEFT", codBoxLabel, "TOPRIGHT", 5, 0)
codBox:SetPoint("TOPRIGHT", -5, -125)
codBox:SetHeight(20)
codBox:SetText(TSMAPI:FormatTextMoney(private.cod))
codBox:SetScript("OnEnterPressed", function(self)
local copper = TSMAPI:UnformatTextMoney(self:GetText():trim())
if copper then
private.cod = copper
self:SetText(TSMAPI:FormatTextMoney(copper))
self:ClearFocus()
private.btn:Update()
else
self:SetFocus()
end
end)
codBox.tooltip = L["Enter the desired COD amount (per item) to send this item with. Setting this to '0c' will result in no COD being set."]
frame.codBox = codBox
local function OnClick()
local itemString = TSMAPI:GetItemString(private.itemLink)
local numHave = 0
for _, _, iString, quantity in TSMAPI:GetBagIterator() do
if iString == itemString then
numHave = numHave + quantity
end
end
local quantity
if private.quantity == 0 then
quantity = numHave
else
quantity = min(private.quantity, numHave)
end
TSM.AutoMail:SendItems({[itemString]=quantity}, private.target, private.SendCallback, private.cod > 0 and private.cod)
private.btn:SetText(L["Sending..."])
private.btn:Disable()
end
local btn = TSMAPI.GUI:CreateButton(frame, 15)
btn:SetPoint("TOPLEFT", 5, -155)
btn:SetPoint("TOPRIGHT", -5, -155)
btn:SetHeight(40)
btn:GetFontString():SetWidth(btn:GetWidth())
btn:GetFontString():SetHeight(btn:GetHeight())
btn:SetScript("OnClick", OnClick)
btn.tooltip = L["Click this button to send off the item to the specified character."]
btn.Update = function(self)
if not private.itemLink then
self:Disable()
self:SetText(L["No Item Specified"])
elseif private.target == "" then
self:Disable()
self:SetText(L["No Target Specified"])
else
self:Enable()
if private.cod > 0 then
if private.quantity == 0 then
self:SetText(format(L["Send all %s to %s - %s per Item COD"], private.itemLink, private.target, TSMAPI:FormatTextMoney(private.cod)))
else
self:SetText(format(L["Send %sx%d to %s - %s per Item COD"], private.itemLink, private.quantity, private.target, TSMAPI:FormatTextMoney(private.cod)))
end
else
if private.quantity == 0 then
self:SetText(format(L["Send all %s to %s - No COD"], private.itemLink, private.target))
else
self:SetText(format(L["Send %sx%d to %s - No COD"], private.itemLink, private.quantity, private.target))
end
end
end
end
btn:Update()
private.btn = btn
return frame
end
function private:SendCallback()
private.btn:Update()
end