changeset 103:dc8a23a47b03

- Add 'chatprefix' function for building loot line jump links, and a 'PCFPrint' method which displays them. - Make use of them for local and remote notifications, boss kills, and manual insertions. - Document the additional slash commands and args feature from previous release. Oops. (Text mostly copied from webpage announcement.)
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Sun, 05 Aug 2012 07:26:06 +0000
parents fe04f5c4114a
children 04198c8d0717
files core.lua gui.lua options.lua verbage.lua
diffstat 4 files changed, 171 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/core.lua	Sat Aug 04 22:03:05 2012 +0000
+++ b/core.lua	Sun Aug 05 07:26:06 2012 +0000
@@ -281,6 +281,8 @@
 
 	requesting		= nil   -- prompting for additional rebroadcasters
 
+	lootjumps		= {}    -- maps hypertext idents to EOI line numbers
+
 	-- don't use NUM_ITEM_QUALITIES as the upper loop bound unless we expect
 	-- heirlooms to show up
 	thresholds		= {}
@@ -421,11 +423,17 @@
 do
 	local hypertext_format_str = "|HOuroLoot:%d|h%s[%s]|r|h"
 	local func_map = {} --_G.setmetatable({}, {__mode = 'k'})
-	local text_map = {} --_G.setmetatable({}, {__mode = 'kv'})
+	local text_map = {} _G.setmetatable({}, {__mode = 'v'})
 	local base = _G.newproxy(true)
 	_G.getmetatable(base).__tostring = function(ud) return text_map[ud] end
 	--@debug@
-	-- collecting these tokens is an interesting micro-optimization but not yet
+	-- auto collecting these tokens is an interesting micro-optimization but not yet
+	_G.getmetatable(base).__index = {
+		['done'] = function (ud)
+			text_map[ud] = nil
+			func_map[ud] = nil
+		end,
+	}
 	_G.getmetatable(base).__gc = function(ud)
 		print("Collecting hyperlink object <",tostring(ud),">")
 	end
@@ -860,9 +868,21 @@
 	-- There is no ITEM_QUALITY_LEGENDARY constant.  Sigh.
 	do
 		local AC = LibStub("AceConsole-3.0")
-		local chat_prefix = self.format_hypertext ("Ouro Loot", --[[legendary]]5,
-			--[[empty -> nil -> main tab]]'')
-		local chat_prefix_s = tostring(chat_prefix)
+		function addon.chatprefix (code, arg)
+			local f = ''   -- empty -> BuildMainDisplay(empty) -> main tab
+			if code == "GoToLootLine" then
+				f = code
+			--elseif .....
+			end
+			local ret, num = self.format_hypertext ("Ouro Loot", --[[legendary]]5, f)
+			if code == "GoToLootLine" then
+				self.lootjumps[num] = arg
+			end
+			return ret, num
+		end
+		--local chat_prefix = self.format_hypertext ("Ouro Loot", --[[legendary]]5, '')
+		--local chat_prefix_s = tostring(chat_prefix)
+		local chat_prefix_s = tostring((addon.chatprefix()))
 		function addon:Print (str, ...)
 			if type(str) == 'string' and str:find("%", nil, --[[plainmatch=]]true) then
 				return AC:Print (chat_prefix_s, str:format(...))
@@ -878,6 +898,14 @@
 				return AC:Print (frame, chat_prefix_s, str, ...)
 			end
 		end
+		function addon:PCFPrint (frame, prefix, str, ...)
+			assert(type(frame)=='table' and frame.AddMessage)
+			if type(str) == 'string' and str:find("%", nil, --[[plainmatch=]]true) then
+				return AC:Print (frame, tostring(prefix), str:format(...))
+			else
+				return AC:Print (frame, tostring(prefix), str, ...)
+			end
+		end
 	end
 
 	-- Copy these over once, now that other addons have mostly loaded.  Any
@@ -1966,7 +1994,8 @@
 
 		addon.dprint ('loot', "notification:", source, index,
 			e.itemlink, from_text, to_text)
