changeset 81:58617c7827fa

Item refilling should now be working. Probably very slow if your bags, bank or guild bank is filled with over 200 unique items or so (needs some real testing, but know that it is a known (possible) issue).
author Zerotorescue
date Thu, 06 Jan 2011 01:01:25 +0100
parents c0bf2ddb5288
children f885805da5d6
files ContainerItem.class.lua Inventorium.toc ItemMove.class.lua Mover.lua Scanner.lua
diffstat 5 files changed, 207 insertions(+), 274 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ContainerItem.class.lua	Thu Jan 06 01:01:25 2011 +0100
@@ -0,0 +1,32 @@
+local addon = select(2, ...);
+
+-- Define the class
+
+addon.ContainerItem = {};
+addon.ContainerItem.__index = addon.ContainerItem;
+
+-- Construct
+function addon.ContainerItem:New(id)
+	local self = {};
+	
+	setmetatable(self, addon.ContainerItem);
+	
+	-- Standard info everything needs
+	self.id = id;
+	self.totalCount = 0;
+	self.locations = {};
+	
+	return self;
+end
+
+function addon.ContainerItem:AddLocation(container, slot, count)
+	table.insert(self.locations, {
+		container = container,
+		slot = slot,
+		count = count,
+	});
+	
+	self.totalCount = (self.totalCount + count);
+	
+	return true;
+end
--- a/Inventorium.toc	Wed Jan 05 13:05:15 2011 +0100
+++ b/Inventorium.toc	Thu Jan 06 01:01:25 2011 +0100
@@ -22,7 +22,7 @@
 # Stuff
 Widgets.lua
 ItemData.class.lua
-ItemMove.class.lua
+ContainerItem.class.lua
 
 # Data
 Data\PremadeGroups.lua
--- a/ItemMove.class.lua	Wed Jan 05 13:05:15 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-local addon = select(2, ...);
-
--- Define the class
-
-addon.ItemMove = {};
-addon.ItemMove.__index = addon.ItemMove;
-
--- Construct
-function addon.ItemMove:New(id)
-	local self = {};
-	
-	setmetatable(self, addon.ItemMove);
-	
-	-- Standard info everything needs
-	self.id = id;
-	self.totalCount = 0;
-	self.locations = {};
-	
-	return self;
-end
-
-function addon.ItemMove:AddLocation(container, slot, count)
-	table.insert(self.locations, {
-		container = container,
-		slot = slot,
-		count = count,
-	});
-	
-	self.totalCount = (self.totalCount + count);
-	
-	return true;
-end
-
-function addon.ItemMove:Move(location, targetBag, targetSlot)
-	-- move location (container, slot, count) to targetBag, targetSlot
-	return true;
-end
--- a/Mover.lua	Wed Jan 05 13:05:15 2011 +0100
+++ b/Mover.lua	Thu Jan 06 01:01:25 2011 +0100
@@ -4,6 +4,7 @@
 local Scanner;
 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called
 local combinedMoves = {}; -- table storing all combined moves (with source and target) that is to be processed by the actual mover in the order of the index (1 to #)
+local movesSource;
 
 function mod:AddMove(itemId, amount)
 	table.insert(queuedMoves, {
@@ -12,7 +13,12 @@
 	});
 end
 
+function mod:HasMoves()
+	return (#queuedMoves ~= 0);
+end
+
 function mod:BeginMove(location, onFinish)
+	addon:Debug("BeginMove");
 	
 	-- Find the outgoing moves
 	-- We need the source container and slot, find all the requires sources and put them in a list which we go through later to find matching targets
@@ -22,17 +28,17 @@
 	
 	local outgoingMoves = {};
 
-	for singleMove in pairs(queuedMoves) do
+	for _, singleMove in pairs(queuedMoves) do
 		local sourceItem = sourceContents[singleMove.id];
 		if not sourceItem then
 			print("Can't move " .. IdToItemLink(singleMove.id) .. ", non-existant in source");
 		else
 			-- We want to move the smallest stacks first to keep stuff pretty
 			table.sort(sourceItem.locations, function(a, b)
-				return a.count > b.count;
+				return a.count < b.count;
 			end);
 			
-			for itemLocation in pairs(sourceItem.locations) do
+			for _, itemLocation in pairs(sourceItem.locations) do
 				-- if this location has more items than we need, only move what we need, otherwise move everything in this stack
 				local movingNum = ((itemLocation.count > singleMove.num and singleMove.num) or itemLocation.count);
 				
@@ -47,7 +53,7 @@
 				
 				if singleMove.num == 0 then
 					-- If we have prepared everything we wanted, go to the next queued move
-					break;
+					break; -- stop the locations-loop
 				end
 			end
 		end
@@ -76,17 +82,20 @@
 			
 			if not itemId then
 				table.insert(emptySlots, {
-					container: bagId,
-					slot: slotId,
+					container = bagId,
+					slot = slotId,
 				});
 			end
 		end
 	end
 	
+	-- Remember where we're moving from
+	movesSource = location;
+	
 	while #outgoingMoves ~= 0 do
 		-- A not equal-comparison should be quicker than a larger/smaller than-comparison
 		
-		for outgoingMove in pairs(outgoingMoves) do
+		for _, outgoingMove in pairs(outgoingMoves) do
 			-- itemId  will be set to nil when this outgoing move was processed - sanity check
 			if outgoingMove.itemId then
 				local targetItem = targetContents[outgoingMove.itemId];
@@ -114,11 +123,11 @@
 						
 						-- We filled an empty slot so the target contents now has one more item,
 						-- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it
-						local itemMove = addon.ItemMove:New();
-						itemMove.AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.count);
+						local itemMove = addon.ContainerItem:New();
+						itemMove:AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.count);
 						targetContents[outgoingMove.itemId] = itemMove;
 						
