Quantcast

Config : type Import should be Export

urnati [04-15-26 - 00:59]
Config : type Import should be Export
TitanAlts : Ready
Titan : Events for Alts
Filename
Titan/Titan.lua
Titan/TitanConfig.lua
Titan/TitanHistory.lua
TitanAlts/TitanAlts.lua
TitanUI/Tools.lua
diff --git a/Titan/Titan.lua b/Titan/Titan.lua
index 00df403..eb568c0 100644
--- a/Titan/Titan.lua
+++ b/Titan/Titan.lua
@@ -341,7 +341,7 @@ local function SetToonPlayedInfo(action, total, level)
 end

 local function SetToonInfo(toon)
-	-- New Dec 2025 Collect some toon info for profile display
+	-- New Dec 2025 Collect some toon info for profile display (Alts)
 	-- Unlikely to change on reload but...
 	local toon_info = TitanSettings.Players[toon].Info ---@class CharInfo
 	local unit = "player"
@@ -380,7 +380,7 @@ local function SetToonInfo(toon)
 	toon_info.gold_toon = GetMoney() -- NO Warband

 	local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel()
-	toon_info.itemLevelAve = avgItemLevel -- using only equp change event, this may not be accurate...
+	toon_info.itemLevelAve = avgItemLevel -- using only equip change event, this may not be accurate...
 	toon_info.itemLevelEquipped = avgItemLevelEquipped -- this is the one we are tracking
 	toon_info.itemLevelPvp = avgItemLevelPvp

@@ -388,6 +388,13 @@ local function SetToonInfo(toon)

 	toon_info.unit_xp = UnitXP("player")
 	toon_info.unit_xp_max = UnitXPMax("player")
+
+	toon_info.zoneText = GetZoneText()
+	toon_info.subZoneText = GetSubZoneText() or ""
+
+	-- seems to return current location if hearth not bound
+	toon_info.hearth_binding = GetBindLocation()
+
 end

 local function SetToonLogout(toon)
@@ -721,6 +728,8 @@ function TitanPanelBarButton:PLAYER_REGEN_DISABLED()
 	TitanPanelBarButton_DisplayBarsWanted("PLAYER_REGEN_DISABLED")
 end

+-- Events 'for profile' are needed because routines called during logout event return invalid results.
+
 ---Titan Store in profile
 function TitanPanelBarButton:PLAYER_MONEY()
 	local toon_info = TitanSettings.Players[TitanSettings.Player].Info
@@ -733,7 +742,7 @@ function TitanPanelBarButton:PLAYER_EQUIPMENT_CHANGED()
 	local toon_info = TitanSettings.Players[TitanSettings.Player].Info
 	-- 2026 Mar Add more info for Alts
 	local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel()
-	toon_info.itemLevelAve = avgItemLevel
+	toon_info.itemLevelAve = avgItemLevel -- not accurate w/o tracking armor in bags
 	toon_info.itemLevelEquipped = avgItemLevelEquipped
 	toon_info.itemLevelPvp = avgItemLevelPvp
 	-- Poss info to save for Alts
@@ -742,25 +751,34 @@ function TitanPanelBarButton:PLAYER_EQUIPMENT_CHANGED()

 end

----Titan Handle TIME_PLAYED_MSG Total and this level for /played
+---Titan For /played in profile
 function TitanPanelBarButton:TIME_PLAYED_MSG(a1, a2, ...)
 	local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo
 	SetToonPlayedInfo('update', a1, a2)
 end

----Titan Handle TIME_PLAYED_MSG Total and this level for /played
+---Titan For player level in profile
 function TitanPanelBarButton:PLAYER_LEVEL_UP(...)
 	local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo
 	SetToonPlayedInfo('level')
 end

----Titan Store XP and Max in profile
+---Titan For player XP in profile
 function TitanPanelBarButton:PLAYER_XP_UPDATE(...)
 	local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo
 	toon_info.unit_xp = UnitXP("player")
 	toon_info.unit_xp_max = UnitXPMax("player")
 end

+---Titan For player hearth in profile
+function TitanPanelBarButton:HEARTHSTONE_BOUND(...)
+	local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo
+	-- seems to return current location if hearth not bound
+	toon_info.hearth_binding = GetBindLocation()
+end
+
+
+-- for profile end

 if Titan_Global.switch.can_edit_ui then
 	-- Do not need to adjust frames
