Quantcast

- Titan: Reverted UI scaling below .64 - was causing problems...

urnati [01-06-23 - 20:00]
- Titan: Reverted UI scaling below .64 - was causing problems...
- TitanRepair: Added feature to auto sell grays or sell on left click when at vendor
- TitanBag: Rewritten; somewhere in 10.xx I began seeing 20/20 (backpack only). Determined that bag names are not always available at PEW (first or reload) so used the # of slots to determine. Bags may still be unknow but counts will be right. Should only impact those using tooltips right away.
- Debug - changed default debug color to a blue to make it distinct
Filename
Titan/TitanConfig.lua
Titan/TitanUtils.lua
Titan/TitanVariables.lua
TitanBag/TitanBag.lua
TitanRepair/TitanRepair.lua
diff --git a/Titan/TitanConfig.lua b/Titan/TitanConfig.lua
index f7d4b9d..263009d 100644
--- a/Titan/TitanConfig.lua
+++ b/Titan/TitanConfig.lua
@@ -33,11 +33,21 @@ local notes = ""
 		.."On PTR the menu & bag frame and the status / xp frame ARE adjustable via edit mode. This adjustment will be removed in a future release.\n"
 		)
 local changes = ""
-	..TitanUtils_GetGoldText("6.00.11.100002 : 2020/12/20\n")
+	..TitanUtils_GetGoldText("6.00.11.100002 : 2023/02/01\n\n")
 	..TitanUtils_GetGreenText("Plugins over another : \n")
 	..TitanUtils_GetHighlightText(""
 		.."- Fix for plugins that could show over another.\n"
 		)
+	..TitanUtils_GetGreenText("TitanRepair : \n")
+	..TitanUtils_GetHighlightText(""
+		.."- Added feature to sell ALL gray items at vendor - auto sell or on left click while at vendor\n"
+		.."- NOTE: ALL grays are sold - use CAUTION!\n"
+		)
+	..TitanUtils_GetGreenText("TitanBag : \n")
+	..TitanUtils_GetHighlightText(""
+		.."- Rewritten due to inaccurate info being seen.\n"
+		.."- NOTE: At entering world or reload the bag names may not be know. This will correct at next bag trigger.\n"
+		)
 	..TitanUtils_GetGreenText("Scaling : \n")
 	..TitanUtils_GetHighlightText(""
 		.."- Fix for error when changing scaling.\n"
@@ -47,7 +57,7 @@ local changes = ""
 		.."- About : Add slash command description to About.\n"
 		.."- Changes : Added to show change history.\n"
 		)