-						firstAvailableSlot = nil; -- no longer empty
+						table.remove(emptySlots, 1); -- no longer empty
 						
 						outgoingMove.count = 0; -- nothing remaining - sanity check
 						outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
@@ -129,10 +138,10 @@
 					
 					-- We want to move to the largest stacks first to keep stuff pretty
 					table.sort(targetItem.locations, function(a, b)
-						return a.count < b.count;
+						return a.count > b.count;
 					end);
 					
-					for itemLocation in pairs(targetItem.locations) do
+					for _, itemLocation in pairs(targetItem.locations) do
 						if itemLocation.count < itemStackCount and outgoingMove.count > 0 then
 							-- Check if this stack isn't already full (and we still need to move this item)
 							
@@ -201,37 +210,84 @@
 	-- No longer needed
 	table.wipe(emptySlots);
 	
-	DoMoveNow();
+	self:ProcessMove();
 	
-	--ProcessMove();
+	self:RegisterEvent("BAG_UPDATE");
 	
-	--mod:RegisterEvent("BAG_UPDATE", BAG_UPDATE);
-	
-	--onFinish();
+	onFinish();
 end
 
-function DoMoveNow()
+if not table.reverse then
+-- 	table.reverse = function(orig)
+-- 		local temp = CopyTable(orig);
+-- 		local origLength = #temp;
+-- 		for i = 1, origLength do
+-- 			orig[(origLength - i + 1)] = temp[i];
+-- 		end
+-- 	end
+	table.reverse = function(orig)
+		local temp = {};
+		local origLength = #orig;
+		for i = 1, origLength do
+			temp[(origLength - i + 1)] = orig[i];
+		end
+		
+-- 		-- Update the original table (can't do orig = temp as that would change the reference-link instead of the original table)
+-- 		for i, v in pairs(temp) do
+-- 			orig[i] = v;
+-- 		end
+		return temp; -- for speed we choose to do a return instead
+	end
+end
+
+function mod:ProcessMove()
+	addon:Debug("ProcessMove");
+	
+	if #combinedMoves == 0 then
+		print("Nothing to move.");
+		
+		self:Abort();
+		
+		return;
+	end
+	
+	self:RegisterEvent("UI_ERROR_MESSAGE");
+	
 	-- combinedMoves now has all moves in it (source -> target)
 	-- go through list, move everything inside it
-	-- add source and target to one single list
-	-- if either is already in this list, skip this move
-	-- repeat every 5 seconds until we're completely done
+	-- add source and target to lists, if either is already in this list, skip the move
+	-- repeat every few seconds until we're completely done
 	
 	local sourceLocationsLocked = {};
 	local targetLocationsLocked = {};
 	
+	-- 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);
+	
 	local numCurrentMove = #combinedMoves;
 	while numCurrentMove ~= 0 do
 		local move = combinedMoves[numCurrentMove];
 		
 		-- sourceContainer, sourceSlot, targetContainer, targetSlot, itemId, num