diff --git a/Titan/TitanConfig.lua b/Titan/TitanConfig.lua
index a0fdb48..d706f91 100644
--- a/Titan/TitanConfig.lua
+++ b/Titan/TitanConfig.lua
@@ -1915,7 +1915,7 @@ local function CreateImportExportList(pos)
 	args["export_header"] = {
 		order = position,
 		type = "header",
-		name = L["TITAN_PANEL_MENU_IMPEXP_IMPORT"] .. " \n",
+		name = L["TITAN_PANEL_MENU_IMPEXP_EXPORT"] .. " \n",
 		cmdHidden = true
 	}
 	local ex_desc = ""
diff --git a/Titan/TitanHistory.lua b/Titan/TitanHistory.lua
index 8009935..5af1900 100644
--- a/Titan/TitanHistory.lua
+++ b/Titan/TitanHistory.lua
@@ -10,99 +10,78 @@ These are in a seperate file to
 --- Release notes. Keep structure; most recent on 'top'
 local recent_changes = {
    {
-      version = "9.1.7",
-      when = "2026/04/05",
+      version = "9.1.8",
+      when = "2026/04/20",
       topics = {
          {
-            topic = "Gold",
+            topic = "Alts",
             lines = {
-               "Delete Database is back.",
+               "New built-in to display profile info on Alts in tooltip format.",
             },
          },
          {
-            topic = "Titan",
+            topic = "TitanUI",
             lines = {
-               "Profile : deletes allowed when using Sync (All) - as long it is not a sync 'source' for any other profile",
+               "Tools : Added /eventtrace and /api",
             },
          },
-      },
-   },
-   {
-      version = "9.1.6",
-      when = "2026/03/25",
-      topics = {
          {
             topic = "Titan",
             lines = {
-               "Scaling : Plugins should properly scale.",
-               "Tooltip : New registry .tooltipTemplateFunction; prevent 'secret' errors.",
+               "Core : Foundational for Alts profile info",
+               "Config : Fixed string in Import / Export text",
             },
          },
       },
    },
    {
-      version = "9.1.5",
-      when = "2026/03/25",
+      version = "9.1.7",
+      when = "2026/04/05",
       topics = {
          {
-            topic = "Titan Repair",
+            topic = "Gold",
             lines = {
-               "Fix for Auto repair not working.",
-               "Durability and cost should update after merchant repair.",
+               "Delete Database is back.",
             },
          },
          {
             topic = "Titan",
             lines = {
-               "LDB : Fix for LDB tooltips (OnTooltipShow)",
-               "Config Bars : plugins can be adjusted vertically",
-               "Locale : Several strings added.",
+               "Profile : deletes allowed when using Sync (All) - as long it is not a sync 'source' for any other profile",
             },
          },
       },
    },
    {
-      version = "9.1.4",
-      when = "2026/03/15",
+      version = "9.1.6",
+      when = "2026/03/25",
       topics = {
          {
-            topic = "Titan Gold",
-            lines = {
-               "On Show / Hide update button to reflect new total.",
-               "Show / Hide Menu cleanup: sort alpha and add server to names.",
-            },
-         },
-         {
             topic = "Titan",
             lines = {
-               "Config : Open config from menu should work (again)",
-               "Config : Titan in Addon Compartment should work (again)",
-               "Config : Refactor code, partly in response to above.",
+               "Scaling : Plugins should properly scale.",
+               "Tooltip : New registry .tooltipTemplateFunction; prevent 'secret' errors.",
             },
          },
       },
    },
    {
-      version = "9.1.3",
-      when = "2026/03/08",
+      version = "9.1.5",
+      when = "2026/03/25",
       topics = {
          {
-            topic = "Titan Gold",
-            lines = {
-               "Added sort descending option.",
-            },
-         },
-         {
-            topic = "Titan XP",
+            topic = "Titan Repair",
             lines = {
-               "Removed Kill to Level if secret values [Retail-only for now].",
+               "Fix for Auto repair not working.",
+               "Durability and cost should update after merchant repair.",
             },
          },
          {
             topic = "Titan",
             lines = {
-               "Menu : Added open Edit Mode OR Config Bars All to hopefully be clearer as Blizzard migrates Edit Mode",
-               "LDB : Fix for when LDB uses Blizzard_Menu scheme. [#1453].",
+               "LDB : Fix for LDB tooltips (OnTooltipShow)",
+               "Config Bars : plugins can be adjusted vertically",
+               "Locale : Several strings added.",
             },
          },
       },
diff --git a/TitanAlts/TitanAlts.lua b/TitanAlts/TitanAlts.lua
index 12fc2be..bba9524 100755
--- a/TitanAlts/TitanAlts.lua
+++ b/TitanAlts/TitanAlts.lua
@@ -1,4 +1,3 @@
----@diagnostic disable: duplicate-set-field
 --[[
 -- **************************************************************************
 -- * TitanUI.lua
@@ -6,6 +5,7 @@
 -- * By: The Titan Panel Development Team
 -- **************************************************************************
 --]]
+
 -- ******************************** Constants *******************************
 local add_on = ...
 local _G = _G --getfenv(0);
@@ -28,14 +28,14 @@ end
 local UNK = TitanUtils_GetGrayText("-")
 --]]