-	..TitanUtils_GetGoldText("6.00.10.100002 : 2020/12/13\n")
+	..TitanUtils_GetGoldText("6.00.10.100002 : 2022/12/13\n\n")
 	..TitanUtils_GetGreenText("TitanBag : \n")
 	..TitanUtils_GetHighlightText(""
 		.."- Made 'open bags' (left click) an option (default off) until container taint resolved.\n"
@@ -68,12 +78,12 @@ local changes = ""
 	..TitanUtils_GetHighlightText(""
 		.."- Fix for some LDB addons not being updating properly.\n"
 		)
-	..TitanUtils_GetGoldText("6.00.09.100002  : 2020/12/01\n")
+	..TitanUtils_GetGoldText("6.00.09.100002  : 2022/12/01\n\n")
 	..TitanUtils_GetGreenText("TitanRepair : \n")
 	..TitanUtils_GetHighlightText(""
 		.."- Quick fix for repair pop up.\n"
 		)
-	..TitanUtils_GetGoldText("6.00.08.100002  : 2020/12/01\n")
+	..TitanUtils_GetGoldText("6.00.08.100002  : 2022/12/01\n\n")
 	..TitanUtils_GetGreenText("TitanRepair rewritten - Notable changes: \n")
 	..TitanUtils_GetHighlightText(""
 		.."- See plugin notes.\n"
@@ -630,24 +640,11 @@ local optionsUIScale = {
 			name = L["TITAN_UISCALE_CONTROL_TITLE_UI"],
 			desc = L["TITAN_UISCALE_SLIDER_DESC"],
 			order = 2, type = "range", width = "full",
-			min = 0.3, max = 1, step = 0.01,
-			get = function()
-				local ui_scale = TitanPanelGetVar("UIScale")
---[[
-print("T cfg UI scale :"
-.." t:"..tostring(format("%0.3f", ui_scale))..""
---]]
-				return ui_scale --UIParent:GetScale()
-				end,
+			min = 0.64, max = 1, step = 0.01,
+			get = function() return UIParent:GetScale() end,
 			set = function(_, a)
-				TitanPanelSetVar("UIScale", a)
-				UIParent:SetScale(a)
---				SetCVar("useUiScale", 1);
---				SetCVar("uiScale", a, "uiScale");
---[[
-Can go below .64 BUT need to set (below) at each init / reload ...
-UIParent:SetScale(a)
---]]
+				SetCVar("useUiScale", 1);
+				SetCVar("uiScale", a, "uiScale");
 			end,
 		},
 		panelscale = {
@@ -659,9 +656,7 @@ UIParent:SetScale(a)
 			set = function(_, a)
 				if not InCombatLockdown() then
 					TitanPanelSetVar("Scale", a)
-					TitanPanel_SetScale()
-					TitanPanel_AdjustFrames(true, "Config: adj scale")
---					TitanAdjustPanelScale(a)
+					TitanAdjustPanelScale(a)
 				end
 			end,
 			disabled = function()
diff --git a/Titan/TitanUtils.lua b/Titan/TitanUtils.lua
index 4525759..95136b2 100644
--- a/Titan/TitanUtils.lua
+++ b/Titan/TitanUtils.lua
@@ -2089,7 +2089,8 @@ function TitanDebug(debug_message, debug_type)
 		TitanUtils_GetGoldText(L["TITAN_DEBUG"].." ")
 		..time_stamp
 		..dtype
-		..TitanUtils_GetGreenText(debug_message)
+--		..TitanUtils_GetBlueText(debug_message)
+		..TitanUtils_GetHexText(debug_message, "1DA6C5")

 	if not TitanAllGetVar("Silenced") then
 		_G["DEFAULT_CHAT_FRAME"]:AddMessage(msg)
diff --git a/Titan/TitanVariables.lua b/Titan/TitanVariables.lua
index c449fd0..accddd1 100644
--- a/Titan/TitanVariables.lua
+++ b/Titan/TitanVariables.lua
@@ -280,7 +280,6 @@ TITAN_PANEL_SAVED_VARIABLES = {
 	MenuAndBagVerticalAdj = 24,
 	XPBarVerticalAdjOn = false,
 	XPBarVerticalAdj = 24,
-	UIScale = 0, -- use C Var setting first time
 };

 --[[ Titan
@@ -662,16 +661,6 @@ TitanDebug("_UseSettings "

 	Sync_panel_settings(TITAN_PANEL_SAVED_VARIABLES);

-	local ui_scale = TitanPanelGetVar("UIScale")
-	local ui_cvar = tonumber(string.format("%0.4f", GetCVar("uiScale"))) -- number not string
-	if ui_scale == 0 then
-		-- First time using or reset
-		TitanPanelSetVar("UIScale", ui_cvar)
-	else
-		-- Have seen. User could have changed.
-		UIParent:SetScale(ui_scale)
-	end
---]]
 	if action == TITAN_PROFILE_RESET then
 		-- default is global profile OFF
 		TitanAll = {}
diff --git a/TitanBag/TitanBag.lua b/TitanBag/TitanBag.lua
index 9a60363..49d4b82 100644
--- a/TitanBag/TitanBag.lua
+++ b/TitanBag/TitanBag.lua
@@ -33,8 +33,8 @@ local bag_info = {
 -- "Khorium Toolbox" removed???
  -- names are for debug only
  -- Can use wowdb.com to look at bags by profession
-
-local bags = {
+
+local prof_bags = {
 	[333]    = {style = "", name = ""},
 	[21858]  = {style = "ENCHANTING", name = "Spellfire Bag"},
 	[22246]  = {style = "ENCHANTING", name = "Enchanted Mageweave Pouch"},
@@ -85,14 +85,143 @@ local bags = {
 	[116404] = {style = "ENGINEERING", name = "Pilgrim's Bounty"}, -- *
 	[130943] = {style = "COOKING", name = "Reusable Tote Bag"}, -- *
 	[162588] = {style = "INSCRIPTION", name = "Weathered Scrollcase"},
---[[
-ZZbags = bags
-print("--")
-print(ZZbags[21858].style)
---]]
 }

+local MIN_BAGS = 0
+local MAX_BAGS = Constants.InventoryConstants.NumBagSlots
+local bag_data = {} -- to hold the user bag data
+
 -- ******************************** Functions *******************************
+local function ToggleBags()
+
+	if TitanGetVar(TITAN_BAG_ID, "OpenBags") then
+		TitanPrint(""
+		.." "..tostring("Feature :")..""
+		.." "..tostring(OPENING or "Opening of")..""
+		.." "..tostring(INVTYPE_BAG or "Bags")..""
+		.." "..tostring(ADDON_DISABLED or "Disabled")..""
+		.." "..tostring("Until taint is fixed or work around found.")..""
+		, "warning")
+	else
+		-- nop
+	end
+
+end
+
+local function GetBagData(id)
+	--[[
+	The old code grabbed the bag name but since 10.00.02 it seems name is not always available by player entering world event
+	Grabbing the total slots is available though to determine if a bag exists.
+	The user may see bag name as <unknown> until an event triggers a bag check AND the name is available.
+	--]]
+
+	local total_slots = 0
+	local total_free = 0
+	local total_used = 0
+
+	for bag_slot = MIN_BAGS, MAX_BAGS do -- assuming 0 (Backpack) will not be a profession bag
+		local slots = C_Container.GetContainerNumSlots(bag_slot)
+
+		if slots > 0 then
+			bag_data[bag_slot].has_bag = true
+
+			local bag_name = (C_Container.GetBagName(bag_slot) or UNKNOWN)
+			bag_data[bag_slot].name = bag_name
+			bag_data[bag_slot].maxi_slots = slots
+
+			local free = C_Container.GetContainerNumFreeSlots(bag_slot)
+			local used = slots - free
+			bag_data[bag_slot].free_slots = free
+			bag_data[bag_slot].used_slots = used
+
+			-- some info is not known until the name is available...
+			-- The API requires name to get the bag ID.
+			local bag_type = "none"
+			local color = {r=0,g=0,b=0} -- black (should never be used...)
+
+			if bag_name == UNKNOWN then
+				-- name not available yet
+			else
+				local itemID, itemType, itemSubType, itemEquipLoc, icon, itemClassID, itemSubClassID = GetItemInfoInstant(bag_name)
+				-- For some inexplicable reason the Backpack does not return as an item...
+				-- so create a default so routine is successful
+				itemID = itemID or 0
+
+				if prof_bags[itemID] then
+					bag_type = prof_bags[itemID].style
+					color = bag_info[bag_type].color
+					bag_type = "profession"
+				else
+					bag_type = "normal"
+				end
+			end
+			bag_data[bag_slot].style = bag_type
+			bag_data[bag_slot].color = color
+
+			-- add to total
+			if bag_data[bag_slot].style == "profession" then
+				if TitanGetVar(TITAN_BAG_ID, "CountProfBagSlots") then
+					total_slots = total_slots + slots
+					total_free = total_free + free
+					total_used = total_used + used
+				else
+					-- ignore in totals
+--[[
+TitanDebug("T Bag: ignore"
+.." "..tostring(bag_slot)..""
+.." "..tostring(bag_data[bag_slot].name)..""
+.." "..tostring(bag_data[bag_slot].style)..""
+)
+--]]
+				end
+			else
+				total_slots = total_slots + slots
+				total_free = total_free + free
+				total_used = total_used + used
+			end
+		else
+			bag_data[bag_slot].has_bag = false
+		end
+--[[
+TitanDebug("T Bag: info"
+.." "..tostring(bag_slot)..""
+.." "..tostring(bag_data[bag_slot].has_bag)..""
+.." "..tostring(bag_data[bag_slot].name)..""
+.." "..tostring(bag_data[bag_slot].maxi_slots)..""
+.." "..tostring(bag_data[bag_slot].used_slots)..""
+.." "..tostring(bag_data[bag_slot].free_slots)..""
+.." "..tostring(bag_data[bag_slot].style)..""
+)
+--]]
+	end
+
+	bag_data.total_slots = total_slots
+	bag_data.total_free = total_free
+	bag_data.total_used = total_used
+
+	local bagText = ""
+	if (TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")) then
+		bagText = format(L["TITAN_BAG_FORMAT"], total_used, total_slots);
+	else
+		bagText = format(L["TITAN_BAG_FORMAT"], total_free, total_slots);
+	end
+
+	local bagRichText = ""
+	if ( TitanGetVar(TITAN_BAG_ID, "ShowColoredText") ) then
+		local color = ""
+		color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, total_used / total_slots);
+		bagRichText = TitanUtils_GetColoredText(bagText, color);
+	else
+		bagRichText = TitanUtils_GetHighlightText(bagText);
+	end
+
+	bagRichText = bagRichText --..bagRichTextProf[1]..bagRichTextProf[2]..bagRichTextProf[3]..bagRichTextProf[4]..bagRichTextProf[5];
+
+--[[
+TitanDebug("GetButtonText: <<<")
+--]]
+	return L["TITAN_BAG_BUTTON_LABEL"], bagRichText
+end

 --[[ plugin
 -- **************************************************************************
@@ -140,7 +269,22 @@ end
 --]]
 function TitanPanelBagButton_OnEvent(self, event, ...)
 	if (event == "PLAYER_ENTERING_WORLD") and (not self:IsEventRegistered("BAG_UPDATE")) then
-		self:RegisterEvent("BAG_UPDATE");
+
+		-- init local structure to known values
+		for bag = MIN_BAGS, MAX_BAGS do
+				bag_data[bag] = {
+				has_bag = false,
+				name = "",
+				maxi_slots = 0,
+				free_slots = 0,
+				used_slots = 0,
+				style = "",
+				color = "",
+				}
+		end
+
+		self:RegisterEvent("BAG_UPDATE")
+		TitanPanelButton_UpdateButton(TITAN_BAG_ID);
 	end

 	if event == "BAG_UPDATE" then
@@ -156,22 +300,6 @@ function TitanPanelBagButton_OnUpdate(self)
 	self:SetScript("OnUpdate", nil)
 end

-local function ToggleBags()
-
-	if TitanGetVar(TITAN_BAG_ID, "OpenBags") then
-		TitanPrint(""
-		.." "..tostring("Feature :")..""
-		.." "..tostring(OPENING or "Opening of")..""
-		.." "..tostring(INVTYPE_BAG or "Bags")..""
-		.." "..tostring(ADDON_DISABLED or "Disabled")..""
-		.." "..tostring("Until taint is fixed or work around found.")..""
-		, "warning")
-	else
-		-- nop
-	end
-
-end
-
 --[[ plugin
 -- **************************************************************************
 -- NAME : TitanPanelBagButton_OnClick(button)
@@ -189,181 +317,9 @@ function TitanPanelBagButton_OnClick(self, button)
 	end
 end

---[[
--- **************************************************************************
--- NAME : isBag(id)
--- DESC : Determine if this is a bag. Then check for a profession bag using its id
--- against the table of known ids.
--- If it is a profession bag then grab its 'color' in case the user requested it.
--- VARS : name = text (localized) of the bag to check
--- VARS : pos  = position of the bag to check
--- **************************************************************************
-	-- using GetItemInfo caused a 'script ran too long' error on Shadowlands ptr (9.x) although it worked in retail (8.x)
-	-- GetItemInfoInstant returns the needed id and uses client files - no server call.
---]]
-local function isBag(bag_name, pos)
---[[
-print("isBag:"
-.." '"..tostring(pos).."'"
-.." '"..tostring(bag_name).."'"
-)
---]]
-	-- set defaults for no bag found
-	local is_bag = false
-	local bag_type = "none"
-	local color = {r=0,g=0,b=0} -- black (should never be used...)
-
-	if bag_name == nil then
-		-- no bag found, return defaults
-	else
-		local itemID, itemType, itemSubType, itemEquipLoc, icon, itemClassID, itemSubClassID = GetItemInfoInstant(bag_name)
---[[
-print("isBag:"
-.." ID:'"..tostring(itemID).."'"
-.." ty:'"..tostring(itemType).."'"
-.." sty:'"..tostring(itemSubType).."'"
-.." EL:'"..tostring(itemEquipLoc).."'"
-.." ic:'"..tostring(icon).."'"
-.." CI:'"..tostring(itemClassID).."'"
-.." SCI:'"..tostring(itemSubClassID).."'"
-)
---]]
-		-- For some inexplicable reason the Backpack does not return as an item...
-		-- so create a default so routine is successful
-		itemID = itemID or 0
-		is_bag = true -- assume non nil is a valid bag name
-
-		if bags[itemID] then
-			bag_type = bags[itemID].style
-			color = bag_info[bag_type].color
-			bag_type = "profession"
-		else
-			bag_type = "normal"
-		end
-	end
-
---[[
-TitanDebug("isBag: "..tostring(itemID)
-.." '"..tostring(bag_name).."'"
-.." '"..tostring(is_bag).."'"
-.." '"..tostring(bag_type).."'"
-.." '"..tostring(string.format("%1.2f",color.r)).."' '"..tostring(string.format("%1.2f",color.g)).."' '"..tostring(string.format("%1.2f",color.b)).."'")
---]]
-	return is_bag, bag_type, color
-end
-
-local function GetButtonText(id)
-	local button, id = TitanUtils_GetButton(id, true);
-	local totalBagSlots, usedBagSlots, availableBagSlots, bag, bagText, bagRichText, bag_type, color;
-	local totalProfBagSlots = {0,0,0,0,0};
-	local usedProfBagSlots = {0,0,0,0,0};
-	local availableProfBagSlots = {0,0,0,0,0};
-	local bagRichTextProf = {"","","","",""};
-
-	-- DF difference between betga and ptr??
-	local get_bag = nil
-	if C_Container.GetBagName then
-		get_bag = C_Container.GetBagName
-	elseif GetBagName then
-		get_bag = GetBagName
-	end
-	local get_slots = nil
-	if C_Container.GetContainerNumSlots then
-		get_slots = C_Container.GetContainerNumSlots
-	elseif GetContainerNumSlots then
-		get_slots = GetContainerNumSlots
-	end
-	local get_info = nil
-	if C_Container.GetContainerItemInfo then
-		get_info = C_Container.GetContainerItemInfo
-	elseif GetContainerItemInfo then
-		get_info = GetContainerItemInfo
-	end
-
---[[
-TitanDebug("GetButtonText: >>>")
---]]
-	totalBagSlots = 0;
-	usedBagSlots = 0;
-	for bag = 0, 4 do -- assuming 0 (Backpack) will not be a profession bag
-		local is_bag, bag_type, color = isBag(get_bag(bag), bag)
-
-		if is_bag then
-			if bag_type == "profession" then -- found a profession bag
-				-- when user wants profession bags counted, they are listed separately in the plugin
-				if TitanGetVar(TITAN_BAG_ID, "CountProfBagSlots") then
-					local size = get_slots(bag);
-					if (size and size > 0) then
-						totalProfBagSlots[bag] = size;
-						for slot = 1, size do
-							if (GetContainerItemInfo(bag, slot)) then
-								usedProfBagSlots[bag] = usedProfBagSlots[bag] + 1;
-							end
-						end
-						availableProfBagSlots[bag] = totalProfBagSlots[bag] - usedProfBagSlots[bag];
-					end
-
-					if (TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")) then
-						bagText = "  [" .. format(L["TITAN_BAG_FORMAT"], usedProfBagSlots[bag], totalProfBagSlots[bag]) .. "]";
-					else
-						bagText = "  [" .. format(L["TITAN_BAG_FORMAT"], availableProfBagSlots[bag], totalProfBagSlots[bag]) .. "]";
-					end
-					if ( TitanGetVar(TITAN_BAG_ID, "ShowColoredText") ) then
-						bagRichTextProf[bag] = TitanUtils_GetColoredText(bagText, color);
-					else
-						bagRichTextProf[bag] = TitanUtils_GetHighlightText(bagText);
-					end
-				end
-			elseif bag_type == "normal" then -- not a profession bag so get used & available counts
-				local size = get_slots(bag);
-				if (size and size > 0) then
-					totalBagSlots = totalBagSlots + size;
-					for slot = 1, size do
-						if (get_info(bag, slot)) then
-							usedBagSlots = usedBagSlots + 1;
-						end
-					end
-				end
-			else -- catch all...
-			end
-		else -- no bag in slot
-		end
---[[
-TitanDebug("GetButtonText:"
-.." "..tostring(bag)
-.." total '"..tostring(totalBagSlots).."'"
-.." used '"..tostring(usedBagSlots).."'"
-.." '"..tostring(is_bag).."'"
-.." '"..tostring(bag_type).."'"
-)
---]]
-	end
-	availableBagSlots = totalBagSlots - usedBagSlots;
-
-	if (TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")) then
-		bagText = format(L["TITAN_BAG_FORMAT"], usedBagSlots, totalBagSlots);
-	else
-		bagText = format(L["TITAN_BAG_FORMAT"], availableBagSlots, totalBagSlots);
-	end
-
-	if ( TitanGetVar(TITAN_BAG_ID, "ShowColoredText") ) then
-		color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, usedBagSlots / totalBagSlots);
-		bagRichText = TitanUtils_GetColoredText(bagText, color);
-	else
-		bagRichText = TitanUtils_GetHighlightText(bagText);
-	end
-
-	bagRichText = bagRichText..bagRichTextProf[1]..bagRichTextProf[2]..bagRichTextProf[3]..bagRichTextProf[4]..bagRichTextProf[5];
-
---[[
-TitanDebug("GetButtonText: <<<")
---]]
-	return L["TITAN_BAG_BUTTON_LABEL"], bagRichText;
-end
-
 -- plugin
 function TitanPanelBagButton_GetButtonText(id)
-	local strA, strB = GetButtonText(id)
+	local strA, strB = GetBagData(id)
 	return strA, strB
 end

@@ -377,26 +333,6 @@ function TitanPanelBagButton_GetTooltipText()
 	local totalSlots, usedSlots, availableSlots;
 	local returnstring = "";

-	-- DF difference between betga and ptr??
-	local get_slots = nil
-	if C_Container.GetContainerNumSlots then
-		get_slots = C_Container.GetContainerNumSlots
-	elseif GetContainerNumSlots then
-		get_slots = GetContainerNumSlots
-	end
-	local get_free = nil
-	if C_Container.GetContainerNumFreeSlots then
-		get_free = C_Container.GetContainerNumFreeSlots
-	elseif GetContainerNumFreeSlots then
-		get_free = GetContainerNumFreeSlots
-	end
-	local get_id = nil
-	if C_Container.ContainerIDToInventoryID then
-		get_id = C_Container.ContainerIDToInventoryID
-	elseif ContainerIDToInventoryID then
-		get_id = ContainerIDToInventoryID
-	end
-
 	if TitanGetVar(TITAN_BAG_ID, "ShowDetailedInfo") then
 		returnstring = "\n";
 		if TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots") then
@@ -407,46 +343,67 @@ function TitanPanelBagButton_GetTooltipText()
 				..":\t"..TitanUtils_GetNormalText(L["TITAN_BAG_FREE_SLOTS"])..":\n";
 		end

-		for bag = 0, 4 do
-			totalSlots = get_slots(bag) or 0;
-			availableSlots = get_free(bag) or 0;
-			usedSlots = totalSlots - availableSlots;
-			local itemlink  = bag > 0 and GetInventoryItemLink("player", get_id(bag))
-				or TitanUtils_GetHighlightText(L["TITAN_BAG_BACKPACK"]).. FONT_COLOR_CODE_CLOSE;
-
-			if itemlink then
-				itemlink = string.gsub( itemlink, "%[", "" );
-				itemlink = string.gsub( itemlink, "%]", "" );
-			end
-
-			if bag > 0 and not GetInventoryItemLink("player", get_id(bag)) then
-				itemlink = nil;
-			end
-
+		for bag = MIN_BAGS, MAX_BAGS do
 			local bagText, bagRichText, color;
-			if (TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")) then
-				bagText = format(L["TITAN_BAG_FORMAT"], usedSlots, totalSlots);
-			else
-				bagText = format(L["TITAN_BAG_FORMAT"], availableSlots, totalSlots);
-			end
+--[[
+TitanDebug("T Bag: TT"
+.." "..tostring(bag)..""
+.." "..tostring(bag_data[bag].has_bag)..""
+.." "..tostring(bag_data[bag].name)..""
+.." "..tostring(bag_data[bag].maxi_slots)..""
+.." "..tostring(bag_data[bag].used_slots)..""
+.." "..tostring(bag_data[bag].free_slots)..""
+)
+--]]
+			if bag_data[bag].has_bag then
+				if (TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")) then
+					bagText = format(L["TITAN_BAG_FORMAT"], bag_data[bag].used_slots, bag_data[bag].maxi_slots);
+				else
+					bagText = format(L["TITAN_BAG_FORMAT"], bag_data[bag].free_slots, bag_data[bag].maxi_slots);
+				end

-			if ( TitanGetVar(TITAN_BAG_ID, "ShowColoredText") ) then
-				if totalSlots == 0 then
-					color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, 1 );
+				if bag_data[bag].style == "profession"
+				and not TitanGetVar(TITAN_BAG_ID, "CountProfBagSlots")
+				then
+					bagRichText = "|cffa0a0a0"..bagText.."|r" -- show as gray
+				elseif ( TitanGetVar(TITAN_BAG_ID, "ShowColoredText") ) then
+					if bag_data[bag].maxi_slots == 0 then
+						color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, 1 );
+					else
+						color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, bag_data[bag].used_slots / bag_data[bag].maxi_slots);
+					end
+					bagRichText = TitanUtils_GetColoredText(bagText, color);
 				else
-					color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, usedSlots / totalSlots);
+					-- use without color
+					bagRichText = TitanUtils_GetHighlightText(bagText);
 				end
-				bagRichText = TitanUtils_GetColoredText(bagText, color);
-			else
-				bagRichText = TitanUtils_GetHighlightText(bagText);
-			end

-			if itemlink then
-				returnstring = returnstring..itemlink.."\t"..bagRichText.."\n";
+				local name_text = bag_data[bag].name
+				if bag_data[bag].style == "profession"
+				then
+					name_text = TitanUtils_GetColoredText(name_text, bag_data[bag].color)
+				else
+					-- use without color
+				end
+				returnstring = returnstring..name_text.."\t"..bagRichText.."\n";
+			else
+				returnstring = returnstring..NONE.."\n";
 			end
 		end
 		returnstring = returnstring.."\n";
 	end
+
+	if TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots") then
+		local xofy = ""..tostring(bag_data.total_used)
+			.."/"..tostring(bag_data.total_slots).."\n"
+		returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_USED_SLOTS"])
+			..":\t"..xofy
+	else
+		local xofy = ""..tostring(bag_data.total_free)
+			.."/"..tostring(bag_data.total_slots).."\n"
+		returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_USED_SLOTS"])
+			..":\t"..xofy
+	end

 	-- Add Hint
 	if TitanGetVar(TITAN_BAG_ID, "OpenBags") then
diff --git a/TitanRepair/TitanRepair.lua b/TitanRepair/TitanRepair.lua
index e010247..672cd02 100644
--- a/TitanRepair/TitanRepair.lua
+++ b/TitanRepair/TitanRepair.lua
@@ -72,6 +72,10 @@ local function RepairInit()
 	TR.repair_bags = { cur = 0, max = 0, dur = 0, total = 0 }
 	TR.repair_equip = { cur = 0, max = 0, dur = 0, total = 0 }

+	TR.dur_total = 0
+
+	TR.grays = { total = 0 }
+
 	TR.money_total = 0
 	TR.bag_list = {}
 	TR.equip_list = {}
@@ -85,6 +89,7 @@ end
 -- VARS :
 -- reason : string : for debug only - why was the scan requested?
 -- force : boolean : whether to force a scan such as on player entering world or user request
+-- Note: On a successful scan, the plugin button is updated.
 -- **************************************************************************
 --]]
 local function Scan(reason, force)
@@ -92,30 +97,42 @@ local function Scan(reason, force)
 	local milli = GetTime() -- seconds with millisecond precision (float)
 	local dmsg = ""
 	local msg = "Scan "
+
+	if (TR.show_debug) then
+		msg = msg
 		.." '"..tostring(reason).."'"
---		.." "..tostring(force)
 		.." "..string.format("%0.2F",(milli - TR.last_scan)).." sec"
+	end

 	if must_do or (milli > TR.last_scan + 1) then -- no more than a scan per sec
-		msg = msg.." : running "
-		debug_msg(msg)
+		local calc_inv = TitanGetVar(TITAN_REPAIR_ID,"ShowInventory")
+		local show_gray = TitanGetVar(TITAN_REPAIR_ID,"ShowGray")
+		local sell_gray = TitanGetVar(TITAN_REPAIR_ID,"SellAllGray")
+		local calc_gray = (show_gray or sell_gray) -- either needs a scan to calc
+
+		if (TR.show_debug) then
+			msg = msg.." : running "
+				.." force:"..tostring(force)..""
+				.." inv:"..tostring(calc_inv)..""
+				.." show grey:"..tostring(show_gray)..""
+				.." sell grey:"..tostring(calc_gray)..""
+			debug_msg(msg)
+		end

-		-- Init the repair tables
+		-- Init the repair tables - equip / bags / grays
 		RepairInit()

-		local itemName, _, itemQuality
-
-		TR.repair_total = 0
-		TR.dur_total = 0

-		TR.repair_equip = { cur = 0, max = 0, dur = 0, total = 0 }
-		TR.scan_running = true
-
-		-- scan equipped
-		dmsg = "Start equip scan"
-			.." - "..(TitanGetVar(TITAN_REPAIR_ID,"ShowUndamaged") and "Include Undamaged" or "Only Damaged")
-		debug_msg(dmsg)
+		-- ++++++++++++++++++++++++++++++++++++++++++++++++++
+		-- scan equipped items - only those with durability
+		--
+		if (TR.show_debug) then
+			dmsg = "Start equip scan"
+				.." - "..(TitanGetVar(TITAN_REPAIR_ID,"ShowUndamaged") and "Include Undamaged" or "Only Damaged")
+			debug_msg(dmsg)
+		end

+		local itemName, _, itemQuality
 		for slotName, slotID in pairs(Enum.InventoryType) do
 			local hasItem = {}
 			local repairCost = 0
@@ -150,7 +167,7 @@ local function Scan(reason, force)
 												cost = (repairCost or 0),
 												}
 							-- debug
-							if show_debug_scan then
+							if TR.show_debug_scan then
 								dbg_str_01 = tostring(slotName)..":"..tostring(slotId)
 												.." '"..tostring(TR.equip_list[slotName].name).."'"
 												.." "..tostring(TR.equip_list[slotName].quality)
@@ -179,20 +196,23 @@ local function Scan(reason, force)
 			end
 		end -- InventoryType
 		TR.repair_equip.dur = (TR.repair_equip.max > 0 and floor(TR.repair_equip.cur / TR.repair_equip.max * 100)) or 100
-		dmsg = "End equip scan "
-			.." $"..tostring(TR.repair_equip.total)
-			.." "..tostring(TR.repair_equip.dur).."%"
-			.." = "..tostring(TR.repair_equip.cur)
-			.." / "..tostring(TR.repair_equip.max)
-		debug_msg(dmsg)

-		TR.repair_bags = { cur = 0, max = 0, dur = 0, total = 0 }
-		if (TitanGetVar(TITAN_REPAIR_ID,"ShowInventory") == 1) then
-			-- scan bags for 'damaged' items
-			debug_msg("Bags scan Start - ShowInventory")
-
-			for bag = 0, 4 do
-				for slot = 1, C_Container.GetContainerNumSlots(bag) do
+		if (TR.show_debug) then
+			dmsg = "End equip scan "
+				.." $"..tostring(TR.repair_equip.total)
+				.." "..tostring(TR.repair_equip.dur).."%"
+				.." = "..tostring(TR.repair_equip.cur)
+				.." / "..tostring(TR.repair_equip.max)
+			debug_msg(dmsg)
+		end
+
+		-- ++++++++++++++++++++++++++++++++++++++++++++++++++
+		-- Check inventory for repair costs AND grays
+		--
+		for bag = 0, 4 do
+			for slot = 1, C_Container.GetContainerNumSlots(bag) do
+				if calc_inv then -- scan bags for 'damaged' items
+					-- Inventory repair costs
 					local repairCost = 0

 					local minimum, maximum = C_Container.GetContainerItemDurability(bag, slot)
@@ -209,28 +229,50 @@ local function Scan(reason, force)
 						TR.repair_bags.cur = TR.repair_bags.cur + minimum
 						TR.repair_bags.max = TR.repair_bags.max + maximum
 					end
+				else
+					-- save a few cycles
+				end
+				if calc_gray then -- scan bags for 'gray' items
+					local info = C_Container.GetContainerItemInfo(bag, slot)
+					if info and info.quality == 0 then
+						-- gray / Poor quality
+						TR.grays.total = TR.grays.total + (info.stackCount * select(11, GetItemInfo(info.itemID)))
+					else
+						-- ignore - not gray
+					end
+				else
+					-- save a few cycles
 				end
 			end
+		end
+		if calc_inv then -- calc total damage - if requested by user.
 			TR.repair_bags.dur = (TR.repair_bags.max > 0 and floor(TR.repair_bags.cur / TR.repair_bags.max * 100)) or 100
-			dmsg = "Bags scan End "
-				.." "..tostring(TR.repair_bags.dur)
-				.." $ "..tostring(TR.repair_bags.total)
-			debug_msg(dmsg)
+			if (TR.show_debug) then
+				dmsg = "Bags repair totals"
+					.." "..tostring(TR.repair_bags.dur)
+					.." $ "..tostring(TR.repair_bags.total)
+				debug_msg(dmsg)
+			end
 		else
-			debug_msg("Bags scan None - User did not request")
+			debug_msg("Bags repair totals None - User did not request")
+		end
+		if (TR.show_debug) then
+			if calc_gray then -- calc total grays - if requested by user.
+				dmsg = "Bags gray scan End "
+					.." $ "..tostring(TR.grays.total)
+				debug_msg(dmsg)
+			else
+				debug_msg("Bags gray totals None - User did not request")
+			end
 		end

+		-- ++++++++++++++++++++++++++++++++++++++++++++++++++
 		-- Calc total durability %
+		-- repair_equip - gear currently worn
+		-- repair_bags - any dmaaged gear in bags
 		TR.dur_total = ((TR.repair_bags.max + TR.repair_equip.max) > 0
 			and floor( (TR.repair_bags.cur + TR.repair_equip.cur) / (TR.repair_bags.max + TR.repair_equip.max) * 100))
 			or 100
-		dmsg = "Calc total durability"
-			.." '"..tostring(TR.dur_total).."'"
-			.." "..tostring(TR.repair_equip.max)
-			.." "..tostring(TR.repair_equip.cur)
-			.." "..tostring(TR.repair_bags.max)
-			.." "..tostring(TR.repair_bags.cur)
-		debug_msg(dmsg)

 		-- cleanup
 		TR.scan_time = GetTime() - milli
@@ -240,11 +282,22 @@ local function Scan(reason, force)
 		-- update button text
 		TitanPanelButton_UpdateButton(TITAN_REPAIR_ID)

-		dmsg = "...Scan complete"
-		debug_msg(dmsg)
+		if (TR.show_debug) then
+			dmsg = "Calc total durability"
+				.." '"..tostring(TR.dur_total).."'"
+				.." "..tostring(TR.repair_equip.max)
+				.." "..tostring(TR.repair_equip.cur)
+				.." "..tostring(TR.repair_bags.max)
+				.." "..tostring(TR.repair_bags.cur)
+			debug_msg(dmsg)
+			dmsg = "...Scan complete"
+			debug_msg(dmsg)
+		end
 	else
-		msg = msg.." : NOT running - too soon "
-		debug_msg(msg)
+		if (TR.show_debug) then
+			msg = msg.." : NOT running - too soon "
+			debug_msg(msg)
+		end
 	end
 end

@@ -359,6 +412,7 @@ end
 -- **************************************************************************
 --]]
 local function TitanRepair_RepairItems()
+	debug_msg("_RepairItems")
 	-- New RepairAll function
 	local cost = GetRepairAllCost();
 	local money = GetMoney();
@@ -418,6 +472,59 @@ end

 --[[ local
 -- **************************************************************************
+-- NAME : TitanRepair_SellGrayItems()
+-- DESC : <research>
+-- **************************************************************************
+--]]
+local function TitanRepair_SellGrayItems()
+	debug_msg("Selling gray items")
+
+	for bag = 0, 4 do
+		for slot = 1, C_Container.GetContainerNumSlots(bag) do
+			local info = C_Container.GetContainerItemInfo(bag, slot)
+			if info and info.quality == 0 then
+				if TR.show_debug then
+					local name, _, value
+						name,
+						_, -- link
+						_, -- quality
+						_, -- level
+						_, -- min level
+						_, -- type
+						_, -- sub type
+						_, -- stack count
+						_, -- loc
+						_, -- texture
+						value,
+						_, -- class id
+						_, -- sub class id
+						_, -- bind type
+						_, -- xpac id
+						_, -- set id
+						_ -- is crafting reagent
+						= GetItemInfo(info.itemID)
+					local msg = "Selling"
+					.." "..tostring(info.stackCount)..""
+					.." "..tostring(name)..""
+					.." $ "..tostring(GetGSC(info.stackCount * value))..""
+					.." "..tostring(bag)..""
+					.." "..tostring(slot)..""
+					debug_msg(msg)
+				end
+
+				-- Sell item(s)
+				for i = 1, info.stackCount do
+					C_Container.UseContainerItem(bag, slot)
+				end
+			else
+				-- ignore - not gray
+			end
+		end
+	end
+end
+
+--[[ local
+-- **************************************************************************
 -- NAME : AutoHighlight (item_frac, valueText)
 -- DESC : Color (green / white / red) the given string (durability as % or x / y) based on the given percentage
 -- VARS :
@@ -494,6 +601,8 @@ function TitanPanelRepairButton_OnLoad(self)
 			ShowDiscounts = true,
 			ShowCosts = true,
 			DisplayOnRightSide = false,
+			ShowGray = false,
+			SellAllGray = false,
 		}
 	};
 end
@@ -533,19 +642,29 @@ function TitanPanelRepairButton_OnEvent(self, event, a1, ...)
 	then
 		Scan(event, false)
 	end
-
+--[[
 	if (event == "PLAYER_MONEY" and TR.MerchantisOpen == true and CanMerchantRepair())
 	then
 		Scan(event, true)
 	end
-
+--]]
 	if (event == "MERCHANT_SHOW") then
 		TR.MerchantisOpen = true;
 		local canRepair = CanMerchantRepair();
-		if not canRepair then
-			return;
+		-- handle sell ALL grays
+		if (TitanGetVar(TITAN_REPAIR_ID,"SellAllGray") == 1) then
+			if (TR.grays.total > 0) then
+				TitanRepair_SellGrayItems()
+				Scan("MERCHANT_SHOW - auto SellAllGray", true)
+			end
+		end
+
+		if canRepair then
+			-- keep going
+		else
+			return -- save a few cycles
 		end
-		self:RegisterEvent("PLAYER_MONEY") -- this prevents extra scans on looting...
+		self:RegisterEvent("PLAYER_MONEY") -- this prevents extra scan requests on looting...
 		if TitanGetVar(TITAN_REPAIR_ID,"ShowPopup") == 1 then
 			if (TR.repair_total > 0) then
 				TR.MONEY = repairCost;
@@ -559,7 +678,6 @@ function TitanPanelRepairButton_OnEvent(self, event, a1, ...)
 				Scan("MERCHANT_SHOW - AutoRepair", true)
 			end
 		end
-
 	end

 	if ( event == "MERCHANT_CLOSED" ) then
@@ -584,6 +702,11 @@ function TitanPanelRepairButton_OnClick(self, button)
 			TitanPanelRightClickMenu_Close();
 		end
 		Scan("User Sh+L click", true)
+	elseif button == "LeftButton" then
+		if TR.MerchantisOpen == true  then
+			TitanRepair_SellGrayItems()
+			Scan("MERCHANT_SHOW - user intiated SellAllGray", true)
+		end
 	else
 		TitanPanelButton_OnClick(self, button);
 	end
@@ -647,12 +770,24 @@ function TitanPanelRepairButton_GetButtonText(id)
 			discountlabel = ""
 		end

+		local gray_header = ""
+		local gray_total = ""
+		if (TitanGetVar(TITAN_REPAIR_ID,"ShowGray")) then
+			gray_header = ITEM_QUALITY0_DESC..": " -- Poor / gray
+			gray_total = GetTextGSC(TR.grays.total)
+		else
+			-- user does not want to see cost; clear the reputation also
+			gray_header = ""
+			gray_total = ""
+		end
 		-- Now that the pieces have been created, return the whole string
 		return L["REPAIR_LOCALE"]["button"],
 			text
 			..costStr
 			..discountlabel
-			..itemNamesToShow
+			..itemNamesToShow,
+			gray_header,
+			gray_total
 	end
 end

@@ -667,12 +802,16 @@ function TitanPanelRepairButton_GetTooltipText()
 	local cost = 0;
 	local sum = TR.repair_total

-	local msg = "Tooltip Start "
-		.." items:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowItems"))
-		.." discounts:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowDiscounts"))
-		.." costs:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowCosts"))
-		.." guild:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"UseGuildBank"))
-	debug_msg(msg)
+	if TR.show_debug then
+		local msg = "Tooltip Start "
+			.." items:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowItems"))
+			.." discounts:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowDiscounts"))
+			.." costs:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowCosts"))
+			.." guild:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"UseGuildBank"))
+			.." show gray:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"ShowGray"))
+			.." sell gray:"..tostring(TitanGetVar(TITAN_REPAIR_ID,"SellAllGray"))
+		debug_msg(msg)
+	end

 	if (TitanGetVar(TITAN_REPAIR_ID,"ShowItems")) then
 		out = out..TitanUtils_GetGoldText(L["REPAIR_LOCALE"]["Items"]).."\n"
