Mercurial > wow > inventory
changeset 89:a12d22ef3f39
AceSerializer has been enabled again as it?s used when exporting/importing groups. All other unused libraries are now really removed.
Adjusted debug function to format only when a debug channel is available.
Fixed moving from guild banks, checking if items are locked is different then with banks.
Now unregistering the item locking event so it doesn?t continue to try to move every time an item is switched after the automated cycle has finished. (geeezus, this description is a total overkill)
Fixed item queueing.
Queue all when there?s a group without any items inside no longer crashes.
Removing cached container data after closing a container.
author | Zerotorescue |
---|---|
date | Fri, 07 Jan 2011 22:19:03 +0100 |
parents | f1c035694545 |
children | 7c12a96fb6f7 |
files | .pkgmeta Core.lua Libraries.xml Modules/Config.lua Modules/Mover.lua Modules/Queue.lua Modules/Scanner.lua Modules/Summary v2.lua Modules/Summary.lua |
diffstat | 9 files changed, 686 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/.pkgmeta Fri Jan 07 10:34:38 2011 +0100 +++ b/.pkgmeta Fri Jan 07 22:19:03 2011 +0100 @@ -8,24 +8,24 @@ Libs/AceDB-3.0: url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDB-3.0 tag: latest - Libs/AceDBOptions-3.0: - url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDBOptions-3.0 - tag: latest +# Libs/AceDBOptions-3.0: +# url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDBOptions-3.0 +# tag: latest Libs/AceEvent-3.0: url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceEvent-3.0 tag: latest Libs/AceGUI-3.0: url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceGUI-3.0 tag: latest - Libs/AceGUI-3.0-SharedMediaWidgets: - url: svn://svn.wowace.com/wow/ace-gui-3-0-shared-media-widgets/mainline/trunk/AceGUI-3.0-SharedMediaWidgets - tag: latest - Libs/AceHook-3.0: - url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceHook-3.0 - tag: latest - Libs/AceLocale-3.0: - url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceLocale-3.0 - tag: latest +# Libs/AceGUI-3.0-SharedMediaWidgets: +# url: svn://svn.wowace.com/wow/ace-gui-3-0-shared-media-widgets/mainline/trunk/AceGUI-3.0-SharedMediaWidgets +# tag: latest +# Libs/AceHook-3.0: +# url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceHook-3.0 +# tag: latest +# Libs/AceLocale-3.0: +# url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceLocale-3.0 +# tag: latest Libs/AceSerializer-3.0: url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceSerializer-3.0 tag: latest @@ -35,9 +35,9 @@ Libs/CallbackHandler-1.0: url: svn://svn.wowace.com/wow/callbackhandler/mainline/trunk/CallbackHandler-1.0 tag: latest - Libs/LibSharedMedia-3.0: - url: svn://svn.wowace.com/wow/libsharedmedia-3-0/mainline/trunk/LibSharedMedia-3.0 - tag: latest +# Libs/LibSharedMedia-3.0: +# url: svn://svn.wowace.com/wow/libsharedmedia-3-0/mainline/trunk/LibSharedMedia-3.0 +# tag: latest Libs/LibStub: url: svn://svn.wowace.com/wow/libstub/mainline/trunk tag: latest
--- a/Core.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Core.lua Fri Jan 07 22:19:03 2011 +0100 @@ -19,8 +19,6 @@ addon.supportedAddons.crafting = {}; function addon:OnInitialize() - self:Debug("OnInitialize"); - -- SAVED VARIABLES local defaults = { @@ -449,7 +447,7 @@ -- Debug -function addon:Debug(t) +function addon:Debug(t, ...) if not self.debugChannel and self.debugChannel ~= false then -- We want to check just once, so if you add a debug channel later just do a /reload (registering an event for this is wasted resources) self.debugChannel = false; @@ -464,6 +462,6 @@ end if self.debugChannel then - self.debugChannel:AddMessage(t); + self.debugChannel:AddMessage(t:format(...)); end end
--- a/Libraries.xml Fri Jan 07 10:34:38 2011 +0100 +++ b/Libraries.xml Fri Jan 07 22:19:03 2011 +0100 @@ -6,16 +6,11 @@ <Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/> <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/> <Include file="Libs\AceDB-3.0\AceDB-3.0.xml"/> - <!--<Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>--> <Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/> - <!--<Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml"/>--> - <!--<Include file="Libs\AceHook-3.0\AceHook-3.0.xml"/>--> <Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/> <Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/> - <!--<Include file="Libs\AceSerializer-3.0\AceSerializer-3.0.xml"/>--> + <Include file="Libs\AceSerializer-3.0\AceSerializer-3.0.xml"/> <Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml"/> <!-- end Ace 3 --> - <!--<Include file="Libs\LibSharedMedia-3.0\lib.xml"/>--> - <!--<Include file="Libs\AceGUI-3.0-SharedMediaWidgets\widget.xml"/>--> <Script file="Libs\ChatHyperlinks\ChatHyperlinks.lua"/> </Ui>
--- a/Modules/Config.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Modules/Config.lua Fri Jan 07 22:19:03 2011 +0100 @@ -214,7 +214,7 @@ end end else - addon:Debug("|cffff0000ERROR|r: Couldn't find proper item id for " .. itemLink); + addon:Debug("|cffff0000ERROR|r: Couldn't find proper item id for %s", itemLink); end end end
--- a/Modules/Mover.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Modules/Mover.lua Fri Jan 07 22:19:03 2011 +0100 @@ -44,7 +44,7 @@ local outgoingMoves = {}; - addon:Debug(#queuedMoves .. " moves were queued."); + addon:Debug("%d moves were queued.", #queuedMoves); for _, singleMove in pairs(queuedMoves) do local sourceItem = sourceContents[singleMove.id]; @@ -77,7 +77,7 @@ end end - addon:Debug(#outgoingMoves .. " outgoing moves are possible."); + addon:Debug("%d outgoing moves are possible.", #outgoingMoves); -- No longer needed table.wipe(queuedMoves); @@ -109,7 +109,7 @@ end end - addon:Debug(#emptySlots .. " empty slots are available."); + addon:Debug("%d empty slots are available.", #emptySlots); -- Remember where we're moving from movesSource = location; @@ -230,7 +230,7 @@ numOutgoingMoves = (numOutgoingMoves - 1); end - addon:Debug(#outgoingMoves .. " moves remaining."); + addon:Debug("%d moves remaining.", #outgoingMoves); backup = (backup + 1); if backup > 1000 then @@ -245,7 +245,7 @@ -- Reverse table, we need to go through it from last to first because we'll be removing elements, but we don't want the actions to be executed in a different order combinedMoves = table.reverse(combinedMoves); - addon:Debug(#combinedMoves .. " moves should be possible."); + addon:Debug("%d moves should be possible.", #combinedMoves); -- No longer needed table.wipe(emptySlots); @@ -283,21 +283,24 @@ if movesSource == addon.Locations.Guild then _GetContainerItemId = function(tabId, slotId) return addon:GetItemID(GetGuildBankItemLink(tabId, slotId)); end; end + local _GetContainerItemInfo = GetContainerItemInfo; + if movesSource == addon.Locations.Guild then + _GetContainerItemInfo = GetGuildBankItemInfo; + end local combinedMovesOriginalLength = #combinedMoves; local numCurrentMove = combinedMovesOriginalLength; while numCurrentMove ~= 0 do local move = combinedMoves[numCurrentMove]; - local isSourceLocked = ((sourceLocationsLocked[move.sourceContainer] and sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) or select(3, GetContainerItemInfo(move.sourceContainer, move.sourceSlot))); - local isTargetLocked = ((targetLocationsLocked[move.targetContainer] or targetLocationsLocked[move.targetContainer][move.targetSlot]) or select(3, GetContainerItemInfo(move.targetContainer, move.targetSlot))); + local isSourceLocked = ((sourceLocationsLocked[move.sourceContainer] and sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) or select(3, _GetContainerItemInfo(move.sourceContainer, move.sourceSlot))); + local isTargetLocked = ((targetLocationsLocked[move.targetContainer] and targetLocationsLocked[move.targetContainer][move.targetSlot]) or select(3, GetContainerItemInfo(move.targetContainer, move.targetSlot))); - -- sourceContainer, sourceSlot, targetContainer, targetSlot, itemId, num - if move and isSourceLocked and isTargetLocked then + if move and not isSourceLocked and not isTargetLocked then print(("Moving %dx%s."):format(move.num, IdToItemLink(move.itemId))); - addon:Debug(("Moving %dx%s from (%d,%d) to (%d,%d)"):format(move.num, IdToItemLink(move.itemId), move.sourceContainer, move.sourceSlot, move.targetContainer, move.targetSlot)); + addon:Debug("Moving %dx%s from (%d,%d) to (%d,%d)", move.num, IdToItemLink(move.itemId), move.sourceContainer, move.sourceSlot, move.targetContainer, move.targetSlot); if _GetContainerItemId(move.sourceContainer, move.sourceSlot) ~= move.itemId then self:Abort("source changed", "Source (" .. move.sourceContainer .. "," .. move.sourceSlot .. ") is not " .. IdToItemLink(move.itemId)); @@ -346,7 +349,7 @@ numCurrentMove = (numCurrentMove - 1); end - addon:Debug((combinedMovesOriginalLength - #combinedMoves) .. " moves processed. " .. #combinedMoves .. " moves remaining."); + addon:Debug("%d moves processed. %d moves remaining.", (combinedMovesOriginalLength - #combinedMoves), #combinedMoves); if #combinedMoves == 0 then print("Finished."); @@ -360,7 +363,7 @@ local tmrProcessNext; function mod:ITEM_LOCK_CHANGED() self:CancelTimer(tmrProcessNext, true); -- silent - tmrProcessNext = self:ScheduleTimer("ProcessMove", 0.5); + tmrProcessNext = self:ScheduleTimer("ProcessMove", .5); end function IdToItemLink(itemId) @@ -377,7 +380,7 @@ function mod:Abort(simple, debugMsg) if debugMsg then - addon:Debug("Aborting:" .. debugMsg); + addon:Debug("Aborting:%s", debugMsg); end if simple then print("|cffff0000Aborting: " .. simple .. ".|r"); @@ -386,7 +389,7 @@ movesSource = nil; -- Stop timer - self:UnregisterEvent("BAG_UPDATE"); + self:UnregisterEvent("ITEM_LOCK_CHANGED"); self:CancelTimer(tmrProcessNext, true); -- silent self:UnregisterEvent("UI_ERROR_MESSAGE");
--- a/Modules/Queue.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Modules/Queue.lua Fri Jan 07 22:19:03 2011 +0100 @@ -69,7 +69,7 @@ local itemLink = GetTradeSkillItemLink(i); if itemLink then - local itemId = addon:GetItemId(itemLink); + local itemId = addon:GetItemID(itemLink); if not itemId then -- If this isn't an item, it can only be an enchant instead itemId = tonumber(itemLink:match("|Henchant:([-0-9]+)|h")); @@ -77,7 +77,7 @@ itemId = addon.scrollIds[itemId]; -- change enchantIds into scrollIds end - if addon.db.profile.groups[groupName].items[itemId] then + if addon.db.profile.groups[groupName].items and addon.db.profile.groups[groupName].items[itemId] then -- This item is in this group, queue it! if temp then
--- a/Modules/Scanner.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Modules/Scanner.lua Fri Jan 07 22:19:03 2011 +0100 @@ -15,10 +15,10 @@ end function mod:CacheLocation(location, remember) + -- Reset cache just in case it was filled + self:ClearCache(); + if location == addon.Locations.Bag or location == addon.Locations.Bank then - -- Reset cache just in case it was filled - self:ClearCache(); - local start, stop; if location == addon.Locations.Bag then start = 0; @@ -60,9 +60,6 @@ end end elseif location == addon.Locations.Guild then - -- Reset cache before we scan - self:ClearCache(); - for tabId = 1, GetNumGuildBankTabs() do local isViewable = select(3, GetGuildBankTabInfo(tabId)); @@ -190,6 +187,8 @@ function mod:BANKFRAME_CLOSED() addon:Debug("Scanner:BANKFRAME_CLOSED"); + self:ClearCache(); + mod:UnregisterEvent("BANKFRAME_CLOSED"); StaticPopup_Hide("InventoriumRefill"); @@ -208,7 +207,7 @@ function mod:DoScanGuild() if not scanned then - addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED"); + addon:Debug("Scanner:DoScanGuild"); scanned = true; @@ -220,6 +219,7 @@ addon:Debug("Scanner:GUILDBANKFRAME_CLOSED"); scanned = nil; + self:ClearCache(); self:UnregisterEvent("GUILDBANKFRAME_CLOSED"); self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/Summary v2.lua Fri Jan 07 22:19:03 2011 +0100 @@ -0,0 +1,639 @@ +local addon = select(2, ...); -- Get a reference to the main addon object +local mod = addon:NewModule("Summary", "AceEvent-3.0", "AceTimer-3.0"); -- register a new module, Summary: resposible for building the summary window + +local unknownItemName = "Unknown (#%d)"; + +local CACHE_ITEMS_TOTAL, CACHE_ITEMS_CURRENT, itemsCache = 0, 0, {}; +local AceGUI, cacheStart; + +local _G = _G; -- prevent looking up of the global table +local printf, sgsub, supper, tinsert, pairs, ceil, GetItemInfo = _G.string.format, _G.string.gsub, _G.string.upper, _G.table.insert, _G.pairs, _G.ceil, _G.GetItemInfo; -- prevent looking up of the most used globals all the time + +function mod:OnEnable() + -- Register the summary specific widget + addon:GetModule("Widgets"):InlineGroupWithButton(); + + AceGUI = LibStub("AceGUI-3.0"); + + -- Register our own slash commands + -- /im summary + addon:RegisterSlash(function() + mod:BuildMain(); + mod:Build(); + end, { "s", "sum", "summary" }, "|Hfunction:InventoriumCommandHandler:summary|h|cff00fff7/im summary|r|h (or /im s) - Show the summary window containing an overview of all items within the groups tracked at this current character."); + + -- /im reset + addon:RegisterSlash(function() + if mod.frame then + mod.frame:SetWidth(700); + mod.frame:SetHeight(600); + + print("Resetting width and height of the summary frame."); + end + end, { "r", "reset" }, "|Hfunction:InventoriumCommandHandler:reset|h|cff00fff7/im reset|r|h (or /im r) - Reset the size of the summary frame."); +end + +local function ShowTooltip(self) + -- If this function is called from a widget, self is the widget and self.frame the actual frame + local this = self.frame or self; + + GameTooltip:SetOwner(this, "ANCHOR_NONE"); + GameTooltip:SetPoint("BOTTOM", this, "TOP"); + GameTooltip:SetText(this.tooltipTitle, 1, .82, 0, 1); + + if type(this.tooltip) == "string" then + GameTooltip:AddLine(this.tooltip, 1, 1, 1, 1); + end + + GameTooltip:Show(); +end + +local function HideTooltip() + GameTooltip:Hide(); +end + +function mod:BuildMain() + LibStub("AceConfigDialog-3.0"):Close("InventoriumOptions"); + + self:CloseFrame(); + + -- Main Window + mod.frame = AceGUI:Create("Frame"); + _G["InventoriumSummary"] = mod.frame; -- name the global frame so it can be put in the UISpecialFrames + mod.frame:SetTitle("Inventory Summary"); + mod.frame:SetLayout("Fill"); + mod.frame:SetCallback("OnClose", function(widget) + mod:CancelTimer(self.tmrUpdater, true); + mod:CloseFrame(); + end); + mod.frame:SetWidth(addon.db.profile.defaults.summary.width); + mod.frame:SetHeight(addon.db.profile.defaults.summary.height); + mod.frame.OnWidthSet = function(_, width) + addon.db.profile.defaults.summary.width = width; + end; + mod.frame.OnHeightSet = function(_, height) + addon.db.profile.defaults.summary.height = height; + end; + + -- Close on escape + tinsert(UISpecialFrames, "InventoriumSummary"); + + -- ScrollFrame child + mod.scrollFrame = AceGUI:Create("ScrollFrame"); + mod.scrollFrame:SetLayout("Flow"); + + mod.frame:AddChild(mod.scrollFrame); + + -- Reset items cache + table.wipe(itemsCache); +end + +function mod:CloseFrame() + if mod.frame then + mod.frame:Release(); + mod.frame = nil; + + -- Stop caching + + -- Stop timer + self:CancelTimer(self.tmrUpdater, true); + end +end + +local sortMethod = "item"; +local sortDirectory = "ASC"; +local function ReSort(subject) + if sortMethod == subject then + sortDirectory = (sortDirectory == "ASC" and "DESC") or "ASC"; + else + sortDirectory = "ASC"; + end + sortMethod = subject; + + mod:Build(); +end + +-- From http://www.wowwiki.com/API_sort +local function pairsByKeys (t, f) + local a = {} + for n in pairs(t) do tinsert(a, n) end + table.sort(a, f) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + +local summaryData = {}; +local cacheMe = {}; + +--[[ + GroupName + minLocalStock + minGlobalStock + showWhenBelow + priceThreshold + hideWhenBelowPriceThreshold + alwaysGetAuctionValue + Items + ItemData + ItemData + ItemData + GroupName + etc. +]] +--[[ +ItemData + -- Standard info everything needs + self.id = itemId; + self.name = itemName; + self.link = itemLink; + self.rarity = itemRarity; + self.icon = itemTexture; + + -- Detailed stuff + self.value = -3; + self.globalCount = -3; + self.localCount = -3; + self.set = {}; +]] + +function mod:MakeList() + local playerName = UnitName("player"); + + -- Item data is being reset + table.wipe(cacheMe); + table.wipe(summaryData); + + -- Go through all our stored groups + for groupName, values in addon.db.profile.groups do + local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters"); + + -- Does this group have any items and do we want to track it at this char? + if values.items and trackAt[playerName] then + -- Get group settings + local groupTemplate = { + minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock"), + minGlobalStock = addon:GetOptionByKey(groupName, "minGlobalStock"), + showWhenBelow = addon:GetOptionByKey(groupName, "summaryThresholdShow"), + priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold"), + hideWhenBelowPriceThreshold = addon:GetOptionByKey(groupName, "summaryHidePriceThreshold"), + alwaysGetAuctionValue = addon:GetOptionByKey(groupName, "alwaysGetAuctionValue"), + items = {}, + }; + + -- Generate itemslist + for itemId, _ in pairs(values.items) do + -- Go through all items for this group + + local itemData = addon.ItemData:New(itemId); + + -- if no price threshold is set for this item and you don't want to always get the auction value, then don't look it up either + if groupTemplate.priceThreshold == 0 and not groupTemplate.alwaysGetAuctionValue then + itemData.value = -4; + end + + groupTemplate.items[itemId] = itemData; + table.insert(cacheMe, itemData); + end + + summaryData[groupName] = groupTemplate; + end + end +end + +local function DisplayItemCount(value, minimumStock) + if value == -1 then + return "|cffffff00Unknown|r"; -- addon doesn't support local + elseif value == -3 then + return "|cffffff00Unknown|r"; -- not yet cached + elseif value == -5 then + return "|cffff9933Error|r"; -- item not found + else + return printf("%s / %d", self:ColorCode(value, minimumStock), minimumStock); + end +end +local function GetLocalItemCount(groupName, itemId) + local count = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].localCount) or -5); + local minStock = (summaryData[groupName] and summaryData[groupName].minLocalStock); + + return DisplayItemCount(count, minStock); +end +local function GetGlobalItemCount(groupName, itemId) + local count = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].globalCount) or -5); + local minStock = (summaryData[groupName] and summaryData[groupName].minGlobalStock); + + return DisplayItemCount(count, minStock); +end +local function GetAuctionValue(groupName, itemId) + local value = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].value) or -5); + local threshold = (summaryData[groupName] and summaryData[groupName].priceThreshold); + + if value == -1 then + return "|cff0000ffNone up|r"; -- no auctions up + elseif value == -2 then + return "|cff0000ffNo AH mod|r"; -- no (working) auction house addon available + elseif value == -3 then + return "|cffffff00Unknown|r"; -- not yet cached + elseif value == -4 then + return "|cff00ff00-|r"; -- don't want to know + elseif value == -5 then + return "|cffff9933Error|r"; -- item not found + elseif threshold and value < threshold then + return printf("|cffaaaaaa%s|r", sgsub(addon:ReadableMoney(value or 0, true), "|([a-fA-F0-9]+)([gsc]+)|r", "%2")); + else + return addon:ReadableMoney(value or 0, true); + end +end + +function mod:Build() + -- We are going to add hunderds of widgets to this container, but don't want it to also cause hunderds of reflows, thus pause reflowing and just do it once when everything is prepared + -- This appears to be required for each container we wish to pause, so also do this for the contents + mod.scrollFrame:PauseLayout(); + + mod.scrollFrame:ReleaseChildren(); + + -- Refresh button + local btnRefresh = AceGUI:Create("Button"); + btnRefresh:SetText("Refresh"); + btnRefresh:SetRelativeWidth(.2); + btnRefresh:SetCallback("OnClick", function() + -- Reset items cache + table.wipe(itemsCache); + + -- Rebuild itemlist and start caching + mod:Build(); + end); + btnRefresh:SetCallback("OnEnter", ShowTooltip); + btnRefresh:SetCallback("OnLeave", HideTooltip); + btnRefresh.frame.tooltipTitle = "Refresh Cache"; + btnRefresh.frame.tooltip = "Refresh the list and recache the item counts and auction values."; + + mod.scrollFrame:AddChild(btnRefresh); + + local lblSpacer = AceGUI:Create("Label"); + lblSpacer:SetRelativeWidth(.03); + + mod.scrollFrame:AddChild(lblSpacer); + + -- Speed slider + local sdrSpeed = AceGUI:Create("Slider"); + sdrSpeed:SetLabel("Processing speed"); + sdrSpeed:SetSliderValues(0.01, 5, 0.01); -- min, max, interval + sdrSpeed:SetIsPercent(true); + sdrSpeed:SetRelativeWidth(.3); + sdrSpeed:SetCallback("OnMouseUp", function(self, event, value) + addon.db.profile.defaults.summary.speed = ceil( ( ( value * 100 ) / 5) - .5 ); + + CACHE_ITEMS_PER_UPDATE = addon.db.profile.defaults.summary.speed; -- max = 20, min = 1 + end); + sdrSpeed:SetValue( addon.db.profile.defaults.summary.speed * 5 / 100 ); + sdrSpeed:SetCallback("OnEnter", ShowTooltip); + sdrSpeed:SetCallback("OnLeave", HideTooltip); + sdrSpeed.frame.tooltipTitle = "Caching Processing Speed"; + sdrSpeed.frame.tooltip = "Change the speed at which item counts and auction values are being cached. Higher is faster but may drastically reduce your FPS while caching.\n\nAnything above 100% will probably become uncomfortable."; + + mod.scrollFrame:AddChild(sdrSpeed); + + local lblSpacer = AceGUI:Create("Label"); + lblSpacer:SetRelativeWidth(.23); + + mod.scrollFrame:AddChild(lblSpacer); + + local lblSpacer = AceGUI:Create("Label"); + lblSpacer:SetRelativeWidth(.03); + + mod.scrollFrame:AddChild(lblSpacer); + + -- Queue all button + local btnQueueAll = AceGUI:Create("Button"); + btnQueueAll:SetText("Queue All"); + btnQueueAll:SetRelativeWidth(.2); + btnQueueAll:SetCallback("OnClick", function() + self:SendMessage("IM_QUEUE_ALL"); + end); + btnQueueAll:SetCallback("OnEnter", ShowTooltip); + btnQueueAll:SetCallback("OnLeave", HideTooltip); + btnQueueAll.frame.tooltipTitle = "Queue all"; + btnQueueAll.frame.tooltip = "Queue everything that requires restocking within every single visible group."; + + mod.scrollFrame:AddChild(btnQueueAll); + + for groupName, items in pairs(summaryData) do + -- Make group container + local iGroup = AceGUI:Create("InlineGroupWithButton"); + iGroup:PauseLayout(); + iGroup:SetTitle(groupName); + iGroup:SetFullWidth(true); + iGroup:SetLayout("Flow"); + iGroup:MakeButton({ + name = "Queue", + desc = "Queue all items in this group.", + exec = function() + print("Queueing all items within " .. groupName .. " craftable by the currently open profession."); + self:SendMessage("IM_QUEUE_GROUP", groupName); + end, + }); + + -- Headers + + -- Itemlink + local lblItem = AceGUI:Create("InteractiveLabel"); + lblItem:SetText("|cfffed000Item|r"); + lblItem:SetFontObject(GameFontHighlight); + lblItem:SetRelativeWidth(.7); + lblItem:SetCallback("OnClick", function() ReSort("item"); end); + lblItem:SetCallback("OnEnter", ShowTooltip); + lblItem:SetCallback("OnLeave", HideTooltip); + lblItem.frame.tooltipTitle = "Item"; + lblItem.frame.tooltip = "Sort on the item quality, then name."; + + iGroup:AddChild(lblItem); + + -- Local quantity + local lblLocal = AceGUI:Create("InteractiveLabel"); + lblLocal:SetText("|cfffed000Loc.|r"); + lblLocal:SetFontObject(GameFontHighlight); + lblLocal:SetRelativeWidth(.099); + lblLocal:SetCallback("OnClick", function() ReSort("local"); end); + lblLocal:SetCallback("OnEnter", ShowTooltip); + lblLocal:SetCallback("OnLeave", HideTooltip); + lblLocal.frame.tooltipTitle = "Local stock"; + lblLocal.frame.tooltip = "Sort on the amount of items currently in local stock."; + + iGroup:AddChild(lblLocal); + + -- Current quantity + local lblQuantity = AceGUI:Create("InteractiveLabel"); + lblQuantity:SetText("|cfffed000Cur.|r"); + lblQuantity:SetFontObject(GameFontHighlight); + lblQuantity:SetRelativeWidth(.099); + lblQuantity:SetCallback("OnClick", function() ReSort("current"); end); + lblQuantity:SetCallback("OnEnter", ShowTooltip); + lblQuantity:SetCallback("OnLeave", HideTooltip); + lblQuantity.frame.tooltipTitle = "Current stock"; + lblQuantity.frame.tooltip = "Sort on the amount of items currently in stock."; + + iGroup:AddChild(lblQuantity); + + -- Lowest value + local lblValue = AceGUI:Create("InteractiveLabel"); + lblValue:SetText("|cfffed000Value|r"); + lblValue:SetFontObject(GameFontHighlight); + lblValue:SetRelativeWidth(.099); + lblValue:SetCallback("OnClick", function() ReSort("value"); end); + lblValue:SetCallback("OnEnter", ShowTooltip); + lblValue:SetCallback("OnLeave", HideTooltip); + lblValue.frame.tooltipTitle = "Value"; + lblValue.frame.tooltip = "Sort on the item auction value."; + + iGroup:AddChild(lblValue); + + + -- Sort items + table.sort(itemsCache[groupName], function(a, b) + local aRarity = a.rarity or 1; + local bRarity = b.rarity or 1; + + if sortMethod == "item" and aRarity == bRarity then + -- Do a name-compare for items of the same rarity + -- Otherwise epics first, then junk + + local aName = a.name or printf(unknownItemName, a.id); + local bName = b.name or printf(unknownItemName, b.id); + + if sortDirectory == "ASC" then + return supper(aName) < supper(bName); + else + return supper(aName) > supper(bName); + end + elseif sortMethod == "item" then + if sortDirectory == "ASC" then + return aRarity > bRarity; -- the comparers were reversed because we want epics first + else + return aRarity < bRarity; -- the comparers were reversed because we want epics first + end + elseif sortMethod == "current" then + if sortDirectory == "ASC" then + return a.globalCount < b.globalCount; + else + return a.globalCount > b.globalCount; + end + elseif sortMethod == "local" then + if sortDirectory == "ASC" then + return a.localCount < b.localCount; + else + return a.localCount > b.localCount; + end + elseif sortMethod == "value" then + if sortDirectory == "ASC" then + return a.value < b.value; + else + return a.value > b.value; + end + end + end); + + -- Show itemslist + for i, item in pairs(itemsCache[groupName]) do + -- Go through all items for this group + + if (( item.globalCount / minGlobalStock ) < showWhenBelow or ( item.localCount / minLocalStock ) < showWhenBelow) and (not hideWhenBelowPriceThreshold or priceThreshold == 0 or item.value < 0 or item.value >= priceThreshold) then + -- if the option "hide when below threshold" is disabled or no price threshold is set or the value is above the price threshold or the value could not be determined, proceed + + local btnItemLink = AceGUI:Create("ItemLinkButton"); + btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName) + local itemName, itemLink = GetItemInfo(itemId); + + if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then + ChatEdit_InsertLink(itemLink); + elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then + -- Start search at page 0 + AuctionFrameBrowse.page = 0; + + -- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated) + BrowseName:SetText(itemName) + + QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0); + end + end); + btnItemLink:SetRelativeWidth(.7); + btnItemLink:SetItem(item); + + iGroup:AddChild(btnItemLink); + + -- Local quantity + local lblLocal = AceGUI:Create("Label"); + lblLocal:SetText(self:DisplayItemCount(item.localCount, minLocalStock)); + lblLocal:SetRelativeWidth(.099); + + iGroup:AddChild(lblLocal); + + -- Current quantity + local lblQuantity = AceGUI:Create("Label"); + lblQuantity:SetText(self:DisplayItemCount(item.globalCount, minGlobalStock)); + lblQuantity:SetRelativeWidth(.099); + + iGroup:AddChild(lblQuantity); + + -- Value + local lblValue = AceGUI:Create("Label"); + lblValue:SetText(self:DisplayMoney(item.value, priceThreshold)); + lblValue:SetRelativeWidth(.099); + + iGroup:AddChild(lblValue); + + -- Remember references to the value and current fields so we can fill them later + item.set.value = lblValue; + item.set.globalCount = lblQuantity; + item.set.localCount = lblLocal; + end + end + + groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 ); + + iGroup:ResumeLayout(); + mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time + + groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 ); + end + + if groupStartTime and groupTimes then + addon:Debug("Building of %s took %d ms (%d / %d / %d / %d / %d).", groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 )); + end + end + + mod.scrollFrame:ResumeLayout(); + mod.scrollFrame:DoLayout(); + + addon:Debug("Done building summary after %d ms.", ceil( ( GetTime() - buildStartTime ) * 1000 )); + + if CACHE_ITEMS_TOTAL > 0 then + cacheStart = GetTime(); + self:CancelTimer(self.tmrUpdater, true); + self.tmrUpdater = self:ScheduleRepeatingTimer("UpdateNextItem", .01); -- Once every 100 frames (or once every x frames if you have less than 100 FPS, basically, once every frame) + end +end + +function mod:UpdateNextItem() + local i = 0; + + for groupName, items in pairs(itemsCache) do + local minGlobalStock = addon:GetOptionByKey(groupName, "minGlobalStock"); + local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock"); + local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold"); + + for _, item in pairs(items) do + if item.globalCount == -3 or item.localCount == -3 or item.value == -3 then + if item.globalCount == -3 then + -- Only if item count was queued, update it + item.globalCount = addon:GetItemCount(item.id, groupName); + if item.set.globalCount and item.set.globalCount.SetText then + item.set.globalCount:SetText(self:DisplayItemCount(item.globalCount, minGlobalStock)); + end + end + + if item.localCount == -3 then + -- Only if item count was queued, update it + item.localCount = addon:GetLocalItemCount(item.id, groupName); + if item.set.localCount and item.set.localCount.SetText then + item.set.localCount:SetText(self:DisplayItemCount(item.localCount, minLocalStock)); + end + end + + if item.value == -3 then + -- Only if item value was queued, update it + + -- The itemlink might not have been loaded yet in which case we retry + item.link = item.link or select(2, GetItemInfo(item.id)); + + if item.link then + item.value = addon:GetAuctionValue(item.link, groupName); + if item.set.value and item.set.value.SetText then + item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold)); + end + end + end + + i = i + 1; + CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1; + + if mod.frame then + mod.frame:SetStatusText(printf("Caching auction values and item-counts... %d%% has already been processed.", floor(CACHE_ITEMS_CURRENT / CACHE_ITEMS_TOTAL * 100))); + end + + if i >= addon.db.profile.defaults.summary.speed then + return; + end + end + end + end + + -- Reset trackers + CACHE_ITEMS_TOTAL = 0; + CACHE_ITEMS_CURRENT = 0; + + -- Stop timer + self:CancelTimer(self.tmrUpdater, true); + + -- Rebuild list so hidden items due to too low prices get added + self:Build(); + + -- Announce + mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds."); + + -- Forget time + cacheStart = nil; +end + +function mod:ColorCode(num, required) + local percentage = ( num / required ); + + if percentage >= addon.db.profile.defaults.colors.green then + return printf("|cff00ff00%d|r", num); + elseif percentage >= addon.db.profile.defaults.colors.yellow then + return printf("|cffffff00%d|r", num); + elseif percentage >= addon.db.profile.defaults.colors.orange then + return printf("|cffff9933%d|r", num); + elseif percentage >= addon.db.profile.defaults.colors.red then + return printf("|cffff0000%d|r", num); + else + return num; + end +end + +function mod:DisplayMoney(value, priceThreshold) + if value == -1 then + return "|cff0000ffNone up|r"; + elseif value == -2 then + return "|cff0000ffNo AH mod|r"; + elseif value == -3 then + return "|cffffff00Unknown|r"; + elseif value == -4 then + return "|cff00ff00-|r"; + elseif value == -5 then + return "|cffff9933Error|r"; + elseif priceThreshold and value < priceThreshold then + return printf("|cffaaaaaa%s|r", sgsub(addon:ReadableMoney(value or 0, true), "|([a-fA-F0-9]+)([gsc]+)|r", "%2")); + else + return addon:ReadableMoney(value or 0, true); + end +end + +function mod:NumberFormat(num) + local formatted = sgsub(num, "(%d)(%d%d%d)$", "%1,%2", 1); + + while true do + formatted, matches = sgsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1); + + if matches == 0 then + break; + end + end + + return formatted; +end
--- a/Modules/Summary.lua Fri Jan 07 10:34:38 2011 +0100 +++ b/Modules/Summary.lua Fri Jan 07 22:19:03 2011 +0100 @@ -457,14 +457,14 @@ end if groupStartTime and groupTimes then - addon:Debug(printf("Building of %s took %d ms (%d / %d / %d / %d / %d).", groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 ))); + addon:Debug("Building of %s took %d ms (%d / %d / %d / %d / %d).", groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 )); end end mod.scrollFrame:ResumeLayout(); mod.scrollFrame:DoLayout(); - addon:Debug(printf("Done building summary after %d ms.", ceil( ( GetTime() - buildStartTime ) * 1000 ))); + addon:Debug("Done building summary after %d ms.", ceil( ( GetTime() - buildStartTime ) * 1000 )); if CACHE_ITEMS_TOTAL > 0 then cacheStart = GetTime();