-local AceConfigDialog = LibStub("AceConfigDialog-3.0")
-
 local artwork_path = "Interface\\AddOns\\TitanAlts\\Artwork\\"
 local TITAN_PLUGIN = "Alts"
 local TITLE = "Alts"
 local TITAN_BUTTON = "TitanPanel" .. TITAN_PLUGIN .. "Button"
+local TITAN_TOOLTIP = "TitanPanel" .. TITAN_PLUGIN .. "Tooltip"
 local VERSION = C_AddOns.GetAddOnMetadata(add_on, "Version")
 local MAX_COLS = 10
+local TT_DELAY = 0.5 -- seconds : default, use Titan setting

 local Alts = {} -- namespace for Alts routines as needed

@@ -255,38 +255,31 @@ local function ClassColors(class, str)
 	return res
 end

-local function SetVal(value)
-	local res = ""
-	if value then
-		res = value
+---Based on 'lock' set timeout to hide
+---@param plugin table Plugin
+local function SetTooltipHide(plugin)
+	if (plugin.qtooltip.locked) then
+		plugin.qtooltip:SetAutoHideDelay(nil)
 	else
-		res = UNK
+		local delay = TT_DELAY
+		if delay < 0.1 then
+			delay = 0.1 -- QTip does NOT like a delay of 0 :)
+		else
+			-- use as is
+		end
+		plugin.qtooltip:SetAutoHideDelay(delay, plugin)
 	end
-	return res
 end

-local function Get_gold(money)
-	local res = ""
-	if money == nil
-		or money == 0 then
-		res = UNK
-	else
-		res = TitanUtils_CashToString(money, ",", ".", true, false, true, true)
-	end
-
-	return res
-end
-
-local function Get_ilvl(level)
-	local res = ""
-	if level == nil
-		or level == 0 then
-		res = UNK
-	else
-		res = string.format("%.0f", level)
-	end
-
-	return res
+---Flip 'lock' to keep tooltip visible or not
+---@param self any
+---@param plugin table Plugin
+local function OnPinClick(self, plugin)
+	-- self out of QTip is nil
+	-- plugin is param passed into QTip SetScript
+	plugin.qtooltip.locked = not plugin.qtooltip.locked
+	SetTooltipHide(plugin)
+	Alts.GenTooltip(plugin)
 end

 local function Get_lvl(level)
@@ -368,7 +361,6 @@ local function SortDB(self, tt_key)
 	Alts.GenTooltip(_G[TITAN_BUTTON])
 end

--- PLAYER_EQUIPMENT_CHANGED
 -- Grab the button text to display
 local function GetButtonText(id)
 	local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel()
@@ -379,54 +371,13 @@ local function GetButtonText(id)
 	return strA, strB, "ilvl : ", eq
 end