-		addon:CFPrint (chatframe, remote_chatty, source, index,
+		local jumpprefix = addon.chatprefix ("GoToLootLine", index)
+		addon:PCFPrint (chatframe, jumpprefix, remote_chatty, source, index,
 			e.itemlink, from_text, to_text)
 	end
 
@@ -2206,7 +2235,9 @@
 			addon:RegisterEvent ("PLAYER_REGEN_DISABLED")
 			addon:_mark_boss_kill (bossi)
 			if opts.chatty_on_kill then
-				addon:Print("Registered kill for '%s' in %s!", boss.bossname, boss.instance)
+				local jumpprefix = addon.chatprefix ("GoToLootLine", bossi)
+				addon:PCFPrint(_G.DEFAULT_CHAT_FRAME, jumpprefix,
+					"Registered kill for '%s' in %s!", boss.bossname, boss.instance)
 			end
 		end
 		wipe(candidates)
--- a/gui.lua	Sat Aug 04 22:03:05 2012 +0000
+++ b/gui.lua	Sun Aug 05 07:26:06 2012 +0000
@@ -472,9 +472,9 @@
 				col2.OLi   = li
 				col2.OLu   = unique
 				local col3 = new()
-				col3.value = player.when[unique]
+				col3.value = assert(player.when[unique])
 
-				local id = player.id[unique]
+				local id = assert(player.id[unique])
 				local itexture = GetItemIcon(id)
 				local iname, ilink, iquality = GetItemInfo(id)
 				local textured
@@ -1084,6 +1084,7 @@
 local function eoi_st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion)
 	if (row == nil) or (realrow == nil) then return end  -- mouseover column header
 	local e = data[realrow]
+	if e == nil then return end  -- something horrible has happened
 	local kind = e.kind
 	local tt = GameTooltip   -- can this be hoisted? does GT ever get securely replaced?
 
@@ -1134,12 +1135,17 @@
 local function eoi_st_OnLeave (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion)
 	GameTooltip:Hide()
 	_hide_debugging_tooltip()
-	if row and realrow and data[realrow].kind ~= 'loot' then
-		stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[data[realrow].reason or data[realrow].kind])
+	if (row == nil) or (realrow == nil) then return false end
+
+	if stable:GetSelection() ~= realrow then
+		if data[realrow].kind ~= 'loot' then
+			stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[data[realrow].reason or data[realrow].kind])
+			return true   -- do not do anything further
+		else
+			return false  -- continue with default un-highlighting behavior
+		end
+	else
 		return true   -- do not do anything further
-	else
-		--setstatus("")
-		return false  -- continue with default un-highlighting behavior
 	end
 end
 
@@ -1155,6 +1161,9 @@
 		return true  -- do not do anything further
 	end
 
+	-- Zap any jump-to-line highlighting
+	stable:ClearSelection()
+
 	-- Remaining actions are all right-click
 	if button ~= "RightButton" then return true end
 	_d:SetUserData("DD index", realrow)
@@ -1259,6 +1268,35 @@
 	return true  -- do not do anything further
 end
 
+-- Used for anything not overridden elsewhere.
+local function eoi_st_default_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
+	if not fShow then
+		cellFrame.text:SetText("")
+		if cellFrame.icontexture then
+			cellFrame.icontexture:Hide()
+		end
+		return
+	end
+
+	local e = data[realrow]
+	local cell = e.cols[column]
+
+	cellFrame.text:SetText(cell.value)
+	-- subset of what the default ST's docellupdate looks for
+	local color = cols[column].color and cols[column].color(data,cols,realrow,column,stable)
+	if color then
+		cellFrame.text:SetTextColor(color.r,color.g,color.b,color.a)
+	else
+		cellFrame.text:SetTextColor(1,1,1,1)
+	end
+
+	if stable:GetSelection() ~= realrow then
+		stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[e.reason or e.kind or ""])
+	else
+		stable:SetHighLightColor (rowFrame, stable:GetDefaultHighlight())
+	end
+end
+
 -- Used for EOI column 2 and Hist column 1.  Both are player name columns.
 local function eoi_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
 	if not fShow then