-		if (not sourceLocationsLocked[move.sourceContainer] or not sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) and 
+		if move and (not sourceLocationsLocked[move.sourceContainer] or not sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) and 
 			(not targetLocationsLocked[move.targetContainer] or not targetLocationsLocked[move.targetContainer][move.targetSlot]) then
 			
 			print("Moving " .. 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));
+			
+			if GetContainerItemID(move.sourceContainer, move.sourceSlot) ~= move.itemId then
+				self:Abort("source changed", "Source (" .. move.sourceContainer .. "," .. move.sourceSlot .. ") is not " .. IdToItemLink(move.itemId));
+				
+				return;
+			end
+			
 			-- Pickup stack
-			SplitGuildBankItem(move.sourceContainer, move.sourceSlot, move.num);
+			if movesSource == addon.Locations.Bank then
+				SplitContainerItem(move.sourceContainer, move.sourceSlot, move.num);
+			elseif movesSource == addon.Locations.Guild then
+				SplitGuildBankItem(move.sourceContainer, move.sourceSlot, move.num);
+			end
 			
 			-- Remember we picked this item up and thus it is now locked
 			if not sourceLocationsLocked[move.sourceContainer] then
@@ -239,214 +295,75 @@
 			end
 			sourceLocationsLocked[move.sourceContainer][move.sourceSlot] = true;
 			
-			if CursorHasItem() then
+			if movesSource == addon.Locations.Guild or CursorHasItem() then -- CursorHasItem is always false if source is a guild tab
+				if GetContainerItemID(move.targetContainer, move.targetSlot) and GetContainerItemID(move.targetContainer, move.targetSlot) ~= move.itemId then
+					self:Abort("target changed", "Target (" .. move.targetContainer .. "," .. move.targetSlot .. ") is not " .. IdToItemLink(move.itemId) .. " nor empty");
+					return;
+				end
+				
 				-- And drop it
 				PickupContainerItem(move.targetContainer, move.targetSlot);
 				
 				-- Remember we dropped an item here and thus this is now locked
-				if not sourceLocationsLocked[move.targetContainer] then
-					sourceLocationsLocked[move.targetContainer] = {};
+				if not targetLocationsLocked[move.targetContainer] then
+					targetLocationsLocked[move.targetContainer] = {};
 				end
-				sourceLocationsLocked[move.targetContainer][move.targetSlot] = true;
+				targetLocationsLocked[move.targetContainer][move.targetSlot] = true;
 				
 				-- This move was processed
 				table.remove(combinedMoves, numCurrentMove);