--- Create the tooltip string
-local function GetTooltipText()
-	local res = ""
-	local rtn = "\n"
-	local tab = "\t"
-
-	local header = "Name" .. tab
-		.. "Realm" .. tab
-		.. "Class" .. tab
-		.. "Zone" .. tab
-		.. "XP" --.. tab
-		.. rtn
-	--		.. TitanUtils_GetHighlightText(GetRealmName()) .. rtn
-	print("alts"
-		.. " " .. tostring(header) .. ""
-	)
-	local now = _G.time()
-
-	local resets = "Resets in Server Time" .. rtn
-	local week_reset = C_DateAndTime.GetSecondsUntilWeeklyReset()
-	local weekly = TitanUtils_GetNormalText("Weekly :") .. tab
-		.. TitanUtils_GetHighlightText(TitanUtils_GetDateText(week_reset + now, true)) .. rtn
-
-	local day_reset = C_DateAndTime.GetSecondsUntilDailyReset()
-	local daily = TitanUtils_GetNormalText("Daily :") .. tab
-		.. TitanUtils_GetHighlightText(TitanUtils_GetDateText(day_reset + now, true)) .. rtn
-
-	local hints = ""
-	--		.. TitanUtils_GetGreenText("Left Click: Reloads the User Interface") .. rtn
-	--		.. TitanUtils_GetGreenText("Right Click: For Shortcuts and Debug Tools") .. rtn
-
-	res = res
-		.. header
-		.. rtn
-		.. resets .. daily .. weekly
-		.. rtn
-		.. hints
-
-	return res
-end
-
 -- Routine per column...
 local headerFont = {}
 local header_justify = "CENTER"

 local function GenFaction(self, row, col, action, tt_info, toon_info)
 	local next = nil
-	if action == 'header' then
+	if action == 'header' then -- show the 'lock' pin
 		row, next = self.qtooltip:SetCell(row,
 			col,
 			artwork_path .. "TitanPanelPushpin" .. (self.qtooltip.locked and "In" or "Out"), -- value
@@ -434,11 +385,12 @@ local function GenFaction(self, row, col, action, tt_info, toon_info)
 		)
 		self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, (self.qtooltip.locked and UNLOCK or LOCK) );
 		self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide);
-		--    self.qtooltip:SetCellScript(row, col, "OnMouseDown", OnLockClick);
-	elseif action == 'row' then
-		if toon_info.faction == "Alliance" then
+		self.qtooltip:SetCellScript(row, col, "OnMouseDown", OnPinClick, self)
+	elseif action == 'row' then -- show faction icon
+		local cell = toon_info[tt_info.tt_key] -- faction or not known or possibly Classic / OLD toon
+		if cell == "Alliance" then
 			row, next = self.qtooltip:SetCell(row, col, artwork_path .. "Alliance",	iconProvider)
-		elseif toon_info.faction == "Horde" then
+		elseif cell == "Horde" then
 			row, next = self.qtooltip:SetCell(row, col, artwork_path .. "Horde", iconProvider)
 		else
 			-- just in case. Technically a faction must be chosen now but there could be OLD toons out there.
@@ -462,7 +414,8 @@ local function GenToonName(self, row, col, action, tt_info, toon_info)
 		self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key)
 		total_shown = 0
 	elseif action == 'row' then
-		row, next = self.qtooltip:SetCell(row, col, ClassColors(toon_info.className, toon_info.name_titan))
+		local cell = (toon_info[tt_info.tt_key] or UNK)
+		row, next = self.qtooltip:SetCell(row, col, ClassColors(toon_info.className, cell))
 		total_shown = total_shown + 1
 	elseif action == 'total' then
 		row, next = self.qtooltip:SetCell(row, col, tostring(total_shown).." / "..tostring(total_toons))
@@ -479,7 +432,8 @@ local function GenLevel(self, row, col, action, tt_info, toon_info)
 		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify);
 		self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key)
 	elseif action == 'row' then
-			row, next = self.qtooltip:SetCell(row, col, SetVal(toon_info.levelText), "RIGHT")
+		local cell = (toon_info[tt_info.tt_key] or UNK) -- whole number or not known
+		row, next = self.qtooltip:SetCell(row, col, cell, "RIGHT")
 	elseif action == 'total' then
 		row, next = self.qtooltip:SetCell(row, col, "")
 	else
@@ -492,23 +446,23 @@ end
 local function GenILevel(self, row, col, action, tt_info, toon_info)
 	local next = nil
 	if action == 'header' then
