diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index b0b6358..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,6 +0,0 @@
-[submodule "libs/LibItemSearch-1.0"]
- path = libs/LibItemSearch-1.0
- url = git@github.com:Tuller/LibItemSearch-1.0.git
-[submodule "libs/LibStub"]
- path = libs/LibStub
- url = git://github.com/p3lim/LibStub.git
diff --git a/GnomishVendorShrinker.lua b/GnomishVendorShrinker.lua
index c76340f..cdb6716 100644
--- a/GnomishVendorShrinker.lua
+++ b/GnomishVendorShrinker.lua
@@ -1,3 +1,4 @@
+
local ItemSearch = LibStub('LibItemSearch-1.0')
local myname, ns = ...
ns.IHASCAT = select(4, GetBuildInfo()) >= 40000
@@ -167,6 +168,7 @@ local rows = {}
for i=1,NUMROWS do
local row = CreateFrame('Button', nil, GVS) -- base frame
row:SetHeight(ROWHEIGHT)
+ row:SetPoint("TOP", r == 1 and GVS or rows[r-1], r == 1 and "TOP" or "BOTTOM")
row:SetPoint("LEFT")
row:SetPoint("RIGHT", -19, 0)
@@ -246,15 +248,14 @@ local grads = setmetatable({
[4] = {1,0,1,0.75, 1,0,1,0}, -- purple
[7] = {1,.75,.5,0.75, 1,.75,.5,0}, -- heirloom
}, {__index = function(t,i) t[i] = default_grad return default_grad end})
-local RECIPE = select(7, GetAuctionItemClasses())
+local _, _, _, _, _, _, RECIPE = GetAuctionItemClasses()
local quality_colors = setmetatable({}, {__index = function() return "|cffffffff" end})
for i=1,7 do quality_colors[i] = select(4, GetItemQualityColor(i)) end
-local ShowMerchantItem = function (r, i)
+local function ShowMerchantItem(row, i)
local name, itemTexture, itemPrice, itemStackCount, numAvailable, isUsable, extendedCost = GetMerchantItemInfo(i)
local link = GetMerchantItemLink(i)
local color = quality_colors.default
- local row = rows[r]
row.backdrop:Hide()
if link then
local name, link2, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(link)
@@ -297,32 +298,32 @@ local ShowMerchantItem = function (r, i)
if isUsable then row.icon:SetVertexColor(1, 1, 1) else row.icon:SetVertexColor(.9, 0, 0) end
row:SetID(i)
row:Show()
- row:SetPoint("TOP", r == 1 and GVS or rows[r-1], r == 1 and "TOP" or "BOTTOM")
end
+
local scrollbar = LibStub("tekKonfig-Scroll").new(GVS, 0, SCROLLSTEP)
local offset = 0
local searchstring
local function Refresh()
local n = GetMerchantNumItems()
- local r = 1
- local v = 0
+ local row, n_searchmatch = 1, 0
for i=1,n do
local link = GetMerchantItemLink(i)
if ItemSearch:Find(link, searchstring) then
- if v >= offset and v < offset + NUMROWS then
- ShowMerchantItem(r, i)
- r = r + 1
+ if n_searchmatch >= offset and n_searchmatch < offset + NUMROWS then
+ ShowMerchantItem(rows[row], i)
+ row = row + 1
end
- v = v + 1
+ n_searchmatch = n_searchmatch + 1
end
end
- scrollbar:SetMinMaxValues(0, math.max(0, v - NUMROWS))
- for i=r,NUMROWS do
+ scrollbar:SetMinMaxValues(0, math.max(0, n_searchmatch - NUMROWS))
+ for i=row,NUMROWS do
rows[i]:Hide()
end
end
+
local editbox = CreateFrame('EditBox', nil, GVS)
editbox:SetAutoFocus(false)
editbox:SetPoint("TOPLEFT", GVS, "BOTTOMLEFT", 0, -51)
diff --git a/embeds.xml b/embeds.xml
index 01090f6..f4909a5 100644
--- a/embeds.xml
+++ b/embeds.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/libs/LibItemSearch-1.0 b/libs/LibItemSearch-1.0
deleted file mode 160000
index ccbc28b..0000000
--- a/libs/LibItemSearch-1.0
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ccbc28bfd62519fa4fe584739a83e33307a67853
diff --git a/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua b/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua
new file mode 100644
index 0000000..27a0a78
--- /dev/null
+++ b/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua
@@ -0,0 +1,444 @@
+--[[
+ ItemSearch
+ An item text search engine of some sort
+
+ Grammar:
+ :=
+ := & ;
+ := | ;
+ := ! ;
+ := ; ; ;
+ := bop ; boa ; bou ; boe ; quest
+ := q ; q
+ := ilvl
+ := t:
+ :=
+ := : | = | == | != | ~= | < | > | <= | >=
+
+ I kindof half want to make a full parser for this
+--]]
+
+local MAJOR, MINOR = "LibItemSearch-1.0", 3
+local ItemSearch = LibStub:NewLibrary(MAJOR, MINOR)
+if not ItemSearch then return end
+
+--[[ general search ]]--
+
+function ItemSearch:Find(itemLink, search)
+ if not search then
+ return true
+ end
+
+ if not itemLink then
+ return false
+ end
+
+ local search = search:lower()
+ if search:match('\124') then
+ return self:FindUnionSearch(itemLink, strsplit('\124', search))
+ end
+ return self:FindUnionSearch(itemLink, search)
+end
+
+
+--[[ union search: & ]]--
+
+function ItemSearch:FindUnionSearch(itemLink, ...)
+ for i = 1, select('#', ...) do
+ local search = select(i, ...)
+ if search and search ~= '' then
+ if search:match('\038') then
+ if self:FindIntersectSearch(itemLink, strsplit('\038', search)) then
+ return true
+ end
+ else
+ if self:FindIntersectSearch(itemLink, search) then
+ return true
+ end
+ end
+ end
+ end
+ return false
+end
+
+
+--[[ intersect search: | ]]--
+
+function ItemSearch:FindIntersectSearch(itemLink, ...)
+ for i = 1, select('#', ...) do
+ local search = select(i, ...)
+ if search and search ~= '' then
+ if not self:FindNegatableSearch(itemLink, search) then
+ return false
+ end
+ end
+ end
+ return true
+end
+
+
+--[[ negated search: ! ]]--
+
+function ItemSearch:FindNegatableSearch(itemLink, search)
+ local negatedSearch = search:match('^\033(.+)$')
+ if negatedSearch then
+ return not self:FindTypedSearch(itemLink, negatedSearch)
+ end
+ return self:FindTypedSearch(itemLink, search)
+end
+
+
+--[[
+ typed search:
+ user defined search types
+
+ A typed search object should look like the following:
+ {
+ string id
+ unique identifier for the search type,
+
+ string searchCapture = function isSearch(self, search)
+ returns a capture if the given search matches this typed search
+ returns nil if the search is not a match for this type
+
+ bool isMatch = function findItem(self, itemLink, searchCapture)
+ returns true if is in the search defined by
+ }
+--]]
+
+local typedSearches = {}
+function ItemSearch:RegisterTypedSearch(typedSearchObj)
+ typedSearches[typedSearchObj.id] = typedSearchObj
+end
+
+function ItemSearch:GetTypedSearches()
+ return pairs(typedSearches)
+end
+
+function ItemSearch:GetTypedSearch(id)
+ return typedSearches[id]
+end
+
+function ItemSearch:FindTypedSearch(itemLink, search)
+ if not search then
+ return false
+ end
+
+ for id, searchInfo in self:GetTypedSearches() do
+ local capture1, capture2, capture3 = searchInfo:isSearch(search)
+ if capture1 then
+ return searchInfo:findItem(itemLink, capture1, capture2, capture3)
+ end
+ end
+
+ return self:GetTypedSearch('itemTypeGeneric'):findItem(itemLink, search) or self:GetTypedSearch('itemName'):findItem(itemLink, search)
+end
+
+
+--[[
+ Basic typed searches
+--]]
+
+function ItemSearch:Compare(op, lhs, rhs)
+ --ugly, but it works
+ if op == ':' or op == '=' or op == '==' then
+ return lhs == rhs
+ end
+ if op == '!=' or op == '~=' then
+ return lhs ~= rhs
+ end
+ if op == '<=' then
+ return lhs <= rhs
+ end
+ if op == '<' then
+ return lhs < rhs
+ end
+ if op == '>' then
+ return lhs > rhs
+ end
+ if op == '>=' then
+ return lhs >= rhs
+ end
+ return false
+end
+
+
+--[[ basic text search n:(.+) ]]--
+
+local function search_IsInText(search, ...)
+ for i = 1, select('#', ...) do
+ local text = select(i, ...)
+ text = text and tostring(text):lower()
+ if text and (text == search or text:match(search)) then
+ return true
+ end
+ end
+ return false
+end
+
+ItemSearch:RegisterTypedSearch{
+ id = 'itemName',
+
+ isSearch = function(self, search)
+ return search and search:match('^n:(.+)$')
+ end,
+
+ findItem = function(self, itemLink, search)
+ local itemName = (GetItemInfo(itemLink))
+ return search_IsInText(search, itemName)
+ end
+}
+
+
+--[[ item type,subtype,equip loc search t:(.+) ]]--
+
+ItemSearch:RegisterTypedSearch{
+ id = 'itemTypeGeneric',
+
+ isSearch = function(self, search)
+ return search and search:match('^t:(.+)$')
+ end,
+
+ findItem = function(self, itemLink, search)
+ local name, link, quality, iLevel, reqLevel, type, subType, maxStack, equipSlot = GetItemInfo(itemLink)
+ if not name then
+ return false
+ end
+ return search_IsInText(search, type, subType, _G[equipSlot])
+ end
+}
+
+
+--[[ item quality search: q(sign)(%d+) | q:(qualityName) ]]--
+
+ItemSearch:RegisterTypedSearch{
+ id = 'itemQuality',
+
+ isSearch = function(self, search)
+ if search then
+ return search:match('^q([%~%:%<%>%=%!]+)(%w+)$')
+ end
+ end,
+
+ descToQuality = function(self, desc)
+ local q = 0
+
+ local quality = _G['ITEM_QUALITY' .. q .. '_DESC']
+ while quality and quality:lower() ~= desc do
+ q = q + 1
+ quality = _G['ITEM_QUALITY' .. q .. '_DESC']
+ end
+
+ if quality then
+ return q
+ end
+ end,
+
+ findItem = function(self, itemLink, op, search)
+ local name, link, quality = GetItemInfo(itemLink)
+ if not name then
+ return false
+ end
+
+ local num = tonumber(search) or self:descToQuality(search)
+ return num and ItemSearch:Compare(op, quality, num) or false
+ end,
+}
+
+--[[ item level search: lvl(sign)(%d+) ]]--
+
+ItemSearch:RegisterTypedSearch{
+ id = 'itemLevel',
+
+ isSearch = function(self, search)
+ if search then
+ return search:match('^ilvl([:<>=!]+)(%d+)$')
+ end
+ end,
+
+ findItem = function(self, itemLink, op, search)
+ local name, link, quality, iLvl = GetItemInfo(itemLink)
+ if not iLvl then
+ return false
+ end
+
+ local num = tonumber(search)
+ return num and ItemSearch:Compare(op, iLvl, num) or false
+ end,
+}
+
+
+--[[ tooltip keyword search ]]--
+
+local tooltipCache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end})
+local tooltipScanner = _G['LibItemSearchTooltipScanner'] or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate')
+
+local function link_FindSearchInTooltip(itemLink, search)
+ --look in the cache for the result
+ local itemID = itemLink:match('item:(%d+)')
+ local cachedResult = tooltipCache[search][itemID]
+ if cachedResult ~= nil then
+ return cachedResult
+ end
+
+ --no match?, pull in the resut from tooltip parsing
+ tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE')
+ tooltipScanner:SetHyperlink(itemLink)
+
+ local result = false
+ if tooltipScanner:NumLines() > 1 and _G[tooltipScanner:GetName() .. 'TextLeft2']:GetText() == search then
+ result = true
+ elseif tooltipScanner:NumLines() > 2 and _G[tooltipScanner:GetName() .. 'TextLeft3']:GetText() == search then
+ result = true
+ end
+ tooltipScanner:Hide()
+
+ tooltipCache[search][itemID] = result
+ return result
+end
+
+ItemSearch:RegisterTypedSearch{
+ id = 'tooltip',
+
+ isSearch = function(self, search)
+ return self.keywords[search]
+ end,
+
+ findItem = function(self, itemLink, search)
+ return search and link_FindSearchInTooltip(itemLink, search)
+ end,
+
+ keywords = {
+ ['boe'] = ITEM_BIND_ON_EQUIP,
+ ['bop'] = ITEM_BIND_ON_PICKUP,
+ ['bou'] = ITEM_BIND_ON_USE,
+ ['quest'] = ITEM_BIND_QUEST,
+ ['boa'] = ITEM_BIND_TO_ACCOUNT
+ }
+}
+
+ItemSearch:RegisterTypedSearch{
+ id = 'tooltipDesc',
+
+ isSearch = function(self, search)
+ return search and search:match('^tt:(.+)$')
+ end,
+
+ findItem = function(self, itemLink, search)
+ --no match?, pull in the resut from tooltip parsing
+ tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE')
+ tooltipScanner:SetHyperlink(itemLink)
+
+ local i = 1
+ while i <= tooltipScanner:NumLines() do
+ local text = _G[tooltipScanner:GetName() .. 'TextLeft' .. i]:GetText():lower()
+ if text and text:match(search) then
+ tooltipScanner:Hide()
+ return true
+ end
+ i = i + 1
+ end
+
+ tooltipScanner:Hide()
+ return false
+ end,
+}
+
+
+--[[ equipment set search ]]--
+
+local function IsWardrobeLoaded()
+ local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo('Wardrobe')
+ return enabled
+end
+
+local function findEquipmentSetByName(search)
+ local startsWithSearch = '^' .. search
+ local partialMatch = nil
+
+ for i = 1, GetNumEquipmentSets() do
+ local setName = (GetEquipmentSetInfo(i))
+ local lSetName = setName:lower()
+
+ if lSetName == search then
+ return setName
+ end
+
+ if lSetName:match(startsWithSearch) then
+ partialMatch = setName
+ end
+ end
+
+ -- Wardrobe Support
+ if Wardrobe then
+ for i, outfit in ipairs( Wardrobe.CurrentConfig.Outfit) do
+ local setName = outfit.OutfitName
+ local lSetName = setName:lower()
+
+ if lSetName == search then
+ return setName
+ end
+
+ if lSetName:match(startsWithSearch) then
+ partialMatch = setName
+ end
+ end
+ end
+
+ return partialMatch
+end
+
+local function isItemInEquipmentSet(itemLink, setName)
+ if not setName then
+ return false
+ end
+
+ local itemIDs = GetEquipmentSetItemIDs(setName)
+ if not itemIDs then
+ return false
+ end
+
+ local itemID = tonumber(itemLink:match('item:(%d+)'))
+ for inventoryID, setItemID in pairs(itemIDs) do
+ if itemID == setItemID then
+ return true
+ end
+ end
+
+ return false
+end
+
+local function isItemInWardrobeSet(itemLink, setName)
+ if not Wardrobe then return false end
+
+ local itemName = (GetItemInfo(itemLink))
+ for i, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
+ if outfit.OutfitName == setName then
+ for j, item in pairs(outfit.Item) do
+ if item and (item.IsSlotUsed == 1) and (item.Name == itemName) then
+ return true
+ end
+ end
+ end
+ end
+
+ return false
+end
+
+ItemSearch:RegisterTypedSearch{
+ id = 'equipmentSet',
+
+ isSearch = function(self, search)
+ return search and search:match('^s:(.+)$')
+ end,
+
+ findItem = function(self, itemLink, search)
+ local setName = findEquipmentSetByName(search)
+ if not setName then
+ return false
+ end
+
+ return isItemInEquipmentSet(itemLink, setName)
+ or isItemInWardrobeSet(itemLink, setName)
+ end,
+}
\ No newline at end of file
diff --git a/libs/LibItemSearch-1.0/LibItemSearch-1.0.toc b/libs/LibItemSearch-1.0/LibItemSearch-1.0.toc
new file mode 100644
index 0000000..c4ccfe6
--- /dev/null
+++ b/libs/LibItemSearch-1.0/LibItemSearch-1.0.toc
@@ -0,0 +1,7 @@
+## Interface: 40000
+## Title: LibItemSearch
+## Notes: An item search library
+## Author: Tuller
+## LoadOnDemand: 1
+LibStub.lua
+LibItemSearch-1.0.lua
\ No newline at end of file
diff --git a/libs/LibItemSearch-1.0/LibItemSearch.toc b/libs/LibItemSearch-1.0/LibItemSearch.toc
new file mode 100644
index 0000000..c4ccfe6
--- /dev/null
+++ b/libs/LibItemSearch-1.0/LibItemSearch.toc
@@ -0,0 +1,7 @@
+## Interface: 40000
+## Title: LibItemSearch
+## Notes: An item search library
+## Author: Tuller
+## LoadOnDemand: 1
+LibStub.lua
+LibItemSearch-1.0.lua
\ No newline at end of file
diff --git a/libs/LibItemSearch-1.0/LibStub.lua b/libs/LibItemSearch-1.0/LibStub.lua
new file mode 100644
index 0000000..cfc97de
--- /dev/null
+++ b/libs/LibItemSearch-1.0/LibStub.lua
@@ -0,0 +1,30 @@
+-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+ LibStub = LibStub or {libs = {}, minors = {} }
+ _G[LIBSTUB_MAJOR] = LibStub
+ LibStub.minor = LIBSTUB_MINOR
+
+ function LibStub:NewLibrary(major, minor)
+ assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+ minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+ local oldminor = self.minors[major]
+ if oldminor and oldminor >= minor then return nil end
+ self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+ return self.libs[major], oldminor
+ end
+
+ function LibStub:GetLibrary(major, silent)
+ if not self.libs[major] and not silent then
+ error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+ end
+ return self.libs[major], self.minors[major]
+ end
+
+ function LibStub:IterateLibraries() return pairs(self.libs) end
+ setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
diff --git a/libs/LibItemSearch-1.0/README b/libs/LibItemSearch-1.0/README
new file mode 100644
index 0000000..2ff0fbb
--- /dev/null
+++ b/libs/LibItemSearch-1.0/README
@@ -0,0 +1,15 @@
+LibItemSearch
+ An item text search engine of some sort
+
+Grammar:
+ :=
+ := & ;
+ := | ;
+ := ! ;
+ := ; ; ;
+ := bop ; boa ; bou ; boe ; quest
+ := q ; q
+ := ilvl
+ := t:
+ :=
+ := : | = | == | != | ~= | < | > | <= | >=
\ No newline at end of file
diff --git a/libs/LibStub b/libs/LibStub
deleted file mode 160000
index ed93b03..0000000
--- a/libs/LibStub
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ed93b036659fd975d5137b24af276b487e8b017e