+			else
+				self:Abort("item disappeared from mouse", "Couldn't move " .. IdToItemLink(move.itemId) .. ", CursorHasItem() is false");
+				return;
 			end
 		end
 		
 		-- Proceed with the next element (or previous considering we're going from last to first)
 		numCurrentMove = (numCurrentMove - 1);
 	end
+	
+	if #combinedMoves == 0 then
+		print("Finished.");
+		
+		self:Abort();
+		
+		return;
+	end
 end
 
 local tmrProcessNext;
-function BAG_UPDATE()
-	mod:CancelTimer(tmrProcessNext, true); -- silent
-	tmrProcessNext = mod:ScheduleTimer(function()
-		ProcessMove();
-	end, 2);
+function mod:BAG_UPDATE()
+	self:CancelTimer(tmrProcessNext, true); -- silent
+	tmrProcessNext = self:ScheduleTimer("ProcessMove", 1);
 end
 
-function ProcessMove()
-	local currentMove = queuedMoves[1];
-	
-	if currentMove then
-		addon:Debug("Moving " .. currentMove.num .. " of " .. IdToItemLink(currentMove.id));
-	
-		local requestedMoves = currentMove.num;
-		
-		if currentMove.src == addon.Locations.Bank then
-			MoveBankItem(currentMove);
-		elseif currentMove.src == addon.Locations.Guild then
-			MoveGuildItem(currentMove);
-		end
-		
-		if requestedMoves == currentMove.num then
-			print("Skipping " .. IdToItemLink(move.id));
-			move.num = 0;
-		elseif currentMove.num > 0 then
-			-- bags are full
-			print("bags are full");
-		end
-		
-		if currentMove.num == 0 then
-			table.remove(queuedMoves, 1);
-		end
+function IdToItemLink(itemId)
+	local itemLink = select(2, GetItemInfo(itemId));
+	itemLink = itemLink or "Unknown (" .. itemId .. ")";
+	return itemLink;
+end
+
+function mod:UI_ERROR_MESSAGE(e, errorMessage)
+	if errorMessage == ERR_SPLIT_FAILED then
+		self:Abort("splitting failed", "Splitting failed.");
 	end
 end
 
-function MoveGuildItem(move)
-	local tabId = GetCurrentGuildBankTab();
-	local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
+function mod:Abort(simple, debugMsg)
+	if debugMsg then
+		addon:Debug("Aborting:" .. debugMsg);
+	end
+	if simple then
+		print("|cffff0000Aborting: " .. simple .. ".|r");
+	end
+	table.wipe(combinedMoves);
+	movesSource = nil;
 	
-	if tabId == nil or tabId < 1 then return; end
+	-- Stop timer
+	self:UnregisterEvent("BAG_UPDATE");
+	self:CancelTimer(tmrProcessNext, true); -- silent
 	
-	while slotId ~= 0 do
-		-- A not equal-comparison should be quicker than a larger than-comparison
-		
-		local itemLink = GetGuildBankItemLink(tabId, slotId);
-		if itemLink then
-			-- If there is actually an item in this slot
-			
-			local itemId = GetItemId(itemLink);
-			
-			if itemId and move.id == itemId then
-				-- This is one of the items we're looking for
-				
-				local itemCount = select(2, GetGuildBankItemInfo(tabId, slotId));
-				
-				if itemCount and itemCount > 0 then
-					-- if the amount we still have to move is more than this stack, move the entire stack, otherwise move the still needed part of the stack
-					local moveable = (move.num > itemCount and itemCount) or move.num;
-					
-					-- Pickup stack
-					SplitGuildBankItem(tabId, slotId, moveable);
-					
-					-- Find an target slot and put it there
-					local reallyMoved = DropItem(itemId, moveable);
-					if reallyMoved then
-						-- Keep track of how many we have moved
-						moved = (moved + reallyMoved);
-						
-						-- Update the required amount of items so it has the remaining num
-						move.num = (move.num - reallyMoved);
-						
-						--if reallyMoved ~= moveable then
-						--	-- Scan this slot again because if we moved a 18 stack onto a 16 stack, we'd actually have moved only 4 items and still need to move the remaining 14 (we're capping stacks before using empty slots)
-						--	slotId = (slotId + 1);
-						--end
-						
-						--if move.num == 0 then
-							-- if no required items are left to move, then stop and tell the caller function how many we moved
-							return moved;
-						--end
-					end
-				end
-			end
-		end
-		
-		-- Continue scanning a different slot
-		slotId = (slotId - 1);
-	end
-end
-
-function MoveBankItem(move)
-	local start = 0;
-	local stop = NUM_BAG_SLOTS;
-	
-	-- If we requested the bank then we don't want the bag info
-	start = ( NUM_BAG_SLOTS + 1 );
-	stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
-	
-	-- Scan the default 100 slots
-	move.num = (move.num - MoveFromContainter(BANK_CONTAINER, move));
-	
-	-- Go through all our bags, including the backpack
-	for bagID = start, stop do
-		move.num = (move.num - MoveFromContainter(bagID, move));
-	end
-end
-
--- Go through all slots of this bag and if a match was found, move the items
-function MoveFromContainter(bagID, move)
-	-- Keep track of how many we have moved
-	local moved = 0;
-	
-	-- Go through all slots of this bag
-	for slot = 1, GetContainerNumSlots(bagID) do
-		local itemId = GetContainerItemID(bagID, slot);
-		
-		if itemId and move.id == itemId then
-			-- This is one of the items we're looking for
-			
-			local itemCount = select(2, GetContainerItemInfo(bagID, slot));
-			
-			if itemCount and itemCount > 0 then
-				-- if the amount we still have to move is more than this stack, move the entire stack, otherwise move the still needed part of the stack
-				local moveable = (move.num > itemCount and itemCount) or move.num;
-				
-				-- Pickup stack
-				SplitContainerItem(bagID, slot, moveable);
-				
-				addon:Debug("Picked " .. IdToItemLink(itemId) .. " up");
-				
-				-- Find an target slot and put it there
-				if CursorHasItem() then
-					local reallyMoved = DropItem(itemId, moveable);
-					
-					if reallyMoved then
-						addon:Debug("Dropped " .. reallyMoved .. " of " .. IdToItemLink(itemId));
-						
-						-- Keep track of how many we have moved
-						moved = (moved + reallyMoved);
-						
-						-- Update the required amount of items so it has the remaining num
-						move.num = (move.num - reallyMoved);
-						
-						--if reallyMoved ~= moveable then
-							-- Scan this slot again because if we moved a 18 stack onto a 16 stack, we'd actually have moved only 4 items and still need to move the remaining 14 (we're capping stacks before using empty slots)
-						--	slot = (slot - 1);
-						--end
-						
-						--if move.num == 0 then
-							-- if no required items are left to move, then stop and tell the caller function how many we moved
-							return moved;
-						--end
-					end
-				end
-			end
-		end
-	end
-	
-	return moved;
-end
-
-
--- This currently only uses empty slots, it will have to fill stacks in the future
-function DropItem(itemId, amount)
-	local start = 0;
-	local stop = NUM_BAG_SLOTS;
-	
-	-- Go through all our bags, including the backpack
-	for bagID = start, stop do
-		-- Go through all our slots
-		for slot = 1, GetContainerNumSlots(bagID) do
-			local itemId = GetContainerItemID(bagID, slot);
-			
-			if not itemId then
-				-- If this slot is empty, put the item here
-				PickupContainerItem(bagID, slot);
-				
-				return amount;
-			end
-		end
-	end
-	
-	return;
-end
-
-function IdToItemLink(itemId)
-	return select(2, GetItemInfo(itemId));
+	self:UnregisterEvent("UI_ERROR_MESSAGE");
 end
 
 function mod:OnEnable()