-		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify);
+		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify)
 		self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key)
 	elseif action == 'row' then
+		local cell = toon_info[tt_info.tt_key] -- need as number to format
 		local str = ""
 		local tt_str = ""
-		if toon_info.itemLevelEquipped == nil
-			or toon_info.itemLevelEquipped == 0 then
+		if cell == nil or cell == 0 then
 			str = UNK
 		else
-			str = string.format("%.0f", toon_info.itemLevelEquipped)
-			tt_str = "Equipped : "..PVP.." "..string.format("%.0f", toon_info.itemLevelPvp)
+			str = string.format("%.0f", cell)
+			tt_str = PVP.." "..string.format("%.0f", toon_info.itemLevelPvp)
 		end
 		row, next = self.qtooltip:SetCell(row, col, str, "RIGHT")
 		if tt_str == "" then
 			-- nothing to show
 		else
-			self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, tt_str);
+			self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, tt_str)
 			self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide);
 		end
 	elseif action == 'total' then
@@ -525,9 +479,13 @@ local function GenZone(self, row, col, action, tt_info, toon_info)
 	if action == 'header' then
 		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify);
 	elseif action == 'row' then
-		row, next = self.qtooltip:SetCell(row, col, SetVal(toon_info.zoneText))
-		self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, (toon_info.subZoneText or "") );
-		self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide);
+		local cell = (toon_info[tt_info.tt_key] or UNK) -- string or not known
+		row, next = self.qtooltip:SetCell(row, col, cell)
+		local tt = ""
+			..L["TITAN_LOCATION_TOOLTIP_SUBZONE"]..(toon_info.subZoneText or "").."\n"
+			..L["TITAN_LOCATION_TOOLTIP_INN"]..(toon_info.hearth_binding or UNK)
+		self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, tt )
+		self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide)
 	elseif action == 'total' then
 		row, next = self.qtooltip:SetCell(row, col, "")
 	else
@@ -542,8 +500,8 @@ local function GenLogout(self, row, col, action, tt_info, toon_info)
 	if action == 'header' then
 		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify);
 	elseif action == 'row' then
-		local str = toon_info.logout
-		row, next = self.qtooltip:SetCell(row, col, str)
+		local cell = (toon_info[tt_info.tt_key] or UNK) -- formatted date or not known
+		row, next = self.qtooltip:SetCell(row, col, cell)
 	elseif action == 'total' then
 		row, next = self.qtooltip:SetCell(row, col, "")
 	else
@@ -562,13 +520,13 @@ local function GenMoney(self, row, col, action, tt_info, toon_info)
 		self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key)
 		total_gold = 0
 	elseif action == 'row' then
+		local cell = toon_info[tt_info.tt_key] -- need number to format
 		str = ""
-		if toon_info.gold_toon == nil
-			or toon_info.gold_toon == 0 then
+		if cell == nil or cell == 0 then
 			str = UNK
 		else
-			str = TitanUtils_CashToString(toon_info.gold_toon, ",", ".", true, false, true, true)
-			total_gold = total_gold + toon_info.gold_toon
+			str = TitanUtils_CashToString(cell, ",", ".", true, false, true, true)
+			total_gold = total_gold + cell
 		end
 		row, next = self.qtooltip:SetCell(row, col, str, "RIGHT")
 	elseif action == 'total' then
@@ -590,14 +548,14 @@ local function GenPlayed(self, row, col, action, tt_info, toon_info)
 		self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key)
 		total_played = 0
 	elseif action == 'row' then
-		total_played = total_played + (toon_info.played_total or 0)
+		local cell = toon_info[tt_info.tt_key] -- need number to format
 		-- total time played
 		str = ""
-		if toon_info.played_total == nil
-			or toon_info.played_total == 0 then
+		if cell == nil or cell == 0 then
 			str = UNK
 		else
-			str = GetAbbrTimeText(toon_info.played_total)
+			str = GetAbbrTimeText(cell)
+			total_played = total_played + (cell or 0)
 		end
 		row, next = self.qtooltip:SetCell(row, col, str, "RIGHT")
 	elseif action == 'total' then
@@ -616,15 +574,8 @@ local function GenSync(self, row, col, action, tt_info, toon_info)
 	if action == 'header' then
 		row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify)
 	elseif action == 'row' then