@@ -750,6 +889,16 @@ function TitanPanelRepairButton_GetTooltipText()
 		out = out .. "\n"
 	end

+	if (TitanGetVar(TITAN_REPAIR_ID,"ShowGray"))
+	or (TitanGetVar(TITAN_REPAIR_ID,"SellAllGray")) then
+		if (TR.grays.total > 0) then
+			out = out..TitanUtils_GetGoldText(ITEM_QUALITY0_DESC).." : ".. "\t" .. GetTextGSC(TR.grays.total).."\n"
+		else
+			out = out..TitanUtils_GetGoldText(ITEM_QUALITY0_DESC).."\t".."|cffa0a0a0"..NONE.."|r".."\n"
+		end
+		out = out .. "\n"
+	end
+
 	-- Show the guild - if player is in one
 	--GUILDBANK_REPAIR
 	if IsInGuild() then
@@ -784,8 +933,12 @@ function TitanPanelRepairButton_GetTooltipText()
 		..TitanUtils_GetHighlightText(tostring(TitanGetVar(TITAN_REPAIR_ID, "AutoRepair") and true or false)).."\n"
 	out = out..L["REPAIR_LOCALE"]["showinventory"].." : ".."\t"
 		..TitanUtils_GetHighlightText(tostring(TitanGetVar(TITAN_REPAIR_ID, "ShowInventory") and true or false)).."\n"
