1871 lines
67 KiB
Lua
1871 lines
67 KiB
Lua
|
-- ------------------------------------------------------------------------------ --
|
||
|
-- TradeSkillMaster --
|
||
|
-- https://tradeskillmaster.com --
|
||
|
-- All Rights Reserved - Detailed license information included with addon. --
|
||
|
-- ------------------------------------------------------------------------------ --
|
||
|
|
||
|
local _, TSM = ...
|
||
|
local Groups = TSM.MainUI:NewPackage("Groups")
|
||
|
local L = TSM.Include("Locale").GetTable()
|
||
|
local Analytics = TSM.Include("Util.Analytics")
|
||
|
local TempTable = TSM.Include("Util.TempTable")
|
||
|
local Table = TSM.Include("Util.Table")
|
||
|
local String = TSM.Include("Util.String")
|
||
|
local Log = TSM.Include("Util.Log")
|
||
|
local Theme = TSM.Include("Util.Theme")
|
||
|
local ItemString = TSM.Include("Util.ItemString")
|
||
|
local Database = TSM.Include("Util.Database")
|
||
|
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||
|
local ItemFilter = TSM.Include("Service.ItemFilter")
|
||
|
local CustomPrice = TSM.Include("Service.CustomPrice")
|
||
|
local BagTracking = TSM.Include("Service.BagTracking")
|
||
|
local Settings = TSM.Include("Service.Settings")
|
||
|
local UIElements = TSM.Include("UI.UIElements")
|
||
|
local private = {
|
||
|
settings = nil,
|
||
|
currentGroupPath = TSM.CONST.ROOT_GROUP_PATH,
|
||
|
moveGroupPath = nil,
|
||
|
itemFilter = ItemFilter.New(),
|
||
|
groupedItemList = {},
|
||
|
ungroupedItemList = { {}, {} },
|
||
|
moduleCollapsed = {},
|
||
|
results = { {}, {} },
|
||
|
resultsRaw = {},
|
||
|
filterText = "",
|
||
|
groupSearch = "",
|
||
|
itemSearch = "",
|
||
|
frame = nil,
|
||
|
operationQuery = nil,
|
||
|
importExportGroupDB = nil,
|
||
|
exportSubGroups = {},
|
||
|
importGroupTreeContext = {},
|
||
|
}
|
||
|
local DRAG_SCROLL_SPEED_FACTOR = 12
|
||
|
local OPERATION_LABELS = {
|
||
|
Auctioning = L["Auctioning operations control posting to and canceling from the AH."],
|
||
|
Crafting = L["Crafting operations control how queuing profession crafts."],
|
||
|
Mailing = L["Mailing operations control mailing to other characters."],
|
||
|
Shopping = L["Shopping operations control buyout from the AH."],
|
||
|
Sniper = L["Sniper operations control sniping from the AH."],
|
||
|
Vendoring = L["Vendoring operations control selling to and buying from a vendor."],
|
||
|
Warehousing = L["Warehousing operations control moving in and out of the bank."],
|
||
|
}
|
||
|
local DEFAULT_IMPORT_GROUP_TREE_CONTEXT = { unselected = {}, collapsed = {} }
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Module Functions
|
||
|
-- ============================================================================
|
||
|
|
||
|
function Groups.OnInitialize()
|
||
|
private.settings = Settings.NewView()
|
||
|
:AddKey("global", "coreOptions", "groupPriceSource")
|
||
|
:AddKey("global", "mainUIContext", "groupsDividedContainer")
|
||
|
:AddKey("char", "mainUIContext", "groupsManagementGroupTree")
|
||
|
:AddKey("profile", "userData", "groups")
|
||
|
TSM.MainUI.RegisterTopLevelPage(L["Groups"], private.GetGroupsFrame)
|
||
|
private.itemFilter:ParseStr("")
|
||
|
private.importExportGroupDB = Database.NewSchema("IMPORT_EXPORT_GROUPS")
|
||
|
:AddStringField("groupPath")
|
||
|
:AddStringField("orderStr")
|
||
|
:AddIndex("groupPath")
|
||
|
:Commit()
|
||
|
end
|
||
|
|
||
|
function Groups.ShowGroupSettings(baseFrame, groupPath)
|
||
|
baseFrame:SetSelectedNavButton(L["Groups"], true)
|
||
|
baseFrame:GetElement("content.groups.groupSelection.groupTree"):SetSelectedGroup(groupPath, true)
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Groups UI
|
||
|
-- ============================================================================
|
||
|
|
||
|
function private.GetGroupsFrame()
|
||
|
TSM.UI.AnalyticsRecordPathChange("main", "groups")
|
||
|
private.currentGroupPath = TSM.CONST.ROOT_GROUP_PATH
|
||
|
private.moveGroupPath = nil
|
||
|
local frame = UIElements.New("DividedContainer", "groups")
|
||
|
:SetSettingsContext(private.settings, "groupsDividedContainer")
|
||
|
:SetMinWidth(250, 250)
|
||
|
:SetLeftChild(UIElements.New("Frame", "groupSelection")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Frame", "search")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(8)
|
||
|
:AddChild(UIElements.New("Input", "input")
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:AllowItemInsert(true)
|
||
|
:SetValue(private.groupSearch)
|
||
|
:SetHintText(L["Search Groups"])
|
||
|
:SetScript("OnValueChanged", private.GroupSearchOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "expandAllBtn")
|
||
|
:SetSize(24, 24)
|
||
|
:SetMargin(8, 0, 0, 0)
|
||
|
:SetBackground("iconPack.18x18/Expand All")
|
||
|
:SetScript("OnClick", private.ExpandAllGroupsOnClick)
|
||
|
:SetTooltip(L["Expand / Collapse All Groups"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "expandAllBtn")
|
||
|
:SetSize(24, 24)
|
||
|
:SetMargin(8, 0, 0, 0)
|
||
|
:SetBackground("iconPack.18x18/Import")
|
||
|
:SetScript("OnClick", private.ImportGroupBtnOnClick)
|
||
|
:SetTooltip(L["Import group"])
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetHeight(2)
|
||
|
:SetTexture("ACTIVE_BG_ALT")
|
||
|
)
|
||
|
:AddChild(UIElements.New("ManagementGroupTree", "groupTree")
|
||
|
:SetSettingsContext(private.settings, "groupsManagementGroupTree")
|
||
|
:SetQuery(TSM.Groups.CreateQuery())
|
||
|
:SetSelectedGroup(private.currentGroupPath)
|
||
|
:SetSearchString(private.groupSearch)
|
||
|
:SetScript("OnGroupSelected", private.GroupTreeOnGroupSelected)
|
||
|
:SetScript("OnNewGroup", private.GroupTreeOnNewGroup)
|
||
|
)
|
||
|
)
|
||
|
:SetRightChild(UIElements.New("ViewContainer", "view")
|
||
|
:SetNavCallback(private.GetViewContainerContent)
|
||
|
:AddPath("content", true)
|
||
|
:AddPath("search")
|
||
|
)
|
||
|
frame:GetElement("view.content.header.title.renameBtn"):Hide()
|
||
|
private.frame = frame
|
||
|
return frame
|
||
|
end
|
||
|
|
||
|
function private.GetViewContainerContent(viewContainer, path)
|
||
|
if path == "content" then
|
||
|
wipe(private.results[1])
|
||
|
wipe(private.results[2])
|
||
|
return private.GetContentFrame()
|
||
|
elseif path == "search" then
|
||
|
return private.GetSearchFrame()
|
||
|
else
|
||
|
error("Unexpected path: "..tostring(path))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.GetContentFrame()
|
||
|
local frame = UIElements.New("Frame", "content")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetSize("EXPAND", 40)
|
||
|
:SetPadding(8)
|
||
|
:AddChild(UIElements.New("Frame", "title")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetWidth("EXPAND")
|
||
|
:AddChild(UIElements.New("Texture", "icon")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetTextureAndSize(TSM.UI.TexturePacks.GetColoredKey("iconPack.18x18/Folder", "TEXT"))
|
||
|
)
|
||
|
:AddChild(UIElements.New("EditableText", "text")
|
||
|
:SetWidth("AUTO")
|
||
|
:AllowItemInsert(true)
|
||
|
:SetFont("BODY_BODY1_BOLD")
|
||
|
:SetText(L["Base Group"])
|
||
|
:SetScript("OnValueChanged", private.GroupNameChanged)
|
||
|
:SetScript("OnEditingChanged", private.NameOnEditingChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
:AddChild(UIElements.New("Button", "renameBtn")
|
||
|
:SetMargin(8, 0, 0, 0)
|
||
|
:SetBackgroundAndSize("iconPack.18x18/Edit")
|
||
|
:SetScript("OnClick", private.RenameBtnOnClick)
|
||
|
:SetTooltip(L["Rename this group"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "exportBtn")
|
||
|
:SetMargin(8, 4, 0, 0)
|
||
|
:SetBackgroundAndSize("iconPack.18x18/Export")
|
||
|
:SetScript("OnClick", private.ExportBtnOnClick)
|
||
|
:SetTooltip(L["Export this group"])
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("TabGroup", "buttons")
|
||
|
:SetMargin(0, 0, 6, 0)
|
||
|
:SetNavCallback(private.GetGroupsPage)
|
||
|
:AddPath(L["Information"], true)
|
||
|
:AddPath(L["Operations"])
|
||
|
)
|
||
|
frame:GetElement("header.title.renameBtn"):Hide()
|
||
|
frame:GetElement("header.title.exportBtn"):Hide()
|
||
|
return frame
|
||
|
end
|
||
|
|
||
|
function private.GetSearchFrame()
|
||
|
return UIElements.New("Frame", "content")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(40)
|
||
|
:SetPadding(8)
|
||
|
:AddChild(UIElements.New("ActionButton", "button")
|
||
|
:SetWidth(64)
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetIcon("iconPack.14x14/Chevron/Right@180")
|
||
|
:SetText(BACK)
|
||
|
:SetScript("OnClick", private.SearchBackButtonOnClick)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Input", "input")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:AllowItemInsert()
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:SetValidateFunc(private.ValidateBaseSearchValue)
|
||
|
:SetValue(private.itemSearch)
|
||
|
:SetScript("OnValueChanged", private.BaseSearchOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "selectAllBtn")
|
||
|
:SetSize(24, 24)
|
||
|
:SetBackground("iconPack.18x18/Select All")
|
||
|
:SetScript("OnClick", private.SelectAllResultsOnClick)
|
||
|
:SetTooltip(L["Select / Deselect All Results"])
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "header2")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(30)
|
||
|
:SetPadding(8, 8, 5, 5)
|
||
|
:AddChild(UIElements.New("Text", "label")
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetText(format(L["%d Results"], 0))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "ignoreItemVariations")
|
||
|
:SetSize("AUTO", 24)
|
||
|
:SetFont("BODY_BODY1")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Ignore variations"])
|
||
|
:SetSettingInfo(private.settings.groups[private.currentGroupPath], "ignoreItemVariations")
|
||
|
:SetScript("OnValueChanged", private.IgnoreSearchRandomOnValueChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetHeight(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("ItemList", "itemList")
|
||
|
:SetScript("OnSelectionChanged", private.ItemListOnSelectionChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetHeight(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "bottom")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(40)
|
||
|
:SetPadding(8)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:AddChild(UIElements.New("GroupSelector", "group")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetHintText(L["Select Group"])
|
||
|
:SetSingleSelection(true)
|
||
|
:AddCreateNew()
|
||
|
:SetSelection(TSM.Groups.Exists(private.moveGroupPath) and private.moveGroupPath)
|
||
|
:SetScript("OnSelectionChanged", private.BaseGroupOnSelectionChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ActionButton", "move")
|
||
|
:SetWidth(124)
|
||
|
:SetDisabled(true)
|
||
|
:SetText(L["Move Item"])
|
||
|
:SetScript("OnClick", private.BaseMoveItemOnClick)
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
|
||
|
function private.GetGroupsPage(_, button)
|
||
|
private.itemSearch = ""
|
||
|
private.itemFilter:ParseStr("")
|
||
|
if button == L["Information"] then
|
||
|
TSM.UI.AnalyticsRecordPathChange("main", "groups", "information")
|
||
|
return UIElements.New("Frame", "items")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetPadding(0, 0, 9, 0)
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Text", "text")
|
||
|
:SetHeight(42)
|
||
|
:SetMargin(8, 8, 0, 8)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetText(L["The Base Group contains all ungrouped items in the game. Use the search and filter controls to find items to add to other groups."])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "filter")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(8, 8, 0, 8)
|
||
|
:AddChild(UIElements.New("Input", "filter")
|
||
|
:SetMargin(0, 12, 0, 0)
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:AllowItemInsert()
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:SetValidateFunc(private.ValidateBaseSearchValue)
|
||
|
:SetHintText(L["Search items"])
|
||
|
:SetScript("OnValueChanged", private.InformationSearchOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "ignoreItemVariations")
|
||
|
:SetSize("AUTO", 24)
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY1")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Ignore variations"])
|
||
|
:SetSettingInfo(private.settings.groups[private.currentGroupPath], "ignoreItemVariations")
|
||
|
:SetScript("OnValueChanged", private.IgnoreBaseRandomOnValueChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ItemList", "itemList")
|
||
|
:SetItems(private.GetUngroupedBagItemList())
|
||
|
:SetFilterFunction(private.ItemListItemIsFiltered)
|
||
|
:SetScript("OnSelectionChanged", private.ItemListOnSelectionChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetHeight(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "bottom")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(40)
|
||
|
:SetPadding(8)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:AddChild(UIElements.New("GroupSelector", "group")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetHintText(L["Select Group"])
|
||
|
:SetSingleSelection(true)
|
||
|
:AddCreateNew()
|
||
|
:SetSelection(TSM.Groups.Exists(private.moveGroupPath) and private.moveGroupPath)
|
||
|
:SetScript("OnSelectionChanged", private.GroupOnSelectionChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ActionButton", "move")
|
||
|
:SetWidth(124)
|
||
|
:SetDisabled(true)
|
||
|
:SetText(L["Move Item"])
|
||
|
:SetScript("OnClick", private.MoveItemOnClick)
|
||
|
)
|
||
|
)
|
||
|
elseif button == L["Items"] then
|
||
|
TSM.UI.AnalyticsRecordPathChange("main", "groups", "items")
|
||
|
assert(private.currentGroupPath ~= TSM.CONST.ROOT_GROUP_PATH)
|
||
|
local parentGroup = TSM.Groups.Path.GetParent(private.currentGroupPath)
|
||
|
parentGroup = parentGroup ~= TSM.CONST.ROOT_GROUP_PATH and parentGroup or nil
|
||
|
return UIElements.New("Frame", "items")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetPadding(8)
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Frame", "filter")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(0, 0, 0, 8)
|
||
|
:AddChild(UIElements.New("Input", "filter")
|
||
|
:SetMargin(0, 12, 0, 0)
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:SetValidateFunc(private.ItemFilterValidateFunc)
|
||
|
:SetHintText(L["Search items in group"])
|
||
|
:SetScript("OnValueChanged", private.ItemFilterOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "ignoreItemVariations")
|
||
|
:SetSize("AUTO", 24)
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY1")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Ignore variations"])
|
||
|
:SetSettingInfo(private.settings.groups[private.currentGroupPath], "ignoreItemVariations")
|
||
|
:SetScript("OnValueChanged", private.IgnoreRandomOnValueChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "content")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:AddChild(UIElements.New("Frame", "ungrouped")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:AddChild(UIElements.New("Frame", "content")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
:AddChild(UIElements.New("Text", "text")
|
||
|
:SetMargin(8, 0, 4, 4)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(L["Ungrouped Items"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "selectAllBtn")
|
||
|
:SetSize(20, 20)
|
||
|
:SetMargin(8, 4, 0, 0)
|
||
|
:SetBackground("iconPack.18x18/Select All")
|
||
|
:SetScript("OnClick", private.ItemListSelectAllOnClick)
|
||
|
:SetTooltip(L["Select / Deselect All Items"])
|
||
|
)
|
||
|
)
|
||
|
-- draw a line along the bottom to hide the rounded corners at the bottom of the header frame
|
||
|
:AddChildNoLayout(UIElements.New("Texture", "line")
|
||
|
:AddAnchor("BOTTOMLEFT", "header")
|
||
|
:AddAnchor("BOTTOMRIGHT", "header")
|
||
|
:SetHeight(4)
|
||
|
:SetTexture("FRAME_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("ItemList", "itemList")
|
||
|
:SetMargin(0, 0, 0, 7)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:SetItems(private.GetUngroupedItemList())
|
||
|
:SetFilterFunction(private.ItemListItemIsFiltered)
|
||
|
:SetScript("OnSelectionChanged", private.UngroupedItemsOnSelectionChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ActionButton", "btn")
|
||
|
:SetHeight(26)
|
||
|
:SetMargin(0, 0, 10, 0)
|
||
|
:SetText(L["Add"])
|
||
|
:SetDisabled(true)
|
||
|
:SetScript("OnClick", private.AddItemsOnClick)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "grouped")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:AddChild(UIElements.New("Frame", "content")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
:AddChild(UIElements.New("Text", "text")
|
||
|
:SetMargin(8, 0, 4, 4)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(L["Grouped Items"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "selectAllBtn")
|
||
|
:SetSize(20, 20)
|
||
|
:SetMargin(8, 4, 0, 0)
|
||
|
:SetBackground("iconPack.18x18/Select All")
|
||
|
:SetScript("OnClick", private.ItemListSelectAllOnClick)
|
||
|
:SetTooltip(L["Select / Deselect All Items"])
|
||
|
)
|
||
|
)
|
||
|
-- draw a line along the bottom to hide the rounded corners at the bottom of the header frame
|
||
|
:AddChildNoLayout(UIElements.New("Texture", "line")
|
||
|
:AddAnchor("BOTTOMLEFT", "header")
|
||
|
:AddAnchor("BOTTOMRIGHT", "header")
|
||
|
:SetHeight(4)
|
||
|
:SetTexture("FRAME_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("ItemList", "itemList")
|
||
|
:SetMargin(0, 0, 0, 7)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:SetItems(private.GetGroupedItemList())
|
||
|
:SetFilterFunction(private.ItemListItemIsFiltered)
|
||
|
:SetScript("OnSelectionChanged", private.GroupedItemsOnSelectionChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChildIf(parentGroup, UIElements.New("ActionButton", "btn")
|
||
|
:SetHeight(26)
|
||
|
:SetMargin(0, 0, 10, 0)
|
||
|
:SetText(L["Remove"])
|
||
|
:SetDisabled(true)
|
||
|
:SetModifierText(L["Move to Parent Group"], "SHIFT")
|
||
|
:SetScript("OnClick", private.RemoveItemsOnClick)
|
||
|
:SetTooltip(L["Hold shift to move the items to the parent group instead of removing them."])
|
||
|
)
|
||
|
:AddChildIf(not parentGroup, UIElements.New("ActionButton", "btn")
|
||
|
:SetHeight(26)
|
||
|
:SetMargin(0, 0, 10, 0)
|
||
|
:SetText(L["Remove"])
|
||
|
:SetDisabled(true)
|
||
|
:SetScript("OnClick", private.RemoveItemsOnClick)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
elseif button == L["Operations"] then
|
||
|
TSM.UI.AnalyticsRecordPathChange("main", "groups", "operations")
|
||
|
return UIElements.New("ScrollFrame", "operations")
|
||
|
:SetPadding(8)
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(private.GetModuleOperationFrame("Auctioning"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Crafting"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Mailing"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Shopping"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Sniper"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Vendoring"))
|
||
|
:AddChild(private.GetModuleOperationFrame("Warehousing"))
|
||
|
else
|
||
|
error("Unknown button!")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.GetModuleOperationFrame(moduleName)
|
||
|
local override = TSM.Groups.HasOperationOverride(private.currentGroupPath, moduleName) or private.currentGroupPath == TSM.CONST.ROOT_GROUP_PATH
|
||
|
local numGroupOperations = 0
|
||
|
for _ in TSM.Groups.OperationIterator(private.currentGroupPath, moduleName) do
|
||
|
numGroupOperations = numGroupOperations + 1
|
||
|
end
|
||
|
|
||
|
return UIElements.New("CollapsibleContainer", "operationInfo"..moduleName)
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetMargin(0, 0, 0, moduleName == "Warehousing" and 0 or 8)
|
||
|
:SetContext(moduleName)
|
||
|
:SetContextTable(private.moduleCollapsed, moduleName)
|
||
|
:SetHeadingText(format(L["%s Operations"], moduleName))
|
||
|
:AddChild(UIElements.New("Text", "moduleDesc")
|
||
|
:SetSize("AUTO", 20)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetText(OPERATION_LABELS[moduleName])
|
||
|
)
|
||
|
:AddChildIf(private.currentGroupPath ~= TSM.CONST.ROOT_GROUP_PATH, UIElements.New("Checkbox", "overrideCheckbox")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 6, 0)
|
||
|
:SetFont("BODY_BODY2")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Override Parent Operations"])
|
||
|
:SetChecked(override)
|
||
|
:SetScript("OnValueChanged", private.OverrideToggleOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "container")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetContext(moduleName)
|
||
|
:SetHeight(36 * numGroupOperations)
|
||
|
:AddChildrenWithFunction(private.AddOperationRows)
|
||
|
)
|
||
|
:AddChildIf(override and numGroupOperations < TSM.Operations.GetMaxNumber(moduleName), UIElements.New("Frame", "addMore")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(0, 0, 8, 0)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
:AddChild(UIElements.New("Button", "button")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 2, 0, 0)
|
||
|
:SetFont("BODY_BODY2")
|
||
|
:SetTextColor("INDICATOR")
|
||
|
:SetText(L["Add More Operations"])
|
||
|
:SetContext(moduleName)
|
||
|
:SetScript("OnClick", private.AddOperationButtonOnClick)
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
|
||
|
function private.AddOperationRows(container)
|
||
|
local moduleName = container:GetContext()
|
||
|
local override = TSM.Groups.HasOperationOverride(private.currentGroupPath, moduleName) or private.currentGroupPath == TSM.CONST.ROOT_GROUP_PATH
|
||
|
for i, operationName in TSM.Groups.OperationIterator(private.currentGroupPath, moduleName) do
|
||
|
container:AddChild(UIElements.New("Frame", "operation"..i)
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(28)
|
||
|
:SetMargin(0, 0, 8, 0)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:AddChild(UIElements.New("Text", "operationNum")
|
||
|
:SetWidth(20)
|
||
|
:SetMargin(2, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY1_BOLD")
|
||
|
:SetText(i)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "title")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetPadding(0, 8, 0, 0)
|
||
|
:SetBackgroundColor("ACTIVE_BG", true)
|
||
|
:AddChildNoLayout(UIElements.New("Button", "dragFrame")
|
||
|
:SetSize(15, 24)
|
||
|
:AddAnchor("LEFT", 1, 0)
|
||
|
:SetContext(i)
|
||
|
:SetScript("OnMouseDown", override and private.DragButtonOnMouseDown or nil)
|
||
|
:SetScript("OnMouseUp", override and private.DragButtonOnMouseUp or nil)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "handleBackground")
|
||
|
:SetSize(16, 28)
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
-- draw a line along the right to hide the rounded corners at the bottom of the header frame
|
||
|
:AddChildNoLayout(UIElements.New("Texture", "line")
|
||
|
:AddAnchor("TOPRIGHT")
|
||
|
:AddAnchor("BOTTOMRIGHT")
|
||
|
:SetWidth(4)
|
||
|
:SetTexture("FRAME_BG")
|
||
|
)
|
||
|
:AddChildNoLayout(UIElements.New("Texture", "texture")
|
||
|
:AddAnchor("LEFT")
|
||
|
:SetTextureAndSize("iconPack.18x18/Grip")
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "name")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 0, 0, 0)
|
||
|
:SetFont("BODY_BODY2")
|
||
|
:SetText(operationName)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "spacer"))
|
||
|
:AddChild(UIElements.New("Button", "configBtn")
|
||
|
:SetBackgroundAndSize("iconPack.18x18/Popout")
|
||
|
:SetContext(operationName)
|
||
|
:SetScript("OnClick", private.ConfigOperationOnClick)
|
||
|
)
|
||
|
:AddChildIf(override, UIElements.New("Button", "removeBtn")
|
||
|
:SetMargin(4, 0, 0, 0)
|
||
|
:SetBackgroundAndSize("iconPack.18x18/Close/Default")
|
||
|
:SetContext(i)
|
||
|
:SetScript("OnClick", private.RemoveOperationOnClick)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Local Script Handlers
|
||
|
-- ============================================================================
|
||
|
|
||
|
function private.DragButtonOnMouseDown(button)
|
||
|
local frame = button:GetParentElement()
|
||
|
frame:SetRelativeLevel(20)
|
||
|
frame:StartMoving()
|
||
|
button:SetScript("OnUpdate", private.DragFrameOnUpdate)
|
||
|
button:GetElement("__parent.name")
|
||
|
:SetTextColor("INDICATOR")
|
||
|
frame:SetWidth(250)
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.DragButtonOnMouseUp(button)
|
||
|
button:SetScript("OnUpdate", nil)
|
||
|
local frame = button:GetParentElement()
|
||
|
frame:StopMovingOrSizing()
|
||
|
frame:SetRelativeLevel(1)
|
||
|
local container = frame:GetParentElement():GetParentElement()
|
||
|
|
||
|
local moduleName = container:GetParentElement():GetParentElement():GetContext()
|
||
|
local index = button:GetContext()
|
||
|
-- TODO: refactor
|
||
|
for k, v in container:LayoutChildrenIterator() do
|
||
|
if k ~= index and v:IsMouseOver() then
|
||
|
TSM.Groups.SwapOperation(private.currentGroupPath, moduleName, index, k)
|
||
|
end
|
||
|
end
|
||
|
for i, operationName in TSM.Groups.OperationIterator(private.currentGroupPath, moduleName) do
|
||
|
container:GetElement("operation"..i..".title.name"):SetText(operationName)
|
||
|
end
|
||
|
|
||
|
frame:SetWidth(nil)
|
||
|
frame:GetElement("name")
|
||
|
:SetTextColor("TEXT")
|
||
|
frame:GetParentElement():GetParentElement()
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.DragFrameOnUpdate(frame)
|
||
|
local scrollFrame = frame:GetElement("__parent.__parent.__parent.__parent.__parent.__parent")
|
||
|
local uiScale = UIParent:GetEffectiveScale()
|
||
|
local x, y = GetCursorPosition()
|
||
|
x = x / uiScale
|
||
|
y = y / uiScale
|
||
|
|
||
|
-- TODO: refactor
|
||
|
local top = scrollFrame:_GetBaseFrame():GetTop()
|
||
|
local bottom = scrollFrame:_GetBaseFrame():GetBottom()
|
||
|
if y > top then
|
||
|
scrollFrame._scrollAmount = top - y
|
||
|
elseif y < bottom then
|
||
|
scrollFrame._scrollAmount = bottom - y
|
||
|
else
|
||
|
scrollFrame._scrollAmount = 0
|
||
|
end
|
||
|
|
||
|
scrollFrame._scrollbar:SetValue(scrollFrame._scrollbar:GetValue() + scrollFrame._scrollAmount / DRAG_SCROLL_SPEED_FACTOR)
|
||
|
end
|
||
|
|
||
|
function private.GroupSearchOnValueChanged(input)
|
||
|
local groupsContentFrame = input:GetElement("__parent.__parent.__parent.view.content")
|
||
|
-- Copy search filter
|
||
|
local text = strlower(input:GetValue())
|
||
|
|
||
|
if private.groupSearch == text then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
private.groupSearch = text
|
||
|
local searchStr = String.Escape(private.groupSearch)
|
||
|
-- Check if the selection is being filtered out
|
||
|
if strmatch(strlower(private.currentGroupPath), searchStr) then
|
||
|
local titleFrame = groupsContentFrame:GetElement("header.title")
|
||
|
local buttonsFrame = groupsContentFrame:GetElement("buttons")
|
||
|
input:GetElement("__parent.__parent.groupTree"):SetSelectedGroup(private.currentGroupPath)
|
||
|
if private.currentGroupPath == TSM.CONST.ROOT_GROUP_PATH then
|
||
|
titleFrame:GetElement("text")
|
||
|
:SetTextColor("TEXT")
|
||
|
:SetText(L["Base Group"])
|
||
|
else
|
||
|
local groupColor = Theme.GetGroupColor(select('#', strsplit(TSM.CONST.GROUP_SEP, private.currentGroupPath)))
|
||
|
titleFrame:GetElement("text")
|
||
|
:SetTextColor(groupColor)
|
||
|
:SetText(TSM.Groups.Path.GetName(private.currentGroupPath))
|
||
|
end
|
||
|
titleFrame:GetElement("renameBtn"):Show()
|
||
|
titleFrame:GetElement("exportBtn"):Show()
|
||
|
buttonsFrame:Show()
|
||
|
buttonsFrame:Draw()
|
||
|
titleFrame:Draw()
|
||
|
else
|
||
|
local titleFrame = groupsContentFrame:GetElement("header.title")
|
||
|
local buttonsFrame = groupsContentFrame:GetElement("buttons")
|
||
|
input:GetElement("__parent.__parent.groupTree"):SetSelectedGroup(TSM.CONST.ROOT_GROUP_PATH)
|
||
|
titleFrame:GetElement("text")
|
||
|
:SetText(L["No group selected"])
|
||
|
:SetEditing(false)
|
||
|
-- Hide the content
|
||
|
titleFrame:GetElement("renameBtn"):Hide()
|
||
|
titleFrame:GetElement("exportBtn"):Hide()
|
||
|
buttonsFrame:Hide()
|
||
|
buttonsFrame:Draw()
|
||
|
titleFrame:Draw()
|
||
|
end
|
||
|
input:GetElement("__parent.__parent.groupTree")
|
||
|
:SetSearchString(private.groupSearch)
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.ExpandAllGroupsOnClick(button)
|
||
|
button:GetElement("__parent.__parent.groupTree")
|
||
|
:ToggleExpandAll()
|
||
|
end
|
||
|
|
||
|
function private.ImportGroupBtnOnClick(button)
|
||
|
local dialogFrame = UIElements.New("Frame", "frame")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetSize(658, 250)
|
||
|
:SetPadding(12)
|
||
|
:AddAnchor("CENTER")
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
:SetMouseEnabled(true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(20, -4, -4, 12)
|
||
|
:AddChild(UIElements.New("Text", "title")
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(L["Import Groups & Operations"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "closeBtn")
|
||
|
:SetBackgroundAndSize("iconPack.24x24/Close/Default")
|
||
|
:SetScript("OnClick", private.ImportExportCloseBtnOnClick)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "desc")
|
||
|
:SetHeight(40)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetText(L["You can import groups by pasting an import string into the box below. Group import strings can be found at: https://tradeskillmaster.com/group-maker/all"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "text")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 8)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(L["Import String"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("MultiLineInput", "input")
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:SetFocused(true)
|
||
|
:SetPasteMode()
|
||
|
:SetScript("OnValueChanged", private.ImportInputOnValueChanged)
|
||
|
)
|
||
|
:SetScript("OnHide", private.ImportOnHide)
|
||
|
button:GetBaseElement():ShowDialogFrame(dialogFrame)
|
||
|
dialogFrame:Draw()
|
||
|
end
|
||
|
|
||
|
function private.GetImportSummaryDialog()
|
||
|
wipe(private.importGroupTreeContext)
|
||
|
local dialogFrame = UIElements.New("Frame", "frame")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetSize(612, 437)
|
||
|
:SetPadding(8)
|
||
|
:AddAnchor("CENTER")
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
:SetMouseEnabled(true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(20, -4, -4, 16)
|
||
|
:AddChild(UIElements.New("Text", "title")
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(L["Import Summary"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "closeBtn")
|
||
|
:SetBackgroundAndSize("iconPack.24x24/Close/Default")
|
||
|
:SetScript("OnClick", private.ImportExportCloseBtnOnClick)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "nav")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 16)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
-- TODO: add the other tabs (and OnClick handlers for these buttons)
|
||
|
:AddChild(UIElements.New("Button", "groups")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(format(L["%d Groups"], 0))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetWidth(2)
|
||
|
:SetTexture("ACTIVE_BG_ALT")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "operations")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(format(L["%d Operations"], 0))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line2")
|
||
|
:SetWidth(2)
|
||
|
:SetTexture("ACTIVE_BG_ALT")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "items")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(format(L["%d Items"], 0))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "container")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetPadding(2)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:SetBorderColor("ACTIVE_BG")
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(8)
|
||
|
:AddChild(UIElements.New("Input", "input")
|
||
|
:AllowItemInsert(true)
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:SetHintText(L["Search Groups"])
|
||
|
:SetScript("OnValueChanged", private.ImportFilterOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "expandAllBtn")
|
||
|
:SetSize(24, 24)
|
||
|
:SetMargin(8, 4, 0, 0)
|
||
|
:SetBackground("iconPack.18x18/Expand All")
|
||
|
:SetScript("OnClick", private.ImportExpandAllOnClick)
|
||
|
:SetTooltip(L["Expand / Collapse All Groups"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "selectAllBtn")
|
||
|
:SetSize(24, 24)
|
||
|
:SetBackground("iconPack.18x18/Select All")
|
||
|
:SetScript("OnClick", private.ImportSelectAllOnClick)
|
||
|
:SetTooltip(L["Select / Deselect All Groups"])
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ApplicationGroupTree", "groupTree")
|
||
|
:SetContextTable(private.importGroupTreeContext, DEFAULT_IMPORT_GROUP_TREE_CONTEXT)
|
||
|
:SetQuery(private.CreateImportExportDBQuery())
|
||
|
:SetScript("OnGroupSelectionChanged", private.ImportGroupTreeOnGroupSelectionChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "items")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:AddChild(UIElements.New("Checkbox", "moveCheckbox")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetChecked(true)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "operations")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:AddChild(UIElements.New("Checkbox", "includeCheckbox")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetChecked(true)
|
||
|
:SetText(L["Include operations?"])
|
||
|
:SetScript("OnValueChanged", private.ImportIncludeOperationsCheckboxOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "replaceCheckbox")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetChecked(true)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
)
|
||
|
:AddChild(UIElements.New("ActionButton", "btn")
|
||
|
:SetHeight(24)
|
||
|
:SetText(L["Import"])
|
||
|
:SetScript("OnClick", private.ImportBtnOnClick)
|
||
|
)
|
||
|
:SetScript("OnHide", private.ImportOnHide)
|
||
|
return dialogFrame
|
||
|
end
|
||
|
|
||
|
function private.ImportInputOnValueChanged(input)
|
||
|
local baseFrame = input:GetBaseElement()
|
||
|
if not TSM.Groups.ImportExport.ProcessImport(input:GetValue()) then
|
||
|
baseFrame:HideDialog()
|
||
|
Log.PrintUser(L["The pasted value was not valid. Ensure you are pasting the entire import string."])
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- build the import group DB
|
||
|
private.importExportGroupDB:TruncateAndBulkInsertStart()
|
||
|
local importGroupName = TSM.Groups.ImportExport.GetPendingImportGroupName()
|
||
|
for groupPath in TSM.Groups.ImportExport.PendingImportGroupIterator() do
|
||
|
groupPath = groupPath == TSM.CONST.ROOT_GROUP_PATH and importGroupName or TSM.Groups.Path.Join(importGroupName, groupPath)
|
||
|
local orderStr = gsub(groupPath, TSM.CONST.GROUP_SEP, "\001")
|
||
|
orderStr = strlower(orderStr)
|
||
|
private.importExportGroupDB:BulkInsertNewRow(groupPath, orderStr)
|
||
|
end
|
||
|
private.importExportGroupDB:BulkInsertEnd()
|
||
|
|
||
|
-- clear the OnHide handler so we don't reset the import context
|
||
|
input:GetParentElement():SetScript("OnHide", nil)
|
||
|
baseFrame:HideDialog()
|
||
|
local dialogFrame = private.GetImportSummaryDialog()
|
||
|
baseFrame:ShowDialogFrame(dialogFrame)
|
||
|
private.UpdateImportConfirmationDialog(dialogFrame)
|
||
|
end
|
||
|
|
||
|
function private.UpdateImportConfirmationDialog(dialogFrame)
|
||
|
local numItems, numGroups, numExistingItems, numOperations, numExistingOperations, numExistingCustomSources = TSM.Groups.ImportExport.GetImportTotals()
|
||
|
dialogFrame:GetElement("nav.groups")
|
||
|
:SetText(format(L["%d Groups"], numGroups))
|
||
|
dialogFrame:GetElement("nav.operations")
|
||
|
:SetText(format(L["%d Operations"], numOperations))
|
||
|
dialogFrame:GetElement("nav.items")
|
||
|
:SetText(format(L["%d Items"], numItems))
|
||
|
if numExistingItems > 0 then
|
||
|
dialogFrame:GetElement("items.moveCheckbox")
|
||
|
:SetText(format(L["Move %d already grouped items?"], numExistingItems))
|
||
|
:SetChecked(true)
|
||
|
dialogFrame:GetElement("items"):Show()
|
||
|
else
|
||
|
dialogFrame:GetElement("items"):Hide()
|
||
|
end
|
||
|
if numOperations > 0 then
|
||
|
dialogFrame:GetElement("operations.includeCheckbox")
|
||
|
:SetChecked(true)
|
||
|
dialogFrame:GetElement("operations.replaceCheckbox")
|
||
|
:SetChecked(true)
|
||
|
if numExistingOperations > 0 then
|
||
|
if numExistingCustomSources > 0 then
|
||
|
dialogFrame:GetElement("operations.replaceCheckbox")
|
||
|
:SetText(format(L["Replace %d existing operations and %d existing custom sources?"], numExistingOperations, numExistingCustomSources))
|
||
|
else
|
||
|
dialogFrame:GetElement("operations.replaceCheckbox")
|
||
|
:SetText(format(L["Replace %d existing operations?"], numExistingOperations))
|
||
|
end
|
||
|
dialogFrame:GetElement("operations.replaceCheckbox"):Show()
|
||
|
else
|
||
|
dialogFrame:GetElement("operations.replaceCheckbox"):Hide()
|
||
|
end
|
||
|
dialogFrame:GetElement("operations"):Show()
|
||
|
else
|
||
|
dialogFrame:GetElement("operations"):Hide()
|
||
|
end
|
||
|
dialogFrame:Draw()
|
||
|
end
|
||
|
|
||
|
function private.ImportFilterOnValueChanged(input)
|
||
|
input:GetElement("__parent.__parent.groupTree")
|
||
|
:SetSearchString(strlower(input:GetValue()))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.ImportExpandAllOnClick(button)
|
||
|
button:GetElement("__parent.__parent.groupTree")
|
||
|
:ToggleExpandAll()
|
||
|
end
|
||
|
|
||
|
function private.ImportSelectAllOnClick(button)
|
||
|
local importGroupName = TSM.Groups.ImportExport.GetPendingImportGroupName()
|
||
|
local groupTree = button:GetElement("__parent.__parent.groupTree")
|
||
|
groupTree:SetGroupSelected(importGroupName, false)
|
||
|
groupTree:ToggleSelectAll()
|
||
|
end
|
||
|
|
||
|
function private.ImportGroupTreeOnGroupSelectionChanged(groupTree)
|
||
|
local importGroupName = TSM.Groups.ImportExport.GetPendingImportGroupName()
|
||
|
groupTree:SetGroupSelected(importGroupName, true)
|
||
|
-- make sure the parent of any selected groups are also selected
|
||
|
for relativeGroupPath in TSM.Groups.ImportExport.PendingImportGroupIterator() do
|
||
|
local groupPath = relativeGroupPath == TSM.CONST.ROOT_GROUP_PATH and importGroupName or TSM.Groups.Path.Join(importGroupName, relativeGroupPath)
|
||
|
local isSelected = groupTree:IsGroupSelected(groupPath)
|
||
|
TSM.Groups.ImportExport.SetGroupFiltered(relativeGroupPath, not isSelected)
|
||
|
if isSelected then
|
||
|
local tempGroupPath = TSM.Groups.Path.Split(groupPath)
|
||
|
while tempGroupPath do
|
||
|
groupTree:SetGroupSelected(tempGroupPath, true)
|
||
|
tempGroupPath = TSM.Groups.Path.Split(tempGroupPath)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
for relativeGroupPath in TSM.Groups.ImportExport.PendingImportGroupIterator() do
|
||
|
local groupPath = relativeGroupPath == TSM.CONST.ROOT_GROUP_PATH and importGroupName or TSM.Groups.Path.Join(importGroupName, relativeGroupPath)
|
||
|
local isSelected = groupTree:IsGroupSelected(groupPath)
|
||
|
TSM.Groups.ImportExport.SetGroupFiltered(relativeGroupPath, not isSelected)
|
||
|
end
|
||
|
private.UpdateImportConfirmationDialog(groupTree:GetParentElement():GetParentElement())
|
||
|
end
|
||
|
|
||
|
function private.ImportIncludeOperationsCheckboxOnValueChanged(checkbox)
|
||
|
if checkbox:IsChecked() then
|
||
|
checkbox:GetElement("__parent.replaceCheckbox"):Show()
|
||
|
else
|
||
|
checkbox:GetElement("__parent.replaceCheckbox"):Hide()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.ImportBtnOnClick(button)
|
||
|
local moveExistingItems = button:GetElement("__parent.items.moveCheckbox"):IsChecked()
|
||
|
local includeOperations = button:GetElement("__parent.operations.includeCheckbox"):IsChecked()
|
||
|
local replaceOperations = button:GetElement("__parent.operations.replaceCheckbox"):IsChecked()
|
||
|
TSM.Groups.ImportExport.CommitImport(moveExistingItems, includeOperations, replaceOperations)
|
||
|
button:GetBaseElement():HideDialog()
|
||
|
end
|
||
|
|
||
|
function private.ImportOnHide()
|
||
|
TSM.Groups.ImportExport.ClearImportContext()
|
||
|
end
|
||
|
|
||
|
function private.GroupTreeOnGroupSelected(groupTree, path)
|
||
|
local view = groupTree:GetElement("__parent.__parent.view")
|
||
|
if view ~= "content" then
|
||
|
view:SetPath("content", true)
|
||
|
end
|
||
|
|
||
|
private.currentGroupPath = path
|
||
|
local contentFrame = view:GetElement("content")
|
||
|
local titleFrame = contentFrame:GetElement("header.title")
|
||
|
local buttonsFrame = contentFrame:GetElement("buttons")
|
||
|
|
||
|
if path == TSM.CONST.ROOT_GROUP_PATH then
|
||
|
titleFrame:GetElement("icon")
|
||
|
:SetTextureAndSize(TSM.UI.TexturePacks.GetColoredKey("iconPack.18x18/Folder", "TEXT"))
|
||
|
titleFrame:GetElement("text")
|
||
|
:SetTextColor("TEXT")
|
||
|
:SetText(L["Base Group"])
|
||
|
:SetEditing(false)
|
||
|
titleFrame:GetElement("renameBtn"):Hide()
|
||
|
titleFrame:GetElement("exportBtn"):Hide()
|
||
|
buttonsFrame:RenamePath(L["Information"], 1)
|
||
|
else
|
||
|
local groupColor = Theme.GetGroupColor(select('#', strsplit(TSM.CONST.GROUP_SEP, path)))
|
||
|
titleFrame:GetElement("icon")
|
||
|
:SetTextureAndSize(TSM.UI.TexturePacks.GetColoredKey("iconPack.18x18/Folder", groupColor))
|
||
|
titleFrame:GetElement("text")
|
||
|
:SetTextColor(groupColor)
|
||
|
:SetText(TSM.Groups.Path.GetName(path))
|
||
|
:SetEditing(false)
|
||
|
titleFrame:GetElement("renameBtn"):Show()
|
||
|
titleFrame:GetElement("exportBtn"):Show()
|
||
|
buttonsFrame:RenamePath(L["Items"], 1)
|
||
|
end
|
||
|
-- Show the frame in case it is hidden by filter
|
||
|
buttonsFrame:Show()
|
||
|
buttonsFrame:Draw()
|
||
|
titleFrame:Draw()
|
||
|
contentFrame:GetElement("buttons"):ReloadContent()
|
||
|
end
|
||
|
|
||
|
function private.GroupTreeOnNewGroup(groupTree)
|
||
|
groupTree:GetElement("__parent.__parent.view.content.header.title.text"):SetEditing(true)
|
||
|
end
|
||
|
|
||
|
function private.GroupNameChanged(text, newValue)
|
||
|
newValue = strtrim(newValue)
|
||
|
local parent = TSM.Groups.Path.GetParent(private.currentGroupPath)
|
||
|
local newPath = parent and parent ~= TSM.CONST.ROOT_GROUP_PATH and (parent..TSM.CONST.GROUP_SEP..newValue) or newValue
|
||
|
if newPath == private.currentGroupPath then
|
||
|
-- didn't change
|
||
|
text:Draw()
|
||
|
elseif strfind(newValue, TSM.CONST.GROUP_SEP) or newValue == "" then
|
||
|
Log.PrintUser(L["Invalid group name."])
|
||
|
text:Draw()
|
||
|
elseif TSM.Groups.Exists(newPath) then
|
||
|
Log.PrintUser(L["Group already exists."])
|
||
|
text:Draw()
|
||
|
else
|
||
|
TSM.Groups.Move(private.currentGroupPath, newPath)
|
||
|
Analytics.Action("MOVED_GROUP", private.currentGroupPath, newPath)
|
||
|
text:GetElement("__parent.__parent.__parent.__parent.__parent.groupSelection.groupTree"):SetSelectedGroup(newPath, true)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.NameOnEditingChanged(text, editing)
|
||
|
if editing then
|
||
|
text:GetElement("__parent.renameBtn"):Hide()
|
||
|
text:GetElement("__parent.exportBtn"):Hide()
|
||
|
else
|
||
|
text:GetElement("__parent.renameBtn"):Show()
|
||
|
text:GetElement("__parent.exportBtn"):Show()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.RenameBtnOnClick(button)
|
||
|
button:GetElement("__parent.text"):SetEditing(true)
|
||
|
end
|
||
|
|
||
|
function private.ExportBtnOnClick(button)
|
||
|
-- build the export DB
|
||
|
wipe(private.exportSubGroups)
|
||
|
private.importExportGroupDB:TruncateAndBulkInsertStart()
|
||
|
for _, groupPath in TSM.Groups.GroupIterator() do
|
||
|
local relGroupPath = nil
|
||
|
if TSM.Groups.Path.IsChild(groupPath, private.currentGroupPath) then
|
||
|
relGroupPath = TSM.Groups.Path.GetRelative(groupPath, private.currentGroupPath)
|
||
|
end
|
||
|
if relGroupPath then
|
||
|
private.exportSubGroups[relGroupPath] = true
|
||
|
local orderStr = gsub(relGroupPath, TSM.CONST.GROUP_SEP, "\001")
|
||
|
orderStr = strlower(orderStr)
|
||
|
private.importExportGroupDB:BulkInsertNewRow(relGroupPath, orderStr)
|
||
|
end
|
||
|
end
|
||
|
private.importExportGroupDB:BulkInsertEnd()
|
||
|
|
||
|
local str, numItems, numSubGroups, numOperations, numCustomSources = TSM.Groups.ImportExport.GenerateExport(private.currentGroupPath, private.exportSubGroups, false, false)
|
||
|
local groupColor = Theme.GetGroupColor(select('#', strsplit(TSM.CONST.GROUP_SEP, private.currentGroupPath)))
|
||
|
button:GetBaseElement():ShowDialogFrame(UIElements.New("Frame", "frame")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetSize(658, 408)
|
||
|
:SetPadding(12)
|
||
|
:AddAnchor("CENTER")
|
||
|
:SetBackgroundColor("FRAME_BG", true)
|
||
|
:SetMouseEnabled(true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(20, -4, -4, 12)
|
||
|
:AddChild(UIElements.New("Text", "title")
|
||
|
:SetFont("BODY_BODY2_BOLD")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(L["Export"]..": "..groupColor:ColorText(TSM.Groups.Path.GetName(private.currentGroupPath)))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "closeBtn")
|
||
|
:SetBackgroundAndSize("iconPack.24x24/Close/Default")
|
||
|
:SetScript("OnClick", private.ImportExportCloseBtnOnClick)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "desc")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetText(L["You can use the export string below to share this group with others."])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "options")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(20)
|
||
|
:SetMargin(0, 0, 0, 12)
|
||
|
:AddChild(UIElements.New("GroupSelector", "subGroups")
|
||
|
:SetWidth(240)
|
||
|
:SetMargin(0, 12, 0, 0)
|
||
|
:SetSelectedText(L["%d subgroups included"])
|
||
|
:SetCustomQueryFunc(private.CreateImportExportDBQuery)
|
||
|
:SetSelection(private.exportSubGroups)
|
||
|
:SetHintText(L["Select included subgroups"])
|
||
|
:SetScript("OnSelectionChanged", private.ExportOptionOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "excludeOperations")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 12, 0, 0)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Exclude operations?"])
|
||
|
:SetScript("OnValueChanged", private.ExportOptionOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Checkbox", "excludeCustomSources")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 12, 0, 0)
|
||
|
:SetFont("BODY_BODY3")
|
||
|
:SetCheckboxPosition("LEFT")
|
||
|
:SetText(L["Exclude custom sources?"])
|
||
|
:SetScript("OnValueChanged", private.ExportOptionOnValueChanged)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "heading")
|
||
|
:SetMargin(0, 0, 0, 8)
|
||
|
:SetHeight(20)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(L["Export String"])
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "content")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||
|
:AddChild(UIElements.New("MultiLineInput", "input")
|
||
|
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||
|
:SetValue(str)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line")
|
||
|
:SetHeight(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "footer")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(28)
|
||
|
:SetPadding(8, 8, 4, 4)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
:AddChild(UIElements.New("Text", "items")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(format(L["%d Items"], numItems))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line1")
|
||
|
:SetWidth(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "subGroups")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(format(L["%d Sub-Groups"], numSubGroups))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line2")
|
||
|
:SetWidth(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "operations")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 8, 0, 0)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(format(L["%d Operations"], numOperations))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Texture", "line3")
|
||
|
:SetWidth(2)
|
||
|
:SetTexture("ACTIVE_BG")
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "customSources")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(8, 0, 0, 0)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetText(format(L["%d Custom Sources"], numCustomSources))
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
|
||
|
function private.CreateImportExportDBQuery()
|
||
|
return private.importExportGroupDB:NewQuery()
|
||
|
:OrderBy("orderStr", true)
|
||
|
end
|
||
|
|
||
|
function private.ImportExportCloseBtnOnClick(button)
|
||
|
button:GetBaseElement():HideDialog()
|
||
|
end
|
||
|
|
||
|
function private.ExportOptionOnValueChanged(element)
|
||
|
wipe(private.exportSubGroups)
|
||
|
for groupPath in element:GetElement("__parent.subGroups"):SelectedGroupIterator() do
|
||
|
private.exportSubGroups[groupPath] = true
|
||
|
end
|
||
|
local excludeOperations = element:GetElement("__parent.excludeOperations"):IsChecked()
|
||
|
local excludeCustomSources = element:GetElement("__parent.excludeCustomSources"):IsChecked()
|
||
|
local str, numItems, numSubGroups, numOperations, numCustomSources = TSM.Groups.ImportExport.GenerateExport(private.currentGroupPath, private.exportSubGroups, excludeOperations, excludeCustomSources)
|
||
|
element:GetElement("__parent.excludeCustomSources")
|
||
|
:SetDisabled(excludeOperations)
|
||
|
:SetChecked(excludeCustomSources and not excludeOperations, true)
|
||
|
:Draw()
|
||
|
local content = element:GetElement("__parent.__parent.content")
|
||
|
content:GetElement("input"):SetValue(str)
|
||
|
content:GetElement("footer.items"):SetText(format(L["%d Items"], numItems))
|
||
|
content:GetElement("footer.subGroups"):SetText(format(L["%d Sub-Groups"], numSubGroups))
|
||
|
content:GetElement("footer.operations"):SetText(format(L["%d Operations"], numOperations))
|
||
|
content:GetElement("footer.customSources"):SetText(format(L["%d Custom Sources"], numCustomSources))
|
||
|
content:Draw()
|
||
|
end
|
||
|
|
||
|
function private.ItemFilterValidateFunc(_, value)
|
||
|
return private.itemFilter:ParseStr(value)
|
||
|
end
|
||
|
|
||
|
function private.ItemFilterOnValueChanged(input)
|
||
|
local text = input:GetValue()
|
||
|
if private.itemSearch == text then
|
||
|
return
|
||
|
end
|
||
|
private.itemSearch = text
|
||
|
|
||
|
input:GetElement("__parent.__parent.content.ungrouped.content.itemList")
|
||
|
:SetFilterFunction(private.ItemListItemIsFiltered)
|
||
|
:Draw()
|
||
|
input:GetElement("__parent.__parent.content.grouped.content.itemList")
|
||
|
:SetFilterFunction(private.ItemListItemIsFiltered)
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.UpdateBaseItemList()
|
||
|
wipe(private.results[1])
|
||
|
wipe(private.results[2])
|
||
|
local addedItems = TempTable.Acquire()
|
||
|
for _, itemString in ipairs(private.resultsRaw) do
|
||
|
if private.settings.groups[private.currentGroupPath].ignoreItemVariations then
|
||
|
itemString = ItemString.GetBase(itemString)
|
||
|
else
|
||
|
if ItemString.IsPet(itemString) and itemString == ItemString.GetBase(itemString) then
|
||
|
addedItems[itemString] = true
|
||
|
end
|
||
|
end
|
||
|
if not TSM.Groups.IsItemInGroup(itemString) and not addedItems[itemString] then
|
||
|
tinsert(private.results[1], itemString)
|
||
|
addedItems[itemString] = true
|
||
|
end
|
||
|
end
|
||
|
TempTable.Release(addedItems)
|
||
|
private.results[1].header = Theme.GetColor("INDICATOR"):ColorText(L["Search Results"].."|r")
|
||
|
end
|
||
|
|
||
|
function private.ValidateBaseSearchValue(_, value)
|
||
|
if value == "" then
|
||
|
return true
|
||
|
elseif #value < 3 then
|
||
|
return false, L["The search term must be at least 3 characters."]
|
||
|
elseif not private.itemFilter:ParseStr(value) then
|
||
|
return false, L["Invalid search term."]
|
||
|
elseif private.itemFilter:GetStr() and #private.itemFilter:GetStr() < 3 then
|
||
|
return false, L["The name portion of the search term must be at least 3 characters if present."]
|
||
|
elseif private.itemFilter:GetMinPrice() or private.itemFilter:GetMaxPrice() then
|
||
|
return false, L["Invalid search term. Cannot filter by price here."]
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
function private.InformationSearchOnValueChanged(input)
|
||
|
local value = input:GetValue()
|
||
|
if private.itemSearch == value or value == "" then
|
||
|
return
|
||
|
end
|
||
|
private.BaseSearchOnValueChanged(input)
|
||
|
private.frame:GetBaseElement():GetElement("content.groups.view.content.header.input")
|
||
|
:SetFocused(true)
|
||
|
:ClearHighlight()
|
||
|
end
|
||
|
|
||
|
function private.BaseSearchOnValueChanged(input)
|
||
|
local value = input:GetValue()
|
||
|
if private.itemSearch == value or value == "" then
|
||
|
return
|
||
|
end
|
||
|
assert(private.itemFilter:ParseStr(value))
|
||
|
private.itemSearch = value
|
||
|
ItemInfo.MatchItemFilter(private.itemFilter, wipe(private.resultsRaw))
|
||
|
private.UpdateBaseItemList()
|
||
|
private.frame:GetBaseElement():GetElement("content.groups.view"):SetPath("search", true)
|
||
|
private.frame:GetBaseElement():GetElement("content.groups.view.content.itemList"):SetItems(private.results, true)
|
||
|
private.frame:GetBaseElement():GetElement("content.groups.view.content.header2.label")
|
||
|
:SetText(format(L["%d Results"], #private.results[1]))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.SelectAllResultsOnClick(button)
|
||
|
button:GetElement("__parent.__parent.itemList"):ToggleSelectAll()
|
||
|
end
|
||
|
|
||
|
function private.IgnoreSearchRandomOnValueChanged(checkbox, checked)
|
||
|
private.UpdateBaseItemList()
|
||
|
checkbox:GetElement("__parent.__parent.itemList"):SetItems(private.results, true)
|
||
|
checkbox:GetElement("__parent.label")
|
||
|
:SetText(format(L["%d Results"], #private.results[1]))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.SearchBackButtonOnClick(button)
|
||
|
button:GetBaseElement():GetElement("content.groups.view"):SetPath("content", true)
|
||
|
end
|
||
|
|
||
|
function private.IgnoreBaseRandomOnValueChanged(checkbox, checked)
|
||
|
-- update the base item list
|
||
|
checkbox:GetElement("__parent.__parent.itemList"):SetItems(private.GetUngroupedBagItemList(), true)
|
||
|
end
|
||
|
|
||
|
function private.ItemListOnSelectionChanged(itemList)
|
||
|
local selection = itemList:GetElement("__parent.bottom.group"):GetSelection()
|
||
|
local button = itemList:GetElement("__parent.bottom.move")
|
||
|
local numSelected = itemList:GetNumSelected()
|
||
|
button:SetDisabled(not selection or numSelected == 0)
|
||
|
:SetText(numSelected == 0 and L["Move Item"] or format(L["Move %d |4Item:Items"], numSelected))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.BaseMoveItemOnClick(button)
|
||
|
assert(private.moveGroupPath)
|
||
|
local itemList = button:GetElement("__parent.__parent.itemList")
|
||
|
local numAdded = 0
|
||
|
for _, itemLink in ipairs(private.results[1]) do
|
||
|
if itemList:IsItemSelected(itemLink) then
|
||
|
local itemString = ItemString.Get(itemLink)
|
||
|
TSM.Groups.SetItemGroup(itemString, private.moveGroupPath)
|
||
|
numAdded = numAdded + 1
|
||
|
end
|
||
|
end
|
||
|
Analytics.Action("ADDED_GROUP_ITEMS", private.moveGroupPath, numAdded)
|
||
|
private.UpdateBaseItemList()
|
||
|
itemList:SetItems(private.results, true)
|
||
|
itemList:GetElement("__parent.header2.label")
|
||
|
:SetText(format(L["%d Results"], #private.results[1]))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.MoveItemOnClick(button)
|
||
|
assert(private.moveGroupPath)
|
||
|
local itemList = button:GetElement("__parent.__parent.itemList")
|
||
|
local numAdded = 0
|
||
|
for _, items in ipairs(private.GetUngroupedBagItemList()) do
|
||
|
for _, itemLink in ipairs(items) do
|
||
|
if itemList:IsItemSelected(itemLink) then
|
||
|
local itemString = ItemString.Get(itemLink)
|
||
|
TSM.Groups.SetItemGroup(itemString, private.moveGroupPath)
|
||
|
numAdded = numAdded + 1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Analytics.Action("ADDED_GROUP_ITEMS", private.moveGroupPath, numAdded)
|
||
|
itemList:SetItems(private.GetUngroupedBagItemList(), true)
|
||
|
end
|
||
|
|
||
|
function private.BaseGroupOnSelectionChanged(self)
|
||
|
local selection = self:GetSelection()
|
||
|
private.moveGroupPath = selection
|
||
|
local numSelected = self:GetBaseElement():GetElement("content.groups.view.content.itemList"):GetNumSelected()
|
||
|
self:GetBaseElement():GetElement("content.groups.view.content.bottom.move")
|
||
|
:SetDisabled(not selection or numSelected == 0)
|
||
|
:SetText(numSelected == 0 and L["Move Item"] or format(L["Move %d |4Item:Items"], numSelected))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.GroupOnSelectionChanged(self)
|
||
|
local selection = self:GetSelection()
|
||
|
private.moveGroupPath = selection
|
||
|
local numSelected = self:GetBaseElement():GetElement("content.groups.view.content.buttons.items.itemList"):GetNumSelected()
|
||
|
self:GetBaseElement():GetElement("content.groups.view.content.buttons.items.bottom.move")
|
||
|
:SetDisabled(not selection or numSelected == 0)
|
||
|
:SetText(numSelected == 0 and L["Move Item"] or format(L["Move %d |4Item:Items"], numSelected))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.IgnoreRandomOnValueChanged(checkbox, checked)
|
||
|
-- update the ungrouped item list
|
||
|
checkbox:GetElement("__parent.__parent.content.ungrouped.content.itemList"):SetItems(private.GetUngroupedItemList(), true)
|
||
|
end
|
||
|
|
||
|
function private.AddItemsOnClick(button)
|
||
|
local itemList = button:GetElement("__parent.content.itemList")
|
||
|
local numAdded = 0
|
||
|
for _, items in ipairs(private.GetUngroupedItemList()) do
|
||
|
for _, itemLink in ipairs(items) do
|
||
|
if itemList:IsItemSelected(itemLink) then
|
||
|
local itemString = ItemString.Get(itemLink)
|
||
|
TSM.Groups.SetItemGroup(itemString, private.currentGroupPath)
|
||
|
numAdded = numAdded + 1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Analytics.Action("ADDED_GROUP_ITEMS", private.currentGroupPath, numAdded)
|
||
|
|
||
|
-- update the item lists
|
||
|
itemList:SetItems(private.GetUngroupedItemList(), true)
|
||
|
local otherItemList = button:GetElement("__parent.__parent.grouped.content.itemList")
|
||
|
otherItemList:SetItems(private.GetGroupedItemList(), true)
|
||
|
end
|
||
|
|
||
|
function private.ItemListSelectAllOnClick(button)
|
||
|
button:GetElement("__parent.__parent.itemList"):ToggleSelectAll()
|
||
|
end
|
||
|
|
||
|
function private.UngroupedItemsOnSelectionChanged(itemList)
|
||
|
local button = itemList:GetElement("__parent.__parent.btn")
|
||
|
local numSelected = itemList:GetNumSelected()
|
||
|
button:SetDisabled(numSelected == 0)
|
||
|
:SetText(numSelected == 0 and L["Add"] or format(L["Add %d |4Item:Items"], numSelected))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.GroupedItemsOnSelectionChanged(itemList)
|
||
|
local button = itemList:GetElement("__parent.__parent.btn")
|
||
|
local numSelected = itemList:GetNumSelected()
|
||
|
local parentGroup = TSM.Groups.Path.GetParent(private.currentGroupPath)
|
||
|
parentGroup = parentGroup ~= TSM.CONST.ROOT_GROUP_PATH and parentGroup or nil
|
||
|
if parentGroup then
|
||
|
button:SetModifierText(numSelected == 0 and L["Move to Parent Group"] or format(L["Move %d |4Item:Items"], numSelected), "SHIFT")
|
||
|
end
|
||
|
button:SetDisabled(numSelected == 0)
|
||
|
:SetText(numSelected == 0 and L["Remove"] or format(L["Remove %d |4Item:Items"], numSelected))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.RebuildModuleOperations(moduleOperationFrame)
|
||
|
local moduleName = moduleOperationFrame:GetContext()
|
||
|
local override = TSM.Groups.HasOperationOverride(private.currentGroupPath, moduleName) or private.currentGroupPath == TSM.CONST.ROOT_GROUP_PATH
|
||
|
|
||
|
-- remove the existing operations container and add more row
|
||
|
local content = moduleOperationFrame:GetElement("content")
|
||
|
local container = content:GetElement("container")
|
||
|
content:RemoveChild(container)
|
||
|
container:Release()
|
||
|
if content:HasChildById("addMore") then
|
||
|
local addMore = content:GetElement("addMore")
|
||
|
content:RemoveChild(addMore)
|
||
|
addMore:Release()
|
||
|
end
|
||
|
|
||
|
local numGroupOperations = 0
|
||
|
for _ in TSM.Groups.OperationIterator(private.currentGroupPath, moduleName) do
|
||
|
numGroupOperations = numGroupOperations + 1
|
||
|
end
|
||
|
moduleOperationFrame:AddChild(UIElements.New("Frame", "container")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetContext(moduleName)
|
||
|
:SetHeight(36 * numGroupOperations)
|
||
|
:AddChildrenWithFunction(private.AddOperationRows)
|
||
|
)
|
||
|
moduleOperationFrame:AddChildIf(override and numGroupOperations < TSM.Operations.GetMaxNumber(moduleName), UIElements.New("Frame", "addMore")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(0, 0, 8, 0)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer"))
|
||
|
:AddChild(UIElements.New("Button", "button")
|
||
|
:SetWidth("AUTO")
|
||
|
:SetMargin(0, 2, 0, 0)
|
||
|
:SetFont("BODY_BODY2")
|
||
|
:SetTextColor("INDICATOR")
|
||
|
:SetText(L["Add More Operations"])
|
||
|
:SetContext(moduleName)
|
||
|
:SetScript("OnClick", private.AddOperationButtonOnClick)
|
||
|
)
|
||
|
)
|
||
|
|
||
|
moduleOperationFrame:GetParentElement():Draw()
|
||
|
end
|
||
|
|
||
|
function private.RemoveItemsOnClick(button)
|
||
|
local itemList = button:GetElement("__parent.content.itemList")
|
||
|
local numRemoved = 0
|
||
|
local parentGroup = TSM.Groups.Path.GetParent(private.currentGroupPath)
|
||
|
parentGroup = parentGroup ~= TSM.CONST.ROOT_GROUP_PATH and parentGroup or nil
|
||
|
local targetGroup = IsShiftKeyDown() and parentGroup or nil
|
||
|
for _, itemLink in ipairs(private.GetGroupedItemList()) do
|
||
|
if itemList:IsItemSelected(itemLink) then
|
||
|
TSM.Groups.SetItemGroup(ItemString.Get(itemLink), targetGroup)
|
||
|
numRemoved = numRemoved + 1
|
||
|
end
|
||
|
end
|
||
|
Analytics.Action("REMOVED_GROUP_ITEMS", private.currentGroupPath, numRemoved, targetGroup or "")
|
||
|
|
||
|
-- update the item lists
|
||
|
itemList:SetItems(private.GetGroupedItemList(), true)
|
||
|
local otherItemList = button:GetElement("__parent.__parent.ungrouped.content.itemList")
|
||
|
otherItemList:SetItems(private.GetUngroupedItemList(), true)
|
||
|
end
|
||
|
|
||
|
function private.OverrideToggleOnValueChanged(checkbox, value)
|
||
|
assert(private.currentGroupPath ~= TSM.CONST.ROOT_GROUP_PATH)
|
||
|
local moduleOperationFrame = checkbox:GetParentElement():GetParentElement()
|
||
|
local moduleName = moduleOperationFrame:GetContext()
|
||
|
TSM.Groups.SetOperationOverride(private.currentGroupPath, moduleName, value)
|
||
|
Analytics.Action("CHANGED_GROUP_OVERRIDE", private.currentGroupPath, moduleName, value)
|
||
|
private.RebuildModuleOperations(moduleOperationFrame)
|
||
|
end
|
||
|
|
||
|
function private.ConfigOperationOnClick(button)
|
||
|
local moduleName = button:GetParentElement():GetParentElement():GetParentElement():GetParentElement():GetParentElement():GetContext()
|
||
|
local operationName = button:GetContext()
|
||
|
local baseFrame = button:GetBaseElement()
|
||
|
TSM.MainUI.Operations.ShowOperationSettings(baseFrame, moduleName, operationName)
|
||
|
end
|
||
|
|
||
|
function private.AddOperationButtonOnClick(button)
|
||
|
local moduleName = button:GetContext()
|
||
|
private.operationQuery = private.operationQuery or TSM.Operations.CreateQuery()
|
||
|
private.operationQuery:Reset()
|
||
|
private.operationQuery
|
||
|
:Contains("operationName", private.filterText)
|
||
|
:Equal("moduleName", moduleName)
|
||
|
:OrderBy("operationName", true)
|
||
|
button:GetBaseElement():ShowDialogFrame(UIElements.New("Frame", "frame")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetSize(464, 318)
|
||
|
:SetPadding(12)
|
||
|
:AddAnchor("CENTER")
|
||
|
:SetBackgroundColor("FRAME_BG")
|
||
|
:SetBorderColor("ACTIVE_BG")
|
||
|
:SetMouseEnabled(true)
|
||
|
:AddChild(UIElements.New("Frame", "header")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(0, 0, -4, 10)
|
||
|
:AddChild(UIElements.New("Spacer", "spacer")
|
||
|
:SetWidth(24)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Text", "title")
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetJustifyH("CENTER")
|
||
|
:SetText(format(L["Add %s Operation"], moduleName))
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "closeBtn")
|
||
|
:SetMargin(0, -4, 0, 0)
|
||
|
:SetBackgroundAndSize("iconPack.24x24/Close/Default")
|
||
|
:SetScript("OnClick", private.AddOperationCloseBtnOnClick)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Frame", "container")
|
||
|
:SetLayout("VERTICAL")
|
||
|
:SetPadding(1)
|
||
|
:SetBackgroundColor("PRIMARY_BG")
|
||
|
:AddChild(UIElements.New("Frame", "search")
|
||
|
:SetLayout("HORIZONTAL")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(8, 8, 8, 12)
|
||
|
:AddChild(UIElements.New("Input", "input")
|
||
|
:SetContext(moduleName)
|
||
|
:SetIconTexture("iconPack.18x18/Search")
|
||
|
:SetClearButtonEnabled(true)
|
||
|
:AllowItemInsert(true)
|
||
|
:SetHintText(format(L["Search %s operations"], strlower(moduleName)))
|
||
|
:SetValue(private.filterText)
|
||
|
:SetScript("OnValueChanged", private.OperationSearchOnValueChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("Button", "createOperation")
|
||
|
:SetHeight(24)
|
||
|
:SetPadding(8, 0, 0, 0)
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetContext(button)
|
||
|
:SetTextColor("INDICATOR")
|
||
|
:SetJustifyH("LEFT")
|
||
|
:SetText(L["Create New Operation"])
|
||
|
:SetScript("OnEnter", private.AddOperationCreateBtnOnEnter)
|
||
|
:SetScript("OnLeave", private.AddOperationCreateBtnOnLeave)
|
||
|
:SetScript("OnClick", private.AddOperationCreateBtnOnClick)
|
||
|
)
|
||
|
:AddChild(UIElements.New("QueryScrollingTable", "list")
|
||
|
:SetContext(moduleName)
|
||
|
:SetHeaderHidden(true)
|
||
|
:SetQuery(private.operationQuery)
|
||
|
:GetScrollingTableInfo()
|
||
|
:NewColumn("name")
|
||
|
:SetTitle("")
|
||
|
:SetFont("BODY_BODY2_MEDIUM")
|
||
|
:SetJustifyH("LEFT")
|
||
|
:SetTextInfo("operationName")
|
||
|
:Commit()
|
||
|
:Commit()
|
||
|
:SetScript("OnSelectionChanged", private.AddOperationSelectionChanged)
|
||
|
)
|
||
|
)
|
||
|
:AddChild(UIElements.New("ActionButton", "addBtn")
|
||
|
:SetHeight(24)
|
||
|
:SetMargin(0, 0, 8, 0)
|
||
|
:SetDisabled(true)
|
||
|
:SetContext(button)
|
||
|
:SetText(L["Add Operation"])
|
||
|
:SetScript("OnClick", private.AddOperationBtnOnClick)
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
|
||
|
function private.AddOperationCloseBtnOnClick(button)
|
||
|
button:GetBaseElement():HideDialog()
|
||
|
end
|
||
|
|
||
|
function private.AddOperationCreateBtnOnEnter(button)
|
||
|
button:SetTextColor("TEXT")
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.AddOperationCreateBtnOnLeave(button)
|
||
|
button:SetTextColor(Theme.GetGroupColor(1))
|
||
|
:Draw()
|
||
|
end
|
||
|
|
||
|
function private.AddOperationCreateBtnOnClick(button)
|
||
|
local scrollingTable = button:GetElement("__parent.list")
|
||
|
local moduleName = scrollingTable:GetContext()
|
||
|
local operationName = L["New Operation"]
|
||
|
local extra = ""
|
||
|
local num = 0
|
||
|
while TSM.Operations.Exists(moduleName, operationName..extra) do
|
||
|
num = num + 1
|
||
|
extra = " "..num
|
||
|
end
|
||
|
operationName = operationName..extra
|
||
|
TSM.Operations.Create(moduleName, operationName)
|
||
|
TSM.Groups.AppendOperation(private.currentGroupPath, moduleName, operationName)
|
||
|
Analytics.Action("ADDED_GROUP_OPERATION", private.currentGroupPath, moduleName, operationName)
|
||
|
TSM.MainUI.Operations.ShowOperationSettings(button:GetBaseElement(), moduleName, operationName)
|
||
|
end
|
||
|
|
||
|
function private.OperationSearchOnValueChanged(input)
|
||
|
local text = strlower(input:GetValue())
|
||
|
if text == private.filterText then
|
||
|
return
|
||
|
end
|
||
|
private.filterText = text
|
||
|
|
||
|
private.operationQuery:SetUpdatesPaused(true)
|
||
|
private.operationQuery:ResetFilters()
|
||
|
:Contains("operationName", private.filterText)
|
||
|
:Equal("moduleName", input:GetContext())
|
||
|
private.operationQuery:SetUpdatesPaused(false)
|
||
|
input:GetElement("__parent.__parent.list"):UpdateData(true)
|
||
|
end
|
||
|
|
||
|
function private.AddOperationBtnOnClick(button)
|
||
|
local scrollingTable = button:GetElement("__parent.container.list")
|
||
|
local moduleName = scrollingTable:GetContext()
|
||
|
local operationName = scrollingTable:GetSelection():GetField("operationName")
|
||
|
TSM.Groups.AppendOperation(private.currentGroupPath, scrollingTable:GetContext(), operationName)
|
||
|
Analytics.Action("ADDED_GROUP_OPERATION", private.currentGroupPath, moduleName, operationName)
|
||
|
local moduleOperationFrame = button:GetContext():GetElement("__parent.__parent.__parent")
|
||
|
private.RebuildModuleOperations(moduleOperationFrame)
|
||
|
moduleOperationFrame:GetBaseElement():HideDialog()
|
||
|
end
|
||
|
|
||
|
function private.AddOperationSelectionChanged(scrollingTable)
|
||
|
if scrollingTable:GetSelection() then
|
||
|
scrollingTable:GetElement("__parent.__parent.addBtn")
|
||
|
:SetDisabled(false)
|
||
|
:Draw()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function private.RemoveOperationOnClick(button)
|
||
|
local moduleOperationFrame = button:GetElement("__parent.__parent.__parent.__parent.__parent")
|
||
|
local moduleName = moduleOperationFrame:GetContext()
|
||
|
local operationIndex = button:GetContext()
|
||
|
local operationName = nil
|
||
|
for index, name in TSM.Groups.OperationIterator(private.currentGroupPath, moduleName) do
|
||
|
if index == operationIndex then
|
||
|
operationName = name
|
||
|
end
|
||
|
end
|
||
|
assert(operationName)
|
||
|
TSM.Groups.RemoveOperation(private.currentGroupPath, moduleName, operationIndex)
|
||
|
Analytics.Action("REMOVED_GROUP_OPERATION", private.currentGroupPath, moduleName, operationName)
|
||
|
private.RebuildModuleOperations(moduleOperationFrame)
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Helper Functions
|
||
|
-- ============================================================================
|
||
|
|
||
|
function private.ItemSortHelper(a, b)
|
||
|
return (ItemInfo.GetName(a) or "") < (ItemInfo.GetName(b) or "")
|
||
|
end
|
||
|
|
||
|
function private.GetUngroupedBagItemList()
|
||
|
wipe(private.ungroupedItemList[1])
|
||
|
wipe(private.ungroupedItemList[2])
|
||
|
|
||
|
-- items in bags
|
||
|
local addedItems = TempTable.Acquire()
|
||
|
local query = BagTracking.CreateQueryBags()
|
||
|
:OrderBy("slotId", true)
|
||
|
:Select("itemString")
|
||
|
:Equal("isBoP", false)
|
||
|
for _, itemString in query:Iterator() do
|
||
|
if private.settings.groups[private.currentGroupPath].ignoreItemVariations then
|
||
|
itemString = ItemString.GetBase(itemString)
|
||
|
end
|
||
|
if not TSM.Groups.IsItemInGroup(itemString) and not addedItems[itemString] then
|
||
|
local itemLink = ItemInfo.GetLink(itemString)
|
||
|
tinsert(private.ungroupedItemList[1], itemLink)
|
||
|
addedItems[itemString] = true
|
||
|
end
|
||
|
end
|
||
|
query:Release()
|
||
|
TempTable.Release(addedItems)
|
||
|
private.ungroupedItemList[1].header = Theme.GetColor("INDICATOR"):ColorText(L["Ungrouped Items in Bags"])
|
||
|
|
||
|
sort(private.ungroupedItemList[1], private.ItemSortHelper)
|
||
|
return private.ungroupedItemList
|
||
|
end
|
||
|
|
||
|
function private.GetUngroupedItemList()
|
||
|
wipe(private.ungroupedItemList[1])
|
||
|
wipe(private.ungroupedItemList[2])
|
||
|
|
||
|
-- items in bags
|
||
|
local addedItems = TempTable.Acquire()
|
||
|
local query = BagTracking.CreateQueryBags()
|
||
|
:OrderBy("slotId", true)
|
||
|
:Select("itemString")
|
||
|
:Equal("isBoP", false)
|
||
|
for _, itemString in query:Iterator() do
|
||
|
if private.settings.groups[private.currentGroupPath].ignoreItemVariations then
|
||
|
itemString = ItemString.GetBase(itemString)
|
||
|
end
|
||
|
if not TSM.Groups.IsItemInGroup(itemString) and not addedItems[itemString] then
|
||
|
local itemLink = ItemInfo.GetLink(itemString)
|
||
|
tinsert(private.ungroupedItemList[1], itemLink)
|
||
|
addedItems[itemString] = true
|
||
|
end
|
||
|
end
|
||
|
query:Release()
|
||
|
TempTable.Release(addedItems)
|
||
|
private.ungroupedItemList[1].header = Theme.GetColor("INDICATOR"):ColorText(L["Ungrouped Items in Bags"])
|
||
|
|
||
|
-- items in the parent group
|
||
|
local parentGroupPath = TSM.Groups.Path.GetParent(private.currentGroupPath)
|
||
|
if parentGroupPath ~= TSM.CONST.ROOT_GROUP_PATH then
|
||
|
for _, itemString in TSM.Groups.ItemIterator(parentGroupPath) do
|
||
|
local itemLink = ItemInfo.GetLink(itemString)
|
||
|
tinsert(private.ungroupedItemList[2], itemLink)
|
||
|
end
|
||
|
end
|
||
|
private.ungroupedItemList[2].header = Theme.GetColor("INDICATOR"):ColorText(L["Parent Items"])
|
||
|
|
||
|
sort(private.ungroupedItemList[1], private.ItemSortHelper)
|
||
|
sort(private.ungroupedItemList[2], private.ItemSortHelper)
|
||
|
return private.ungroupedItemList
|
||
|
end
|
||
|
|
||
|
function private.GetGroupedItemList()
|
||
|
wipe(private.groupedItemList)
|
||
|
|
||
|
-- items in this group or a subgroup
|
||
|
local itemNames = TempTable.Acquire()
|
||
|
for _, itemString in TSM.Groups.ItemIterator(private.currentGroupPath, true) do
|
||
|
local link = ItemInfo.GetLink(itemString)
|
||
|
tinsert(private.groupedItemList, link)
|
||
|
itemNames[link] = ItemInfo.GetName(itemString) or ""
|
||
|
end
|
||
|
|
||
|
Table.SortWithValueLookup(private.groupedItemList, itemNames)
|
||
|
TempTable.Release(itemNames)
|
||
|
return private.groupedItemList
|
||
|
end
|
||
|
|
||
|
function private.ItemListItemIsFiltered(itemLink)
|
||
|
local basePrice = CustomPrice.GetValue(private.settings.groupPriceSource, itemLink)
|
||
|
return not private.itemFilter:Matches(itemLink, basePrice)
|
||
|
end
|