-		-- total time played
-		str = ""
-		if toon_info.sync_titan == nil
-			or toon_info.sync_titan == 0 then
-			str = UNK
-		else
-			str = toon_info.sync_titan
-		end
-		row, next = self.qtooltip:SetCell(row, col, str)
+		local cell = (toon_info[tt_info.tt_key] or UNK) -- sync profile or not known
+		row, next = self.qtooltip:SetCell(row, col, cell)
 	elseif action == 'total' then
 		row, next = self.qtooltip:SetCell(row, col, "")
 	else
@@ -768,7 +719,6 @@ local tt_data = { -- index MUST include all tt_cols values !!!
 ---Generate or wipe the tooltip DB
 ---@param action string create | wipe
 local function GenDB(self, action)
-	self.qtooltip.locked = false;

 	wipe(alts_tt)
 	if action == 'wipe' then
@@ -805,6 +755,8 @@ local function GenDB(self, action)
 				alt_info.xp_max = toon_info.unit_xp_max
 				alt_info.xp_per = ""

+				alt_info.hearth_binding = toon_info.hearth_binding
+
 				-- Get Alts plugin info;
 				-- this will create .Alts table on a character profile, if it does not exist
 				local res, plugin_info = TitanUtils_GetProfileInfo(idx, "Alts", true)
@@ -844,7 +796,7 @@ function Alts.GenTooltip(self)
 	self.qtooltip:Clear()
 	self.qtooltip:SetScale(TitanPanelGetVar("Scale"));
 	self.qtooltip:SmartAnchorTo(self);
-	self.qtooltip.parent = self;
+	self.qtooltip.parent = self

 	headerFont = self.qtooltip:GetHeaderFont()
 	headerFont:SetTextColor(NORMAL_FONT_COLOR:GetRGB())
@@ -918,14 +870,10 @@ function Alts.GenTooltip(self)
 		CheckCol(tt_cols[idx], 'total', nil)
 	end

-	self.qtooltip:UpdateScrolling(512);
-	self.qtooltip:Show();
+	self.qtooltip:UpdateScrolling(512)
+	self.qtooltip:Show()
+	SetTooltipHide(self)

-	if (self.qtooltip.locked) then
-		self.qtooltip:SetAutoHideDelay(nil);
-	else
-		self.qtooltip:SetAutoHideDelay(0.5, self)
-	end
 end

 local scroll_hgt = math.floor(GetScreenHeight() * .6) -- virtual height in pixels
@@ -1027,7 +975,7 @@ local function OnLoad(self)
 			logout = false,
 			gold_toon = true,
 			played_total = false,
-			profile = false,
+			sync_titan = false,
 			xp_now = true,
 			-- end show / hide cols
 			use_class_colors = true,
@@ -1067,7 +1015,9 @@ local function OnShow(self)
 --	GenDB(self, 'create')
 	TitanPanelButton_UpdateButton(TITAN_PLUGIN)

-	max_level = GetMaxLevelForPlayerExpansion()
+	max_level = GetMaxPlayerLevel() -- GetMaxLevelForPlayerExpansion()
+
+	TitanPanelGetVar("TooltipTimeout")
 end

 local function OnHide(self)
@@ -1123,97 +1073,136 @@ local function Create_Frames()
 	end)

 	-- Create tooltip frame for this plugin
+
 	-- OnUpdate starts as soon as OnShow is done...