@@ -455,4 +372,6 @@
 
 function mod:OnDisable()
 	Scanner = nil;
+	
+	self:Abort();
 end
--- a/Scanner.lua	Wed Jan 05 13:05:15 2011 +0100
+++ b/Scanner.lua	Thu Jan 06 01:01:25 2011 +0100
@@ -10,18 +10,6 @@
 local Mover, paused;
 local itemCache = {};
 
-local function _GetItemCount(itemId, location)
-	if location == addon.Locations.Bank then
-		-- No longer using GetItemCount as this includes equiped items and containers (e.g. bank bags)
-		--return (GetItemCount(itemId, true) - GetItemCount(itemId, false)); -- GetItemCount(X, true) provides count for bag+bank, GetItemCount(X, false) provides just bag, so (GetItemCount(X, true) - GetItemCount(X, false)) = just bank
-		return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
-	elseif location == addon.Locations.Guild then
-		return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
-	else
-		error("Invalid location provided for the local _GetItemCount. Must be Bag or Bank.");
-	end
-end
-
 local function GetItemID(link)
 	return tonumber(link:match("|Hitem:([-0-9]+):"));
 end
@@ -46,7 +34,7 @@
 		end
 		
 		-- Go through all our bags, including the backpack
-		for i = start, ((addon.Locations.Bag and stop) or (addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too
+		for i = start, ((location == addon.Locations.Bag and stop) or (location == addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too
 			-- Scan the default 100 slots whenever we're at a non-existing index
 			local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
 			local slotId = GetContainerNumSlots(bagId);
@@ -61,13 +49,14 @@
 					local itemMove;
 					if not itemCache[itemId] then
 						-- If this is the first time we see this item, make a new object
-						itemMove = addon.ItemMove:New();
+						itemMove = addon.ContainerItem:New();
+						itemCache[itemId] = itemMove;
 					else
 						-- If we had this item in another slot too
 						itemMove = itemCache[itemId];
 					end
 					
-					itemMove.AddLocation(bagId, slotId, itemCount);
+					itemMove:AddLocation(bagId, slotId, itemCount);
 				end
 			
 				-- Continue scanning a different slot
@@ -96,13 +85,14 @@
 				local itemMove;
 				if not itemCache[itemId] then
 					-- If this is the first time we see this item, make a new object
-					itemMove = addon.ItemMove:New();
+					itemMove = addon.ContainerItem:New();
+					itemCache[itemId] = itemMove;
 				else
 					-- If we had this item in another slot too
 					itemMove = itemCache[itemId];
 				end
 				
-				itemMove.AddLocation(tabId, slotId, itemCount);
+				itemMove:AddLocation(tabId, slotId, itemCount);
 			end
 			
 			-- Continue scanning a different slot
@@ -144,19 +134,19 @@
 			-- Go through all items
 			for itemId, _ in pairs(values.items) do
 				
-				-- Check if we have enough items local
-				local missingItems = (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
+				-- Check if we have enough items local (but only do so if this location also has enough available)
+				local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
 				
-				if missingItems > 0 then
+				if itemCache[itemId] and missingItems > 0 then
 					-- Check how many are available
-					local availableItems = _GetItemCount(itemId, location);
+					local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
 					
 					if availableItems > 0 then
 						print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
 						
 						Mover:AddMove(itemId, missingItems);
 					else
-						print("Insufficient " .. select(2, GetItemInfo(itemId)));
+						print("Insufficient " .. IdToItemLink(itemId));
 					end
 				end
 			end
@@ -165,47 +155,72 @@
 	
 	self:ClearCache();
 	
-	self:Pause();
-	Mover:BeginMove(location, self.Unpause);
+	if Mover:HasMoves() then
+		StaticPopupDialogs["InventoriumRefill"] = {
+			text = "There are items that can be refilled from this location, do you wish to proceed?",
+			button1 = YES,
+			button2 = NO,
+			OnAccept = function()
+				mod:Pause();
+				Mover:BeginMove(location, self.Unpause);
+			end,
+			timeout = 0,
+			whileDead = 1,
+			hideOnEscape = 1,
+		};
+		StaticPopup_Show("InventoriumRefill");
+	end
+end
+
+local function BANKFRAME_CLOSED()
+	addon:Debug("Scanner:BANKFRAME_CLOSED");
+	
+	mod:UnregisterEvent("BANKFRAME_CLOSED");
+	
+	StaticPopup_Hide("InventoriumRefill");
 end
 
 local function BANKFRAME_OPENED()
+	addon:Debug("Scanner:BANKFRAME_OPENED");
+	
+	mod:RegisterEvent("BANKFRAME_CLOSED", BANKFRAME_CLOSED);
+	
 	-- Scan once when the bank is opened, but no need to scan after
 	mod:Scan(addon.Locations.Bank);
-	
-	addon:Debug("Scanner:BANKFRAME_OPENED");
 end
 
 -- Remember which tabs were scanned and don't scan them again
 local guildBankTabsScanned = {};
 
 local function GUILDBANKFRAME_CLOSED()
+	addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
+	
+	table.wipe(guildBankTabsScanned);
+	
 	mod:UnregisterEvent("GUILDBANKFRAME_CLOSED");
 	mod:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
 	
-	table.wipe(guildBankTabsScanned);
-	
-	addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
+	StaticPopup_Hide("InventoriumRefill");
 end
 
 local function GUILDBANKBAGSLOTS_CHANGED()
 	if not guildBankTabsScanned[GetCurrentGuildBankTab()] then
+		addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - scanning");
+		
 		mod:Scan(addon.Locations.Guild);
 		guildBankTabsScanned[GetCurrentGuildBankTab()] = true;
-		
-		addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - scanning");
 	else
 		addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - not scanning");
 	end
 end
 
 local function GUILDBANKFRAME_OPENED()
+	addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
+	
 	table.wipe(guildBankTabsScanned);
 	
 	mod:RegisterEvent("GUILDBANKFRAME_CLOSED", GUILDBANKFRAME_CLOSED);
 	mod:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED", GUILDBANKBAGSLOTS_CHANGED);
-	
-	addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
 end
 
 function mod:OnEnable()