Zerotorescue@62: local addon = select(2, ...); Zerotorescue@62: local mod = addon:NewModule("Config"); Zerotorescue@62: Zerotorescue@62: local options, groupIdToName, groupIsVirtual, temp, count, includeTradeSkillItems, currentGroupType = {}, {}, {}, {}, 0, 500, "Normal"; Zerotorescue@62: local AceConfigDialog, AceConfigRegistry, AceSerializer; Zerotorescue@62: Zerotorescue@76: local unknownItemName = "Unknown (#%d)"; Zerotorescue@76: Zerotorescue@62: -- Private functions and tables Zerotorescue@62: Zerotorescue@62: local function SetOption(info, value, multiSelectEnabled) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local optionName = info[#info]; Zerotorescue@62: Zerotorescue@62: -- Special treatment for override toggle boxes Zerotorescue@62: if optionName:find("override") then Zerotorescue@62: if not value and info.arg then Zerotorescue@62: -- If this override was disabled and a saved variable name was provided, set it to nil rather than false Zerotorescue@62: Zerotorescue@62: value = nil; Zerotorescue@62: Zerotorescue@62: -- If this is an override toggler then also set the related field to nil Zerotorescue@62: addon.db.profile.groups[groupName][info.arg] = nil; Zerotorescue@62: elseif value and info.arg then Zerotorescue@62: -- If this override is now enabled, we need to copy the default into this field (unless it is not nil (which is supposed to be impossible), in which case we'll use the already selected value) Zerotorescue@62: Zerotorescue@68: local inheritedValue = addon:GetOptionByKey(groupName, info.arg); Zerotorescue@68: Zerotorescue@75: addon.db.profile.groups[groupName][info.arg] = (type(inheritedValue) == "table" and CopyTable(inheritedValue)) or inheritedValue; -- copying defaults by reference would let one (unintendedly) change the defaults Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: if multiSelectEnabled ~= nil then Zerotorescue@62: -- The saved vars for a multiselect will always be an array, it may not yet exist in which case it must be created. Zerotorescue@62: if not addon.db.profile.groups[groupName][optionName] then Zerotorescue@62: addon.db.profile.groups[groupName][optionName] = {}; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: addon.db.profile.groups[groupName][optionName][value] = multiSelectEnabled or nil; Zerotorescue@62: else Zerotorescue@62: addon.db.profile.groups[groupName][optionName] = value; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local function GetOption(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local optionName = info[#info]; Zerotorescue@62: Zerotorescue@62: local noDefault; Zerotorescue@62: Zerotorescue@62: if optionName:find("override") then Zerotorescue@62: noDefault = true; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return addon:GetOptionByKey(groupName, optionName, noDefault); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local function GetMultiOption(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local optionName = info[#info]; Zerotorescue@62: Zerotorescue@68: local multiSelectValue = addon:GetOptionByKey(groupName, optionName); Zerotorescue@68: Zerotorescue@68: return multiSelectValue and multiSelectValue[value]; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local function GetDisabled(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local optionName = info[#info]; Zerotorescue@62: Zerotorescue@62: if optionName:find("override") or not info.arg then Zerotorescue@62: return false; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return (addon:GetOptionByKey(groupName, info.arg, true) == nil); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local function ValidateGroupName(_, value) Zerotorescue@62: value = string.lower(string.trim(value or "")); Zerotorescue@62: Zerotorescue@62: for name, _ in pairs(addon.db.profile.groups) do Zerotorescue@62: if string.lower(name) == value then Zerotorescue@62: return ("A group named \"%s\" already exists."):format(name); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return true; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local tblAddItemTemplate = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "input", Zerotorescue@62: name = function(info) Zerotorescue@62: local itemName, _, itemRarity = GetItemInfo(info[#info]); Zerotorescue@62: return tostring( 7 - (itemRarity or 0) ) .. (itemName or ""); Zerotorescue@62: end, Zerotorescue@62: get = function(info) Zerotorescue@140: return tostring(info[#info]); -- Ace is going to be bitching about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side Zerotorescue@62: end, Zerotorescue@75: set = function(groupId, itemData) Zerotorescue@62: -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info. Zerotorescue@62: Zerotorescue@76: if itemData then Zerotorescue@76: local groupName = groupIdToName[groupId]; Zerotorescue@76: Zerotorescue@76: if not itemData:AddToGroup(groupName) then Zerotorescue@98: addon:Print("Couldn't add the item with itemId (" .. itemData.id .. ") because it is already in a group.", addon.Colors.Red); Zerotorescue@76: end Zerotorescue@76: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: width = "double", Zerotorescue@62: dialogControl = "ConfigItemLinkButton", Zerotorescue@62: }; Zerotorescue@62: Zerotorescue@62: local tblRemoveItemTemplate = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "input", Zerotorescue@62: name = function(info) Zerotorescue@62: local itemName, _, itemRarity = GetItemInfo(info[#info]); Zerotorescue@62: return tostring( 7 - (itemRarity or 0) ) .. (itemName or ""); Zerotorescue@62: end, Zerotorescue@62: get = function(info) Zerotorescue@62: return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side Zerotorescue@62: end, Zerotorescue@75: set = function(groupId, itemData) Zerotorescue@62: -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info. Zerotorescue@62: Zerotorescue@76: if itemData then Zerotorescue@62: local groupName = groupIdToName[groupId]; Zerotorescue@62: Zerotorescue@76: itemData:RemoveFromGroup(groupName); Zerotorescue@62: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: width = "double", Zerotorescue@62: dialogControl = "ConfigItemLinkButton", Zerotorescue@62: }; Zerotorescue@62: Zerotorescue@62: local function UpdateAddItemList(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: if not addon.db.profile.groups[groupName].items then Zerotorescue@62: addon.db.profile.groups[groupName].items = {}; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@140: -- Merge all items from all groups together (we only use this to check if an item is already in a group) Zerotorescue@62: local items = {}; Zerotorescue@62: for groupName, values in pairs(addon.db.profile.groups) do Zerotorescue@62: if values.items then Zerotorescue@140: for itemId, count in pairs(values.items) do Zerotorescue@140: items[itemId] = tonumber(count) or 0; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local ref = options.args.groups.args[info[2]].args.add.args.list.args; Zerotorescue@62: Zerotorescue@62: -- Remaking the list, so out with the old, in with the new Zerotorescue@62: table.wipe(ref); Zerotorescue@62: Zerotorescue@62: -- Parse bags and show these Zerotorescue@62: for bagID = 4, 0, -1 do Zerotorescue@62: for slot = 1, GetContainerNumSlots(bagID) do Zerotorescue@62: local itemId = addon:GetItemId(GetContainerItemLink(bagID, slot)); Zerotorescue@62: Zerotorescue@62: if itemId then Zerotorescue@62: if not items[itemId] then Zerotorescue@62: -- If this item isn't used in any group yet Zerotorescue@62: ref[itemId] = tblAddItemTemplate; Zerotorescue@62: else Zerotorescue@62: -- It's already used in a group, don't show it Zerotorescue@62: ref[itemId] = nil; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: if includeTradeSkillItems ~= 500 then Zerotorescue@62: -- Include tradeskill items Zerotorescue@62: Zerotorescue@62: -- Go through all trade skills for the profession Zerotorescue@62: for i = 1, GetNumTradeSkills() do Zerotorescue@62: -- Try to retrieve the itemlink, this will be nil if current item is a group instead Zerotorescue@62: local itemLink = GetTradeSkillItemLink(i); Zerotorescue@62: Zerotorescue@62: if itemLink then Zerotorescue@62: local itemId = addon:GetItemId(itemLink); Zerotorescue@62: if not itemId then Zerotorescue@62: -- If this isn't an item, it can only be an enchant instead Zerotorescue@62: itemId = tonumber(itemLink:match("|Henchant:([-0-9]+)|h")); Zerotorescue@62: Zerotorescue@62: itemId = addon.scrollIds[itemId]; -- change enchantIds into scrollIds Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: if itemId then Zerotorescue@62: local itemLevel = select(4, GetItemInfo(itemId)) or 0; Zerotorescue@62: Zerotorescue@62: if includeTradeSkillItems == 0 or itemLevel >= includeTradeSkillItems then Zerotorescue@62: if not items[itemId] then Zerotorescue@62: -- If this item isn't used in any group yet Zerotorescue@62: ref[itemId] = tblAddItemTemplate; Zerotorescue@62: else Zerotorescue@62: -- It's already used in a group, don't show it Zerotorescue@62: ref[itemId] = nil; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: else Zerotorescue@89: addon:Debug("|cffff0000ERROR|r: Couldn't find proper item id for %s", itemLink); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local function UpdateRemoveItemList(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: if not addon.db.profile.groups[groupName].items then Zerotorescue@62: addon.db.profile.groups[groupName].items = {}; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local ref = options.args.groups.args[info[2]].args.remove.args.list.args; Zerotorescue@62: Zerotorescue@62: -- Unset all Zerotorescue@62: for itemId, _ in pairs(ref) do Zerotorescue@62: ref[itemId] = nil; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: -- Parse items in group and show these Zerotorescue@62: for itemId, _ in pairs(addon.db.profile.groups[groupName].items) do Zerotorescue@62: ref[itemId] = tblRemoveItemTemplate; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@161: local function ImportPremadeItemsGroup(groupName, name) Zerotorescue@161: local premadeItemGroup = addon.defaultGroups[name]; Zerotorescue@161: Zerotorescue@161: addon:Print(("Importing items from the premade group \"|cfffed000%s|r\"."):format(name)); Zerotorescue@161: Zerotorescue@161: -- Remember we imported this group and it's version so if it is ever changed, people can be notified Zerotorescue@161: if not addon.db.profile.groups[groupName].premadeGroups then Zerotorescue@161: addon.db.profile.groups[groupName].premadeGroups = {}; Zerotorescue@161: end Zerotorescue@161: addon.db.profile.groups[groupName].premadeGroups[name] = premadeItemGroup.version; Zerotorescue@161: Zerotorescue@161: for itemId, version in pairs(premadeItemGroup.items) do Zerotorescue@161: if version > 0 then Zerotorescue@161: -- Sanity check Zerotorescue@161: itemId = itemId and tonumber(itemId); Zerotorescue@161: Zerotorescue@161: local itemData = addon.ItemData:New(itemId); Zerotorescue@161: Zerotorescue@161: if not itemId then Zerotorescue@161: addon:Print(("\"|cfffed000%s|r\" is not a number."):format(name), addon.Colors.Red); Zerotorescue@161: elseif itemData:InGroup() then Zerotorescue@161: addon:Print(("Skipping |cfffed000%s|r as it is already in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() ), addon.Colors.Red); Zerotorescue@161: elseif itemData:AddToGroup(groupName) then Zerotorescue@161: addon:Print(("Added %s to the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), groupName ), addon.Colors.Green); Zerotorescue@161: end Zerotorescue@161: end Zerotorescue@161: end Zerotorescue@161: end Zerotorescue@161: Zerotorescue@62: -- Default group Zerotorescue@62: local defaultGroup = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "group", Zerotorescue@62: childGroups = "tab", Zerotorescue@62: name = function(info) Zerotorescue@62: local groupId = info[#info]; Zerotorescue@62: if groupIsVirtual[groupId] then Zerotorescue@62: return ("%s |cfffed000Virtual|r"):format(groupIdToName[groupId]); Zerotorescue@62: else Zerotorescue@62: return groupIdToName[groupId]; Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: desc = function(info) Zerotorescue@62: local groupId = info[#info]; Zerotorescue@62: if groupIsVirtual[groupId] then Zerotorescue@62: return "This is a virtual group, you can use it to override the defaults for other groups."; Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: args = { Zerotorescue@62: general = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: name = "General", Zerotorescue@62: desc = "Change the general settings for just this group.", Zerotorescue@62: args = { Zerotorescue@62: general = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "General", Zerotorescue@62: set = SetOption, Zerotorescue@62: get = GetOption, Zerotorescue@62: disabled = GetDisabled, Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@62: name = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@106: local t = ""; Zerotorescue@106: if not addon.db.profile.defaults.hideHelp then Zerotorescue@155: t = "Here you can set general settings for the currently selected group. If you do not wish to override a setting, the default setting specified in the general group will be used."; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return t; Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: header = { Zerotorescue@62: order = 5, Zerotorescue@62: type = "header", Zerotorescue@62: name = "", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@155: overrideTrackAtCharacters = { Zerotorescue@155: order = 19, Zerotorescue@62: type = "toggle", Zerotorescue@155: name = "Override track at", Zerotorescue@176: desc = "Allows you to override at which characters groups should be tracked, appear in the summary or generate alerts.", Zerotorescue@155: arg = "trackAtCharacters", Zerotorescue@62: }, Zerotorescue@155: trackAtCharacters = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "multiselect", Zerotorescue@155: name = "Track at", Zerotorescue@176: desc = "Select at which characters groups should be tracked, appear in the summary or generate alerts.", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@155: for charName in pairs(addon.db.factionrealm.characters) do Zerotorescue@155: temp[charName] = charName; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@155: get = GetMultiOption, Zerotorescue@155: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@155: arg = "overrideTrackAtCharacters", Zerotorescue@62: }, Zerotorescue@176: overrideDontAlertAtCharacters = { Zerotorescue@176: order = 29, Zerotorescue@176: type = "toggle", Zerotorescue@176: name = "Override not alerting at", Zerotorescue@176: desc = "Allows you to override at which characters items in groups should |cffff0000not|r generate alerts when they are below the required stock.", Zerotorescue@176: arg = "dontAlertAtCharacters", Zerotorescue@176: }, Zerotorescue@176: dontAlertAtCharacters = { Zerotorescue@176: order = 30, Zerotorescue@176: type = "multiselect", Zerotorescue@176: name = "Do |cffff0000not|r alert at", Zerotorescue@176: desc = "Select at which characters items in groups should |cffff0000not|r generate alerts when they are below the required stock.", Zerotorescue@176: values = function() Zerotorescue@176: local temp = {}; Zerotorescue@176: for charName in pairs(addon.db.factionrealm.characters) do Zerotorescue@176: temp[charName] = charName; Zerotorescue@176: end Zerotorescue@176: Zerotorescue@176: return temp; Zerotorescue@176: end, Zerotorescue@176: get = GetMultiOption, Zerotorescue@176: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@176: arg = "overrideDontAlertAtCharacters", Zerotorescue@176: }, Zerotorescue@62: overrideLocalItemData = { Zerotorescue@62: order = 39, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override local item data", Zerotorescue@62: desc = "Allows you to override the local item data setting for this group.", Zerotorescue@62: arg = "localItemData", Zerotorescue@62: }, Zerotorescue@62: localItemData = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "multiselect", Zerotorescue@62: name = "Include in local item data", Zerotorescue@62: desc = "Select which data should be included in the local item data.", Zerotorescue@62: values = { Zerotorescue@62: ["Bag"] = "Bag", Zerotorescue@62: ["Bank"] = "Bank", Zerotorescue@62: ["Auction House"] = "Auction House", Zerotorescue@62: ["Mailbox"] = "Mailbox", Zerotorescue@62: }, Zerotorescue@62: get = GetMultiOption, Zerotorescue@65: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@62: arg = "overrideLocalItemData", Zerotorescue@62: }, Zerotorescue@62: virtualGroup = { Zerotorescue@62: order = 50, Zerotorescue@62: type = "select", Zerotorescue@62: name = "Use virtual group settings", Zerotorescue@62: desc = "Use the settings from a virtual group before using the general defaults.\n\n|cffff9933This is an advanced option, you will probably not need it unless you manage a lot of groups.|r\n\n|cfffed000Off|r: Use the overridden options in this group and then the defaults.\n\n|cfffed000On|r: Use the overridden options in this group, then the ones in the selected virtual group and then the defaults.", Zerotorescue@62: values = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: local temp = {}; Zerotorescue@62: Zerotorescue@62: temp[""] = ""; Zerotorescue@62: for name, values in pairs(addon.db.profile.groups) do Zerotorescue@62: if values.isVirtual and name ~= groupName then Zerotorescue@62: temp[name] = name; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: set = function(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local optionName = info[#info]; Zerotorescue@62: Zerotorescue@62: addon.db.profile.groups[groupName][optionName] = value ~= "" and value; Zerotorescue@62: end, Zerotorescue@62: disabled = false, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: minimumStock = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Minimum stock", Zerotorescue@62: set = SetOption, Zerotorescue@62: get = GetOption, Zerotorescue@62: disabled = GetDisabled, Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@62: name = "Here you can specify the minimum amount of items you wish to keep in stock and related settings for the currently selected group. Please note the values entered here do not affect the queued quantities, you must set settings for that in the area below.", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: header = { Zerotorescue@62: order = 5, Zerotorescue@62: type = "header", Zerotorescue@62: name = "", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: Zerotorescue@62: overrideMinLocalStock = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override min local stock", Zerotorescue@62: desc = "Allows you to override the minimum local stock setting for this group.", Zerotorescue@62: arg = "minLocalStock", Zerotorescue@62: }, Zerotorescue@62: minLocalStock = { Zerotorescue@62: order = 11, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 100000, Zerotorescue@62: softMax = 100, Zerotorescue@62: step = 1, Zerotorescue@62: name = "Minimum local stock", Zerotorescue@62: desc = "You can manually enter a value between 100 and 100.000 in the text box below if the provided range is insufficient.", Zerotorescue@62: arg = "overrideMinLocalStock", Zerotorescue@62: }, Zerotorescue@62: overrideAlertBelowLocalMinimum = { Zerotorescue@62: order = 15, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override local minimum alert", Zerotorescue@62: desc = "Allows you to override wether an alert should be shown when an item in this group gets below the local minimum stock threshold.", Zerotorescue@62: arg = "alertBelowLocalMinimum", Zerotorescue@62: }, Zerotorescue@62: alertBelowLocalMinimum = { Zerotorescue@62: order = 16, Zerotorescue@62: type = "toggle", Zerotorescue@181: name = "Alert when below local minimum", Zerotorescue@62: desc = "Show an alert when an item in this group gets below the local minimum stock threshold.", Zerotorescue@62: arg = "overrideAlertBelowLocalMinimum", Zerotorescue@62: }, Zerotorescue@82: overrideAutoRefill = { Zerotorescue@82: order = 17, Zerotorescue@82: type = "toggle", Zerotorescue@82: name = "Override auto refill", Zerotorescue@82: desc = "Allows you to override wether you want to automatically refill items when below the minimum local stock.", Zerotorescue@82: arg = "autoRefill", Zerotorescue@82: }, Zerotorescue@82: autoRefill = { Zerotorescue@82: order = 18, Zerotorescue@82: type = "toggle", Zerotorescue@131: name = "Auto refill from storage", Zerotorescue@131: desc = "Automatically refill items from your storage (bank/mailbox - unless this is included in the local count - or the guild bank) when below the minimum local stock.", Zerotorescue@82: arg = "overrideAutoRefill", Zerotorescue@82: }, Zerotorescue@184: spacer = { Zerotorescue@184: order = 19, Zerotorescue@184: type = "description", Zerotorescue@184: name = "", Zerotorescue@184: }, Zerotorescue@62: Zerotorescue@62: overrideMinGlobalStock = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override min global stock", Zerotorescue@62: desc = "Allows you to override the minimum global stock setting for this group.", Zerotorescue@62: arg = "minGlobalStock", Zerotorescue@62: }, Zerotorescue@62: minGlobalStock = { Zerotorescue@62: order = 21, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 100000, Zerotorescue@62: softMax = 100, Zerotorescue@62: step = 1, Zerotorescue@62: name = "Minimum global stock", Zerotorescue@62: desc = "You can manually enter a value between 100 and 100.000 in the text box below if the provided range is insufficient.", Zerotorescue@62: arg = "overrideMinGlobalStock", Zerotorescue@62: }, Zerotorescue@62: overrideAlertBelowGlobalMinimum = { Zerotorescue@62: order = 25, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override global minimum alert", Zerotorescue@62: desc = "Allows you to override wether an alert should be shown when an item in this group gets below the global minimum stock threshold.", Zerotorescue@62: arg = "alertBelowGlobalMinimum", Zerotorescue@62: }, Zerotorescue@62: alertBelowGlobalMinimum = { Zerotorescue@62: order = 26, Zerotorescue@62: type = "toggle", Zerotorescue@181: name = "Alert when below global minimum", Zerotorescue@62: desc = "Show an alert when an item in this group gets below the global minimum stock threshold.", Zerotorescue@62: arg = "overrideAlertBelowGlobalMinimum", Zerotorescue@62: }, Zerotorescue@62: Zerotorescue@62: overrideSummaryThresholdShow = { Zerotorescue@62: order = 34, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override summary showing", Zerotorescue@62: desc = "Allows you to override when this group should appear in the summary.", Zerotorescue@62: arg = "summaryThresholdShow", Zerotorescue@62: }, Zerotorescue@62: summaryThresholdShow = { Zerotorescue@62: order = 35, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 10, Zerotorescue@62: softMax = 100, Zerotorescue@62: step = 0.05, Zerotorescue@62: isPercent = true, Zerotorescue@62: name = "Show in summary when below", Zerotorescue@62: desc = "Show items in the summary when below the specified percentage of the minimum stock.\n\nYou can manually enter a value between 1.000% and 10.000% in the edit box if the provided range is insufficient.", Zerotorescue@62: arg = "overrideSummaryThresholdShow", Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: refill = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Replenishing stock", Zerotorescue@62: set = SetOption, Zerotorescue@62: get = GetOption, Zerotorescue@62: disabled = GetDisabled, Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@62: name = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: local r = "Here you can specify the amount of items to which you wish to restock when you are collecting new items for the currently selected group. This may be higher than the minimum stock.\n\n"; Zerotorescue@62: Zerotorescue@62: r = r .. "When restocking the target amount is |cfffed000" .. addon:GetOptionByKey(groupName, "restockTarget") .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * addon:GetOptionByKey(groupName, "restockTarget") ) .. "|r (|cfffed000" .. ( addon:GetOptionByKey(groupName, "minCraftingQueue") * 100 ) .. "%|r) of the restock target and making |cfffed000" .. floor( ( addon:GetOptionByKey(groupName, "bonusQueue") * addon:GetOptionByKey(groupName, "restockTarget") ) + .5 ) .. "|r (|cfffed000" .. ( addon:GetOptionByKey(groupName, "bonusQueue") * 100 ) .. "%|r) extra items when you completely ran out. "; Zerotorescue@62: Zerotorescue@62: if addon:GetOptionByKey(groupName, "priceThreshold") == 0 then Zerotorescue@62: r = r .. "Queueing items at |cfffed000any|r auction value."; Zerotorescue@62: else Zerotorescue@62: r = r .. "Queueing items worth |cfffed000" .. addon:ReadableMoney(addon:GetOptionByKey(groupName, "priceThreshold")) .. "|r or more."; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return r; Zerotorescue@62: end, Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: header = { Zerotorescue@62: order = 5, Zerotorescue@62: type = "header", Zerotorescue@62: name = "", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: overrideRestockTarget = { Zerotorescue@62: order = 9, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override restock target", Zerotorescue@62: desc = "Allows you to override the restock target setting for this group.", Zerotorescue@62: arg = "restockTarget", Zerotorescue@62: }, Zerotorescue@62: restockTarget = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 100000, Zerotorescue@62: softMax = 100, Zerotorescue@62: step = 1, Zerotorescue@62: name = "Restock target", Zerotorescue@62: desc = "You can manually enter a value between 100 and 100.000 in the edit box if the provided range is insufficient.", Zerotorescue@62: arg = "overrideRestockTarget", Zerotorescue@62: }, Zerotorescue@62: overrideMinCraftingQueue = { Zerotorescue@62: order = 19, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override min queue", Zerotorescue@62: desc = "Allows you to override the minimum craftable items queue setting for this group.", Zerotorescue@62: arg = "minCraftingQueue", Zerotorescue@62: }, Zerotorescue@62: minCraftingQueue = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 1, Zerotorescue@62: step = 0.01, Zerotorescue@62: isPercent = true, Zerotorescue@154: name = "Don't queue when only missing...", Zerotorescue@154: desc = "Don't add a craftable item to the queue when only missing this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.", Zerotorescue@62: arg = "overrideMinCraftingQueue", Zerotorescue@62: }, Zerotorescue@62: overrideBonusQueue = { Zerotorescue@62: order = 29, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override bonus queue", Zerotorescue@62: desc = "Allows you to override the bonus craftable items queue setting for this group.", Zerotorescue@62: arg = "bonusQueue", Zerotorescue@62: }, Zerotorescue@62: bonusQueue = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "range", Zerotorescue@62: min = 0, Zerotorescue@62: max = 10, -- 1000% Zerotorescue@62: step = 0.01, -- 1% Zerotorescue@62: isPercent = true, Zerotorescue@62: name = "Bonus queue", Zerotorescue@62: desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.", Zerotorescue@62: arg = "overrideBonusQueue", Zerotorescue@62: }, Zerotorescue@62: overridePriceThreshold = { Zerotorescue@62: order = 39, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override price threshold", Zerotorescue@62: desc = "Allows you to override the price threshold setting for this group.", Zerotorescue@62: arg = "priceThreshold", Zerotorescue@62: }, Zerotorescue@62: priceThreshold = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Price threshold", Zerotorescue@62: desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.", Zerotorescue@62: validate = function(info, value) return addon:ValidateReadableMoney(info, value); end, Zerotorescue@62: get = function(i) return addon:ReadableMoney(GetOption(i)); end, Zerotorescue@62: set = function(i, v) SetOption(i, addon:ReadableMoneyToCopper(v)); end, Zerotorescue@62: arg = "overridePriceThreshold", Zerotorescue@62: }, Zerotorescue@62: overrideSummaryHidePriceThreshold = { Zerotorescue@62: order = 49, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override summary showing", Zerotorescue@62: desc = "Allows you to override if items in this group should be hidden from the summary while their value is below the price threshold.", Zerotorescue@62: arg = "summaryHidePriceThreshold", Zerotorescue@62: }, Zerotorescue@62: summaryHidePriceThreshold = { Zerotorescue@62: order = 50, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Hide when below threshold", Zerotorescue@62: desc = "Hide items from the summary when their value is below the set price threshold.", Zerotorescue@62: arg = "overrideSummaryHidePriceThreshold", Zerotorescue@62: }, Zerotorescue@62: overrideAlwaysGetAuctionValue = { Zerotorescue@62: order = 59, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Override auction value showing", Zerotorescue@62: desc = "Allows you to override if the auction value of items in this group should be cached and displayed even when the price threshold is set to 0|cffeda55fc|r.", Zerotorescue@62: arg = "alwaysGetAuctionValue", Zerotorescue@62: }, Zerotorescue@62: alwaysGetAuctionValue = { Zerotorescue@62: order = 60, Zerotorescue@62: type = "toggle", Zerotorescue@62: name = "Always show auction value", Zerotorescue@62: desc = "Always cache and show the auction value of items in this group, even if the price threshold is set to 0|cffeda55fc|r.", Zerotorescue@62: arg = "overrideAlwaysGetAuctionValue", Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@155: addons = { Zerotorescue@155: order = 30, Zerotorescue@155: type = "group", Zerotorescue@155: inline = true, Zerotorescue@155: name = "Prefered addons", Zerotorescue@155: set = SetOption, Zerotorescue@155: get = GetOption, Zerotorescue@155: disabled = GetDisabled, Zerotorescue@155: args = { Zerotorescue@155: description = { Zerotorescue@155: order = 0, Zerotorescue@155: type = "description", Zerotorescue@155: name = function(info) Zerotorescue@155: local groupName = groupIdToName[info[2]]; Zerotorescue@155: Zerotorescue@155: local t = ""; Zerotorescue@155: if not addon.db.profile.defaults.hideHelp then Zerotorescue@155: t = "Selecting your prefered addons is optional, the first working addon will be used if the selected addon doesn't exist. You only need to set this when you are running multiple addons of a kind and wish to specify which addons to use for what groups.\n\n"; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: local currentAddon, selectedAddonName = addon:GetItemCountAddon(groupName); Zerotorescue@155: local preferedAddon = addon:GetOptionByKey(groupName, "itemCountAddon"); Zerotorescue@155: Zerotorescue@155: if currentAddon then Zerotorescue@155: --GetCharacterCount Zerotorescue@155: --addon.supportedAddons.itemCount[selectedExternalAddon] Zerotorescue@155: t = t .. "Currently using |cfffed000" .. selectedAddonName .. "|r as your item count addon. This addon is " .. ((currentAddon.IsEnabled() and "|cff00ff00enabled|r") or "|cffff0000disabled|r") .. "."; Zerotorescue@155: Zerotorescue@155: if currentAddon.GetTotalCount and currentAddon.GetCharacterCount then Zerotorescue@155: t = t .. " This addon supports |cfffed000both total as local|r item counts."; Zerotorescue@155: elseif currentAddon.GetTotalCount then Zerotorescue@155: t = t .. " This addon supports |cfffed000only total|r item counts."; Zerotorescue@155: elseif currentAddon.GetCharacterCount then Zerotorescue@155: t = t .. " This addon supports |cfffed000only local|r item counts."; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: if preferedAddon ~= selectedAddonName then Zerotorescue@216: t = t .. "\n\n|cffff0000You have selected |cfffed000" .. preferedAddon .. "|r|cffff0000 as your item count addon, but this appears to be disabled and thus the best alternative was selected.|r"; Zerotorescue@155: end Zerotorescue@240: else Zerotorescue@240: t = t .. "|cffff0000Warning! No item count addon detected!|r"; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return t; Zerotorescue@155: end, Zerotorescue@155: }, Zerotorescue@155: header = { Zerotorescue@155: order = 5, Zerotorescue@155: type = "header", Zerotorescue@155: name = "", Zerotorescue@155: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@155: }, Zerotorescue@155: overrideAuctionPricingAddon = { Zerotorescue@155: order = 9, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Override pricing addon", Zerotorescue@155: desc = "Allows you to override the pricing addon setting for this group.", Zerotorescue@155: arg = "auctionPricingAddon", Zerotorescue@155: }, Zerotorescue@155: auctionPricingAddon = { Zerotorescue@155: order = 10, Zerotorescue@155: type = "select", Zerotorescue@155: name = "Prefered pricing addon", Zerotorescue@155: desc = "Select the addon you prefer data for this group to be retrieved from. A random supported addon will be used if the selected addon can not be found.", Zerotorescue@155: values = function() Zerotorescue@155: local temp = {}; Zerotorescue@155: for name, value in pairs(addon.supportedAddons.auctionPricing) do Zerotorescue@155: temp[name] = name; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return temp; Zerotorescue@155: end, Zerotorescue@155: set = function(info, value) Zerotorescue@155: local groupName = groupIdToName[info[2]]; Zerotorescue@155: local optionName = info[#info]; Zerotorescue@155: Zerotorescue@155: addon.db.profile.groups[groupName][optionName] = value ~= "" and value; Zerotorescue@155: Zerotorescue@155: if addon.supportedAddons.auctionPricing[value].OnSelect then Zerotorescue@155: addon.supportedAddons.auctionPricing[value].OnSelect(); Zerotorescue@155: end Zerotorescue@155: end, Zerotorescue@155: arg = "overrideAuctionPricingAddon", Zerotorescue@155: }, Zerotorescue@155: overrideItemCountAddon = { Zerotorescue@155: order = 19, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Override item count addon", Zerotorescue@155: desc = "Allows you to override the item count addon setting for this group.", Zerotorescue@155: arg = "itemCountAddon", Zerotorescue@155: }, Zerotorescue@155: itemCountAddon = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "select", Zerotorescue@155: name = "Prefered item count addon", Zerotorescue@216: desc = "Select the addon you prefer data for this group to be retrieved from. The best supported addon will be used if the selected addon can not be found.", Zerotorescue@155: values = function() Zerotorescue@155: local temp = {}; Zerotorescue@155: for name, value in pairs(addon.supportedAddons.itemCount) do Zerotorescue@155: temp[name] = name; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return temp; Zerotorescue@155: end, Zerotorescue@155: set = function(info, value) Zerotorescue@155: local groupName = groupIdToName[info[2]]; Zerotorescue@155: local optionName = info[#info]; Zerotorescue@155: Zerotorescue@155: addon.db.profile.groups[groupName][optionName] = value ~= "" and value; Zerotorescue@155: Zerotorescue@155: if addon.supportedAddons.itemCount[value].OnSelect then Zerotorescue@155: addon.supportedAddons.itemCount[value].OnSelect(); Zerotorescue@155: end Zerotorescue@155: end, Zerotorescue@155: arg = "overrideItemCountAddon", Zerotorescue@155: }, Zerotorescue@155: overrideCraftingAddon = { Zerotorescue@155: order = 29, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Override crafting addon", Zerotorescue@155: desc = "Allows you to override the crafting addon setting for this group.", Zerotorescue@155: arg = "craftingAddon", Zerotorescue@155: }, Zerotorescue@155: craftingAddon = { Zerotorescue@155: order = 30, Zerotorescue@155: type = "select", Zerotorescue@155: name = "Prefered crafting addon", Zerotorescue@155: desc = "Select the addon you prefer data from this group to be queued into. A random supported addon will be used if the selected addon can not be found.", Zerotorescue@155: values = function() Zerotorescue@155: local temp = {}; Zerotorescue@155: for name, value in pairs(addon.supportedAddons.crafting) do Zerotorescue@155: temp[name] = name; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return temp; Zerotorescue@155: end, Zerotorescue@155: set = function(info, value) Zerotorescue@155: local groupName = groupIdToName[info[2]]; Zerotorescue@155: local optionName = info[#info]; Zerotorescue@155: Zerotorescue@155: addon.db.profile.groups[groupName][optionName] = value ~= "" and value; Zerotorescue@155: Zerotorescue@155: if addon.supportedAddons.crafting[value].OnSelect then Zerotorescue@155: addon.supportedAddons.crafting[value].OnSelect(); Zerotorescue@155: end Zerotorescue@155: end, Zerotorescue@155: arg = "overrideCraftingAddon", Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: group = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Management", Zerotorescue@62: desc = "Rename, delete, duplicate or export this group.", Zerotorescue@62: args = { Zerotorescue@62: actions = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Actions", Zerotorescue@62: inline = true, Zerotorescue@62: args = { Zerotorescue@62: rename = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Rename group - New name", Zerotorescue@62: desc = "Change the name of this group to something else. You can also use item links here as you wish.", Zerotorescue@62: validate = ValidateGroupName, Zerotorescue@62: set = function(info, value) Zerotorescue@62: local oldGroupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: addon.db.profile.groups[value] = CopyTable(addon.db.profile.groups[oldGroupName]); Zerotorescue@62: addon.db.profile.groups[oldGroupName] = nil; Zerotorescue@62: Zerotorescue@62: groupIdToName[info[2]] = value; Zerotorescue@62: groupIdToName[value] = true; Zerotorescue@62: groupIdToName[oldGroupName] = nil; Zerotorescue@62: Zerotorescue@62: mod:FillGroupOptions(); Zerotorescue@62: end, Zerotorescue@62: get = function(info) Zerotorescue@62: return groupIdToName[info[2]]; Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: duplicate = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Duplicate group - New name", Zerotorescue@62: desc = "Duplicate this group. You can also use item links here as you wish.\n\nAll item data will be erased.", Zerotorescue@62: validate = ValidateGroupName, Zerotorescue@62: set = function(info, value) Zerotorescue@62: local oldGroupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: addon.db.profile.groups[value] = CopyTable(addon.db.profile.groups[oldGroupName]); Zerotorescue@62: Zerotorescue@62: -- Reset item data (duplicate items me no want) Zerotorescue@62: addon.db.profile.groups[value].items = nil; Zerotorescue@62: Zerotorescue@62: mod:FillGroupOptions(); Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: delete = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "execute", Zerotorescue@62: name = "Delete group", Zerotorescue@62: desc = "Delete the currently selected group.", Zerotorescue@62: confirm = true, Zerotorescue@62: confirmText = "Are you sure you wish to |cffff0000DELETE|r this group? This action is not reversable!", Zerotorescue@62: func = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: addon.db.profile.groups[groupName] = nil; Zerotorescue@62: Zerotorescue@62: mod:FillGroupOptions(); Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: export = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Export", Zerotorescue@62: inline = true, Zerotorescue@62: args = { Zerotorescue@62: input = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "input", Zerotorescue@62: multiline = true, Zerotorescue@62: name = "Group data", Zerotorescue@62: width = "full", Zerotorescue@62: desc = "Export the group data for the currently selected group. Press CTRL-A to select all and CTRL-C to copy the text.", Zerotorescue@62: set = false, Zerotorescue@62: get = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@152: return mod:ExportGroup(groupName); Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: add = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Add items", Zerotorescue@62: desc = "Add new items to this group.", Zerotorescue@62: hidden = function(info) return groupIsVirtual[info[2]]; end, Zerotorescue@62: args = { Zerotorescue@62: singleAdd = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Add items", Zerotorescue@62: args = { Zerotorescue@62: help = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "description", Zerotorescue@62: name = "You can add a single item to this group at a time by pasting the item-id or an item-link in the field to the left or you can also import multiple items at once by pasting exported item data in the field to the right. Scroll further down to add items based on your inventory contents.", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: itemLink = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Single item add (item-link or item-id)", Zerotorescue@62: desc = "Shift-click an item-link or enter an item-id to add the related item to this group. You can only add one item link or item id at a time.", Zerotorescue@62: validate = function(info, value) Zerotorescue@62: -- If the value is empty we'll allow passing to clear the carret Zerotorescue@62: if value == "" then return true; end Zerotorescue@62: Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@76: local itemId = (addon:GetItemId(string.trim(value)) or tonumber(string.trim(value))); Zerotorescue@76: Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@62: Zerotorescue@62: if not itemId then Zerotorescue@76: return "This is not a valid item link or id."; Zerotorescue@76: elseif itemData:InGroup() then Zerotorescue@76: return ("This item is already in the group |cfffed000%s|r."):format(itemData:InGroup()); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return true; Zerotorescue@62: end, Zerotorescue@62: set = function(info, value) Zerotorescue@62: if value and value ~= "" then Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@76: local itemId = (addon:GetItemId(string.trim(value)) or tonumber(string.trim(value))); Zerotorescue@62: Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@76: Zerotorescue@76: if itemData:AddToGroup(groupName) then Zerotorescue@98: addon:Print(("Added %s to the selected group."):format( (itemData.link or unknownItemName:format(itemId)) ), addon.Colors.Green); Zerotorescue@76: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@76: else Zerotorescue@98: addon:Print(("%s is already in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() ), addon.Colors.Red); Zerotorescue@76: end Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: importItemData = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Import item data", Zerotorescue@62: desc = "Import item data from an exported item data-string. Any items already grouped will be skipped.", Zerotorescue@62: set = function(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: local allItemIds = { string.split(";", value or "") }; Zerotorescue@62: Zerotorescue@62: for _, value in pairs(allItemIds) do Zerotorescue@62: local itemId = tonumber(value); Zerotorescue@62: Zerotorescue@76: if itemId then Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@76: Zerotorescue@76: if itemData:InGroup() then Zerotorescue@98: addon:Print(("Skipping %s (#%d) as it is already in the group |cfffed000%s|r."):format(itemData.link or "Unknown", itemId, itemData:InGroup()), addon.Colors.Red); Zerotorescue@98: addon:Print(("Skipping %s (#%d) as it is already in the group |cfffed000%s|r."):format(itemData.link or "Unknown", itemId, itemData:InGroup()), addon.Colors.Red); Zerotorescue@76: elseif itemData:AddToGroup(groupName) then Zerotorescue@98: addon:Print(("Added %s to the group |cfffed000%s|r."):format(itemData.link or unknownItemName:format(itemId), groupName), addon.Colors.Green); Zerotorescue@76: end Zerotorescue@62: else Zerotorescue@98: addon:Print(("\"%s\" is not a number."):format(value), addon.Colors.Red); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@76: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: importPremadeData = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "select", Zerotorescue@106: width = "double", Zerotorescue@62: name = "Import premade data", Zerotorescue@62: desc = "Import item data from a premade item-group. Any items already grouped will be skipped.", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@62: for key, group in pairs(addon.defaultGroups) do Zerotorescue@62: temp[key] = key; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: set = function(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@161: local premadeItemGroup = addon.defaultGroups[value]; Zerotorescue@62: Zerotorescue@161: if premadeItemGroup.isParent and premadeItemGroup.childs then Zerotorescue@161: for _, premadeItemGroupName in pairs(premadeItemGroup.childs) do Zerotorescue@161: ImportPremadeItemsGroup(groupName, premadeItemGroupName); Zerotorescue@62: end Zerotorescue@161: else Zerotorescue@161: ImportPremadeItemsGroup(groupName, value); Zerotorescue@62: end Zerotorescue@76: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: massAdd = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Mass add", Zerotorescue@62: args = { Zerotorescue@62: help = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "description", Zerotorescue@62: name = "Click the items you wish to add to this group or add multiple of these items at once by providing a name filter in the field below.", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: massAdd = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Add all items matching...", Zerotorescue@62: desc = "Add every item in your inventory matching the name entered in this field. If you enter \"Glyph\" as a filter, any items in your inventory containing this in their name will be added to this group.", Zerotorescue@62: set = function(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: if not value then return; end Zerotorescue@62: Zerotorescue@62: value = value:lower(); Zerotorescue@62: Zerotorescue@62: local ref = options.args.groups.args[info[2]].args.add.args.list.args; Zerotorescue@62: Zerotorescue@62: for itemId, test in pairs(ref) do Zerotorescue@62: if test then Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@62: Zerotorescue@76: if itemData.name:lower():find(value) then Zerotorescue@76: if itemData:AddToGroup(groupName) then Zerotorescue@98: addon:Print(("Added %s to the selected group."):format( (itemData.link or unknownItemName:format(itemId)) ), addon.Colors.Green); Zerotorescue@76: else Zerotorescue@98: addon:Print(("Couldn't add %s because it is already in a group."):format(itemData.link or unknownItemName:format(itemId)), addon.Colors.Red); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@76: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: minItemLevel = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "select", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@62: Zerotorescue@62: temp[0] = "Include everything"; Zerotorescue@62: Zerotorescue@62: local itemLevelTemplate = "Itemlevel >= %d"; Zerotorescue@62: Zerotorescue@62: for i = 1, 49 do Zerotorescue@62: temp[( i * 10 )] = itemLevelTemplate:format(( i * 10 )); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: temp[500] = "Include nothing"; Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: name = "Include tradeskill items", Zerotorescue@62: desc = "Include all items above this item level from the currently opened tradeskill window in the below item list.\n\nSetting this very low this might considerably slow down this config window.\n\nSet to 500 to disable showing of items completely.", Zerotorescue@62: set = function(i, v) includeTradeSkillItems = v; end, Zerotorescue@62: get = function() return includeTradeSkillItems; end, Zerotorescue@62: disabled = function() Zerotorescue@62: if GetTradeSkillLine() == "UNKNOWN" then Zerotorescue@62: includeTradeSkillItems = 500; Zerotorescue@62: return true; -- disabled Zerotorescue@62: else Zerotorescue@62: return false; Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: list = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Item list", Zerotorescue@62: hidden = UpdateAddItemList, Zerotorescue@62: args = { Zerotorescue@62: Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: remove = { Zerotorescue@62: order = 40, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Current items", Zerotorescue@62: desc = "View, export or remove items from this group.", Zerotorescue@62: hidden = function(info) return groupIsVirtual[info[2]]; end, Zerotorescue@62: args = { Zerotorescue@62: help = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@106: name = "Remove items", Zerotorescue@62: hidden = false, Zerotorescue@62: args = { Zerotorescue@62: help = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "description", Zerotorescue@62: name = "Click the items you wish to remove from this group.", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: }, Zerotorescue@62: massRemove = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Remove all items matching...", Zerotorescue@62: desc = "Remove every item in this group matching the name entered in this field. If you enter \"Glyph\" as a filter, any items in this group containing this in their name will be removed from this group.", Zerotorescue@62: set = function(info, value) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: if not value then return; end Zerotorescue@62: Zerotorescue@62: value = value:lower(); Zerotorescue@62: Zerotorescue@62: local ref = options.args.groups.args[info[2]].args.remove.args.list.args; Zerotorescue@62: Zerotorescue@62: for itemId, test in pairs(ref) do Zerotorescue@62: if test then Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@62: Zerotorescue@76: if itemData.name:lower():find(value) then Zerotorescue@76: itemData:RemoveFromGroup(groupName); Zerotorescue@76: Zerotorescue@98: addon:Print(("Removed %s from the selected group."):format( (itemData.link or unknownItemName:format(itemId)) ), addon.Colors.Red); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: }, Zerotorescue@62: premadeGroups = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "select", Zerotorescue@106: width = "double", Zerotorescue@62: name = "Imported premade groups", Zerotorescue@62: desc = "This is a list of all premade groups that were imported into this group. You will be notified when any of these premade groups have changed and you will be able to import these changes.\n\nSelect a group to stop reminding you of changes to the premade group (the item list will be unaffected). Doing so will require you to manually update this when new items are added to the game.", Zerotorescue@62: values = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: local temp = {}; Zerotorescue@76: temp[""] = ""; Zerotorescue@62: if addon.db.profile.groups[groupName].premadeGroups then Zerotorescue@62: for name, version in pairs(addon.db.profile.groups[groupName].premadeGroups) do Zerotorescue@62: temp[name] = name; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: set = function(info, value) Zerotorescue@76: if value and value ~= "" then Zerotorescue@76: -- Remove premade group from this group Zerotorescue@76: local groupName = groupIdToName[info[2]]; Zerotorescue@76: Zerotorescue@76: addon.db.profile.groups[groupName].premadeGroups[value] = nil; Zerotorescue@76: Zerotorescue@98: addon:Print(("No longer notifying you about changes made to the premade group named \"|cfffed000%s|r\"."):format(value)); Zerotorescue@76: end Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: disabled = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: return (not addon.db.profile.groups[groupName].premadeGroups); Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: list = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Item list", Zerotorescue@62: hidden = UpdateRemoveItemList, Zerotorescue@62: args = { Zerotorescue@62: Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: export = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Export", Zerotorescue@62: inline = true, Zerotorescue@62: args = { Zerotorescue@62: input = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Item data", Zerotorescue@62: width = "full", Zerotorescue@62: desc = "Export the item data for the currently selected group. Press CTRL-A to select all and CTRL-C to copy the text.", Zerotorescue@62: set = false, Zerotorescue@62: get = function(info) Zerotorescue@62: local groupName = groupIdToName[info[2]]; Zerotorescue@62: Zerotorescue@62: local combinedItemIds; Zerotorescue@62: -- Parse items in group and show these Zerotorescue@62: for itemId, _ in pairs(addon.db.profile.groups[groupName].items) do Zerotorescue@62: if not combinedItemIds then Zerotorescue@62: combinedItemIds = tostring(itemId); Zerotorescue@62: else Zerotorescue@62: combinedItemIds = combinedItemIds .. (";%d"):format(itemId); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return combinedItemIds; -- We don't serialize this because we actually DO want people to be able to manually modify it - besides, parsing it isn't going to be hard Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }; Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: -- Object functions Zerotorescue@62: Zerotorescue@62: function mod:OnEnable() Zerotorescue@62: -- Register our config slash command Zerotorescue@62: -- /im config Zerotorescue@205: addon:RegisterSlash(function() Zerotorescue@205: if mod:IsFrameOpen() then Zerotorescue@205: mod:CloseFrame(); Zerotorescue@205: else Zerotorescue@205: mod:Show(); Zerotorescue@62: end Zerotorescue@62: end, { "c", "config", "conf", "option", "options", "opt", "setting", "settings" }, "|Hfunction:InventoriumCommandHandler:config|h|cff00fff7/im config|r|h (or /im c) - Open the config window to change the settings and manage groups."); Zerotorescue@62: Zerotorescue@172: self:Load(false); Zerotorescue@172: Zerotorescue@62: -- Whenever the profile is changed, update the groups | args: (object for the functionName, eventName, functionName) Zerotorescue@62: addon.db.RegisterCallback(self, "OnProfileChanged", "RefreshConfig"); Zerotorescue@62: addon.db.RegisterCallback(self, "OnProfileCopied", "RefreshConfig"); Zerotorescue@62: addon.db.RegisterCallback(self, "OnProfileReset", "RefreshConfig"); Zerotorescue@62: Zerotorescue@62: -- Register our custom widgets Zerotorescue@62: local Widgets = addon:GetModule("Widgets"); Zerotorescue@62: Widgets:ItemLinkButton(); Zerotorescue@62: Widgets:ConfigItemLinkButton(); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@205: function mod:Show() Zerotorescue@205: -- We don't want any other windows open at this time. Zerotorescue@205: for name, module in addon:IterateModules() do Zerotorescue@205: if module.CloseFrame then Zerotorescue@205: module:CloseFrame(); Zerotorescue@205: end Zerotorescue@205: end Zerotorescue@205: Zerotorescue@205: self:Load(true); Zerotorescue@205: Zerotorescue@205: AceConfigDialog:Open("Inventorium"); Zerotorescue@205: end Zerotorescue@205: Zerotorescue@205: function mod:IsFrameOpen() Zerotorescue@205: return (AceConfigDialog.OpenFrames["Inventorium"] ~= nil); Zerotorescue@205: end Zerotorescue@205: Zerotorescue@205: function mod:CloseFrame() Zerotorescue@205: LibStub("AceConfigDialog-3.0"):Close("Inventorium"); Zerotorescue@205: end Zerotorescue@205: Zerotorescue@152: function mod:ExportGroup(groupName) Zerotorescue@152: -- We want to include the group name, so we copy the table then set another value Zerotorescue@152: local temp = CopyTable(addon.db.profile.groups[groupName]); Zerotorescue@152: temp.name = groupName; Zerotorescue@152: temp.trackAtCharacters = nil; Zerotorescue@152: temp.overrideTrackAtCharacters = nil; Zerotorescue@176: temp.dontAlertAtCharacters = nil; Zerotorescue@176: temp.overrideDontAlertAtCharacters = nil; Zerotorescue@152: Zerotorescue@152: if not AceSerializer then Zerotorescue@152: AceSerializer = LibStub("AceSerializer-3.0"); Zerotorescue@152: end Zerotorescue@152: Zerotorescue@152: return AceSerializer:Serialize(temp); Zerotorescue@152: end Zerotorescue@152: Zerotorescue@62: function mod:RefreshConfig() Zerotorescue@65: self:PremadeGroupsCheck(); Zerotorescue@65: Zerotorescue@62: self:FillGroupOptions(); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@172: function mod:Load(premadeGroupsCheck) Zerotorescue@172: if premadeGroupsCheck then Zerotorescue@172: self:PremadeGroupsCheck(); Zerotorescue@172: end Zerotorescue@172: Zerotorescue@62: if not AceConfigDialog and not AceConfigRegistry then Zerotorescue@62: self:FillOptions(); Zerotorescue@62: Zerotorescue@62: -- Build options dialog Zerotorescue@62: AceConfigDialog = LibStub("AceConfigDialog-3.0"); Zerotorescue@62: AceConfigRegistry = LibStub("AceConfigRegistry-3.0"); Zerotorescue@62: -- Register options table Zerotorescue@172: LibStub("AceConfig-3.0"):RegisterOptionsTable("Inventorium", options); Zerotorescue@62: -- Set a nice default size (so that 4 normal sized elements fit next to eachother) Zerotorescue@172: AceConfigDialog:SetDefaultSize("Inventorium", 975, 600); Zerotorescue@62: Zerotorescue@62: -- In case the addon is loaded from another condition, always call the remove interface options Zerotorescue@62: if AddonLoader and AddonLoader.RemoveInterfaceOptions then Zerotorescue@62: AddonLoader:RemoveInterfaceOptions("Inventorium"); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: -- Add to the blizzard addons options thing Zerotorescue@172: AceConfigDialog:AddToBlizOptions("Inventorium", "Inventorium"); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function mod:FillOptions() Zerotorescue@62: options = { Zerotorescue@62: type = "group", Zerotorescue@62: name = "Inventorium Config", Zerotorescue@62: childGroups = "tree", Zerotorescue@62: args = { Zerotorescue@62: }, Zerotorescue@62: }; Zerotorescue@62: Zerotorescue@62: -- General Zerotorescue@62: self:FillGeneralOptions(); Zerotorescue@62: Zerotorescue@62: -- Help Zerotorescue@62: self:FillHelpOptions(); Zerotorescue@62: Zerotorescue@62: -- Profile Zerotorescue@62: options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(addon.db, true); Zerotorescue@62: options.args.profiles.order = 200; Zerotorescue@62: Zerotorescue@106: -- Extra Zerotorescue@106: self:FillExtraOptions(); Zerotorescue@106: Zerotorescue@62: -- Groups Zerotorescue@62: self:MakeGroupOptions(); Zerotorescue@62: Zerotorescue@62: -- Groups-contents Zerotorescue@62: self:FillGroupOptions(); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function mod:FillGeneralOptions() Zerotorescue@62: options.args.general = { Zerotorescue@62: order = 100, Zerotorescue@62: type = "group", Zerotorescue@62: name = "General", Zerotorescue@62: desc = "Change general Inventorium settings.", Zerotorescue@62: args = { Zerotorescue@62: general = { Zerotorescue@62: order = 1, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "General", Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@62: name = function() Zerotorescue@106: local t = ""; Zerotorescue@106: if not addon.db.profile.defaults.hideHelp then Zerotorescue@155: t = "Here you can set general settings. The settings entered here will be used when you choose not to override the settings within an individual group."; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return t; Zerotorescue@155: end, Zerotorescue@155: }, Zerotorescue@155: header = { Zerotorescue@155: order = 5, Zerotorescue@155: type = "header", Zerotorescue@155: name = "", Zerotorescue@155: }, Zerotorescue@155: trackAtCharacters = { Zerotorescue@155: order = 10, Zerotorescue@155: type = "multiselect", Zerotorescue@176: name = "Track at", Zerotorescue@176: desc = "Select at which characters groups should be tracked, appear in the summary or generate alerts.", Zerotorescue@155: values = function() Zerotorescue@155: local temp = {}; Zerotorescue@155: for charName in pairs(addon.db.factionrealm.characters) do Zerotorescue@155: temp[charName] = charName; Zerotorescue@155: end Zerotorescue@155: Zerotorescue@155: return temp; Zerotorescue@155: end, Zerotorescue@155: get = function(i, v) Zerotorescue@155: return addon.db.profile.defaults.trackAtCharacters[v]; Zerotorescue@155: end, Zerotorescue@155: set = function(i, v, e) Zerotorescue@155: addon.db.profile.defaults.trackAtCharacters[v] = e or nil; Zerotorescue@155: end, Zerotorescue@155: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@155: }, Zerotorescue@176: dontAlertAtCharacters = { Zerotorescue@176: order = 15, Zerotorescue@176: type = "multiselect", Zerotorescue@176: name = "Do |cffff0000not|r alert at:", Zerotorescue@176: desc = "Select at which characters items in groups should |cffff0000not|r generate alerts when they are below the required stock.", Zerotorescue@176: values = function() Zerotorescue@176: local temp = {}; Zerotorescue@176: for charName in pairs(addon.db.factionrealm.characters) do Zerotorescue@176: temp[charName] = charName; Zerotorescue@176: end Zerotorescue@176: Zerotorescue@176: return temp; Zerotorescue@176: end, Zerotorescue@176: get = function(i, v) Zerotorescue@176: return addon.db.profile.defaults.dontAlertAtCharacters[v]; Zerotorescue@176: end, Zerotorescue@176: set = function(i, v, e) Zerotorescue@176: addon.db.profile.defaults.dontAlertAtCharacters[v] = e or nil; Zerotorescue@176: end, Zerotorescue@176: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@176: }, Zerotorescue@176: --[[stockLevelAlertScanRepeatInterval = { Zerotorescue@176: order = 17, Zerotorescue@176: type = "multiselect", Zerotorescue@176: name = "Stock scan repeat interval", Zerotorescue@176: desc = "Select when or how often your stock levels should be checked and show alerts.", Zerotorescue@176: values = { Zerotorescue@176: ["00Login"] = "At login", Zerotorescue@176: ["01Repeat5"] = "Every 5 minutes", Zerotorescue@176: ["02Repeat10"] = "Every 10 minutes", Zerotorescue@176: ["03Repeat15"] = "Every 15 minutes", Zerotorescue@176: ["04Repeat30"] = "Every 30 minutes", Zerotorescue@176: ["05Repeat60"] = "Every 1 hour", Zerotorescue@176: ["06Repeat120"] = "Every 2 hours", Zerotorescue@176: }, Zerotorescue@176: get = function(i, v) return addon.db.profile.defaults.scanRepeatInterval and addon.db.profile.defaults.scanRepeatInterval[v]; end, Zerotorescue@176: set = function(i, v, e) addon.db.profile.defaults.scanRepeatInterval[v] = e; end, -- can't be nil or the defaults will be used Zerotorescue@176: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@176: },]] Zerotorescue@155: localItemData = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "multiselect", Zerotorescue@155: name = "Include in local item data", Zerotorescue@155: desc = "Select which data should be included in the local item data.", Zerotorescue@155: values = { Zerotorescue@155: ["Bag"] = "Bag", Zerotorescue@155: ["Bank"] = "Bank", Zerotorescue@155: ["Auction House"] = "Auction House", Zerotorescue@155: ["Mailbox"] = "Mailbox", Zerotorescue@155: }, Zerotorescue@155: get = function(i, v) return addon.db.profile.defaults.localItemData and addon.db.profile.defaults.localItemData[v]; end, Zerotorescue@155: set = function(i, v, e) addon.db.profile.defaults.localItemData[v] = e; end, -- can't be nil or the defaults will be used Zerotorescue@155: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: minimumStock = { Zerotorescue@155: order = 10, Zerotorescue@155: type = "group", Zerotorescue@155: inline = true, Zerotorescue@155: name = "Minimum stock", Zerotorescue@155: args = { Zerotorescue@155: description = { Zerotorescue@155: order = 0, Zerotorescue@155: type = "description", Zerotorescue@155: name = "Here you can specify the default minimum amount of items you wish to keep in stock and related settings. The settings entered here will be used when you choose not to override the settings within an individual group.", Zerotorescue@155: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@155: }, Zerotorescue@155: header = { Zerotorescue@155: order = 5, Zerotorescue@155: type = "header", Zerotorescue@155: name = "", Zerotorescue@155: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@155: }, Zerotorescue@176: Zerotorescue@155: minLocalStock = { Zerotorescue@155: order = 10, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 100000, Zerotorescue@155: softMax = 100, Zerotorescue@155: step = 1, Zerotorescue@155: name = "Minimum local stock", Zerotorescue@155: desc = "You can manually enter a value between 100 and 100.000 in the text box below if the provided range is insufficient.", Zerotorescue@155: get = function() return addon.db.profile.defaults.minLocalStock; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.minLocalStock = v; end, Zerotorescue@155: }, Zerotorescue@155: alertBelowLocalMinimum = { Zerotorescue@155: order = 11, Zerotorescue@155: type = "toggle", Zerotorescue@181: name = "Alert when below local minimum", Zerotorescue@155: desc = "Show an alert when this item gets below this threshold.", Zerotorescue@155: get = function() return addon.db.profile.defaults.alertBelowLocalMinimum; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.alertBelowLocalMinimum = v; end, Zerotorescue@155: }, Zerotorescue@155: autoRefill = { Zerotorescue@155: order = 12, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Auto refill from storage", Zerotorescue@155: desc = "Automatically refill items from your storage (bank/mailbox - unless this is included in the local count - or the guild bank) when below the minimum local stock.", Zerotorescue@155: get = function() return addon.db.profile.defaults.autoRefill; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.autoRefill = v; end, Zerotorescue@155: }, Zerotorescue@184: spacer = { Zerotorescue@184: order = 19, Zerotorescue@184: type = "description", Zerotorescue@184: name = "", Zerotorescue@184: }, Zerotorescue@176: Zerotorescue@155: minGlobalStock = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 100000, Zerotorescue@155: softMax = 100, Zerotorescue@155: step = 1, Zerotorescue@155: name = "Minimum global stock", Zerotorescue@155: desc = "You can manually enter a value between 100 and 100.000 in the text box below if the provided range is insufficient.", Zerotorescue@155: get = function() return addon.db.profile.defaults.minGlobalStock; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.minGlobalStock = v; end, Zerotorescue@155: }, Zerotorescue@155: alertBelowGlobalMinimum = { Zerotorescue@155: order = 21, Zerotorescue@155: type = "toggle", Zerotorescue@181: name = "Alert when below global minimum", Zerotorescue@155: desc = "Show an alert when this item gets below this threshold.", Zerotorescue@155: get = function() return addon.db.profile.defaults.alertBelowGlobalMinimum; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.alertBelowGlobalMinimum = v; end, Zerotorescue@155: }, Zerotorescue@176: Zerotorescue@155: summaryThresholdShow = { Zerotorescue@155: order = 30, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 100, Zerotorescue@155: softMax = 100, Zerotorescue@155: step = 0.05, Zerotorescue@155: isPercent = true, Zerotorescue@155: name = "Show in summary when below", Zerotorescue@155: desc = "Show items in the summary when below this percentage of the minimum stock. This can be either below the minimum or the global stock.", Zerotorescue@155: get = function() return addon.db.profile.defaults.summaryThresholdShow; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.summaryThresholdShow = v; end, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: refill = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "group", Zerotorescue@155: inline = true, Zerotorescue@155: name = "Replenishing stock", Zerotorescue@155: args = { Zerotorescue@155: description = { Zerotorescue@155: order = 0, Zerotorescue@155: type = "description", Zerotorescue@155: name = function() Zerotorescue@155: local r = "Here you can specify the default amount of items to which you wish to restock when you are collecting new items. This may be higher than the minimum stock. The settings entered here will be used when you choose not to override the settings within an individual group.\n\n"; Zerotorescue@155: Zerotorescue@155: r = r .. "When restocking the target amount is |cfffed000" .. addon.db.profile.defaults.restockTarget .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( addon.db.profile.defaults.minCraftingQueue * addon.db.profile.defaults.restockTarget ) .. "|r (|cfffed000" .. ( addon.db.profile.defaults.minCraftingQueue * 100 ) .. "%|r) of the restock target."; Zerotorescue@155: Zerotorescue@155: return r; Zerotorescue@155: end, Zerotorescue@155: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@155: }, Zerotorescue@155: header = { Zerotorescue@155: order = 5, Zerotorescue@155: type = "header", Zerotorescue@155: name = "", Zerotorescue@155: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@155: }, Zerotorescue@155: restockTarget = { Zerotorescue@155: order = 10, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 100000, Zerotorescue@155: softMax = 100, Zerotorescue@155: step = 1, Zerotorescue@155: name = "Restock target", Zerotorescue@155: desc = "You can manually enter a value between 100 and 100.000 in the edit box if the provided range is insufficient.", Zerotorescue@155: get = function() return addon.db.profile.defaults.restockTarget; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.restockTarget = v; end, Zerotorescue@155: }, Zerotorescue@155: minCraftingQueue = { Zerotorescue@155: order = 20, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 1, Zerotorescue@155: step = 0.01, -- 1% Zerotorescue@155: isPercent = true, Zerotorescue@155: name = "Don't queue if I only miss", Zerotorescue@155: desc = "Don't add a craftable item to the queue if I only miss this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.", Zerotorescue@155: get = function() return addon.db.profile.defaults.minCraftingQueue; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.minCraftingQueue = v; end, Zerotorescue@155: }, Zerotorescue@155: bonusQueue = { Zerotorescue@155: order = 30, Zerotorescue@155: type = "range", Zerotorescue@155: min = 0, Zerotorescue@155: max = 10, -- 1000% Zerotorescue@155: step = 0.01, -- 1% Zerotorescue@155: isPercent = true, Zerotorescue@155: name = "Bonus queue", Zerotorescue@155: desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.", Zerotorescue@155: get = function() return addon.db.profile.defaults.bonusQueue; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.bonusQueue = v; end, Zerotorescue@155: }, Zerotorescue@155: priceThreshold = { Zerotorescue@155: order = 40, Zerotorescue@155: type = "input", Zerotorescue@155: name = "Price threshold", Zerotorescue@155: desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.", Zerotorescue@155: validate = function(info, value) return addon:ValidateReadableMoney(info, value); end, Zerotorescue@155: get = function() return addon:ReadableMoney(addon.db.profile.defaults.priceThreshold); end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.priceThreshold = addon:ReadableMoneyToCopper(v); end, Zerotorescue@155: }, Zerotorescue@155: summaryHidePriceThreshold = { Zerotorescue@155: order = 50, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Hide when below threshold", Zerotorescue@155: desc = "Hide items from the summary when their value is below the set price threshold.", Zerotorescue@155: get = function() return addon.db.profile.defaults.summaryHidePriceThreshold; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.summaryHidePriceThreshold = v; end, Zerotorescue@155: }, Zerotorescue@155: alwaysGetAuctionValue = { Zerotorescue@155: order = 60, Zerotorescue@155: type = "toggle", Zerotorescue@155: name = "Always show auction value", Zerotorescue@155: desc = "Always cache and show the auction value of items, even if the price threshold is set to 0|cffeda55fc|r.", Zerotorescue@155: get = function() return addon.db.profile.defaults.alwaysGetAuctionValue; end, Zerotorescue@155: set = function(i, v) addon.db.profile.defaults.alwaysGetAuctionValue = v; end, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: }, Zerotorescue@155: addon = { Zerotorescue@155: order = 30, Zerotorescue@155: type = "group", Zerotorescue@155: inline = true, Zerotorescue@155: name = "Prefered addons", Zerotorescue@155: args = { Zerotorescue@155: description = { Zerotorescue@155: order = 0, Zerotorescue@155: type = "description", Zerotorescue@155: name = function() Zerotorescue@155: local t = ""; Zerotorescue@155: if not addon.db.profile.defaults.hideHelp then Zerotorescue@155: t = "Selecting your prefered addons is optional, the first working addon will be used if the selected addon doesn't exist. You only need to set this when you are running multiple addons of a kind and wish to specify which addons to use for what groups.\n\n"; Zerotorescue@106: end Zerotorescue@62: Zerotorescue@62: local currentAddon, selectedAddonName = addon:GetItemCountAddon(); Zerotorescue@62: local preferedAddon = addon.db.profile.defaults.itemCountAddon; Zerotorescue@62: Zerotorescue@62: if currentAddon then Zerotorescue@62: t = t .. "Currently using |cfffed000" .. selectedAddonName .. "|r as your item count addon. This addon is " .. ((currentAddon.IsEnabled() and "|cff00ff00enabled|r") or "|cffff0000disabled|r") .. "."; Zerotorescue@62: Zerotorescue@62: if currentAddon.GetTotalCount and currentAddon.GetCharacterCount then Zerotorescue@62: t = t .. " This addon supports |cfffed000both total as local|r item counts."; Zerotorescue@62: elseif currentAddon.GetTotalCount then Zerotorescue@62: t = t .. " This addon supports |cfffed000only total|r item counts."; Zerotorescue@62: elseif currentAddon.GetCharacterCount then Zerotorescue@62: t = t .. " This addon supports |cfffed000only local|r item counts."; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: if preferedAddon ~= selectedAddonName then Zerotorescue@216: t = t .. "\n\n|cffff0000You have selected |cfffed000" .. preferedAddon .. "|r|cffff0000 as your item count addon, but this appears to be disabled and thus the best alternative was selected.|r"; Zerotorescue@62: end Zerotorescue@240: else Zerotorescue@240: t = t .. "|cffff0000Warning! No item count addon detected!|r"; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return t; Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: header = { Zerotorescue@62: order = 5, Zerotorescue@62: type = "header", Zerotorescue@62: name = "", Zerotorescue@62: }, Zerotorescue@62: auctionPricingAddon = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "select", Zerotorescue@62: name = "Prefered pricing addon", Zerotorescue@62: desc = "Select the addon you prefer data to be retrieved from. A random supported addon will be used if the selected addon can not be found.", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@62: for name, value in pairs(addon.supportedAddons.auctionPricing) do Zerotorescue@62: temp[name] = name; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: get = function() return addon.db.profile.defaults.auctionPricingAddon; end, Zerotorescue@62: set = function(i, v) Zerotorescue@62: addon.db.profile.defaults.auctionPricingAddon = v; Zerotorescue@62: Zerotorescue@62: if addon.supportedAddons.auctionPricing[v].OnSelect then Zerotorescue@62: addon.supportedAddons.auctionPricing[v].OnSelect(); Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: itemCountAddon = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "select", Zerotorescue@62: name = "Prefered item count addon", Zerotorescue@216: desc = "Select the addon you prefer data to be retrieved from. The best supported addon will be used if the selected addon can not be found.", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@62: for name, value in pairs(addon.supportedAddons.itemCount) do Zerotorescue@62: temp[name] = name; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: get = function() return addon.db.profile.defaults.itemCountAddon; end, Zerotorescue@62: set = function(i, v) Zerotorescue@62: addon.db.profile.defaults.itemCountAddon = v; Zerotorescue@62: Zerotorescue@62: if addon.supportedAddons.itemCount[v].OnSelect then Zerotorescue@62: addon.supportedAddons.itemCount[v].OnSelect(); Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@62: craftingAddon = { Zerotorescue@62: order = 30, Zerotorescue@62: type = "select", Zerotorescue@62: name = "Prefered crafting addon", Zerotorescue@62: desc = "Select the addon you prefer data to be queued into. A random supported addon will be used if the selected addon can not be found.", Zerotorescue@62: values = function() Zerotorescue@62: local temp = {}; Zerotorescue@62: for name, value in pairs(addon.supportedAddons.crafting) do Zerotorescue@62: temp[name] = name; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: return temp; Zerotorescue@62: end, Zerotorescue@62: get = function() return addon.db.profile.defaults.craftingAddon; end, Zerotorescue@62: set = function(i, v) Zerotorescue@62: addon.db.profile.defaults.craftingAddon = v; Zerotorescue@62: Zerotorescue@62: if addon.supportedAddons.crafting[v].OnSelect then Zerotorescue@62: addon.supportedAddons.crafting[v].OnSelect(); Zerotorescue@62: end Zerotorescue@62: end, Zerotorescue@62: }, Zerotorescue@157: guildSelection = { Zerotorescue@157: order = 40, Zerotorescue@157: type = "multiselect", Zerotorescue@157: name = "Include guild bank data", Zerotorescue@157: desc = "Select which guild data should be included in the item counts.", Zerotorescue@157: values = function() Zerotorescue@157: local temp = {}; Zerotorescue@157: Zerotorescue@157: local currentAddon, selectedAddonName = addon:GetItemCountAddon(groupName); Zerotorescue@157: Zerotorescue@176: if currentAddon and currentAddon.GetGuildNames then Zerotorescue@157: local guilds = currentAddon.GetGuildNames(); Zerotorescue@157: Zerotorescue@157: if guilds and type(guilds) == "table" then Zerotorescue@157: for guildName, state in pairs(guilds) do Zerotorescue@157: temp[guildName] = guildName; Zerotorescue@157: Zerotorescue@157: if addon.db.profile.defaults.itemCountGuildsExcluded[guildName] then Zerotorescue@157: currentAddon.SetGuildState(guildName, false); Zerotorescue@157: else Zerotorescue@157: currentAddon.SetGuildState(guildName, true); Zerotorescue@157: end Zerotorescue@157: end Zerotorescue@157: end Zerotorescue@157: end Zerotorescue@157: Zerotorescue@157: return temp; Zerotorescue@157: end, Zerotorescue@157: get = function(i, v) Zerotorescue@157: local currentAddon, selectedAddonName = addon:GetItemCountAddon(groupName); Zerotorescue@157: Zerotorescue@176: return currentAddon and currentAddon.GetGuildNames and currentAddon.GetGuildNames()[v]; Zerotorescue@157: end, Zerotorescue@157: set = function(i, v, e) Zerotorescue@157: local currentAddon, selectedAddonName = addon:GetItemCountAddon(groupName); Zerotorescue@157: Zerotorescue@157: if e then Zerotorescue@157: -- Guild is enabled, so not excluded Zerotorescue@157: addon.db.profile.defaults.itemCountGuildsExcluded[v] = nil; Zerotorescue@157: else Zerotorescue@157: addon.db.profile.defaults.itemCountGuildsExcluded[v] = true; -- this is excluded, excluded is indicated by true Zerotorescue@157: end Zerotorescue@157: Zerotorescue@176: if currentAddon and currentAddon.SetGuildState then Zerotorescue@157: currentAddon.SetGuildState(v, e); Zerotorescue@157: end Zerotorescue@157: end, -- can't be nil or the defaults will be used Zerotorescue@157: dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead. Zerotorescue@157: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@106: }, Zerotorescue@106: }; Zerotorescue@106: end Zerotorescue@106: Zerotorescue@106: function mod:FillExtraOptions() Zerotorescue@189: local selectedExportGroups, enableBackupGeneration; Zerotorescue@106: options.args.extra = { Zerotorescue@106: order = 300, Zerotorescue@106: type = "group", Zerotorescue@106: name = "Extra", Zerotorescue@106: desc = "Change additional (but completely optional) settings.", Zerotorescue@106: args = { Zerotorescue@106: misc = { Zerotorescue@106: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@106: name = "Miscellaneous", Zerotorescue@62: args = { Zerotorescue@210: minimapIcon = { Zerotorescue@210: order = 0, Zerotorescue@210: type = "toggle", Zerotorescue@210: width = "full", Zerotorescue@210: name = "Display the minimap icon", Zerotorescue@210: desc = "Display the minimap icon for Inventorium allowing functionality to be used without typing slash commands.", Zerotorescue@210: get = function() return addon.db.profile.defaults.minimapIcon; end, Zerotorescue@210: set = function(i, v) Zerotorescue@210: addon.db.profile.defaults.minimapIcon = v; Zerotorescue@210: Zerotorescue@210: if v then Zerotorescue@210: addon:GetModule("MinimapIcon"):ShowIcon(); Zerotorescue@210: else Zerotorescue@210: addon:GetModule("MinimapIcon"):HideIcon(); Zerotorescue@210: end Zerotorescue@210: end, Zerotorescue@210: }, Zerotorescue@106: hideHelp = { Zerotorescue@106: order = 10, Zerotorescue@106: type = "toggle", Zerotorescue@106: width = "full", Zerotorescue@106: name = "Hide any help tooltips, descriptions and the help config category", Zerotorescue@106: desc = "Hide any optional help tooltips, descriptions and the help config category.\n\nPlease note some tooltips may not disappear until next login.", Zerotorescue@106: get = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.hideHelp = v; end, Zerotorescue@62: }, Zerotorescue@106: autoRefillSkipConfirm = { Zerotorescue@62: order = 20, Zerotorescue@106: type = "toggle", Zerotorescue@106: width = "full", Zerotorescue@131: name = "Skip the confirmation window for storage refilling", Zerotorescue@131: desc = "Automatically start moving items from the storage (bank, guild bank or mailbox) without showing the confirmation window.", Zerotorescue@106: get = function() return addon.db.profile.defaults.autoRefillSkipConfirm; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.autoRefillSkipConfirm = v; end, Zerotorescue@76: }, Zerotorescue@176: stockAlertScanInterval = { Zerotorescue@176: order = 25, Zerotorescue@176: type = "select", Zerotorescue@176: width = "double", Zerotorescue@176: name = "Stock scan speed", Zerotorescue@176: desc = "Select the speed at which items should be scanned for stock alerts. Faster requires more resources and may drastically reduce your frame rate during a scan.", Zerotorescue@176: values = { Zerotorescue@184: ["0"] = "(Near) instant", -- scans in steps of 100 Zerotorescue@184: ["0.01"] = "Very fast", -- scans in steps of 2 Zerotorescue@176: ["0.05"] = "Fast", Zerotorescue@176: ["0.1"] = "Default", Zerotorescue@176: ["0.2"] = "Medium", Zerotorescue@176: ["0.3"] = "Slow", Zerotorescue@176: ["0.5"] = "Very slow", Zerotorescue@176: }, Zerotorescue@176: get = function() return addon.db.profile.defaults.scanInterval; end, Zerotorescue@176: set = function(i, v) addon.db.profile.defaults.scanInterval = v; end, Zerotorescue@176: }, Zerotorescue@176: spacer = { Zerotorescue@176: order = 26, Zerotorescue@176: type = "description", Zerotorescue@176: name = "", Zerotorescue@176: }, Zerotorescue@76: removeCharacter = { Zerotorescue@106: order = 30, Zerotorescue@76: type = "select", Zerotorescue@106: width = "double", Zerotorescue@106: name = "Remove a character from Inventorium's memory", Zerotorescue@76: desc = "Select a character to remove all traces of it from Inventorium's memory.\n\nYour current character can not be removed, you must login to a different character to do so.", Zerotorescue@76: values = function() Zerotorescue@76: local temp = {}; Zerotorescue@76: Zerotorescue@76: temp[""] = ""; Zerotorescue@76: Zerotorescue@76: local playerName = UnitName("player"); Zerotorescue@76: for charName in pairs(addon.db.factionrealm.characters) do Zerotorescue@76: if playerName ~= charName then Zerotorescue@76: temp[charName] = charName; Zerotorescue@76: end Zerotorescue@76: end Zerotorescue@76: Zerotorescue@76: return temp; Zerotorescue@76: end, Zerotorescue@76: set = function(i, value) Zerotorescue@76: if value and value ~= "" then Zerotorescue@76: addon.db.factionrealm.characters[value] = nil; Zerotorescue@76: addon.db.profile.defaults.trackAtCharacters[value] = nil; Zerotorescue@176: addon.db.profile.defaults.dontAlertAtCharacters[value] = nil; Zerotorescue@76: for name, values in pairs(addon.db.profile.groups) do Zerotorescue@76: if values.trackAtCharacters then Zerotorescue@76: values.trackAtCharacters[name] = nil; Zerotorescue@76: end Zerotorescue@176: Zerotorescue@176: if values.dontAlertAtCharacters then Zerotorescue@176: values.dontAlertAtCharacters[name] = nil; Zerotorescue@176: end Zerotorescue@76: end Zerotorescue@76: end Zerotorescue@76: end, Zerotorescue@76: }, Zerotorescue@76: }, Zerotorescue@76: }, Zerotorescue@106: colorCodes = { Zerotorescue@106: order = 30, Zerotorescue@106: type = "group", Zerotorescue@106: inline = true, Zerotorescue@106: name = "Color codes", Zerotorescue@106: args = { Zerotorescue@106: description = { Zerotorescue@106: order = 0, Zerotorescue@106: type = "description", Zerotorescue@106: name = "Change the color code thresholds based on the current stock remaining of the required minimum stock.", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@106: }, Zerotorescue@106: header = { Zerotorescue@106: order = 5, Zerotorescue@106: type = "header", Zerotorescue@106: name = "", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@106: }, Zerotorescue@106: green = { Zerotorescue@106: order = 10, Zerotorescue@106: type = "range", Zerotorescue@106: min = 0, Zerotorescue@106: max = 1, Zerotorescue@106: step = 0.01, Zerotorescue@106: isPercent = true, Zerotorescue@106: name = "|cff00ff00Green|r", Zerotorescue@106: desc = "Show quantity in green when at least this much of the minimum stock is available.", Zerotorescue@106: get = function() return addon.db.profile.defaults.colors.green; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.colors.green = v; end, Zerotorescue@106: }, Zerotorescue@106: yellow = { Zerotorescue@106: order = 20, Zerotorescue@106: type = "range", Zerotorescue@106: min = 0, Zerotorescue@106: max = 1, Zerotorescue@106: step = 0.01, Zerotorescue@106: isPercent = true, Zerotorescue@106: name = "|cffffff00Yellow|r", Zerotorescue@106: desc = "Show quantity in yellow when at least this much of the minimum stock is available.", Zerotorescue@106: get = function() return addon.db.profile.defaults.colors.yellow; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.colors.yellow = v; end, Zerotorescue@106: }, Zerotorescue@106: orange = { Zerotorescue@106: order = 30, Zerotorescue@106: type = "range", Zerotorescue@106: min = 0, Zerotorescue@106: max = 1, Zerotorescue@106: step = 0.01, Zerotorescue@106: isPercent = true, Zerotorescue@106: name = "|cffff9933Orange|r", Zerotorescue@106: desc = "Show quantity in orange when at least this much of the minimum stock is available.", Zerotorescue@106: get = function() return addon.db.profile.defaults.colors.orange; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.colors.orange = v; end, Zerotorescue@106: }, Zerotorescue@106: red = { Zerotorescue@106: order = 40, Zerotorescue@106: type = "range", Zerotorescue@106: min = 0, Zerotorescue@106: max = 1, Zerotorescue@106: step = 0.01, Zerotorescue@106: isPercent = true, Zerotorescue@106: name = "|cffff0000Red|r", Zerotorescue@106: desc = "Show quantity in red when at least this much of the minimum stock is available.", Zerotorescue@106: get = function() return addon.db.profile.defaults.colors.red; end, Zerotorescue@106: set = function(i, v) addon.db.profile.defaults.colors.red = v; end, Zerotorescue@106: }, Zerotorescue@106: }, Zerotorescue@106: }, Zerotorescue@189: export = { Zerotorescue@189: order = 80, Zerotorescue@189: type = "group", Zerotorescue@189: inline = true, Zerotorescue@189: name = "Export groups", Zerotorescue@189: args = { Zerotorescue@189: description = { Zerotorescue@189: order = 0, Zerotorescue@189: type = "description", Zerotorescue@189: name = "Select the groups you wish to export below. Each group will have any account specific data removed and can safely and freely be shared with other users. All exported groups can be imported at once at the bottom of the \"Groups\" category of the config.", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@189: header = { Zerotorescue@189: order = 5, Zerotorescue@189: type = "header", Zerotorescue@189: name = "", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@242: selectExportGroups = { Zerotorescue@189: order = 9, Zerotorescue@189: type = "multiselect", Zerotorescue@189: name = "Select groups", Zerotorescue@189: desc = "Select which groups should be included in the export.", Zerotorescue@189: values = function() Zerotorescue@189: local temp = {}; Zerotorescue@189: Zerotorescue@189: if addon.db.profile.groups then Zerotorescue@189: temp["*InverseAll"] = "Inverse"; Zerotorescue@189: Zerotorescue@189: for groupName, _ in pairs(addon.db.profile.groups) do Zerotorescue@189: temp[groupName] = groupName; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: return temp; Zerotorescue@189: end, Zerotorescue@189: get = function(info, value) Zerotorescue@189: --local groupName = groupIdToName[info[2]]; Zerotorescue@189: --local optionName = info[#info]; Zerotorescue@189: Zerotorescue@189: return selectedExportGroups and selectedExportGroups[value]; Zerotorescue@189: end, Zerotorescue@189: set = function(info, name, value) Zerotorescue@189: --local groupName = groupIdToName[info[2]]; Zerotorescue@189: --local optionName = info[#info]; Zerotorescue@189: Zerotorescue@189: if not selectedExportGroups then Zerotorescue@189: selectedExportGroups = {}; Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: if name == "*InverseAll" then Zerotorescue@189: for groupName, _ in pairs(addon.db.profile.groups) do Zerotorescue@189: if selectedExportGroups and selectedExportGroups[groupName] then Zerotorescue@189: selectedExportGroups[groupName] = nil; Zerotorescue@189: else Zerotorescue@189: selectedExportGroups[groupName] = true; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: else Zerotorescue@189: if selectedExportGroups and selectedExportGroups[name] then Zerotorescue@189: selectedExportGroups[name] = nil; Zerotorescue@189: else Zerotorescue@189: selectedExportGroups[name] = true; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: end, Zerotorescue@189: }, Zerotorescue@189: input = { Zerotorescue@189: order = 10, Zerotorescue@189: type = "input", Zerotorescue@189: multiline = true, Zerotorescue@189: width = "full", Zerotorescue@189: name = "Exported data", Zerotorescue@189: desc = "Exported group data for the currently selected group(s). Press CTRL-A to select all and CTRL-C to copy the text.", Zerotorescue@189: set = false, Zerotorescue@189: get = function() Zerotorescue@189: local result = ""; Zerotorescue@189: if selectedExportGroups then Zerotorescue@189: for groupName, v in pairs(selectedExportGroups) do Zerotorescue@189: if v then Zerotorescue@189: result = result .. mod:ExportGroup(groupName) .. "\n"; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: return result; Zerotorescue@189: end, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@189: backup = { Zerotorescue@189: order = 100, Zerotorescue@189: type = "group", Zerotorescue@189: inline = true, Zerotorescue@189: name = "Generate a full backup", Zerotorescue@189: args = { Zerotorescue@189: description = { Zerotorescue@189: order = 0, Zerotorescue@189: type = "description", Zerotorescue@189: name = "With this you can generate a full backup of all your Inventorium settings. You can store this in a text file on your computer so you can import it at a later time if anything breaks to prevent losing a time consuming setup. You can also use it to share with other users but keep in mind this will include account specific data which you might not want in the wrong hands.", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@189: header = { Zerotorescue@189: order = 5, Zerotorescue@189: type = "header", Zerotorescue@189: name = "", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@189: generate = { Zerotorescue@189: order = 9, Zerotorescue@189: type = "toggle", Zerotorescue@189: width = "full", Zerotorescue@189: name = "Generate a full backup (might take a second)", Zerotorescue@189: desc = "Generate a full backup. This process might take 1 to 2 seconds.", Zerotorescue@189: set = function(_, v) Zerotorescue@189: enableBackupGeneration = v; Zerotorescue@189: end, Zerotorescue@189: get = function() Zerotorescue@189: return enableBackupGeneration; Zerotorescue@189: end, Zerotorescue@189: }, Zerotorescue@189: input = { Zerotorescue@189: order = 10, Zerotorescue@189: type = "input", Zerotorescue@189: multiline = true, Zerotorescue@189: width = "full", Zerotorescue@189: name = "Exported data", Zerotorescue@189: desc = "Exported backup data. Press CTRL-A to select all and CTRL-C to copy the text.\n\nPlease note this includes character data.", Zerotorescue@189: set = false, Zerotorescue@189: get = function() Zerotorescue@189: if not enableBackupGeneration then Zerotorescue@189: return; Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: -- We want to include the group name, so we copy the table then set another value Zerotorescue@189: local temp = { Zerotorescue@189: ["type"] = "backup", Zerotorescue@189: ["global"] = addon.db.global or {}, Zerotorescue@189: ["profiles"] = addon.db.profiles or {}, Zerotorescue@189: ["factionrealm"] = addon.db.factionrealm or {}, Zerotorescue@189: }; Zerotorescue@189: Zerotorescue@189: if not AceSerializer then Zerotorescue@189: AceSerializer = LibStub("AceSerializer-3.0"); Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: return AceSerializer:Serialize(temp); Zerotorescue@189: end, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@189: importBackup = { Zerotorescue@189: order = 101, Zerotorescue@189: type = "group", Zerotorescue@189: inline = true, Zerotorescue@189: name = "Import a full backup", Zerotorescue@189: args = { Zerotorescue@189: description = { Zerotorescue@189: order = 0, Zerotorescue@189: type = "description", Zerotorescue@189: name = "With this you can import a full backup of all your Inventorium settings. |cffff0000Warning! Importing a backup will TRASH all your current settings and profiles. You are advised to store your own backup prior to importing one.|r", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@189: header = { Zerotorescue@189: order = 5, Zerotorescue@189: type = "header", Zerotorescue@189: name = "", Zerotorescue@189: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@189: }, Zerotorescue@189: input = { Zerotorescue@189: order = 10, Zerotorescue@189: type = "input", Zerotorescue@189: multiline = true, Zerotorescue@189: width = "full", Zerotorescue@189: name = "Paste the backup data here", Zerotorescue@189: desc = "Exported backup data. To copy the backup data, press CTRL-A to select all and CTRL-C to copy it. Then click this textblock and hit CTRL-V to paste it.", Zerotorescue@189: set = function(_, v) Zerotorescue@189: if v and string.trim(v) ~= "" then Zerotorescue@189: if not AceSerializer then Zerotorescue@189: AceSerializer = LibStub("AceSerializer-3.0"); Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: local result, temp = AceSerializer:Deserialize(v); Zerotorescue@189: Zerotorescue@189: if result and temp and type(temp) == "table" and temp.type and temp.type == "backup" then Zerotorescue@189: addon.db:ResetDB("TEMPPROFILENAME" .. GetTime()); Zerotorescue@189: Zerotorescue@189: local tempProfileName = addon.db:GetCurrentProfile(); Zerotorescue@189: Zerotorescue@189: if temp.global then Zerotorescue@189: print("Importing |cfffed000global|r data..."); Zerotorescue@189: Zerotorescue@189: -- Update by reference, rather than changing the reference Zerotorescue@189: for k, v in pairs(temp.global) do Zerotorescue@189: addon.db.global[k] = v; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: if temp.profiles then Zerotorescue@189: print("Importing |cfffed000profiles|r data..."); Zerotorescue@189: Zerotorescue@189: -- Update by reference, rather than changing the reference Zerotorescue@189: for profileName, profile in pairs(temp.profiles) do Zerotorescue@189: print("Importing profile |cfffed000" .. profileName .. "|r..."); Zerotorescue@189: Zerotorescue@189: addon.db.profiles[profileName] = profile; Zerotorescue@189: Zerotorescue@189: -- If the current profile is the temp profile, select the first profile in the backup Zerotorescue@189: if addon.db:GetCurrentProfile() == tempProfileName or profileName == "Default" then Zerotorescue@189: addon.db:SetProfile(profileName); Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: -- If our backup contains a profile with the same name as the temp profile, then don't delete the temp profile Zerotorescue@189: if profileName == tempProfileName then Zerotorescue@189: tempProfileName = nil; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: -- Delete the temp profile Zerotorescue@189: if tempProfileName then Zerotorescue@189: addon.db:DeleteProfile(tempProfileName); Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: if temp.factionrealm then Zerotorescue@189: print("Importing |cfffed000character|r data..."); Zerotorescue@189: Zerotorescue@189: -- Update by reference, rather than changing the reference Zerotorescue@189: for k, v in pairs(temp.factionrealm) do Zerotorescue@189: addon.db.factionrealm[k] = v; Zerotorescue@189: end Zerotorescue@189: end Zerotorescue@189: Zerotorescue@189: mod:FillGroupOptions(); Zerotorescue@189: Zerotorescue@189: addon:Print("Import finished.", addon.Colors.Green); Zerotorescue@189: else Zerotorescue@189: addon:Print("The data provided is not supported.", addon.Colors.Red); Zerotorescue@189: end Zerotorescue@189: else Zerotorescue@189: addon:Print("The data provided is not supported.", addon.Colors.Red); Zerotorescue@189: end Zerotorescue@189: end, Zerotorescue@189: get = false, Zerotorescue@189: confirm = function() return "Are you sure you wish to override all your current settings with this data?"; end, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@189: }, Zerotorescue@62: }, Zerotorescue@62: }; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function mod:FillHelpOptions() Zerotorescue@62: options.args.help = { Zerotorescue@62: order = 150, Zerotorescue@62: type = "group", Zerotorescue@106: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@62: childGroups = "tab", Zerotorescue@62: name = "Help", Zerotorescue@62: desc = "Useful information for if you're unfamiliar with a part of the addon.", Zerotorescue@62: args = { Zerotorescue@62: general = { Zerotorescue@62: order = 1, Zerotorescue@62: type = "group", Zerotorescue@62: name = "General", Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@214: name = "You can find a |cfffed000User Manual|r inside your addon folder or online at Google Docs (see the addon download page for a link). If you are new to this addon it may be a wealth of information.\n\n" .. Zerotorescue@214: "Dropdown boxes that allow you to select more than 1 option should be closed using the \"|cfffed000Close|r\" option at the bottom before switching groups or closing the config. If this dropdown is still opened while switching groups or closing the config, it may cause an error and break the config requiring you to do /reloadui to continue working with the config.\n\n" .. Zerotorescue@214: "Please request things you want and report anything that's clunky, weird, vague or otherwise buggy at |cfffed000the Inventorium ticket tracker|r. You can find this by going to the addon page.\n\n" .. Zerotorescue@214: "You might notice the summary window currently gets a little slow when refreshed once you get over 200ish items in the list. This is a known issue and the summary window will be rewritten to resolve this somewhere in a future patch.", Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: FAQ = { Zerotorescue@62: order = 3, Zerotorescue@62: type = "group", Zerotorescue@62: name = "FAQ", Zerotorescue@62: args = { Zerotorescue@62: description = { Zerotorescue@62: order = 0, Zerotorescue@62: type = "description", Zerotorescue@214: name = "|cfffed000My groups don't appear in the summary window.|r\n" .. Zerotorescue@214: "Please ensure your current character is toggled on at the \"track at\" option beneath the \"minimum stock\" category within a group or the defaults.\n\n" .. Zerotorescue@214: Zerotorescue@214: "|cfffed000The auction value column always shows a \"-\".|r\n" .. Zerotorescue@214: "The auction value will not be cached when you set the \"price threshold\" beneath the \"replenishing stock\" category to |cfffed0000c|r. You can change this behavior by adjusting this value or toggling the \"Always show auction value\" option on.\n\n" .. Zerotorescue@214: Zerotorescue@214: "|cfffed000Some items appear in the \"unqueueable\" frame while I can find them in the profession.|r\n" .. Zerotorescue@214: "Old items from before Cataclysm (such as any old gems) may have been renamed and their crafting skill removed. This might have resulted in certain items having the same name as others but with different ids, for example for Smooth King's Amber (search that at Wowhead for more info). Remove both items with the same name and add the one in your profession window again and this should no longer occur.\n\n" .. Zerotorescue@214: Zerotorescue@214: "|cfffed000What use do profiles have?|r\n" .. Zerotorescue@214: "Because there is already the \"track at\" option, profiles may not be useful to anyone. Nevertheless someone might find a use for it in some way and thus it is left available. You can use it to test certain things for example without the risk of your main groups being destroyed (although this should never be an excuse not to back up your settings from time to time).\n\n" .. Zerotorescue@214: Zerotorescue@214: "|cfffed000Can you provide me with an example scenario for virtual groups?|r\n" .. Zerotorescue@214: "The simplest (and possibly most popular) setup to imagine for using virtual groups are glyphs. There are over 300 glyphs available distributed over 10 classes (or 8 inks). Glyphs for certain classes (such as the tribrids; Druids & Paladins) might sell a lot more often than those for others (such as pure DPS; Hunters, etc.).\n\n" .. Zerotorescue@214: "To get an easily adjustable setup you can make one virtual group, called \"Glyphs\" and override all your prefered settings in there. After you are done, make a glyph-group for each class (such as \"Glyphs (Death Knight)\" etc.) and select \"Glyphs\" as virtual group for every one of them (you can easily insert item data to these class specific groups by selecting premade data).\n\n" .. Zerotorescue@214: "Now, to change the settings for all glyph groups you can just change the settings within the virtual \"Glyph\" group. To change the settings for one class in particular, such as Paladins because they sell more often than others, you can click this group and override the appropriate settings for just that group. There are many more possibilities for you to find out.\n\n" .. Zerotorescue@62: "", Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function mod:MakeGroupOptions() Zerotorescue@242: local selectedImportGroups; Zerotorescue@62: options.args.groups = { Zerotorescue@62: order = 1100, Zerotorescue@62: type = "group", Zerotorescue@62: name = "Groups", Zerotorescue@62: desc = "Change a group.", Zerotorescue@62: args = { Zerotorescue@62: create = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@62: name = "Create a brand new group", Zerotorescue@62: args = { Zerotorescue@62: name = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "input", Zerotorescue@62: name = "Group name", Zerotorescue@62: desc = "The name of the group. You can also use item links as you wish.", Zerotorescue@62: validate = ValidateGroupName, Zerotorescue@62: set = function(_, value) Zerotorescue@62: addon.db.profile.groups[value] = {}; Zerotorescue@62: if currentGroupType == "Virtual" then Zerotorescue@62: addon.db.profile.groups[value].isVirtual = true; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: mod:FillGroupOptions(); Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: width = "double", Zerotorescue@62: }, Zerotorescue@62: type = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "select", Zerotorescue@62: name = "Type (advanced)", Zerotorescue@62: desc = "The type of the new group. This can not be changed at a later time.\n\n|cffff9933This is an advanced option, you will probably not need it unless you manage a lot of groups.|r\n\n|cfffed000Normal|r: A normal group with complete functionality.\n\n|cfffed000Virtual|r: A virtual group which you can use to override the defaults for a set of groups. You can not add items to virtual groups.", Zerotorescue@62: values = { Zerotorescue@62: ["Normal"] = "Normal", Zerotorescue@62: ["Virtual"] = "Virtual", Zerotorescue@62: }, Zerotorescue@62: set = function(_, value) currentGroupType = value; end, Zerotorescue@62: get = function() return currentGroupType; end, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@242: importExport = { Zerotorescue@62: order = 20, Zerotorescue@62: type = "group", Zerotorescue@62: inline = true, Zerotorescue@242: name = "Import a group export", Zerotorescue@62: args = { Zerotorescue@242: help = { Zerotorescue@242: order = 5, Zerotorescue@242: type = "description", Zerotorescue@242: name = "If you have exported one or more groups (which can be done by clicking a group and opening the management tab or at the middle of the extra tab) you can instantly import them here. These groups will be added if no groups with the same name already exist.", Zerotorescue@242: hidden = function() return addon.db.profile.defaults.hideHelp; end, Zerotorescue@242: }, Zerotorescue@62: input = { Zerotorescue@62: order = 10, Zerotorescue@62: type = "input", Zerotorescue@62: multiline = true, Zerotorescue@242: name = "Exported group data", Zerotorescue@62: desc = "Paste the group data as provided by a group export. If you are trying to import multiple groups at the same time, make sure to use newlines to seperate them.", Zerotorescue@62: set = function(info, value) Zerotorescue@62: local data = { string.split("\n", value or "") }; Zerotorescue@62: Zerotorescue@62: for _, current in pairs(data) do Zerotorescue@152: if current and string.trim(current) ~= "" then Zerotorescue@152: if not AceSerializer then Zerotorescue@152: AceSerializer = LibStub("AceSerializer-3.0"); Zerotorescue@152: end Zerotorescue@62: Zerotorescue@152: local result, temp = AceSerializer:Deserialize(current); Zerotorescue@152: Zerotorescue@152: if not temp.name then Zerotorescue@152: addon:Print("The provided data is not supported.", addon.Colors.Red); Zerotorescue@152: elseif ValidateGroupName(nil, temp.name) ~= true then Zerotorescue@152: addon:Print(("Aborting: A group named \"%s\" already exists."):format(temp.name), addon.Colors.Red); Zerotorescue@152: else Zerotorescue@152: local name = temp.name; Zerotorescue@152: temp.name = nil; Zerotorescue@152: addon:Print(("Importing %s..."):format(name)); Zerotorescue@152: Zerotorescue@152: if temp.items then Zerotorescue@152: -- Remove items that are already in another group Zerotorescue@152: for value, count in pairs(temp.items) do Zerotorescue@152: local itemId = tonumber(value); Zerotorescue@152: Zerotorescue@152: local itemData = addon.ItemData:New(itemId); Zerotorescue@152: Zerotorescue@152: if not itemId then Zerotorescue@152: addon:Print(("\"%s\" is not a number."):format(value), addon.Colors.Red); Zerotorescue@152: temp.items[value] = nil; Zerotorescue@152: elseif itemData:InGroup() then Zerotorescue@152: addon:Print(("Skipping %s as it is already in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() ), addon.Colors.Red); Zerotorescue@152: temp.items[value] = nil; Zerotorescue@152: else Zerotorescue@152: -- Ensure the keys are numeric Zerotorescue@152: temp.items[value] = nil; Zerotorescue@152: temp.items[itemId] = tonumber(count) or 0; Zerotorescue@152: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@152: Zerotorescue@152: -- Ensure this data isn't received (this would be silly/buggy as exports from other accounts - with different characters - won't know what to do with this) Zerotorescue@152: temp.trackAtCharacters = nil; Zerotorescue@152: temp.overrideTrackAtCharacters = nil; Zerotorescue@176: temp.dontAlertAtCharacters = nil; Zerotorescue@176: temp.overrideDontAlertAtCharacters = nil; Zerotorescue@152: Zerotorescue@152: addon.db.profile.groups[name] = temp; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: self:FillGroupOptions(); Zerotorescue@62: end, Zerotorescue@62: get = false, Zerotorescue@62: width = "full", Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@62: }, Zerotorescue@242: importFromOtherAddons = { Zerotorescue@242: order = 30, Zerotorescue@242: type = "group", Zerotorescue@242: inline = true, Zerotorescue@242: name = "Import groups from other addons", Zerotorescue@242: args = { Zerotorescue@242: selectImportGroups = { Zerotorescue@242: order = 10, Zerotorescue@242: type = "multiselect", Zerotorescue@242: name = "Select groups", Zerotorescue@242: desc = "Select which groups should be imported.", Zerotorescue@242: values = function() Zerotorescue@242: local temp = {}; Zerotorescue@242: temp["*InverseAll"] = "Inverse"; Zerotorescue@242: Zerotorescue@242: local Ace = LibStub("AceAddon-3.0", true); Zerotorescue@242: if Ace then Zerotorescue@242: local ZA = Ace:GetAddon("ZeroAuctions", true); Zerotorescue@242: Zerotorescue@242: if ZA then Zerotorescue@242: for groupName, contents in pairs(ZA.db.global.groups) do Zerotorescue@242: temp["ZeroAuctions$" .. groupName] = string.format("ZA: %s", groupName); Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: local APM = Ace:GetAddon("AuctionProfitMaster", true); Zerotorescue@242: Zerotorescue@242: if APM then Zerotorescue@242: for groupName, contents in pairs(APM.db.global.groups) do Zerotorescue@242: temp["AuctionProfitMaster$" .. groupName] = string.format("APM: %s", groupName); Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: return temp; Zerotorescue@242: end, Zerotorescue@242: get = function(info, value) Zerotorescue@242: --local groupName = groupIdToName[info[2]]; Zerotorescue@242: --local optionName = info[#info]; Zerotorescue@242: Zerotorescue@242: return selectedImportGroups and selectedImportGroups[value]; Zerotorescue@242: end, Zerotorescue@242: set = function(info, name, value) Zerotorescue@242: --local groupName = groupIdToName[info[2]]; Zerotorescue@242: --local optionName = info[#info]; Zerotorescue@242: Zerotorescue@242: if not selectedImportGroups then Zerotorescue@242: selectedImportGroups = {}; Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: if name == "*InverseAll" then Zerotorescue@242: for groupName, _ in pairs(info.option.values()) do Zerotorescue@242: if selectedImportGroups and selectedImportGroups[groupName] then Zerotorescue@242: selectedImportGroups[groupName] = nil; Zerotorescue@242: else Zerotorescue@242: selectedImportGroups[groupName] = true; Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: else Zerotorescue@242: if selectedImportGroups and selectedImportGroups[name] then Zerotorescue@242: selectedImportGroups[name] = nil; Zerotorescue@242: else Zerotorescue@242: selectedImportGroups[name] = true; Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: end, Zerotorescue@242: }, Zerotorescue@242: import = { Zerotorescue@242: order = 20, Zerotorescue@242: type = "execute", Zerotorescue@242: name = "Import selected groups", Zerotorescue@242: desc = "Import the groups selected above.", Zerotorescue@242: func = function(info) Zerotorescue@242: -- Go through all selected groups Zerotorescue@242: for selection in pairs(selectedImportGroups) do Zerotorescue@242: local sourceAddon, groupName = string.match(selection, "^(%a+)\$(.+)$"); Zerotorescue@242: Zerotorescue@242: if sourceAddon == "ZeroAuctions" or sourceAddon == "AuctionProfitMaster" then Zerotorescue@242: -- ZeroAuctions/AuctionProfitMaster-group Zerotorescue@242: Zerotorescue@242: local ZA = LibStub("AceAddon-3.0"):GetAddon(sourceAddon); -- If it was in the list, we're sure the addon is enabled Zerotorescue@242: Zerotorescue@242: local temp = {}; Zerotorescue@242: Zerotorescue@242: do-- Set settings region Zerotorescue@242: local currentProfile = ZA.db.profile; Zerotorescue@242: if currentProfile then Zerotorescue@242: -- Set price threshold Zerotorescue@242: local threshold = currentProfile.threshold and currentProfile.threshold[groupName]; Zerotorescue@242: if threshold then Zerotorescue@242: -- Set price threshold Zerotorescue@242: temp.overridePriceThreshold = true; Zerotorescue@242: temp.priceThreshold = threshold; Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: -- Set minimum global stock, minimum local stock and restock target Zerotorescue@242: local postCap = currentProfile.postCap and currentProfile.postCap[groupName]; Zerotorescue@242: local perAuction = currentProfile.perAuction and currentProfile.perAuction[groupName]; Zerotorescue@242: if postCap and perAuction then Zerotorescue@242: -- Restock target Zerotorescue@242: temp.overrideRestockTarget = true; Zerotorescue@242: temp.restockTarget = (postCap * perAuction); Zerotorescue@242: Zerotorescue@242: -- Minimum global stock Zerotorescue@242: temp.overrideMinGlobalStock = true; Zerotorescue@242: temp.minGlobalStock = (postCap * perAuction); Zerotorescue@242: Zerotorescue@242: -- Minimum local stock Zerotorescue@242: temp.overrideMinLocalStock = true; Zerotorescue@242: temp.minLocalStock = perAuction; Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: local items = ZA.db.global.groups[groupName]; Zerotorescue@242: Zerotorescue@242: if not groupName or not items then Zerotorescue@242: addon:Print("The provided data is not supported.", addon.Colors.Red); Zerotorescue@242: elseif ValidateGroupName(nil, groupName) ~= true then Zerotorescue@242: addon:Print(("Aborting: A group named \"%s\" already exists."):format(groupName), addon.Colors.Red); Zerotorescue@242: else Zerotorescue@242: addon:Print(("Importing %s..."):format(groupName)); Zerotorescue@242: Zerotorescue@242: temp.items = {}; Zerotorescue@242: Zerotorescue@242: if items then Zerotorescue@242: -- Remove items that are already in another group Zerotorescue@242: for value, _ in pairs(items) do Zerotorescue@242: local textItemId = string.match(value, "^item:(%d+)$"); Zerotorescue@242: local itemId = tonumber(textItemId or ""); Zerotorescue@242: Zerotorescue@242: local itemData = addon.ItemData:New(itemId); Zerotorescue@242: Zerotorescue@242: if not itemId then Zerotorescue@242: addon:Print(("\"%s\" is not a number."):format(value), addon.Colors.Red); Zerotorescue@242: elseif itemData:InGroup() then Zerotorescue@242: addon:Print(("Skipping %s as it is already in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() ), addon.Colors.Red); Zerotorescue@242: else Zerotorescue@242: temp.items[itemId] = 0; Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: addon.db.profile.groups[groupName] = temp; Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: end Zerotorescue@242: Zerotorescue@242: mod:FillGroupOptions(); Zerotorescue@242: end, Zerotorescue@242: }, Zerotorescue@242: }, Zerotorescue@242: }, Zerotorescue@62: }, Zerotorescue@62: }; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function mod:FillGroupOptions() Zerotorescue@62: for id, name in pairs(groupIdToName) do Zerotorescue@62: if type(name) == "string" and not addon.db.profile.groups[name] then Zerotorescue@62: options.args.groups.args[id] = nil; Zerotorescue@62: groupIdToName[id] = nil; Zerotorescue@62: groupIdToName[name] = nil; Zerotorescue@62: groupIsVirtual[id] = nil; Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: for name, values in pairs(addon.db.profile.groups) do Zerotorescue@62: if not groupIdToName[name] then Zerotorescue@62: options.args.groups.args[tostring(count)] = defaultGroup; Zerotorescue@62: Zerotorescue@62: groupIdToName[tostring(count)] = name; Zerotorescue@62: groupIdToName[name] = true; Zerotorescue@62: if values.isVirtual then Zerotorescue@62: groupIsVirtual[tostring(count)] = true; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: count = ( count + 1 ); Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@62: end Zerotorescue@65: Zerotorescue@65: Zerotorescue@65: Zerotorescue@65: Zerotorescue@65: Zerotorescue@65: Zerotorescue@65: -- Verify premade groups Zerotorescue@65: Zerotorescue@65: function mod:PremadeGroupsCheck(updateGroupName, updateKey, accept) Zerotorescue@65: -- Compare the current premade groups with those used, notify about changes Zerotorescue@65: if addon.defaultGroups then Zerotorescue@65: for premadeGroupName, groupInfo in pairs(addon.defaultGroups) do Zerotorescue@65: -- Go through all default groups Zerotorescue@65: Zerotorescue@65: for groupName, values in pairs(addon.db.profile.groups) do Zerotorescue@65: -- Go through all groups to find those with this premade group Zerotorescue@65: Zerotorescue@65: if values.premadeGroups and values.premadeGroups[premadeGroupName] and values.premadeGroups[premadeGroupName] < groupInfo.version then Zerotorescue@65: -- Outdated group Zerotorescue@65: Zerotorescue@65: if updateGroupName and updateKey then Zerotorescue@65: -- This function was called after pressing yes or no in a confirm box Zerotorescue@65: Zerotorescue@65: if accept then Zerotorescue@65: -- Yes was clicked Zerotorescue@65: Zerotorescue@65: for itemId, version in pairs(groupInfo.items) do Zerotorescue@65: -- Go through all items in this premade group Zerotorescue@65: Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@76: Zerotorescue@65: if version > values.premadeGroups[premadeGroupName] then Zerotorescue@65: -- This item was added in a more recent version than this group: Add item Zerotorescue@65: Zerotorescue@76: if itemData:InGroup() then Zerotorescue@98: addon:Print(("Skipping %s as it is already in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() )); Zerotorescue@76: elseif itemData:AddToGroup(groupName) then Zerotorescue@98: addon:Print(("Added %s found in the premade group |cfffed000%s|r to the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), premadeGroupName, itemData:InGroup() ), addon.Colors.Green); Zerotorescue@65: end Zerotorescue@65: elseif ( version * -1 ) > values.premadeGroups[premadeGroupName] then Zerotorescue@76: if itemData:InGroup() == groupName then Zerotorescue@76: itemData:RemoveFromGroup(groupName); Zerotorescue@76: Zerotorescue@98: addon:Print(("Removed %s from the group |cfffed000%s|r as it was removed from the premade group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup(), premadeGroupName ), addon.Colors.Red); Zerotorescue@65: else Zerotorescue@98: addon:Print(("Skipping the removal of %s as it isn't in the group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() )); Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: Zerotorescue@76: if AceConfigRegistry then Zerotorescue@76: -- Now rebuild the list Zerotorescue@172: AceConfigRegistry:NotifyChange("Inventorium"); Zerotorescue@76: end Zerotorescue@76: Zerotorescue@65: -- Remember the new version Zerotorescue@65: values.premadeGroups[premadeGroupName] = groupInfo.version; Zerotorescue@65: else Zerotorescue@65: -- No was clicked Zerotorescue@65: Zerotorescue@65: -- Let user know what was not added Zerotorescue@65: for itemId, version in pairs(groupInfo.items) do Zerotorescue@65: -- Go through all items in this premade group Zerotorescue@65: Zerotorescue@76: local itemData = addon.ItemData:New(itemId); Zerotorescue@76: Zerotorescue@65: if version > values.premadeGroups[premadeGroupName] then Zerotorescue@65: -- This item was added in a more recent version than this group: don't add (since we clicked no), but announce it Zerotorescue@65: Zerotorescue@98: addon:Print(("Skipping %s found in the premade group |cfffed000%s|r."):format( (itemData.link or unknownItemName:format(itemId)), itemData:InGroup() )); Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: Zerotorescue@65: -- Remember the new version Zerotorescue@65: values.premadeGroups[premadeGroupName] = groupInfo.version; Zerotorescue@65: end Zerotorescue@65: else Zerotorescue@65: StaticPopupDialogs["InventoriumConfirmUpdatePremadeGroup"] = { Zerotorescue@65: text = "The premade group |cfffed000%s|r used in the group |cfffed000%s|r has been changed. Do you wish to copy these changes?", Zerotorescue@65: button1 = YES, Zerotorescue@65: button2 = NO, Zerotorescue@65: OnAccept = function() Zerotorescue@131: mod:PremadeGroupsCheck(groupName, premadeGroupName, true); Zerotorescue@65: end, Zerotorescue@65: OnCancel = function(_, _, reason) Zerotorescue@65: if reason == "clicked" then Zerotorescue@131: mod:PremadeGroupsCheck(groupName, premadeGroupName, false); Zerotorescue@65: end Zerotorescue@65: end, Zerotorescue@65: timeout = 0, Zerotorescue@65: whileDead = 1, Zerotorescue@65: hideOnEscape = 1, Zerotorescue@65: }; Zerotorescue@65: StaticPopup_Show("InventoriumConfirmUpdatePremadeGroup", premadeGroupName, groupName); Zerotorescue@65: Zerotorescue@65: return; Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: end Zerotorescue@65: end