-	tt_frame = CreateFrame("GameTooltip", "TitanRepairTooltip", UIParent, "GameTooltipTemplate")
-	local tt_init_timeout = .5
+	tt_frame = CreateFrame("GameTooltip", TITAN_TOOLTIP, UIParent, "GameTooltipTemplate")
+
+	window.qtooltip.locked = false -- not needed but be explicit for tooltip 'pin'

 	tt_frame:SetScript("OnShow", function(self)
-		local time_out = TitanPanelGetVar("TooltipTimeout")
-		local dbg_msg = "OnShow"
-			.. " timeout: " .. tostring(time_out) .. ""
-			.. " USING:  " .. tostring(tt_init_timeout) .. ""
-			.. " isCounting: " .. tostring(self.isCounting) .. ""
-			.. " timer: " .. tostring(self.frameTimer) .. ""
-			.. " plugin: " .. tostring(self.registry_id) .. ""
-			.. " plugin_frame: " .. tostring(self.plugin_frame_str) .. ""
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
+		TT_DELAY = TitanPanelGetVar("TooltipTimeout") -- in case user changed in Titan

 		-- OnShow will start the OnUpdate.
 		-- If user enters plugin, the tooltip will show
 		-- BUT if the user never enters the tooltip, it will keep showing because
 		-- the OnLeave did not kick the timer.
-		TitanUtils_StartFrameCounting(self, tt_init_timeout)
+		TitanUtils_StartFrameCounting(self, TT_DELAY)
 	end)
 	tt_frame:SetScript("OnEnter", function(self)
-		local time_out = TitanPanelGetVar("TooltipTimeout")
-
-		local dbg_msg = "OnEnter"
-			.. " timeout: " .. tostring(time_out) .. ""
-			.. " isCounting: " .. tostring(self.isCounting) .. ""
-			.. " timer: " .. tostring(self.frameTimer) .. ""
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)

 		TitanUtils_StopFrameCounting(self)
 	end)
 	tt_frame:SetScript("OnLeave", function(self)
-		local time_out = TitanPanelGetVar("TooltipTimeout")

-		local dbg_msg = "OnLeave"
-			.. " timeout: " .. tostring(time_out) .. ""
-			.. " isCounting: " .. tostring(self.isCounting) .. ""
-			.. " timer: " .. tostring(self.frameTimer) .. ""
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
-
-		if time_out < 0.1 then
+		if TT_DELAY < 0.1 then
 			tt_frame:Hide() -- hide right away
 		else
-			TitanUtils_StartFrameCounting(self, time_out)
+			TitanUtils_StartFrameCounting(self, TT_DELAY)
 		end
 	end)

-	local debug_over = false
-	local debug_over_new = false
 	tt_frame:SetScript("OnUpdate", function(self, elapsed)
-		local time_out = TitanPanelGetVar("TooltipTimeout")
-
-		--[[ -- Be VERY careful enabling this debug :)
-	local dbg_msg = "TT OnUpdate"
-		.. " timeout: " .. tostring(time_out) .. ""
-		.. " isCounting: " .. tostring(self.isCounting) .. ""
-		.. " timer: " .. tostring(self.frameTimer) .. ""
-	--Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
-	if self.isCounting == nil then
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
-	elseif self.frameTimer <= 0.01 then
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
-	else
-	end
-	--]]
-
 		-- Compromise to keep tooltip open if the user stays over plugin
 		-- and does not mouse over tooltip frame (OnEnter)
 		local is_over = self.parent_frame:IsMouseOver()
 		if is_over then
 			TitanUtils_StopFrameCounting(self)
-			debug_over_new = true
 		else
 			TitanUtils_CheckFrameCounting(self, elapsed);
-			debug_over = false
 		end
+	end)

-		--[[
-	if debug_over ~= debug_over_new then
-		debug_over = debug_over_new
-		local dbg_msg = "OnUpdate"
-			.. " over: " .. tostring(is_over) .. ""
-			.. " timeout: " .. tostring(time_out) .. ""
-			.. " isCounting: " .. tostring(self.isCounting) .. ""
-			.. " timer: " .. tostring(self.frameTimer) .. ""
-		Titan_Debug.Out('alts', 'tool_tips', dbg_msg)
-	else
-	end
-	--]]
+	--[[ TODO : not working - try later :)
+	tt_frame:SetScript("OnMouseDown", function (self, button)
+		local locked = self.parent_frame.qtooltip.locked
+		if ( locked and button == "RightButton" ) then
+			self:SetMovable(true)
+			self:StartMoving()
+			self.isMoving = true
+		end
+	end)
+	tt_frame:SetScript("OnMouseUp", function (self, button)
+		if ( self.isMoving ) then
+			self:StopMovingOrSizing()
+			self:SetMovable(false)
+			self.isMoving = false
+		end
 	end)
+--]]
 end

 Create_Frames() -- do the work