@@ -1299,11 +1337,11 @@
 		cellFrame.text:SetTextColor(1,1,1,1)
 	end
 
-	--if e.kind ~= 'loot' then
+	if stable:GetSelection() ~= realrow then
 		stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[e.reason or e.kind or ""])
-	--else
-	--	stable:SetHighLightColor (rowFrame, table:GetDefaultHighlightBlank())
-	--end
+	else
+		stable:SetHighLightColor (rowFrame, stable:GetDefaultHighlight())
+	end
 end
 
 local eoi_st_cols = {
@@ -1346,6 +1384,7 @@
 		_G.OLST = ST
 	end
 
+	ST.DoCellUpdate = eoi_st_default_DoCellUpdate
 	if not eoi_st_otherrow_bgcolortable_default then
 		eoi_st_otherrow_bgcolortable_default = ST:GetDefaultHighlightBlank()
 		setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key)
@@ -1367,6 +1406,7 @@
 	end
 	-- safety check  end
 	ST:SetData(g_loot)
+	ST:EnableSelection(true)
 	ST:RegisterEvents{
 		OnEnter = eoi_st_OnEnter,
 		OnLeave = eoi_st_OnLeave,
@@ -1488,10 +1528,32 @@
 
 <Right>-click any row to display a dropdown menu.  The menu is different for
 the Player column than it is for the Item/Notes columns, and different for
-loot entries than it is for other rows.]]
---tabs_CLI_special["eoi"] = function (name)
---	-- try and scroll to a specific boss/player?
---end
+loot entries than it is for other rows.
+
+A normal click on a line will remove any highlighting from opening the
+display from a chat link.]]
+tabs_CLI_special["eoi"] = function (name_or_lineno)
+	if type(name_or_lineno) == 'string' then
+		-- uh
+	elseif type(name_or_lineno) == 'number' then
+		if name_or_lineno < 1 or name_or_lineno > #g_loot then
+			return
+		end
+		local scrollhere = -9
+		repeat
+			scrollhere = scrollhere + 10
+			gui.eoiST.offset = scrollhere
+		until gui.eoiST:RowIsVisible(name_or_lineno)
+		-- Value must be in pixels, not "how many rows"
+		scrollhere = scrollhere * eoi_st_rowheight
+		-- But not past the bottom, it looks ugly
+		scrollhere = math.min (scrollhere,
+			(#gui.eoiST.filtered - eoi_st_displayed_rows) * eoi_st_rowheight)
+		gui.eoiST:SetSelection(name_or_lineno)
+		local sf = gui.eoiST.scrollframe
+		sf:GetScript("OnVerticalScroll")(sf,scrollhere)
+	end
+end
 
 
 -- Tab 2/3 (generated text)
@@ -2219,6 +2281,11 @@
 	tabs_OnGroupSelected_func (unpack(tabs_OnGroupSelected_func_args))
 end
 
+function addon:GoToLootLine (line)
+	local lineno = tonumber(self.lootjumps[line])
+	self:OpenMainDisplayToTab ("Loot", lineno)
+end
+
 
 ------ Popup dialogs
 local function build_my_slider_widget()
@@ -2400,8 +2467,11 @@
 		tinsert(g_loot,data.rowindex,entry)
 		addon:_mark_boss_kill(data.rowindex)
 		gui.eoiST:OuroLoot_Refresh(data.rowindex)
+		local jumpprefix = addon.chatprefix ("GoToLootLine", data.rowindex)
 		dialog.data = nil   -- free up memory
-		addon:Print("Inserted %s %s at entry %d.", data.kind, data.name, data.rowindex)
+		addon:PCFPrint (_G.DEFAULT_CHAT_FRAME, jumpprefix,
+			"Inserted %s %s at entry %d.",
+			data.kind, data.name, data.rowindex)
 		return
 	end
 
@@ -2452,8 +2522,10 @@
 		addon:_fill_out_eoi_data(data.rowindex)
 		addon:BuildMainDisplay()
 		local clicky = _new_rebroadcast_hyperlink (entry.unique)
+		local jumpprefix = addon.chatprefix ("GoToLootLine", data.rowindex)
 		dialog.data = nil
-		addon:Print ("Inserted %s %s at entry %d.  %s",
+		addon:PCFPrint (_G.DEFAULT_CHAT_FRAME, jumpprefix,
+			"Inserted %s %s at entry %d.  %s",
 			data.kind, data.name, data.rowindex, tostring(clicky))
 		return
 	end
--- a/options.lua	Sat Aug 04 22:03:05 2012 +0000
+++ b/options.lua	Sun Aug 05 07:26:06 2012 +0000
@@ -273,7 +273,7 @@
 
 		w = AceGUI:Create("Label")
 		w:SetFullWidth(true)
-		w:SetText("This controls the output of the |cff00ffff'Be chatty on <X> changes'|r options.  If this field is a number, it designates which chat frame to use.  Otherwise it is the Lua variable name of a frame with AddMessage capability.")
+		w:SetText("This controls the output of the two |cff00ffff'Be chatty on <X> changes'|r options.  If this field is a number, it designates which chat frame to use.  Otherwise it is the Lua variable name of a frame with AddMessage capability.")
 		chatgroup:AddChild(w)
 		editbox = mkbutton("EditBox", nil, opts.chatty_on_changes_frame,
 			[[1 = default chat frame, 2 = combat log, etc]])
@@ -802,7 +802,11 @@
 end
 
 addon:register_tab_control_AT_END ("opt", [[Options]],
-	[[Options for fine-tuning behavior]], tabs_OGS)
+	[[Options for fine-tuning behavior]], tabs_OGS, [[
+The "be chatty" options can be noisy, but they make the
+|cffff8000[Ouro Loot]|r link much more useful.  See
+<Help -- Handy Tips> for details!
+]])
 
 
 ---------------
--- a/verbage.lua	Sat Aug 04 22:03:05 2012 +0000
+++ b/verbage.lua	Sun Aug 05 07:26:06 2012 +0000
@@ -119,7 +119,7 @@
 <www.curse.com/addons/wow/ouroloot>
 
 
-or send them to <farmbuyer@gmail.com>.
+or send them to <farmbuyer@gmail.com> in non-HTML format.
 ]]
 
 T.basic = [[
@@ -141,12 +141,11 @@
 
 T.basic_loot = [[
 A "loot row" in the first tab has three columns:  the item, the recipient, and any
-extra notes.  The recipient's class icon is displayed by their names, if class
-information is available at the time.
+extra notes.
 
 <Mouse Hover>
 
-Hovering the mouse over the first column will display the item in a tooltip.
+Hovering the mouse over the first column will display the item tooltip.
 
 Hovering over the second column will display a tooltip with the loot that person
 has received.  If they've won more than 10 items, the list is cut off with '...'
@@ -158,9 +157,9 @@
 Right-clicking a loot row shows a dropdown menu.
 
 Right-clicking in the first or third columns will display options for special
-treatment of that loot entry (marking as offspec, etcetera).  Using any of those
-options will change the text in the third column (which will then affect the text
-in the generated tabs, such as forum markup).
+treatment of that loot entry (e.g., marking as offspec).  Using any of those
+options will change the text in the third column, which will then affect the
+text in the generated tabs, such as forum markup.
 
 Right-clicking in the second column allows you to temporarily remove all other
 players from the loot display.  Use the reset button in the lower-right corner to
@@ -404,12 +403,12 @@
 default, 5 loot events).  It is another good periodic maintenance step, but
 does not discard as much data as the other actions.
 
-Using +Reassign to...> will also move the item between player histories.  The timestamp
-will not be changed; it will "always have been" received by the new recipient.
-
-Using +Mark as disenchanted> or +Mark as guild vault> will remove the item from
-history altogether.  Remarking such an item as +normal> or +offspec> will replace
-the item back into the player's history.
+From the right-click menu on the main tab, using +Reassign to...> will also
+move the item between player histories.  The timestamp will not be changed;
+it will "always have been" received by the new recipient.  Using
++Mark as disenchanted> or +Mark as guild vault> will remove the item from
+history altogether.  Remarking such an item as +normal> or +offspec> will
+replace the item back into the player's history.
 
 Note:  the first time you display the histories during a game session, you will
 likely see several items listed as +UNKNOWN>.  This is not a bug; these items are
@@ -421,10 +420,11 @@
 
 T.tips = [[
 The |cffff8000[Ouro Loot]|r "legendary item" displayed at the start of all
-chat messages is a clickable link.  Clicking opens the main display.  An option
-on the <Options> tab will cause a message (and thus, the clickable link) to be
-printed after a boss kill,
-mostly for lazy loot trackers who don't like typing slash commands to open windows.
+chat messages is a clickable link.  Clicking opens the main display, and if
+possible will jump to and/or highlight the relevent data which caused the
+associated chat message to be printed in the first place.
+The "Be chatty" options on the <Options> tab will cause a chat message to be
+printed after various events, thus providing a way to quickly view them.
 
 If you are broadcasting to somebody else who is tracking, you should probably be
 using the same threshold.  If yours is lower, then some of the loot you broadcast
@@ -452,14 +452,25 @@
 If you give an unrecognized argument to a slash command, it will
 search the tab titles left to right for a title beginning with the same letters as
 the argument, and open the display to that tab.  For example, <"/ol a"> would
-open the <Attendance> tab, and <"/ol ad"> would open the <Advanced> tab.  If
+open the <Attendance> tab, and <"/ol o"> would open the <Options> tab.  If
 you had added a theoretical <EQDKP> tab, then <"/ol eq"> would be the fastest
-way to see it.
+way to see it.  Only enough text to be unambiguous is required, and all of it
+is case-insensitive.
+
+Some tabs will accept additional text after the tab title, and try to Do The
+Right Thing.  For example, <"/ol history blah"> will search for a player named
+"blah", and if found, will act as if you had clicked on that row, switching
+the display to every loot received by that player.  The same unambiguous prefix
+searching is used for names as for tab titles, so <"/ol hi farm"> is enough to
+trigger Farmbuyer's history display (as long as nobody named Farmville joins
+the raid), and so forth. 
 
 The </ouroloot> command can take arguments to do things without going through
 the UI.  Parts given in *(angle brackets)* are required, parts in [square brackets]
 are optional:
 
++help>:  opens the UI to the help tab|r
+
 +broadcast>/+bcast>:  turns on rebroadcasting|r
 
 +on [T]>:  turns on full tracking, optionally setting threshold to T|r
@@ -468,6 +479,8 @@
 
 +thre[shold] T>:  sets tracking threshold to T|r
 
++ping>:  same as clicking "Ping!" on the Options tab|r
+
 +list>:  prints saved text names and numbers|r
 
 +save *(your set name)*>:  saves texts as "your set name"|r
@@ -476,9 +489,9 @@
 
 +delete *(N)*>:  deletes set number N|r
 
-+help>:  opens the UI to the help tab|r
++toggle>:  opens or closes the UI (used mostly in automated wrappers)|r
 
-+toggle>:  opens or closes the UI (used mostly in automated wrappers)|r
++fix ?>:  lists the available automated data integrity fixes|r
 
 
 If you use the slash commands to enable tracking or set loot thresholds, you can
@@ -642,14 +655,13 @@
 		end
 	end
 
-	local noob = [[
+	addon:register_tab_control_AT_END ("help", [[Help]],
+		[[Instructions, reminders, and tips for non-obvious features]],
+		tabs_OGS, [[
 Every tab across the top also gets its own special buttons here in the lower
 right, under the same name as the tab.  Some controls do not become visible
-until that tab has data to work with.]]
+until that tab has data to work with.]])
 
-	addon:register_tab_control_AT_END ("help", [[Help]],
-		[[Instructions, reminders, and tips for non-obvious features]],
-		tabs_OGS, --[[opt_noobtip=]]noob)
 end
 
 -- vim:noet