AuctioneerSuite/Auc-Advanced/Modules/Auc-Util-SearchUI/SearchMain.lua
2026-04-13 17:48:13 -04:00

2062 lines
68 KiB
Lua

--[[
Auctioneer - Search UI
Version: 5.9.4961 (WhackyWallaby)
Revision: $Id: SearchMain.lua 4933 2010-10-13 17:16:14Z Nechckn $
URL: http://auctioneeraddon.com/
This Addon provides a Search tab on the AH interface, which allows
Auctioneer users to use Searcher plug-ins to search for good deals
in the auction house. It searches the "snapshot", which requires
having data from recent auction house scans.
License:
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program(see GPL.txt); if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Note:
This AddOn's source code is specifically designed to work with
World of Warcraft's interpreted AddOn system.
You have an implicit license to use this AddOn with these facilities
since that is its designated purpose as per:
http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat
--]]
local libType, libName = "Util", "SearchUI"
local AucAdvanced = AucAdvanced
local lib,parent,private = AucAdvanced.NewModule(libType, libName)
if not lib then return end
local print,decode,_,_,replicate,_,get,set,default,debugPrint,fill = AucAdvanced.GetModuleLocals()
local debugPrint = AucAdvanced.Debug.DebugPrint
local empty = wipe
local ipairs,pairs,type,select = ipairs,pairs,type,select
local tostring,tonumber = tostring,tonumber
local floor,ceil,abs = floor,ceil,abs
local strmatch,format = strmatch,format
local tinsert,tremove = tinsert,tremove
-- GLOBALS: CreateFrame, GameTooltip
-- Our official name:
AucSearchUI = lib
function lib.GetName()
return libName
end
local Const = AucAdvanced.Const
local gui
private.data = {}
private.sheetData = {}
private.sheetStyle = {}
private.isSearching = false
local coSearch
local SettingCache = {}
local currentSettings = {}
local hasUnsaved = nil
local TAB_NAME = "Search"
private.tleft = {
"|cff000001|cffe5e5e530m", -- 30m
"|cff000002|cffe5e5e52h", --2h
"|cff000003|cffe5e5e512h", --12h
"|cff000004|cffe5e5e548h" --48h
}
lib.CleanTable = wipe -- for compatibility
local resources = {}
lib.Resources = resources
local flagResourcesUpdateRequired = false
local flagScanStats = false
-- Faction Resources
-- Commonly used values which change depending whether you are at home or neutral Auctionhouse
-- Modules should expect these to always contain valid values; nil tests should not be required
resources.Realm = GetRealmName() -- will not change during session
function private.UpdateFactionResources()
local serverKey, _, Faction = AucAdvanced.GetFaction()
if serverKey ~= resources.serverKey then
-- store new settings
resources.Faction = Faction
resources.faction = Faction:lower() -- lowercase for GetDepositCost
resources.serverKey = serverKey
resources.CutAdjust = 1 - AucAdvanced.cutRate -- multiply price by .CutAdjust to subtract the AH brokerage fees
-- notify the change
lib.NotifyCallbacks("resources", "faction", serverKey)
end
end
-- todo: we really should update when Zone changes, but there in't a processor event for that
-- Selectbox Resources
--[[ Usages:
gui:AddControl(id, "Selectbox", column, indent, resources.selectorPriceModels, "searcher.model")
gui:AddControl(id, "Selectbox", column, indent, resources.selectorPriceModelsEnx, "searcher.model")
gui:AddControl(id, "Selectbox", column, indent, resources.selectorAuctionLength, "searcher.deplength")
local price, seen, curModel = resources.lookupPriceModel[model](model, link || itemID [, serverKey]) ~ price, seen or curModel may be nil
local price, seen, curModel = resources.GetPrice(model, link || itemID [, serverKey]) ~ simplified wrapper function for lookupPriceModel
if not resources.isValidPriceModel(get("searcher.model")) then <code to report warning...>
--]]
do -- limit scope of locals
resources.selectorAuctionLength = AucAdvanced.selectorAuctionLength
lib.AucLengthSelector = AucAdvanced.selectorAuctionLength -- for compatibility
resources.selectorPriceModels = AucAdvanced.selectorPriceModels
local pricemodelsenx
function resources.selectorPriceModelsEnx()
if not pricemodelsenx then
pricemodelsenx = replicate(resources.selectorPriceModels())
if resources.isEnchantrixLoaded then
tinsert(pricemodelsenx, 1, {"Enchantrix", "Enchantrix"})
end
end
return pricemodelsenx
end
function private.ResetPriceModelEnx()
pricemodelsenx = nil
end
function resources.isValidPriceModel(testmodel)
local pricemodels = resources.selectorPriceModelsEnx() -- make sure table is up to date
local found -- default return value nil
for pos, model in ipairs(pricemodels) do
if model[1] == testmodel then
found = model[2]
break
end
end
return found
end
-- lookup functions
local function UnknownFunc() end -- return nil
local function MarketFunc(model, link, serverKey)
local price, seen = AucAdvanced.API.GetMarketValue(link, serverKey)
return price, seen, model
end
local function AppraiserFunc(model, link, serverKey)
local market, bid, _, seen, curModel = AucAdvanced.Modules.Util.Appraiser.GetPrice(link, serverKey)
if not market or market == 0 then
market = bid -- fallback to bid price if no market
end
return market, seen, curModel
end
local function EnchantrixFunc(model, link, serverKey)
-- GetReagentPrice does not handle serverKey, and it does not return a seen count
local extra, mkt, five, _
_, extra = Enchantrix.Util.GetPricingModel()
_, _, mkt, five = Enchantrix.Util.GetReagentPrice(link, extra)
return five or mkt, nil, extra or model
end
local function AlgorithmFunc(model, link, serverKey)
local market, seen = AucAdvanced.API.GetAlgorithmValue(model, link, serverKey)
return market, seen, model
end
local function indexFunc(lookup, model)
local func
if model == "Appraiser" and AucAdvanced.Modules.Util.Appraiser then
func = AppraiserFunc
elseif model == "Enchantrix" and resources.isEnchantrixLoaded then
func = EnchantrixFunc
elseif AucAdvanced.API.IsValidAlgorithm(model) then
func = AlgorithmFunc
end
if func then
rawset(lookup, model, func)
return func
end
return UnknownFunc
end
local lookuppricemodel = setmetatable({market = MarketFunc}, {__index = indexFunc})
resources.lookupPriceModel = lookuppricemodel
function resources.GetPrice(model, link, serverKey) -- simplified wrapper
return lookuppricemodel[model](model, link, serverKey)
end
end
-- Enchantrix Load detection
if Enchantrix and Enchantrix.Storage and Enchantrix.Util then
resources.isEnchantrixLoaded = true
else
local _, _, _, enabled, loadable = GetAddOnInfo("Enchantrix") -- check it's actually possible to load
if enabled and loadable then
Stubby.RegisterAddOnHook("Enchantrix", "Auc-Util-SearchUI", function()
if Enchantrix and Enchantrix.Storage and Enchantrix.Util then
Stubby.UnregisterAddOnHook("Enchantrix", "Auc-Util-SearchUI")
resources.isEnchantrixLoaded = true
private.ResetPriceModelEnx()
lib.NotifyCallbacks("onload", "enchantrix")
end
end)
end
end
function lib.OnLoad(addon)
-- Notify that SearchUI is fully loaded
resources.isSearchUILoaded = true
lib.NotifyCallbacks("onload", addon)
-- Initialize
private.UpdateFactionResources()
end
function lib.Processor(callbackType, ...)
if callbackType == "load" then
private.ResetPriceModelEnx()
elseif (callbackType == "auctionclose") then
if private.isAttached then
lib.DetachFromAH()
end
flagResourcesUpdateRequired = true
elseif callbackType == "auctionopen" then
flagResourcesUpdateRequired = true
elseif (callbackType == "auctionui") then
if lib.Searchers.RealTime then
lib.Searchers.RealTime.HookAH()
end
--we need to make sure that the GUI is made by the time the AH opens, as RealTime could be trying to add lines to it.
if not gui then
lib.MakeGuiConfig()
end
lib.CreateAuctionFrames()
elseif (callbackType == "pagefinished") then
if lib.Searchers.RealTime then
lib.Searchers.RealTime.FinishedPage(...)
end
elseif (callbackType == "bidcancelled") then --bid was cancelled, we need to ignore auction for current session
private.bidcancelled(...)
elseif (callbackType == "tooltip") then
lib.ProcessTooltip(...)
elseif callbackType == "scanstats" then
-- pass the message in next OnUpdate
flagScanStats = true
elseif callbackType == "scanprogress" and private.UpdateScanProgress then
private.UpdateScanProgress(...)
elseif callbackType == "buyqueue" and private.UpdateBuyQueue then
private.UpdateBuyQueue()
end
end
lib.Processors = {}
function lib.Processors.load(callbackType, ...)
private.ResetPriceModelEnx()
end
function lib.Processors.auctionclose(callbackType, ...)
if private.isAttached then
lib.DetachFromAH()
end
flagResourcesUpdateRequired = true
end
function lib.Processors.auctionopen(callbackType, ...)
flagResourcesUpdateRequired = true
end
function lib.Processors.auctionui(callbackType, ...)
if lib.Searchers.RealTime then
lib.Searchers.RealTime.HookAH()
end
--we need to make sure that the GUI is made by the time the AH opens, as RealTime could be trying to add lines to it.
if not gui then
lib.MakeGuiConfig()
end
lib.CreateAuctionFrames()
end
function lib.Processors.pagefinished(callbackType, ...)
if lib.Searchers.RealTime then
lib.Searchers.RealTime.FinishedPage(...)
end
end
function lib.Processors.bidcancelled(callbackType, ...)
private.bidcancelled(...)
end
function lib.Processors.tooltip(callbackType, ...)
lib.ProcessTooltip(...)
end
function lib.Processors.scanstats(callbackType, ...)
-- pass the message in next OnUpdate
flagScanStats = true
end
function lib.Processors.scanprogress(callbackType, ...)
if private.UpdateScanProgress then
private.UpdateScanProgress(...)
end
end
function lib.Processors.buyqueue(callbackType, ...)
if private.UpdateBuyQueue then
private.UpdateBuyQueue()
end
end
function lib.ProcessTooltip(tooltip, name, hyperlink, quality, quantity, cost, additional)
if not additional or additional.event ~= "SetAuctionItem" then
--this isn't an auction, so we're not interested
return
end
if not lib.GetSetting("debug.show") then
--we're not interested in adding debug
return
end
local button = GetMouseFocus():GetParent() --Note: check that it works without CompactUI
local id = button.id --CompactUI's layout
if not id then
id = button:GetID() + FauxScrollFrame_GetOffset(BrowseScrollFrame) --without CompactUI
end
local name, _, count, _, canUse, level, minBid, minInc, buyout, curBid, isHigh, owner = GetAuctionItemInfo("list", id)
local price
if curBid > 0 then
price = curBid + minInc
if buyout > 0 and price > buyout then
price = buyout
end
elseif minBid > 0 then
price = minBid
else
price = 1
end
owner = owner or ""
local timeleft = GetAuctionItemTimeLeft("list", id)
local _, _, _, iLevel, _, iType, iSubType, stack, iEquip = GetItemInfo(hyperlink)
iEquip = Const.EquipEncode[iEquip]
local _, itemid, suffix, factor, enchant, seed = AucAdvanced.DecodeLink(hyperlink)
local ItemTable = {}
-- put the data into a table laid out the same way as the AAdv Scandata, as that's what the searchers need
ItemTable[Const.LINK] = hyperlink
ItemTable[Const.ILEVEL] = iLevel
ItemTable[Const.ITYPE] = iType
ItemTable[Const.ISUB] = iSubType
ItemTable[Const.IEQUIP] = iEquip
ItemTable[Const.PRICE] = price
ItemTable[Const.TLEFT] = timeleft
ItemTable[Const.NAME] = name
ItemTable[Const.COUNT] = count
ItemTable[Const.QUALITY] = quality
ItemTable[Const.CANUSE] = canUse
ItemTable[Const.ULEVEL] = level
ItemTable[Const.MINBID] = minBid
ItemTable[Const.MININC] = minInc
ItemTable[Const.BUYOUT] = buyout
ItemTable[Const.CURBID] = curBid
ItemTable[Const.AMHIGH] = isHigh
ItemTable[Const.SELLER] = owner
ItemTable[Const.ITEMID] = itemid
ItemTable[Const.SUFFIX] = suffix
ItemTable[Const.FACTOR] = factor
ItemTable[Const.ENCHANT] = enchant
ItemTable[Const.SEED] = seed
tooltip:AddLine("SearchUI:", 1, 0.7, 0.3)
local active = false
for name, searcher in pairs(lib.Searchers) do
if lib.GetSetting("debug."..name) then
active = true
local success, returnvalue, value = lib.SearchItem(name, ItemTable, true, true)
if success then
if value then
tooltip:AddLine(" "..name.." profit:"..floor(100*returnvalue/value).."%:", returnvalue, 1, 0.7, 0.3)
elseif returnvalue then
tooltip:AddLine(" "..name.." profit:", returnvalue, 1, 0.7, 0.3)
else
tooltip:AddLine(" "..name.." success", 1, 0.7, 0.3)
end
else
tooltip:AddLine(" "..name..":"..returnvalue, 1, 0.7, 0.3)
end
end
end
if not active then --if it hasn't changed, we're not enabled for any searcher
tooltip:AddLine(" No debugging enabled", 1, 0.7, 0.3)
end
end
-- Default setting values
local settingDefaults = {
["processpriority"] = 80,
["reserve"] = 0,
["reserve.enable"] = false,
["global.createtab"] = true,
["maxprice"] = 10000000,
["maxprice.enable"] = false,
["tooltiphelp.show"] = true,
--Scrollframe defaults
["columnwidth.Item"] = 120,
["columnwidth.Pct"] = 30,
["columnwidth.Profit"] = 85,
["columnwidth.Stk"] = 30,
["columnwidth.Buyout"] = 85,
["columnwidth.Bid"] = 85,
["columnwidth.Reason"] = 85,
["columnwidth.Seller"] = 75,
["columnwidth.Left"] = 40,
["columnwidth.Buy/ea"] = 85,
["columnwidth.Bid/ea"] = 85,
["columnwidth.MinBid"] = 85,
["columnwidth.CurBid"] = 85,
["columnwidth.Min/ea"] = 85,
["columnwidth.Cur/ea"] = 85,
}
local function getDefault(setting)
return settingDefaults[setting]
end
function lib.GetDefault(setting)
return getDefault(setting)
end
function lib.SetDefault(setting, default)
settingDefaults[setting] = default
end
local function initData()
local data = AucAdvancedData.UtilSearchUiData
if not data then
data = {}
data.Version = 1
AucAdvancedData.UtilSearchUiData = data
end
if not data.SavedSearches then data.SavedSearches = {} end
if not data.Current then data.Current = {} end
if not data.Global then data.Global = {} end
end
local function isGlobalSetting(setting)
local a,b,c = strsplit(".", setting)
if a == "configator" then return true end
if a == "global" then return true end
return
end
local function setter(setting, value)
AucAdvancedData.UtilSearchUI = nil -- Remove old settings
initData()
local db = currentSettings
-- turn value into a canonical true or false
if value == 'on' then
value = true
elseif value == 'off' then
value = false
end
if (isGlobalSetting(setting)) then
AucAdvancedData.UtilSearchUiData.Global[setting] = value
return
end
-- for defaults, just remove the value and it'll fall through
if (value == 'default') or (value == getDefault(setting)) then
-- Don't save default values
value = nil
end
if db[setting] == value then
if type(value) == "table" then
-- same table as before
-- call UpdateSave to check if the *contents* of the table have changed
-- but don't send Processor message as *setting* is the same (consistent with Core version of 'setter')
hasUnsaved = true
lib.UpdateSave()
end
return
end
db[setting] = value
hasUnsaved = true
lib.UpdateSave()
AucAdvanced.SendProcessorMessage("configchanged", setting, value)
lib.NotifyCallbacks('config', 'changed', setting, value)
end
function lib.SetSetting(...)
setter(...)
if (gui) then
gui:Refresh()
end
end
local function getter(setting)
initData()
local db = currentSettings
if (isGlobalSetting(setting)) then
local value = AucAdvancedData.UtilSearchUiData.Global[setting]
if value ~= nil then return value end
return getDefault(setting)
end
if ( db[setting] ~= nil ) then
return db[setting]
else
return getDefault(setting)
end
end
function lib.GetSetting(setting, default)
--use settings cache during a search
if private.isSearching then
if SettingCache[setting]~=nil then
return SettingCache[setting]
end
end
local option = getter(setting)
if ( option ~= nil ) then
if private.isSearching then
SettingCache[setting] = option
end
return option
else
if private.isSearching then
SettingCache[setting] = default
end
return default
end
end
function lib.Show()
if not gui then --no need to make the GUI if it already exists
lib.MakeGuiConfig()
end
gui:Show()
private.UpdateFactionResources()
end
function lib.Hide()
if (gui) then
gui:Hide()
end
end
function lib.Toggle()
if private.isAttached then return end
if (gui and gui:IsShown()) then
lib.Hide()
else
lib.Show()
end
end
private.callbacks = {}
function lib.AddCallback(name, callback)
if private.callbacks[name] then -- prevent overwriting an exisiting callback
error("AucSearchUI.AddCallback Error:\nCallback for "..name.." already exists", 2) -- level 2 is calling function
end
private.callbacks[name] = callback
-- fire certain callbacks, that have already happened, to new callback function
if resources.isEnchantrixLoaded then
callback("onload", "enchantrix")
end
if resources.isSearchUILoaded then
callback("onload", "auc-util-searchui")
end
if gui then
callback("guiconfig", gui)
end
end
function lib.NotifyCallbacks(msg, ...)
for name, callback in pairs(private.callbacks) do
callback(msg, ...)
end
for name, searcher in pairs(lib.Searchers) do
local processor = searcher.Processor
if processor then
local pType = type(processor)
if pType == "table" then
processor = processor[msg]
if type(processor) == "function" then
processor(...)
end
elseif pType == "function" then
processor(msg, ...)
end
end
end
for name, filter in pairs(lib.Filters) do
local processor = filter.Processor
if processor then
local pType = type(processor)
if pType == "table" then
processor = processor[msg]
if type(processor) == "function" then
processor(...)
end
elseif pType == "function" then
processor(msg, ...)
end
end
end
end
function lib.RemoveCallback(name, callback)
if callback and private.callbacks[name] == callback then
private.callbacks[name] = nil
return true
end
end
local searcherKit = {}
function searcherKit:GetName()
return self.name
end
lib.Searchers = {}
function lib.NewSearcher(searcherName)
if not lib.Searchers[searcherName] then
local searcher = {}
searcher.name = searcherName
for k,v in pairs(searcherKit) do
searcher[k] = v
end
lib.Searchers[searcherName] = searcher
return searcher, lib, {}
end
end
local filterKit = {}
function filterKit:GetName()
return self.name
end
lib.Filters = {}
function lib.NewFilter(filterName)
if not lib.Filters[filterName] then
local filter = {}
filter.name = filterName
for k,v in pairs(filterKit) do
filter[k] = v
end
lib.Filters[filterName] = filter
return filter, lib, {}
end
end
function lib.GetSearchLocals()
return lib.GetSetting, lib.SetSetting, lib.SetDefault, Const, resources
end
function private.removeline()
local selected = gui.sheet.selected
--find the place in the sort list, so we can select the next one.
for i,j in ipairs(gui.sheet.sort) do
if j == selected then
selected = i
break
end
end
tremove(private.sheetData, gui.sheet.selected)
--regenerate style elements, to match shorter data table
local total = #private.sheetData
for i = gui.sheet.selected, total do
private.sheetStyle[i] = private.sheetStyle[i+1]
if i == total then private.sheetStyle[i+1] = nil end --remove extra style
end
--gui.frame.remove:Disable()
gui.sheet.selected = nil
gui.sheet:SetData(private.sheetData, private.sheetStyle)
lib.UpdateControls()
gui.sheet.selected = gui.sheet.sort[selected]
gui.sheet:Render() --need to redraw, so the selection looks right
lib.UpdateControls()
end
function private.removeall()
empty(private.sheetData)
empty(private.sheetStyle)
gui.sheet.selected = nil
gui.sheet:SetData(private.sheetData, private.sheetStyle)
gui.sheet:Render() --need to redraw, so the selection looks right
lib.UpdateControls()
end
function private.repaintSheet()
local wasEmpty = #gui.sheet.data < 1
gui.sheet:SetData(private.sheetData, private.sheetStyle)
if wasEmpty then --sheet was empty, so select the just added auction
gui.sheet.selected = 1
gui.sheet:Render() --need to redraw, so the selection looks right
lib.UpdateControls()
end
end
function private.cropreason(reason)
if reason then
reason = strsplit(":", reason)
return reason
end
end
function private.buyauction()
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, private.data.buyout, private.cropreason(private.data.reason))
private.removeline()
end
function private.bidauction()
local bid = MoneyInputFrame_GetCopper(gui.frame.bidbox)
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, bid, private.cropreason(private.data.reason))
private.removeline()
end
function private.buyfirst()
gui.sheet.selected = gui.sheet.sort[1]
if not gui.sheet.selected then
return
end
lib.UpdateControls()
if strmatch(private.data.reason, ":buy") then
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, private.data.buyout, private.cropreason(private.data.reason))
elseif strmatch(private.data.reason, ":bid") then
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, private.data.bid, private.cropreason(private.data.reason))
elseif private.data.buyout > 0 then
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, private.data.buyout, private.cropreason(private.data.reason))
else
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, private.data.bid, private.cropreason(private.data.reason))
end
private.removeline()
end
--private.purchase
--Will buy/bid selected auction based on "reason" column
function private.purchase()
if not gui.sheet.selected then
return
end
local enableres = lib.GetSetting("reserve.enable")
local reserve = lib.GetSetting("reserve") or 1
local bidqueue = gui.frame.cancel.value or 0
local balance = GetMoney()
balance = balance - bidqueue --account for money we've already "spent"
local price = 0
if strmatch(private.data.reason, ":buy") then
price = private.data.buyout
elseif strmatch(private.data.reason, ":bid") then
price = private.data.bid
elseif private.data.buyout > 0 then
price = private.data.buyout
else
price = private.data.bid
end
if ((balance-price) > reserve or not enableres) then
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, price, private.cropreason(private.data.reason))
else
print("Purchase cancelled: Reserve reached")
end
private.removeline()
end
--Will buy/bid ALL auctions based on "reason" column
function private.purchaseall()
gui.sheet.selected = gui.sheet.sort[1]
if not gui.sheet.selected then
return
end
lib.UpdateControls()
local count = 0
while #gui.sheet.sort > 0 and (gui.sheet.sort[1] or count < 5000 ) do
count = count+1--emergency break routine
local enableres = lib.GetSetting("reserve.enable")
local reserve = lib.GetSetting("reserve") or 1
local bidqueue = gui.frame.cancel.value or 0
local balance = GetMoney()
balance = balance - bidqueue --account for money we've already "spent"
local price = 0
if strmatch(private.data.reason, ":buy") then
price = private.data.buyout
elseif strmatch(private.data.reason, ":bid") then
price = private.data.bid
elseif private.data.buyout > 0 then
price = private.data.buyout
else
price = private.data.bid
end
if ((balance-price) > reserve or not enableres) then
AucAdvanced.Buy.QueueBuy(private.data.link, private.data.seller, private.data.stack, private.data.minbid, private.data.buyout, price, private.cropreason(private.data.reason))
else
print("Purchase cancelled: Reserve reached")
end
private.removeline()
end
end
function private.ignore()
local sig = AucAdvanced.API.GetSigFromLink(private.data.link)
local price
if strmatch(private.data.reason, ":buy") then
price = private.data.buyout
elseif strmatch(private.data.reason, ":bid") then
price = private.data.bid
elseif private.data.buyout > 0 then
price = private.data.buyout
else
price = private.data.bid
end
local count = private.data.stack or 1
price = floor(price/count)
AucSearchUI.Filters.ItemPrice.AddIgnore(sig, price)
print("SearchUI now ignoring "..private.data.link.." at "..AucAdvanced.Coins(price, true))
private.removeline()
end
function private.ignoreperm()
local sig = AucAdvanced.API.GetSigFromLink(private.data.link)
AucSearchUI.Filters.ItemPrice.AddIgnore(sig, 0)
print("SearchUI now ignoring "..private.data.link.." at any price")
private.removeline()
end
--a bid was cancelled, so ignore for session
function private.bidcancelled(callbackstring)
local link, price, count = strsplit(";", callbackstring)
local sig = AucAdvanced.API.GetSigFromLink(link)
local price = floor(price/count) - 1
if AucSearchUI.Filters.ItemPrice then
AucSearchUI.Filters.ItemPrice.AddIgnore(sig, price, true)
print("SearchUI now ignoring "..link.." at "..AucAdvanced.Coins(price, true).." for the session")
end
end
function private.ignoretemp()
local sig = AucAdvanced.API.GetSigFromLink(private.data.link)
local price
if strmatch(private.data.reason, ":buy") then
price = private.data.buyout
elseif strmatch(private.data.reason, ":bid") then
price = private.data.bid
elseif private.data.buyout > 0 then
price = private.data.buyout
else
price = private.data.bid
end
local count = private.data.stack or 1
price = floor(price/count)
AucSearchUI.Filters.ItemPrice.AddIgnore(sig, price, true)
print("SearchUI now ignoring "..private.data.link.." at "..AucAdvanced.Coins(price, true).." for the session")
private.removeline()
end
function private.snatch()
local link = private.data.link
local price
if strmatch(private.data.reason, ":buy") then
price = private.data.buyout
elseif strmatch(private.data.reason, ":bid") then
price = private.data.bid
elseif private.data.buyout > 0 then
price = private.data.buyout
else
price = private.data.bid
end
local count = private.data.stack or 1
price = floor(price/count) + 1 -- +1 so the current item also matches the search
lib.Searchers.Snatch.AddSnatch(link,price)
print("SearchUI will now snatch "..private.data.link.." at "..AucAdvanced.Coins(price, true))
end
local function keyPairs(t,f)
local a, i = {}, 0
for n in pairs(t) do tinsert(a, n) end
table.sort(a, f)
local iter = function ()
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]] end
end
return iter
end
local function isEqual(a, b, l)
if not l then l = 0
elseif l > 10 then return false end
local ta, tb = type(a), type(b)
if ta ~= tb then return false end
if ta == 'table' then
for k,v in pairs(a) do
if not isEqual(v, b[k], l+1) then return false end
end
for k,v in pairs(b) do
if not isEqual(v, a[k], l+1) then return false end
end
else
if tostring(a) ~= tostring(b) then
return false
end
end
return true
end
lib.IsEqual = isEqual
function lib.LoadCurrent()
initData()
local name = gui.saves.name:GetText()
currentSettings = AucAdvancedData.UtilSearchUiData.Current
if not currentSettings then
lib.LoadSearch()
return
end
local existing = AucAdvancedData.UtilSearchUiData.SavedSearches[name]
if not existing then
hasUnsaved = true
elseif not isEqual(currentSettings, existing) then
hasUnsaved = true
else
hasUnsaved = nil
end
lib.UpdateSave()
gui:Refresh()
lib.NotifyCallbacks('config', 'loaded', nil)
end
function lib.LoadSearch()
initData()
local name = gui.saves.name:GetText()
if not AucAdvancedData.UtilSearchUiData.SavedSearches[name] then
message("SearchUI warning:\nThat search does not exist, please select an available search from the menu.")
return
end
currentSettings = replicate(AucAdvancedData.UtilSearchUiData.SavedSearches[name])
AucAdvancedData.UtilSearchUiData.Current = currentSettings
AucAdvancedData.UtilSearchUiData.Selected = name
hasUnsaved = nil
lib.UpdateSave()
gui:Refresh()
lib.NotifyCallbacks('config', 'loaded', name)
end
function lib.SaveSearch()
initData()
local name = gui.saves.name:GetText()
AucAdvancedData.UtilSearchUiData.SavedSearches[name] = replicate(currentSettings)
AucAdvancedData.UtilSearchUiData.Selected = name
hasUnsaved = nil
lib.UpdateSave()
gui:Refresh()
lib.NotifyCallbacks('config', 'saved', name)
end
function lib.DeleteSearch()
initData()
local name = gui.saves.name:GetText()
AucAdvancedData.UtilSearchUiData.SavedSearches[name] = nil
hasUnsaved = nil
AucAdvancedData.UtilSearchUiData.Selected = ""
gui.saves.name:SetText("")
lib.UpdateSave()
gui:Refresh()
lib.NotifyCallbacks('config', 'deleted', name)
end
function lib.ResetSearch()
initData()
currentSettings = {}
AucAdvancedData.UtilSearchUiData.Current = currentSettings
hasUnsaved = nil
AucAdvancedData.UtilSearchUiData.Selected = ""
gui.saves.name:SetText("")
lib.UpdateSave()
gui:Refresh()
lib.NotifyCallbacks('config', 'reset')
end
local curColor = "white"
function lib.UpdateSave()
if not (gui and AucAdvancedData.UtilSearchUiData) then return end
local name = gui.saves.name:GetText()
if hasUnsaved then
local saved = AucAdvancedData.UtilSearchUiData.SavedSearches[name]
if saved and isEqual(currentSettings, saved) then
hasUnsaved = false
end
end
if AucAdvancedData.UtilSearchUiData.Selected ~= name then
if curColor ~= "white" then
gui.saves.name:SetTextColor(1, 1, 1, 1)
curColor = "white"
end
elseif hasUnsaved then
if curColor ~= "red" then
gui.saves.name:SetTextColor(1, 0.5, 0.1, 1)
curColor = "red"
end
else
if curColor ~= "green" then
gui.saves.name:SetTextColor(0.3, 1, 0.3, 1)
curColor = "green"
end
end
end
function lib.AddSearcher(gui, searchType, searchDetail, searchPos)
if not gui.searchers[searchPos] then gui.searchers[searchPos] = {} end
gui.searchers[searchPos][searchType] = searchDetail
end
function lib.AttachToAH()
if private.isAttached then return end
local height, width = 410, 830
gui.buttonTop = -30
gui:SetPosition(gui.AuctionFrame, width, height, 5, 7+height)
gui:HideBackdrop()
gui:EnableMouse(false)
gui:RealSetScale(0.9999)
gui:RealSetScale(1.0)
gui:Show()
private.isAttached = true
end
function lib.DetachFromAH()
if not private.isAttached then return end
gui.buttonTop = 0
gui:SetPosition()
gui:EnableMouse(true)
gui:ShowBackdrop()
gui:RealSetScale(0.9999)
gui:RealSetScale(private.scale or 1)
gui:Hide()
private.isAttached = nil
end
function lib.CreateAuctionFrames()
if not lib.GetSetting("global.createtab") then return end
local frame = CreateFrame("Frame", "AucAdvSearchUiAuctionFrame", AuctionFrame)
gui.AuctionFrame = frame
frame:SetParent(AuctionFrame)
frame:SetPoint("TOPLEFT", AuctionFrame, "TOPLEFT")
frame:SetPoint("BOTTOMRIGHT", AuctionFrame, "BOTTOMRIGHT")
frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
frame.title:SetPoint("TOP", frame, "TOP", 20, -17)
frame.title:SetText("SearchUI - Auction search interface")
local myTabName = "AuctionFrameTabUtilSearchUi"
frame.tab = CreateFrame("Button", myTabName, AuctionFrame, "AuctionTabTemplate")
frame.tab:SetText(TAB_NAME)
frame.tab:Show()
function frame.tab.OnClick(self, button, down)
local index = self:GetID()
local tab = _G["AuctionFrameTab"..index]
if (tab and tab:GetName() == myTabName) then
AuctionFrameTopLeft:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameTopLeft")
AuctionFrameTop:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameTopMid")
AuctionFrameTopRight:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameTopRight")
AuctionFrameBotLeft:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameBotLeft")
AuctionFrameBot:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameBotMid")
AuctionFrameBotRight:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\AuctionFrameBotRight")
AuctionFrameMoneyFrame:Hide()
frame:Show()
lib.AttachToAH()
else
AuctionFrameMoneyFrame:Show()
frame:Hide()
lib.DetachFromAH()
end
end
PanelTemplates_DeselectTab(frame.tab)
AucAdvanced.AddTab(frame.tab, frame)
hooksecurefunc("AuctionFrameTab_OnClick", frame.tab.OnClick)
frame.money = frame:CreateTexture(nil, "ARTWORK")
frame.money:SetTexture("Interface\\AddOns\\Auc-Advanced\\Textures\\GoldMoney")
frame.money:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 18, 34)
frame.money:SetWidth(256)
frame.money:SetHeight(32)
frame.backing = CreateFrame("Frame", nil, frame)
frame.backing:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -70)
frame.backing:SetPoint("BOTTOMRIGHT", frame.money, "TOPLEFT", 145, 50)
frame.backing:SetBackdrop({ bgFile="Interface\\AddOns\\Auc-Advanced\\Textures\\BlackBack", edgeFile="Interface\\AddOns\\Auc-Advanced\\Textures\\WhiteCornerBorder", tile=1, tileSize=8, edgeSize=8, insets={left=3, right=3, top=3, bottom=3} })
frame.backing:SetBackdropColor(0,0,0, 0.60)
frame.scanslabel = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame.scanslabel:SetPoint("TOPLEFT", frame, "TOPLEFT", 72, -20)
frame.scanslabel:SetText("Pending Scans")
frame.scanscount = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame.scanscount:ClearAllPoints()
frame.scanscount:SetPoint("LEFT", frame.scanslabel, "RIGHT", 5, 0)
frame.scanscount:SetText("0")
frame.scanscount:SetJustifyH("RIGHT")
frame.scanscount.last = 0
function private.UpdateScanProgress(_, _, _, _, _, _, _, scansQueued)
if AucAdvanced.Scan.IsScanning() then
scansQueued = scansQueued + 1
end
if scansQueued ~= frame.scanscount.last then
frame.scanscount.last = scansQueued
frame.scanscount:SetText(scansQueued)
end
end
end
function lib.MakeGuiConfig()
if gui then return end
local Configator = LibStub("Configator")
local ScrollSheet = LibStub("ScrollSheet")
local id, last, cont
local selected
gui = Configator:Create(setter,getter, 900, 500, 5, 350, 20, 5)
gui:SetBackdropColor(0,0,0,1)
gui.expandGap = 25
gui.expandOnActivate = true
gui.autoScrollTabs = true
gui.searchers = {}
gui.AddSearcher = function (self, searchType, searchDetail, searchPos)
lib.AddSearcher(self, searchType, searchDetail, searchPos)
end
-- Only set scale if the gui isn't attached to the AH frame
gui.RealSetScale = gui.SetScale
function gui:SetScale(scale)
private.scale = scale
if private.isAttached then return end
gui:RealSetScale(scale)
end
-- hook ActivateTab to notify callback
gui.RealActivateTab = gui.ActivateTab
function gui:ActivateTab(...)
gui:RealActivateTab(...)
local newtab = gui.config.selectedTab
if newtab ~= gui.LastActiveTab then
gui.LastActiveTab = newtab
lib.NotifyCallbacks("selecttab", newtab)
end
gui.Search.updateDisplay()
end
private.gui = gui
-- common functions and scripthandlers, used by various buttons and frames
local function showTooltipText(button)
if lib.GetSetting("tooltiphelp.show") then
GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT")
GameTooltip:SetText(button.TooltipText)
end
end
local function hideTooltip()
GameTooltip:Hide()
end
gui.frame = CreateFrame("Frame", nil, gui)
gui.frame:SetPoint("TOP", gui, "TOP", 0, -115)
gui.frame:SetPoint("BOTTOMRIGHT", gui.Done, "TOPRIGHT", 0,25)
gui.frame:SetPoint("LEFT", gui:GetButton(1), "RIGHT", 5,0)
gui.frame:SetBackdrop({
bgFile = "Interface/Tooltips/ChatBubble-Background",
edgeFile = "Interface/Tooltips/ChatBubble-BackDrop",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 32, right = 32, top = 32, bottom = 32 }
})
gui.frame:SetBackdropColor(0, 0, 0, 1)
gui.saves = CreateFrame("Frame", nil, gui)
gui.saves:SetPoint("TOPRIGHT", gui, "TOPRIGHT", -5,-7)
gui.saves:SetPoint("LEFT", gui:GetButton(1), "RIGHT", 10,0)
gui.saves:SetHeight(28)
-- gui.saves:SetBackdrop({
-- bgFile = "Interface/Tooltips/ChatBubble-Background",
-- edgeFile = "Interface/Tooltips/ChatBubble-BackDrop",
-- tile = true, tileSize = 32, edgeSize = 18,
-- insets = { left = 20, right = 20, top = 20, bottom = 20 }
-- })
-- gui.saves:SetBackdropColor(0, 0, 0, 1)
gui.saves.title = gui.saves:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
gui.saves.title:SetPoint("LEFT", gui.saves, "LEFT", 10,0)
gui.saves.title:SetText("Saved searches:")
gui.saves.name = CreateFrame("EditBox", "SearchUiSaveName", gui.saves, "InputBoxTemplate")
gui.saves.name:SetPoint("LEFT", gui.saves.title, "RIGHT", 10,0)
gui.saves.name:SetAutoFocus(false)
gui.saves.name:SetWidth(200)
gui.saves.name:SetHeight(18)
gui.saves.name:SetScript("OnTextChanged", function() lib.UpdateSave() end)
if AucAdvancedData.UtilSearchUiData then
local curSearch = AucAdvancedData.UtilSearchUiData.Selected or ""
if AucAdvancedData.UtilSearchUiData.SavedSearches[curSearch] then
gui.saves.name:SetText(curSearch)
else
gui.saves.name:SetText("")
end
lib.LoadCurrent()
end
local SelectBox = LibStub:GetLibrary("SelectBox")
gui.saves.select = SelectBox:Create("SearchUiSaveSelect", gui.saves, 220, function(pos, key, value)
gui.saves.name:SetText(value)
end, function ()
local saves = AucAdvancedData.UtilSearchUiData.SavedSearches
local items = {}
if (saves) then
for name, sdata in keyPairs(saves) do
tinsert(items, name)
end
end
return items
end, "")
gui.saves.select:SetParent(gui.saves)
gui.saves.select:SetScale(0.999)
gui.saves.select:SetScale(1.0)
gui.saves.select:SetPoint("RIGHT", gui.saves.name, "RIGHT", 38,-4)
gui.saves.select:SetInputHidden(true)
gui.saves.load = CreateFrame("Button", nil, gui.saves, "OptionsButtonTemplate")
gui.saves.load:SetPoint("LEFT", gui.saves.name, "RIGHT", 25, 0)
gui.saves.load:SetWidth(70)
gui.saves.load:SetHeight(20)
gui.saves.load:SetText("Load")
gui.saves.load:SetScript("OnClick", function() lib.LoadSearch() end)
gui.saves.save = CreateFrame("Button", nil, gui.saves, "OptionsButtonTemplate")
gui.saves.save:SetPoint("LEFT", gui.saves.load, "RIGHT", 5, 0)
gui.saves.save:SetWidth(70)
gui.saves.save:SetHeight(20)
gui.saves.save:SetText("Save")
gui.saves.save:SetScript("OnClick", function() lib.SaveSearch() end)
gui.saves.delete = CreateFrame("Button", nil, gui.saves, "OptionsButtonTemplate")
gui.saves.delete:SetPoint("LEFT", gui.saves.save, "RIGHT", 5, 0)
gui.saves.delete:SetWidth(70)
gui.saves.delete:SetHeight(20)
gui.saves.delete:SetText("Delete")
gui.saves.delete:SetScript("OnClick", function() lib.DeleteSearch() end)
gui.saves.reset = CreateFrame("Button", nil, gui.saves, "OptionsButtonTemplate")
gui.saves.reset:SetPoint("LEFT", gui.saves.delete, "RIGHT", 10, 0)
gui.saves.reset:SetWidth(70)
gui.saves.reset:SetHeight(20)
gui.saves.reset:SetText("Reset")
gui.saves.reset:SetScript("OnClick", function()
if IsShiftKeyDown() and IsControlKeyDown() and IsAltKeyDown() then
lib.ResetSearch()
print("All searchUI settings have been reset.")
else
print("This resets all searchUI settings, you must hold CTRL + SHIFT + ALT when clicking this button")
end
end)
function lib.UpdateControls()
if gui.sheet.selected then
gui.frame.ignore:Enable()
gui.frame.ignoreperm:Enable()
gui.frame.notnow:Enable()
gui.frame.snatch:Enable()
else
gui.frame.ignore:Disable()
gui.frame.ignoreperm:Disable()
gui.frame.notnow:Disable()
gui.frame.snatch:Disable()
end
if selected ~= gui.sheet.selected then
selected = gui.sheet.selected
local data = gui.sheet:GetSelection()
if not data then
empty(private.data)
else
private.data.link = data[1]
private.data.seller = data[8]
private.data.stack = data[4]
private.data.bid = data[6]
private.data.minbid = data[12]
private.data.curbid = data[13]
private.data.buyout = data[5]
private.data.reason = data[7]
end
if private.data.buyout and (private.data.buyout > 0) then
gui.frame.buyout:Enable()
gui.frame.buyoutbox:SetText(AucAdvanced.Coins(private.data.buyout, true))
else
gui.frame.buyout:Disable()
gui.frame.buyoutbox:SetText(AucAdvanced.Coins(0, true))
end
if private.data.bid then
MoneyInputFrame_SetCopper(gui.frame.bidbox, private.data.bid)
gui.frame.bid:Enable()
else
MoneyInputFrame_SetCopper(gui.frame.bidbox, 0)
gui.frame.bid:Disable()
end
elseif private.data.curbid then--bid price was changed, so make sure that it's allowable
if MoneyInputFrame_GetCopper(gui.frame.bidbox) < ceil(private.data.curbid*1.05) then
MoneyInputFrame_SetCopper(gui.frame.bidbox, ceil(private.data.curbid*1.05))
end
gui.frame.bid:Enable()
end
--if bid >= buyout, it's going to be a buyout anyway, so disable bid button to indicate that
if private.data.buyout and (private.data.buyout > 0) and (MoneyInputFrame_GetCopper(gui.frame.bidbox) >= private.data.buyout) then
MoneyInputFrame_SetCopper(gui.frame.bidbox, private.data.buyout)
gui.frame.bid:Disable()
end
gui.frame.purchase.updateEnable()
end
function lib.OnEnterSheet(button, row, index)
if gui.sheet.rows[row][index]:IsShown() then --Hide tooltip for hidden cells
local link, count
link = gui.sheet.rows[row][index]:GetText()
if link and link:find("\124Hitem:%d") then
if gui.sheet.order then
for i, label in pairs(gui.sheet.labels) do
if label:GetText() == "Stk" then --need to localize this when we localize the rest of searchUI
count = tonumber(gui.sheet.rows[row][i]:GetText())
break
end
end
else
count = tonumber(gui.sheet.rows[row][4]:GetText() )
end
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
AucAdvanced.ShowItemLink(GameTooltip, link, count)
end
end
end
function lib.OnClickSheet(button, row, index)
index = index - (index%15-1)
if IsShiftKeyDown() then --Add the item link to chat
local link = gui.sheet.rows[row][index]:GetText()
if not link then
return
end
ChatEdit_InsertLink(link)
elseif IsAltKeyDown() then --Search for the item in browse tab.
local name = gui.sheet.rows[row][index]:GetText()
if not name then
return
end
name = GetItemInfo(name)
QueryAuctionItems(name)
end
end
--records the column width changes
--store width by header name, that way if column reorginizing is added we apply size to proper column
function private.OnResizeSheet(self, column, width)
if not width then
lib.SetSetting("columnwidth."..self.labels[column]:GetText(), "default") --reset column if no width is passed. We use CTRL+rightclick to reset column
self.labels[column].button:SetWidth(lib.GetSetting("columnwidth."..self.labels[column]:GetText()))
else
lib.SetSetting("columnwidth."..self.labels[column]:GetText(), width)
end
end
gui.sheet = ScrollSheet:Create(gui.frame, {
{ "Item", "TOOLTIP", lib.GetSetting("columnwidth.Item") }, --120
{ "Pct", "INT", lib.GetSetting("columnwidth.Pct") }, --30
{ "Profit", "COIN", lib.GetSetting("columnwidth.Profit") , { DESCENDING=true } }, --85
{ "Stk", "INT", lib.GetSetting("columnwidth.Stk") }, --30
{ "Buyout", "COIN", lib.GetSetting("columnwidth.Buyout"), { DESCENDING=true } }, --85
{ "Bid", "COIN", lib.GetSetting("columnwidth.Bid"), { DESCENDING=true } }, --85
{ "Reason", "TEXT", lib.GetSetting("columnwidth.Reason") }, --85
{ "Seller", "TEXT", lib.GetSetting("columnwidth.Seller") }, --75
{ "Left", "TEXT", lib.GetSetting("columnwidth.Left") }, --40
{ "Buy/ea", "COIN", lib.GetSetting("columnwidth.Buy/ea"), { DESCENDING=true, DEFAULT=true } }, --85
{ "Bid/ea", "COIN", lib.GetSetting("columnwidth.Bid/ea"), { DESCENDING=true, DEFAULT=true } }, --85
{ "MinBid", "COIN", lib.GetSetting("columnwidth.MinBid"), { DESCENDING=true } }, --85
{ "CurBid", "COIN", lib.GetSetting("columnwidth.CurBid"), { DESCENDING=true } }, --85
{ "Min/ea", "COIN", lib.GetSetting("columnwidth.Min/ea"), { DESCENDING=true } }, --85
{ "Cur/ea", "COIN", lib.GetSetting("columnwidth.Cur/ea"), { DESCENDING=true } }, --85
})
gui.sheet:EnableSelect(true)
gui.sheet:EnableVerticalScrollReset(false) --tells scrollframes we do NOT want to reset position when rendering a new data table
--If we have a saved order reapply
if lib.GetSetting("columnorder") then
--print("saved order applied")
gui.sheet:SetOrder(lib.GetSetting("columnorder") )
end
--Apply last column sort used
if lib.GetSetting("columnsortcurSort") then
gui.sheet.curSort = lib.GetSetting("columnsortcurSort") or 1
gui.sheet.curDir = lib.GetSetting("columnsortcurDir") or 1
gui.sheet:PerformSort()
end
--After we have finished creating the scrollsheet and all saved settings have been applied set our event processor
function gui.sheet.Processor(callback, self, button, column, row, order, curDir, ...)
if (callback == "ColumnOrder") then
lib.SetSetting("columnorder", order)
elseif (callback == "ColumnWidthSet") then
private.OnResizeSheet(self, column, button:GetWidth() )
elseif (callback == "ColumnWidthReset") then
private.onResize(self, column, nil)
elseif (callback == "OnEnterCell") then
lib.OnEnterSheet(button, row, column)
elseif (callback == "OnLeaveCell") then
GameTooltip:Hide()
elseif (callback == "OnClickCell") then
lib.OnClickSheet(button, row, column)
elseif (callback == "ColumnSort") then
lib.SetSetting("columnsortcurDir", curDir)
lib.SetSetting("columnsortcurSort", column)
elseif (callback == "OnMouseDownCell") then
lib.UpdateControls()
end
end
gui.Search = CreateFrame("Button", "AucSearchUISearchButton", gui, "OptionsButtonTemplate")
gui.Search:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 30, 50)
gui.Search:SetText("Search")
gui.Search:SetScript("OnClick", lib.PerformSearch)
gui.Search:SetFrameLevel(11)
gui.Search.TooltipText = "Search Snapshot using current Searcher"
gui.Search:SetScript("OnEnter", showTooltipText)
gui.Search:SetScript("OnLeave", hideTooltip)
gui.Search:Disable()
gui.Search.updateDisplay = function()
if gui.config.selectedCat == "Searchers" then
gui.Search:Enable()
else
gui.Search:Disable()
end
end
gui:AddCat("Welcome")
id = gui:AddTab("About")
gui.aboutTab = id
gui:MakeScrollable(id)
gui:AddControl(id, "Subhead", 0, "About the SearchUI")
gui:AddCat("Searchers", nil, nil, true)
gui:AddCat("Filters")
gui:AddCat("Options")
id = gui:AddTab("General Options", "Options")
gui:MakeScrollable(id)
gui:AddControl(id, "Header", 0, "Setup general options")
gui:AddControl(id, "WideSlider", 0, 1, "processpriority", 10, 100, 10, "Search process priority: %s")
gui:AddControl(id, "Subhead", 0, "Purchase Settings")
gui:AddControl(id, "Checkbox", 0, 1, "reserve.enable", "Enable reserve amount:")
gui:AddControl(id, "MoneyFramePinned", 0, 2, "reserve", 0, 99999999, "Reserve Amount")
gui:AddTip(id, "Sets the amount that you don't want your cash-on-hand to fall below")
gui:AddControl(id, "Checkbox", 0, 1, "maxprice.enable", "Enable maximum price:")
gui:AddControl(id, "MoneyFramePinned", 0, 2, "maxprice", 1, 99999999, "Maximum Price")
gui:AddTip(id, "Sets the amount that you don't want to spend more than")
id = gui:AddTab("Global Settings", "Settings")
gui:MakeScrollable(id)
gui:AddControl(id, "Header", 0, "Setup global options")
gui:AddControl(id, "Subhead", 0, "Tooltip")
gui:AddControl(id, "Checkbox", 0, 1, "tooltiphelp.show", "Show tooltip help over buttons")
gui:AddControl(id, "Checkbox", 0, 1, "debug.show", "Show debug line in tooltip for auctions")
for name, searcher in pairs(lib.Searchers) do
if searcher and searcher.Search then
gui:AddControl(id, "Checkbox", 0, 2, "debug."..name, "Show debug for "..name)
gui:AddTip(id, "Show a debug line in the tooltip over auctions for searcher: "..name)
end
end
gui:AddControl(id, "Subhead", 0, "Integration")
gui:AddControl(id, "Checkbox", 0, 1, "global.createtab", "Create tab in auction house (requires restart)")
--gui:SetScript("OnKeyDown", lib.UpdateControls)
gui.frame.purchase = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.purchase:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 170, 35)
gui.frame.purchase:SetText("Purchase")
gui.frame.purchase:SetScript("OnClick", private.purchase)
gui.frame.purchase:Disable()
gui.frame.purchase.TooltipText = "Bid/BuyOut selected auction\nbased on 'reason' column. \nHold CTRL+ALT+SHIFT to purchase all items."
gui.frame.purchase:SetScript("OnEnter", showTooltipText)
gui.frame.purchase:SetScript("OnLeave", hideTooltip)
gui.frame.purchase.toggleAll = false
gui.frame.purchase.updateEnable = function()
if gui.frame.purchase.toggleAll then
if gui.sheet.sort[1] then
gui.frame.purchase:Enable()
else
gui.frame.purchase:Disable()
end
else
if (gui.frame.bid:IsEnabled()==1) or (gui.frame.buyout:IsEnabled()==1) then
gui.frame.purchase:Enable()
else
gui.frame.purchase:Disable()
end
end
end
gui.frame.purchase.updateDisplay = function()
local all = IsShiftKeyDown() and IsControlKeyDown() and IsAltKeyDown()
if all ~= gui.frame.purchase.toggleAll then
gui.frame.purchase.toggleAll = all
if all then
gui.frame.purchase:SetText("Purchase All")
gui.frame.purchase:SetScript("OnClick", private.purchaseall)
else
gui.frame.purchase:SetText("Purchase")
gui.frame.purchase:SetScript("OnClick", private.purchase)
end
end
gui.frame.purchase.updateEnable()
end
Stubby.RegisterEventHook("MODIFIER_STATE_CHANGED", "Auc-Util-SearchUI", gui.frame.purchase.updateDisplay)
gui.frame.notnow = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.notnow:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 260, 35)
gui.frame.notnow:SetText("Not Now")
gui.frame.notnow:SetScript("OnClick", private.ignoretemp)
gui.frame.notnow:Disable()
gui.frame.notnow.TooltipText = "Ignore selected auction for session"
gui.frame.notnow:SetScript("OnEnter", showTooltipText)
gui.frame.notnow:SetScript("OnLeave", hideTooltip)
gui.frame.ignore = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.ignore:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 400, 35)
gui.frame.ignore:SetText("Ignore Price")
gui.frame.ignore:SetScript("OnClick", private.ignore)
gui.frame.ignore:Disable()
gui.frame.ignore.TooltipText = "Ignore selected auction at listed price"
gui.frame.ignore:SetScript("OnEnter", showTooltipText)
gui.frame.ignore:SetScript("OnLeave", hideTooltip)
gui.frame.ignoreperm = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.ignoreperm:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 490, 35)
gui.frame.ignoreperm:SetText("Ignore")
gui.frame.ignoreperm:SetScript("OnClick", private.ignoreperm)
gui.frame.ignoreperm:Disable()
gui.frame.ignoreperm.TooltipText = "Ignore selected auction at any price"
gui.frame.ignoreperm:SetScript("OnEnter", showTooltipText)
gui.frame.ignoreperm:SetScript("OnLeave", hideTooltip)
gui.frame.snatch = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.snatch:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 630, 35)
gui.frame.snatch:SetText("Snatch")
gui.frame.snatch:SetScript("OnClick", private.snatch)
gui.frame.snatch:Disable()
gui.frame.snatch.TooltipText = "Add selected auction to snatch list"
gui.frame.snatch:SetScript("OnEnter", showTooltipText)
gui.frame.snatch:SetScript("OnLeave", hideTooltip)
gui.frame.clear = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.clear:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 170, 10)
gui.frame.clear:SetText("Clear")
gui.frame.clear:SetScript("OnClick", private.removeall)
gui.frame.clear:Enable()
gui.frame.clear.TooltipText = "Clear results list"
gui.frame.clear:SetScript("OnEnter", showTooltipText)
gui.frame.clear:SetScript("OnLeave", hideTooltip)
gui.frame.cancel = CreateFrame("Button", "AucAdvSearchUICancelButton", gui.frame, "OptionsButtonTemplate")
gui.frame.cancel:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 30, 30)
gui.frame.cancel:SetWidth(22)
gui.frame.cancel:SetHeight(18)
gui.frame.cancel:Disable()
gui.frame.cancel:SetScript("OnClick", function()
AucAdvanced.Buy.CancelBuyQueue(true)
gui.frame.cancel.value = 0
end)
gui.frame.cancel.value = 0
private.UpdateBuyQueue = function ()
local queuelen, queuecost, prompt, promptcost = AucAdvanced.Buy.GetQueueStatus()
if prompt then
queuelen = queuelen + 1
queuecost = queuecost + promptcost
end
if queuelen > 0 then
gui.frame.cancel.label:SetText(tostring(queuelen)..": "..AucAdvanced.Coins(queuecost, true))
gui.frame.cancel.value = queuecost
gui.frame.cancel:Enable()
gui.frame.cancel.tex:SetVertexColor(1.0, 0.9, 0.1)
else
gui.frame.cancel.label:SetText("")
gui.frame.cancel.value = 0
gui.frame.cancel:Disable()
gui.frame.cancel.tex:SetVertexColor(0.3, 0.3, 0.3)
end
end
gui.frame.cancel.tex = gui.frame.cancel:CreateTexture(nil, "OVERLAY")
gui.frame.cancel.tex:SetPoint("TOPLEFT", gui.frame.cancel, "TOPLEFT", 4, -2)
gui.frame.cancel.tex:SetPoint("BOTTOMRIGHT", gui.frame.cancel, "BOTTOMRIGHT", -4, 2)
gui.frame.cancel.tex:SetTexture("Interface\\Addons\\Auc-Advanced\\Textures\\NavButtons")
gui.frame.cancel.tex:SetTexCoord(0.25, 0.5, 0, 1)
gui.frame.cancel.tex:SetVertexColor(0.3, 0.3, 0.3)
gui.frame.cancel.label = gui.frame.cancel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
gui.frame.cancel.label:SetPoint("LEFT", gui.frame.cancel, "RIGHT", 5, 0)
gui.frame.cancel.label:SetTextColor(1, 0.8, 0)
gui.frame.cancel.label:SetText("")
gui.frame.cancel.label:SetJustifyH("LEFT")
gui.frame.buyout = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.buyout:SetPoint("BOTTOMLEFT", gui, "BOTTOMLEFT", 650, 10)
gui.frame.buyout:SetText("Buyout")
gui.frame.buyout:SetScript("OnClick", private.buyauction)
gui.frame.buyout:Disable()
gui.frame.buyout.TooltipText = "Buyout selected auction"
gui.frame.buyout:SetScript("OnEnter", showTooltipText)
gui.frame.buyout:SetScript("OnLeave", hideTooltip)
gui.frame.buyoutbox = gui.frame.buyout:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
gui.frame.buyoutbox:SetPoint("BOTTOMRIGHT", gui.frame.buyout, "BOTTOMLEFT", -4, 4)
gui.frame.buyoutbox:SetWidth(100)
gui.frame.bid = CreateFrame("Button", nil, gui.frame, "OptionsButtonTemplate")
gui.frame.bid:SetPoint("BOTTOMRIGHT", gui.frame.buyoutbox, "BOTTOMLEFT", -10, -4)
gui.frame.bid:SetText("Bid")
gui.frame.bid:SetScript("OnClick", private.bidauction)
gui.frame.bid:Disable()
gui.frame.bid.TooltipText = "Bid on selected auction using custom price"
gui.frame.bid:SetScript("OnEnter", showTooltipText)
gui.frame.bid:SetScript("OnLeave", hideTooltip)
gui.frame.bidbox = CreateFrame("Frame", "AucAdvSearchUIBidBox", gui.frame, "MoneyInputFrameTemplate")
gui.frame.bidbox:SetPoint("BOTTOMRIGHT", gui.frame.bid, "BOTTOMLEFT", -4, 4)
MoneyInputFrame_SetOnValueChangedFunc(gui.frame.bidbox, lib.UpdateControls)
gui.frame.progressbar = CreateFrame("STATUSBAR", nil, gui.frame, "TextStatusBar")
gui.frame.progressbar:SetWidth(400)
gui.frame.progressbar:SetHeight(30)
gui.frame.progressbar:SetPoint("BOTTOM", gui.frame, "BOTTOM", 0, 100)
gui.frame.progressbar:SetBackdrop({
bgFile="Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
tile=1, tileSize=10, edgeSize=10,
insets={left=3, right=3, top=3, bottom=3}
})
gui.frame.progressbar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
gui.frame.progressbar:SetStatusBarColor(0.6, 0, 0, 0.4)
gui.frame.progressbar:SetMinMaxValues(0, 1000)
gui.frame.progressbar:SetValue(0)
gui.frame.progressbar:SetFrameLevel(10)
gui.frame.progressbar:Hide()
gui.frame.progressbar.text = gui.frame.progressbar:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
gui.frame.progressbar.text:SetPoint("CENTER", gui.frame.progressbar, "CENTER")
gui.frame.progressbar.text:SetText("AucAdv SearchUI: Searching")
gui.frame.progressbar.text:SetTextColor(1,1,1)
gui.frame.progressbar.cancel = CreateFrame("Button", nil, gui.frame.progressbar, "OptionsButtonTemplate")
gui.frame.progressbar.cancel:SetPoint("BOTTOMRIGHT", gui.frame.progressbar, "BOTTOMRIGHT", -5, 5)
gui.frame.progressbar.cancel:SetPoint("TOPLEFT", gui.frame.progressbar, "TOPRIGHT", -25, -5)
gui.frame.progressbar.cancel:SetText("X")
gui.frame.progressbar.cancel:SetScript("OnClick", private.cancelSearch)
-- Alert our searchers?
for name, searcher in pairs(lib.Searchers) do
if searcher.MakeGuiConfig then
searcher:MakeGuiConfig(gui)
end
end
--Alert our Filters
for name, filter in pairs(lib.Filters) do
if filter.MakeGuiConfig then
filter:MakeGuiConfig(gui)
end
end
lib.NotifyCallbacks('guiconfig', gui)
-- Add the welcome text now
local b = " |TInterface\\QuestFrame\\UI-Quest-BulletPoint.blp:13|t "
local w = ""
w=w.."The Auctioneer Search UI is here to assist you in finding the Auctions that are of special interest to you.\n"
w=w.."\n"
w=w.."It has 2 modes of operation:\n"
w=w..b.."Offline - Searches are applied against the current data\n"
w=w..b.."Realtime - Searches are applied against the realtime scans of the AH\n"
w=w.."\n"
w=w.."There are also 2 types of searching modules that exist in the Search UI:\n"
w=w..b.."Searchers - Searches for a specific set of criteria, only 1 searcher is active at once\n"
w=w..b.."Filters - All filters always apply their criteria, excluding non-matching items from the search.\n"
w=w.."\n"
w=w.."In order to begin using the Search UI, you should first setup your filters to exclude the items you don't wish to find, then select a searcher to perform a search.\n"
w=w.."\n"
w=w.."Here's a quick list of the searchers and filters that you may wish to investigate:\n"
for pos, sdata in keyPairs(gui.searchers) do
for searchType, searchDetail in keyPairs(sdata) do
w=w..b.."|cffffce00"..searchType.."|r - "..searchDetail.."\n"
end
end
gui:AddControl(gui.aboutTab, "Note", 0, 1, nil, nil, w)
gui:ActivateTab(gui.aboutTab)
end
if LibStub then
--Need to figure out if we're embedded first
local embedded = false
for _, module in ipairs(AucAdvanced.EmbeddedModules) do
if module == "Auc-Util-SearchUI" then
embedded = true
end
end
local sideIcon
if embedded then
sideIcon = "Interface\\AddOns\\Auc-Advanced\\Modules\\Auc-Util-SearchUI\\Textures\\SearchUIIcon"
else
sideIcon = "Interface\\AddOns\\Auc-Util-SearchUI\\Textures\\SearchUIIcon"
end
local LibDataBroker = LibStub:GetLibrary("LibDataBroker-1.1", true)
if LibDataBroker then
private.LDBButton = LibDataBroker:NewDataObject("Auc-Util-SearchUI", {
type = "launcher",
icon = sideIcon,
OnClick = function(self, button) lib.Toggle(self, button) end,
})
function private.LDBButton:OnTooltipShow()
self:AddLine("Auction SearchUI", 1,1,0.5, 1)
self:AddLine("Allows you to perform searches on the Auctioneer auction cache snapshot, even when away from the Auction House", 1,1,0.5, 1)
self:AddLine("|cff1fb3ff".."Click|r to open the Search UI.", 1,1,0.5, 1)
end
function private.LDBButton:OnEnter()
GameTooltip:SetOwner(self, "ANCHOR_NONE")
GameTooltip:SetPoint("TOPLEFT", self, "BOTTOMLEFT")
GameTooltip:ClearLines()
private.LDBButton.OnTooltipShow(GameTooltip)
GameTooltip:Show()
end
function private.LDBButton:OnLeave()
GameTooltip:Hide()
end
end
end
function private.FindSearcher(item)
if not gui.config.selectedTab then
return
end
for name, searcher in pairs(lib.Searchers) do
if searcher and searcher.tabname and searcher.tabname == gui.config.selectedTab and searcher.Search then
return searcher, name
end
end
end
function private.cancelSearch()
private.SearchCancel = true
end
--lib.SearchItem(searcherName, item, nodupes)
--purpose: handles sending the item to the specified searcher, and if necessary, adds it to the SearchUI results
--nodupes is boolean flag. If true, no duplicate checking is done. This flag is true for searching from the cache, but false for realtime.
--skipresults is boolean flag, If true, nothing gets added to the results list
--returns true, value, profit when successful
--returns false, reason when not
function lib.SearchItem(searcherName, item, nodupes, skipresults)
if not searcherName or not item or #item == 0 then
return
end
if item[Const.SELLER] == UnitName("player") then
return false, "Blocked: Can't buy own auction"
end
local searcher = lib.Searchers[searcherName]
if not searcher then
return
end
local debugstring
--next, pass the item through the filters
local isfiltered = false
for filtername, filter in pairs(lib.Filters) do
if filter.Filter then
local dofilter, filterreturn = filter.Filter(item, searcherName)
if dofilter then
return false, "Filter:"..filtername..": "..tostring(filterreturn)
end
end
end
--buyorbid must be either "bid", "buy", true, false, or nil
--if string is returned for buyorbid, value must be number or nil (in which case value will be Marketprice)
local buyorbid, value, pct, reason
buyorbid, value, pct, reason = searcher.Search(item)
if buyorbid then
--give the filters a second chance to filter out, based on bid/buy differences
for filtername, filter in pairs(lib.Filters) do
if filter.PostFilter then
local dofilter, filterreturn = filter.PostFilter(item, searcherName, buyorbid)
if dofilter then
return false, "Filtered by "..filtername..": "..filterreturn
end
end
end
local cost
if type(buyorbid) == "string" then
item["reason"] = searcher.tabname..":"..buyorbid
if reason then
item["reason"] = item["reason"]..":"..reason
end
if buyorbid == "bid" then
--don't show result if we're already the highest bidder
if item[Const.AMHIGH] then
return false, "Bid blocked: Already high bidder"
end
cost = item[Const.PRICE]
else
cost = item[Const.BUYOUT]
end
else --the searcher only returned that it matches the criteria, so assume buyout if possible.
item["reason"] = searcher.tabname
if item[Const.BUYOUT] and item[Const.BUYOUT] > 0 then
cost = item[Const.BUYOUT]
elseif item[Const.PRICE] and item[Const.PRICE] > 0 then
cost = item[Const.PRICE]
if item[Const.AMHIGH] then
return false, "Bid blocked: Already high bidder"
end
end
end
if not value then
local market = AucAdvanced.API.GetMarketValue(item[Const.LINK])
if market then -- needs a nil check
value = item[Const.COUNT]*market
end
end
if not value then
value = 0
end
if not cost then
return false, "Bid blocked: No valid price possible"
end
item["profit"] = value - cost
local enablemax = lib.GetSetting("maxprice.enable")
local maxprice = lib.GetSetting("maxprice") or 10000000
local enableres = lib.GetSetting("reserve.enable")
local reserve = lib.GetSetting("reserve") or 1
local bidqueue = gui.frame.cancel.value or 0
local balance = GetMoney()
balance = balance - bidqueue --account for money we've already "spent"
if (cost <= maxprice or not enablemax) and ((balance-cost) > reserve or not enableres) then
--Check to see whether the item already exists in the results table
local isdupe = false
if not nodupes then
if not private.sheetData then
private.sheetData = {}
private.sheetStyle = {}
end
for j,k in pairs(private.sheetData) do
if (k[1] == item[Const.LINK]) and (k[7] == item["reason"]) then
isdupe = true
end
end
end
if nodupes or (not isdupe) then
local level, _, r, g, b
pct = tonumber(pct) --make sure its not a string
if not pct and AucAdvanced.Modules.Util.PriceLevel then
local valueper
if value and value > 0 then
valueper = value/item[Const.COUNT]
end
if buyorbid == "bid" then
level, _, r, g, b = AucAdvanced.Modules.Util.PriceLevel.CalcLevel(item[Const.LINK], item[Const.COUNT], item[Const.PRICE], item[Const.PRICE], valueper)
else
level, _, r, g, b = AucAdvanced.Modules.Util.PriceLevel.CalcLevel(item[Const.LINK], item[Const.COUNT], item[Const.PRICE], item[Const.BUYOUT], valueper)
end
if not r or not b or not g then
--print("price level failure in searchUI")
--print(r,g,b, item[Const.LINK], item[Const.COUNT], item[Const.PRICE], item[Const.BUYOUT], valueper)
r,g,b = 1,1,1
end
local total = #private.sheetData+1
private.sheetStyle[total] = {}
private.sheetStyle[total][2] = {["textColor"] = {r, g, b}}
private.sheetStyle[total][1] = {["rowColor"] = {r, g, b, 0, 0.2, "Horizontal"}} --allow row coloring, needs config options
level = level or 0
pct = floor(level)
end
item["pct"] = pct
item["cost"] = cost
local count = item[Const.COUNT] or 1
local min = item[Const.MINBID] or 0
local cur = item[Const.CURBID] or 0
local buy = item[Const.BUYOUT] or 0
local price = item[Const.PRICE] or 0
if not skipresults then
tinsert(private.sheetData, {
item[Const.LINK],
item["pct"],
item["profit"],
count,
buy,
price,
item["reason"],
item[Const.SELLER],
private.tleft[item[Const.TLEFT]],
buy/count,
price/count,
min,
cur,
min/count,
cur/count
})
end
return true, item["profit"], value
end
elseif cost > maxprice and enablemax then
return false, "Price higher than maxprice"
else
return false, "Balance lower than reserve"
end
end
return false, value
end
local PerformSearch = function()
if gui.tabs.active then
gui:ContractFrame(gui.tabs.active)
end
gui:ClearFocus()
--Perform the search. We're not using API.QueryImage() because we need it to be a coroutine
local image = AucAdvanced.Scan.GetImageCopy()
local imagesize = #image
local speed = lib.GetSetting("processpriority") or 50
speed = (speed / 100)^2.5
local processingTime = speed * 0.1 + 0.02
local GetTime = GetTime
local nextPause = GetTime() + processingTime
local searcher, searcherName = private.FindSearcher()
if not searcher then
print("No valid Searches selected")
return
end
gui.frame.progressbar.text:SetText("AucAdv SearchUI: Searching |cffffcc19"..gui.config.selectedTab)
gui.frame.progressbar:Show()
--clear the results table
private.removeall()
local repaintSheet = false
local nextRepaint = 0 -- can do it immediately
private.isSearching = true
AucAdvanced.SendProcessorMessage("searchbegin", searcherName)
lib.NotifyCallbacks("search", "begin", searcherName)
for i, data in ipairs(image) do
if GetTime() > nextPause then
gui.frame.progressbar:SetValue((i/imagesize)*1000)
coroutine.yield()
nextPause = GetTime() + processingTime
if private.SearchCancel then
private.SearchCancel = nil
break
end
if repaintSheet and GetTime()>=nextRepaint then
local b=GetTime()
private.repaintSheet()
repaintSheet = false
local e=GetTime()
nextRepaint = e + ((e-b)*10) -- only let repainting consume 10% of our total CPU
end
end
if lib.SearchItem(searcher.name, data, true) then
repaintSheet = true
end
end
private.repaintSheet()
private.isSearching = false
empty(SettingCache)
gui.frame.progressbar:Hide()
AucAdvanced.SendProcessorMessage("searchcomplete", searcherName)
lib.NotifyCallbacks("search", "complete", searcherName)
end
function lib.IsSearching()
return private.isSearching
end
function lib.PerformSearch(searcher)
if (not coSearch) or (coroutine.status(coSearch) == "dead") then
coSearch = coroutine.create(PerformSearch)
local status, result = coroutine.resume(coSearch, searcher)
if not status and result then
error("Error in search coroutine: "..result.."\n\n{{{Coroutine Stack:}}}\n"..debugstack(coSearch));
end
else
print("coroutine already running: "..coroutine.status(coSearch))
end
end
function private.OnUpdate(self, elapsed)
if coSearch then
if coroutine.status(coSearch) == "suspended" then
local status, result = coroutine.resume(coSearch)
if not status and result then
error("Error in search coroutine: "..result.."\n\n{{{Coroutine Stack:}}}\n"..debugstack(coSearch));
end
elseif coroutine.status(coSearch) == "dead" then
coSearch = nil
end
end
if flagResourcesUpdateRequired then
-- Update Faction resources following Auctionhouse open or close (to handle Neutral AH)
-- Delayed until OnUpdate handler to give GetFaction time to update its own internal settings
flagResourcesUpdateRequired = false
private.UpdateFactionResources()
end
if flagScanStats then
flagScanStats = false
lib.NotifyCallbacks("postscanupdate")
end
end
private.updater = CreateFrame("Frame", nil, UIParent)
private.updater:SetScript("OnUpdate", private.OnUpdate)
AucAdvanced.RegisterRevision("$URL: http://svn.norganna.org/auctioneer/branches/5.9/Auc-Util-SearchUI/SearchMain.lua $", "$Rev: 4933 $")