+
+
+--[[ ==== Design
+
+This plugin will show values stored in the Titan profile so the user can see Alts info
+in a tooltip.
+The data is stored in the profile because the game API allows access to the current logged in toon only.
+Titan core does not rely on the logout event to capture info.
+API routines called within the logout event processing return invalid results.
+The tooltip is large and complex so the QTip lib (library) is used to present the info in
+a readable format with tooltips on tooltips :).
+QTip essentially builds a spreadsheet like frame within the tooltip frame.
+We are using a custom tooltip that inherits from GameTooltip to avoid 'secret' errors.
+
+
+NOTE: The Alts plugin table tt_data uses tt_key as the field element link between:
+- Data from Titan profiles of each user toon
+- Alts tooltip column data of each user toon
+- Alts registry to hide / show columns
+It makes for funky looking code but allows the field element to be changed in two places.
+And allows new column routines to be created via copy paste and min edits
+without changing the tooltip generator loop or the menu generation.
+
+
+==== Instructions to add a new column: ====
+- Add collection of the data to Titan to place in profile. See
+local function SetToonInfo(toon)    to start.
+Events may need to be added to collect the data.
+Also add to @class ClassInfo for IDE (in _TitanIDE.lua file)
+
+- Add an entry to tt_cols : The order is the order the columns are displayed!
+Use a descriptive, searchable name for the entry.
+
+- Add the same, as an index, to tt_data
+		config = false, -- true if user can toggle show / hide
+		tt_key = "faction", -- this is the field element link !!!
+		sortable = false, -- true if user can sort by clicking the col header
+		title = "", -- Header title
+		cell_func = GenFaction, -- function (Gen*) to be called for header / row / total
+
+- Edit GenDB to copy the profile info into Alts.
+Also add to @class AltInfo for IDE (in this file)
+Use the format :
+alt_info[tt_data["faction"].tt_key] = toon_info.faction
+for column data that is shown and, more imnportantly, may be sorted.
+Ensure to add any non column data that is needed - example subZone for Zone.
+alt_info.subZoneText = toon_info.subZoneText
+Note: The non column data should only be needed in GenDB and the cooresponding Gen* routine.
+The result is stored for the tooltip:
+table.insert(alts_tt, alt_info)
+
+- Add the column to the registry in OnLoad.
+Use the same values as tt_key !!!!
+
+- Copy a Gen* routine that is close to what you want.
+Paste and rename it the same assigned in cell_func.
+The parameters are the same for all column routines.
+Then edit it to add tooltips, color, totals, etc.
+Note : Each routine has 3 sections to process the column:
+- header : Title of the column; add sort or tooltip as needed
+- row : How each cell should look; add tooltip if needed
+- total : total OR x / total OR blank
+
+Note : Sort is auto-magic. SortDB allows only one column to be sorted at a time.
+SortDB sorts the 'row' data using tt_key field; not header ot total.
+Alphabetic sort only - Deep in QTip all cells are strings.
+SortDB 'flips' between ascending and descending. Usually ascending (A-Z) first but
+if the user is clicking a lot, it is possible they need to click twice to get the order they want.
+
+
+There should be no need to change the tooltip generator (Alts.GenTooltip)
+nor the menu generator (GeneratorFunction).
+
+--]]
\ No newline at end of file
diff --git a/TitanUI/Tools.lua b/TitanUI/Tools.lua
index 52ec364..ffc6e7c 100755
--- a/TitanUI/Tools.lua
+++ b/TitanUI/Tools.lua
@@ -76,11 +76,27 @@ local function GeneratorFunction(owner, rootDescription)
 		function()
 			SendSlash(lua_cmd)
 		end)
+
+	Titan_Menu.AddDivider(root)
+	local etrace_cmd = "/eventtrace"
+	Titan_Menu.AddCommand(root, id, etrace_cmd,
+		function()
+			SendSlash(etrace_cmd)
+		end)
+
+	Titan_Menu.AddDivider(root)
+	local api_cmd = "/api"
+	Titan_Menu.AddCommand(root, id, api_cmd,
+		function()
+			SendSlash(api_cmd)
+		end)
 end

+-- PLAYER_EQUIPMENT_CHANGED
 -- Grab the button text to display
 local function GetButtonText(id)
-	local strA, strB = TITLE, ""
+	local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel()
+	local strA, strB = L["TITAN_PANEL_MENU_RELOADUI"], ""
 	return strA, strB
 end