+	out = out.."Sell ALL "..ITEM_QUALITY0_DESC.." : ".."\t"
+		..TitanUtils_GetHighlightText(tostring(TitanGetVar(TITAN_REPAIR_ID, "SellAllGray") and true or false)).."\n"
 	out = out.."\n"

+	out = out..TitanUtils_GetGreenText("Hint: Left click to sell ALL "..ITEM_QUALITY0_DESC.." items - CAUTION\n")
+	out = out.."\t"..TitanUtils_GetGreenText("Only while merchant is open ".."\n")
 	out = out..TitanUtils_GetGreenText("Hint: Shift + Left click to force a scan of repair info.")

 	return out, itemLabel
@@ -891,6 +1044,24 @@ function TitanPanelRightClickMenu_PrepareRepairMenu()
 				end
 			info.checked = TitanGetVar(TITAN_REPAIR_ID,"ShowRepairCost");
 			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
+
+			info = {};
+			info.text = "Show "..ITEM_QUALITY0_DESC.." Total" --L["REPAIR_LOCALE"]["ShowRepairCost"];
+			info.func = function()
+				TitanToggleVar(TITAN_REPAIR_ID, "ShowGray");
+				Scan("Calc inventory gray", true)
+				TitanPanelButton_UpdateButton(TITAN_REPAIR_ID);
+				end
+			info.checked = TitanGetVar(TITAN_REPAIR_ID,"ShowGray");
+			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
+
+			info = {};
+			info.text = "Sell ALL "..ITEM_QUALITY0_DESC.." Items - CAUTION" -- L["REPAIR_LOCALE"]["ShowRepairCost"];
+			info.func = function()
+				TitanToggleVar(TITAN_REPAIR_ID, "SellAllGray");
+				end
+			info.checked = TitanGetVar(TITAN_REPAIR_ID,"SellAllGray");
+			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
 		end

 		if TitanPanelRightClickMenu_GetDropdMenuValue() == "AutoRepair" then