diff gui.lua @ 37:cd745a18d7c7

Mostly code cosmetic tweaks. Split up EOI and History dropdown tables. Draw attention to realm names in popups, as they don't have to match the currently-played realm.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Sat, 10 Dec 2011 01:04:16 +0000
parents f62d582c5c52
children 8f7ec6ccf5e3
line wrap: on
line diff
--- a/gui.lua	Fri Dec 09 03:16:59 2011 +0000
+++ b/gui.lua	Sat Dec 10 01:04:16 2011 +0000
@@ -58,25 +58,25 @@
 -- Working around this bug:
 -- http://forums.wowace.com/showpost.php?p=295202&postcount=31
 do
-	local function FixFrameLevel (level, ...)
+	local function fix_frame_level (level, ...)
 		for i = 1, select("#", ...) do
 			local button = select(i, ...)
 			button:SetFrameLevel(level)
 		end
 	end
 
-	local function FixMenuFrameLevels()
-		local f = DropDownList1
+	local function fix_menu_frame_levels()
+		local f = _G.DropDownList1
 		local i = 1
 		while f do
-			FixFrameLevel (f:GetFrameLevel() + 2, f:GetChildren())
+			fix_frame_level (f:GetFrameLevel() + 2, f:GetChildren())
 			i = i + 1
 			f = _G["DropDownList"..i]
 		end
 	end
 
 	-- To fix Blizzard's bug caused by the new "self:SetFrameLevel(2);"
-	hooksecurefunc("UIDropDownMenu_CreateFrames", FixMenuFrameLevels)
+	hooksecurefunc("UIDropDownMenu_CreateFrames", fix_menu_frame_levels)
 end
 
 
@@ -326,10 +326,7 @@
 
 
 ------ Main GUI Window
--- Lots of shared data here, kept in a large local scope.  For readability,
--- indentation of the scope as a whole is kicked left a notch.
-do
-local _d
+local _d   -- display when it's open, eoiST when it's not
 local function setstatus(txt) _d:SetStatusText(txt) end
 local function statusy_OnLeave() setstatus("") end
 local tabgroup_tabs
@@ -372,10 +369,25 @@
 	end
 end
 
--- Tab 1:  Events Of Interest
--- This actually takes up quite a bit of the file.
+--[[
+Dropdown menu handling
+]]
+-- forward decls
 local eoi_editcell
 
+local dropdownfuncs
+do
+	local ddf_mt = {
+		__index = {
+			-- more stuff should be moved into this table
+			[CLOSE] = function() CloseDropDownMenus() end,
+		}
+	}
+	dropdownfuncs = function(t)
+		return setmetatable(t, ddf_mt)
+	end
+end
+
 local function dropdownmenu_handler (ddbutton, subfunc, arg)
 	local i = _d and _d.GetUserData and _d:GetUserData("DD loot index")
 	if i then
@@ -414,10 +426,12 @@
 end
 
 local dropdownmenuframe = CreateFrame("Frame", "OuroLootDropDownMenu", nil, "UIDropDownMenuTemplate")
-local dropdownfuncs
-dropdownfuncs = {
-	[CLOSE] = function() CloseDropDownMenus() end,
 
+
+-- Tab 1:  Events Of Interest
+-- This actually takes up quite a bit of the file.
+local eoi_dropdownfuncs
+eoi_dropdownfuncs = dropdownfuncs{
 	df_INSERT = function(rowi,text)
 		local which = (text == 'loot') and "OUROL_EOI_INSERT_LOOT" or "OUROL_EOI_INSERT"
 		local dialog = StaticPopup_Show(which,text)
@@ -434,18 +448,12 @@
 		end
 	end,
 
-	["Delete this history event"] = function(rowi)
-		--local gone = tremove(g_loot,rowi)
-		--addon:Print("Removed %s.",
-			--gone.itemlink or gone.bosskill or gone.startday.text)
-	end,
-
 	["Delete remaining entries for this day"] = function(rowi,kind)
 		-- if kind is boss, also need to stop at new timestamp
 		local fencepost = addon._find_timeboss_fencepost (kind, rowi)
 		local count = fencepost and (fencepost-rowi) or (#g_loot-rowi+1)
 		repeat
-			dropdownfuncs.df_DELETE(rowi)
+			eoi_dropdownfuncs.df_DELETE(rowi)
 			count = count - 1
 		until count < 1
 	end,
@@ -512,15 +520,16 @@
 }
 -- Would be better to move the %arg to this list rather than below, but
 -- that's a lot of extra effort that doesn't buy much in return.
-dropdownfuncs["Delete this loot event"] = dropdownfuncs.df_DELETE
-dropdownfuncs["Delete this boss event"] = dropdownfuncs.df_DELETE
-dropdownfuncs["Insert new loot entry"] = dropdownfuncs.df_INSERT
-dropdownfuncs["Insert new boss kill event"] = dropdownfuncs.df_INSERT
-dropdownfuncs["Mark as disenchanted"] = dropdownfuncs["Mark as normal"]
-dropdownfuncs["Mark as guild vault"] = dropdownfuncs["Mark as normal"]
-dropdownfuncs["Mark as offspec"] = dropdownfuncs["Mark as normal"]
-dropdownfuncs["Delete remaining entries for this boss"] = dropdownfuncs["Delete remaining entries for this day"]
-dropdownfuncs["Rebroadcast this day"] = dropdownfuncs["Rebroadcast this boss"]
+eoi_dropdownfuncs["Delete this loot event"] = eoi_dropdownfuncs.df_DELETE
+eoi_dropdownfuncs["Delete this boss event"] = eoi_dropdownfuncs.df_DELETE
+eoi_dropdownfuncs["Insert new loot entry"] = eoi_dropdownfuncs.df_INSERT
+eoi_dropdownfuncs["Insert new boss kill event"] = eoi_dropdownfuncs.df_INSERT
+eoi_dropdownfuncs["Mark as disenchanted"] = eoi_dropdownfuncs["Mark as normal"]
+eoi_dropdownfuncs["Mark as guild vault"] = eoi_dropdownfuncs["Mark as normal"]
+eoi_dropdownfuncs["Mark as offspec"] = eoi_dropdownfuncs["Mark as normal"]
+eoi_dropdownfuncs["Delete remaining entries for this boss"] =
+	eoi_dropdownfuncs["Delete remaining entries for this day"]
+eoi_dropdownfuncs["Rebroadcast this day"] = eoi_dropdownfuncs["Rebroadcast this boss"]
 local eoi_time_dropdown = gen_easymenu_table(
 	{{
 		-- this is the dropdown title, text filled in on the fly
@@ -534,7 +543,7 @@
 		"Insert new loot entry%loot|Inserts new loot above this one, prompting you for information.",
 		"Insert new boss kill event%boss|Inserts new event above this one, prompting you for information.",
 		CLOSE
-	}, dropdownfuncs)
+	}, eoi_dropdownfuncs)
 local eoi_loot_dropdown = gen_easymenu_table(
 	{{
 		-- this is the dropdown title, text filled in on the fly
@@ -555,7 +564,7 @@
 		"Edit note|Same as double-clicking in the notes column.",
 		"--",
 		CLOSE
-	}, dropdownfuncs)
+	}, eoi_dropdownfuncs)
 local eoi_player_dropdown = gen_easymenu_table(
 	{
 		{
@@ -575,7 +584,7 @@
 	{
 		"Show only this player",
 		CLOSE
-	}, dropdownfuncs)
+	}, eoi_dropdownfuncs)
 local eoi_boss_dropdown = gen_easymenu_table(
 	{{
 		-- this is the dropdown title, text filled in on the fly
@@ -592,19 +601,7 @@
 		"Insert new boss kill event%boss|Inserts new event above this one, prompting you for information.",
 		"--",
 		CLOSE
-	}, dropdownfuncs)
-local hist_dropdown = gen_easymenu_table(
-	{{
-		-- this is the dropdown title, text filled in on the fly
-		notClickable = true,
-		notCheckable = true,
-	}},
-	{
-		"Delete this history event|Permanent, no going back!",
-		--"Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day",
-		"--",
-		CLOSE
-	}, dropdownfuncs)
+	}, eoi_dropdownfuncs)
 
 --[[ quoted verbatim from lib-st docs:
 rowFrame This is the UI Frame table for the row.
@@ -708,13 +705,13 @@
 			raiders[i] = {
 				text = name,
 				func = dropdownmenu_handler,
-				arg1 = dropdownfuncs.df_REASSIGN,
+				arg1 = eoi_dropdownfuncs.df_REASSIGN,
 				arg2 = name,
 				notCheckable = true,
 			}
 		end
 		eoi_player_dropdown[2].menuList =
-			gen_easymenu_table (raiders, {"Enter name...",CLOSE}, dropdownfuncs)
+			gen_easymenu_table (raiders, {"Enter name...",CLOSE}, eoi_dropdownfuncs)
 		if e.disposition == 'shard' or e.disposition == 'gvault' then
 			eoi_player_dropdown[2].disabled = true
 			eoi_player_dropdown[2].tooltipTitle = "Cannot Reassign"
@@ -1003,6 +1000,7 @@
 	return tabs_OnGroupSelected["eoi"](ocontainer,specials)
 end
 
+
 -- Tab 2/3 (generated text)
 function tabs_generated_text_OGS (container, specials, text_kind)
 	container:SetLayout("Fill")
@@ -1054,246 +1052,272 @@
 	_populate_text_specials (box, specials, mkbutton, text_kind)
 end
 
+
 -- Tab 4:  History
 -- Much of the implementation here follows a similar desgin for the first
 -- tab's handling of ST objects.  We will even reuse its controlling tables
 -- when feasible.
-do
-	local histST
-	local hist_st_cols = {
-		{  -- col 1
-			name	= "Player",
-			width	= 130,
-			DoCellUpdate = eoi_st_col2_DoCellUpdate,
-		},
-		{  -- col 2
-			name	= "Most Recent Loot",
-			width	= 250,
-			DoCellUpdate = hist_st_col2_DoCellUpdate,
-		},
-		{  -- col 3
-			name	= "When",
-			width	= 250,
-			DoCellUpdate = hist_st_col3_DoCellUpdate,
-			defaultsort = "asc",
-			sort = "asc",
-			sortnext = 1,
-		},
-	}
+local histST, hist_dropdownfuncs
 
-	local hist_normal_status = [[Click on a row to view all history for that player only.  (Click column headers to re-sort.)]]
-	local hist_name_status = [[Right-click on any row to return to normal history display.]]
+hist_dropdownfuncs = dropdownfuncs{
+	["Delete this loot history"] = function(rowi)
+		--local gone = tremove(g_loot,rowi)
+		--addon:Print("Removed %s.",
+			--gone.itemlink or gone.bosskill or gone.startday.text)
+	end,
+}
+local hist_dropdown = gen_easymenu_table(
+	{{
+		-- this is the dropdown title, text filled in on the fly
+		notClickable = true,
+		notCheckable = true,
+	}},
+	{
+		"Delete this loot history|Permanent, no going back!",
+		--"Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day",
+		"--",
+		CLOSE
+	}, hist_dropdownfuncs)
 
-	local history_filter_by_recent = function (st, e)
-		if e.kind ~= 'history' then return true end
-		return e.cols[2].OLi == 1
+local hist_st_cols = {
+	{  -- col 1
+		name	= "Player",
+		width	= 130,
+		DoCellUpdate = eoi_st_col2_DoCellUpdate,
+	},
+	{  -- col 2
+		name	= "Most Recent Loot",
+		width	= 250,
+		DoCellUpdate = hist_st_col2_DoCellUpdate,
+	},
+	{  -- col 3
+		name	= "When",
+		width	= 250,
+		DoCellUpdate = hist_st_col3_DoCellUpdate,
+		defaultsort = "asc",
+		sort = "asc",
+		sortnext = 1,
+	},
+}
+
+local hist_normal_status =
+	[[Click on a row to view all history for that player only.  (Click column headers to re-sort.)]]
+local hist_name_status =
+	[[Right-click on any row to return to normal history display.]]
+
+local history_filter_by_recent = function (st, e)
+	if e.kind ~= 'history' then return true end
+	return e.cols[2].OLi == 1
+end
+
+local history_filter_who
+local history_filter_by_name = function (st, e)
+	if e.kind ~= 'history' then return true end
+	return e.OLwho == history_filter_who
+end
+
+-- Loot column
+local function hist_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...)
+	print("col2 DCU", realrow)
+end
+
+-- Formatted timestamp column
+local function hist_st_col3_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...)
+	print("col3 DCU", realrow)
+	if not fShow then
+		cellFrame.text:SetText("")
+		return
 	end
 
-	local history_filter_who
-	local history_filter_by_name = function (st, e)
-		if e.kind ~= 'history' then return true end
-		return e.OLwho == history_filter_who
+	local d = data[realrow]
+	local cell = d.cols[column]
+
+	cellFrame.text:SetText(cell.value)
+	cellFrame.text:SetTextColor(1,1,1,1)
+
+	--if d.kind ~= 'loot' then
+		stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[d.kind])
+	--else
+	--	table:SetHighLightColor (rowFrame, table:GetDefaultHighlightBlank())
+	--end
+end
+
+local function hist_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...)
+	if (row == nil) or (realrow == nil) then return false end  -- click column header, do default resorting
+	local h = data[realrow]
+	local kind = h.kind
+
+	if history_filter_who and button == "RightButton" then  -- now filtering and wanting not to
+		history_filter_who = nil
+		stable:SetFilter(history_filter_by_recent)
+		setstatus(hist_normal_status)
+	elseif (not history_filter_who) and button == "LeftButton" then  -- not filtering and wanting to
+		history_filter_who = h.OLwho
+		stable:SetFilter(history_filter_by_name)
+		setstatus(hist_name_status)
 	end
 
-	-- Loot column
-	local function hist_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...)
-		print("col2 DCU", realrow)
+	return true  -- do not do anything further
+end
+
+--[[
+local function hist_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...)
+	if (row == nil) or (realrow == nil) then return true end  -- they clicked on column header, suppress reordering
+	local h = data[realrow]
+	local kind = h.kind
+
+	return true  -- do not do anything further
+end]]
+
+-- Tab 4:  History (implementation)
+tabs_OnGroupSelected["hist"] = function(container,specials)
+	histST = LibStub("ScrollingTable"):CreateST(hist_st_cols,eoi_st_displayed_rows,eoi_st_rowheight)
+	_d:SetUserData("histST",histST)
+	if addon.author_debug then
+		_G.OLHST = histST
 	end
 
-	-- Formatted timestamp column
-	local function hist_st_col3_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...)
-		print("col3 DCU", realrow)
-		if not fShow then
-			cellFrame.text:SetText("")
-			return
-		end
-
-		local d = data[realrow]
-		local cell = d.cols[column]
-
-		cellFrame.text:SetText(cell.value)
-		cellFrame.text:SetTextColor(1,1,1,1)
-
-		--if d.kind ~= 'loot' then
-			stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[d.kind])
-		--else
-		--	table:SetHighLightColor (rowFrame, table:GetDefaultHighlightBlank())
-		--end
+	if not eoi_st_otherrow_bgcolortable_default then
+		eoi_st_otherrow_bgcolortable_default = histST:GetDefaultHighlightBlank()
+		setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key)
+			return eoi_st_otherrow_bgcolortable_default
+		end})
 	end
 
-	local function hist_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...)
-		if (row == nil) or (realrow == nil) then return false end  -- click column header, do default resorting
-		local h = data[realrow]
-		local kind = h.kind
-
-		if history_filter_who and button == "RightButton" then  -- now filtering and wanting not to
-			history_filter_who = nil
-			stable:SetFilter(history_filter_by_recent)
-			setstatus(hist_normal_status)
-		elseif (not history_filter_who) and button == "LeftButton" then  -- not filtering and wanting to
-			history_filter_who = h.OLwho
-			stable:SetFilter(history_filter_by_name)
-			setstatus(hist_name_status)
-		end
-
-		return true  -- do not do anything further
+	addon:_build_history_names()
+	addon:_fill_out_hist_data(1)
+	histST:SetData(addon.history.st)
+	histST:RegisterEvents{
+		OnEnter = eoi_st_OnEnter,
+		OnLeave = eoi_st_OnLeave,
+		OnClick = hist_st_OnClick,
+		--OnDoubleClick = hist_st_OnDoubleClick,
+	}
+	local oldrefresh = histST.Refresh
+	histST.Refresh = function (self, opt_index)
+		addon:_fill_out_hist_data(opt_index)
+		return oldrefresh(self)
+	end
+	histST.OuroLoot_Refresh = function (self, opt_index)
+		addon:_fill_out_hist_data(opt_index)
+		self:SortData()  -- calls hooked refresh
 	end
 
-	--[[
-	local function hist_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...)
-		if (row == nil) or (realrow == nil) then return true end  -- they clicked on column header, suppress reordering
-		local h = data[realrow]
-		local kind = h.kind
+	histST:SetFilter(history_filter_by_recent)
 
-		return true  -- do not do anything further
-	end]]
+	-- Zaps history for the given realm, or the current (current-playing
+	-- realm, not currently-displayed realm) one if not specified.
+	local function reset_current_realm (opt_realmname)
+		local r = assert(opt_realmname or GetRealmName())
+		-- new .history table:
+		addon.history_all[r] = addon:_prep_new_history_category (nil, r)
+		addon.history = addon.history_all[r]
+		addon.hist_clean = nil
+		-- new .history.st table:
+		histST:OuroLoot_Refresh()
+		histST:SetData(addon.history.st)
+	end
 
 	tabs_OnGroupSelected["hist"] = function(container,specials)
-		histST = LibStub("ScrollingTable"):CreateST(hist_st_cols,eoi_st_displayed_rows,eoi_st_rowheight)
-		_d:SetUserData("histST",histST)
-		if addon.author_debug then
-			_G.OLHST = histST
-		end
+		local st_widget = GUI:Create("lib-st")
+		-- don't need _d:GetUserData("histST") here, as it's already a local
+		histST:OuroLoot_Refresh()
+		st_widget:WrapST(histST)
+		st_widget.head_offset = 15
+		st_widget.tail_offset = 0
+		container:SetLayout("Fill")
+		container:AddChild(st_widget)
+		setstatus(hist_normal_status)
 
-		if not eoi_st_otherrow_bgcolortable_default then
-			eoi_st_otherrow_bgcolortable_default = histST:GetDefaultHighlightBlank()
-			setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key)
-				return eoi_st_otherrow_bgcolortable_default
-			end})
-		end
-
-		addon:_build_history_names()
-		addon:_fill_out_hist_data(1)
-		histST:SetData(addon.history.st)
-		histST:RegisterEvents{
-			OnEnter = eoi_st_OnEnter,
-			OnLeave = eoi_st_OnLeave,
-			OnClick = hist_st_OnClick,
-			--OnDoubleClick = hist_st_OnDoubleClick,
-		}
-		local oldrefresh = histST.Refresh
-		histST.Refresh = function (self, opt_index)
-			addon:_fill_out_hist_data(opt_index)
-			return oldrefresh(self)
-		end
-		histST.OuroLoot_Refresh = function (self, opt_index)
-			addon:_fill_out_hist_data(opt_index)
-			self:SortData()  -- calls hooked refresh
-		end
-
-		histST:SetFilter(history_filter_by_recent)
-
-		-- Zaps history for the given realm, or the current (current-playing
-		-- realm, not currently-displayed realm) one if not specified.
-		local function reset_current_realm (opt_realmname)
-			local r = assert(opt_realmname or GetRealmName())
-			-- new .history table:
-			addon.history_all[r] = addon:_prep_new_history_category (nil, r)
-			addon.history = addon.history_all[r]
-			addon.hist_clean = nil
-			-- new .history.st table:
-			histST:OuroLoot_Refresh()
-			histST:SetData(addon.history.st)
-		end
-
-		tabs_OnGroupSelected["hist"] = function(container,specials)
-			local st_widget = GUI:Create("lib-st")
-			-- don't need _d:GetUserData("histST") here, as it's already a local
-			histST:OuroLoot_Refresh()
-			st_widget:WrapST(histST)
-			st_widget.head_offset = 15
-			st_widget.tail_offset = 0
-			container:SetLayout("Fill")
-			container:AddChild(st_widget)
-			setstatus(hist_normal_status)
-
-			local b
-			do
-				local realms,current = {},1
-				for realmname,histtable in pairs(addon.history_all) do
-					if type(histtable) == 'table' then
-						tinsert(realms,realmname)
-						if addon.history == histtable then current = #realms end
-					end
+		local b
+		do
+			local realms,current = {},1
+			for realmname,histtable in pairs(addon.history_all) do
+				if type(histtable) == 'table' then
+					tinsert(realms,realmname)
+					if addon.history == histtable then current = #realms end
 				end
-				b = mkbutton("Dropdown", nil, "", [[Which realm to display]])
-				b:SetFullWidth(true)
-				b:SetLabel()  -- required even when empty, see ace3 ticket #234
-				b:SetList(realms)
-				b:SetValue(current)
-				b:SetCallback("OnValueChanged", function(_dd,event,choice)
-					local r = realms[choice]
-					addon.history = addon:_prep_new_history_category (addon.history_all[r], r)
-					addon.hist_clean = nil
-					histST:OuroLoot_Refresh()
-					histST:SetData(addon.history.st)
-					-- Reset filters to normal
-					history_filter_who = nil
-					histST:SetFilter(history_filter_by_recent)
-					setstatus(hist_normal_status)
-					return addon:redisplay()
-				end)
-				specials:AddChild(b)
 			end
-
-			--[[ b = GUI:Create("Spacer") b:SetFullWidth(true) b:SetHeight(10) specials:AddChild(b) ]]
-
-			b = mkbutton("Regenerate",
-				[[Erases all history entries from the displayed realm, and regenerates it from current loot information.]])
+			b = mkbutton("Dropdown", nil, "", [[Which realm to display]])
 			b:SetFullWidth(true)
-			b:SetDisabled (#addon.history == 0)
-			b:SetCallback("OnClick", function(_b)
-				addon:rewrite_history (addon.history.realm)
+			b:SetLabel()  -- required even when empty, see ace3 ticket #234
+			b:SetList(realms)
+			b:SetValue(current)
+			b:SetCallback("OnValueChanged", function(_dd,event,choice)
+				local r = realms[choice]
+				addon.history = addon:_prep_new_history_category (addon.history_all[r], r)
+				addon.hist_clean = nil
 				histST:OuroLoot_Refresh()
 				histST:SetData(addon.history.st)
-				addon:Print("%s history has been regenerated.", addon.history.realm)
+				-- Reset filters to normal
+				history_filter_who = nil
+				histST:SetFilter(history_filter_by_recent)
+				setstatus(hist_normal_status)
 				return addon:redisplay()
 			end)
 			specials:AddChild(b)
+		end
 
-			b = mkbutton('hist_clear', "Clear Realm History",
-				[[|cffff1010Erases absolutely all> history entries from the displayed realm.]])
-			b:SetFullWidth(true)
-			b:SetCallback("OnClick", function (_b)
-				local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", addon.history.realm)
-				dialog.data = addon
-				dialog.data2 = function(_addon)
-					reset_current_realm(_addon.history.realm)
-				end
-			end)
-			specials:AddChild(b)
+		--[[ b = GUI:Create("Spacer") b:SetFullWidth(true) b:SetHeight(10) specials:AddChild(b) ]]
 
-			b = mkbutton('hist_clear_all', "Clear All History",
-				[[|cffff1010Erases absolutely all> history entries from ALL realms.]])
-			b:SetFullWidth(true)
-			b:SetCallback("OnClick", function (_b)
-				local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", "ALL realms")
-				dialog.data = addon
-				dialog.data2 = function(_addon)
-					_addon.history_all = {}
-					reset_current_realm()
-				end
-			end)
-			specials:AddChild(b)
+		b = mkbutton("Regenerate",
+			[[Erases all history entries from the displayed realm, and regenerates it from current loot information.]])
+		b:SetFullWidth(true)
+		b:SetDisabled (#addon.history == 0)
+		b:SetCallback("OnClick", function(_b)
+			local dialog = StaticPopup_Show("OUROL_HIST_REGEN", addon.history.realm)
+			dialog.data = addon
+			dialog.data2 = function(_addon)
+				_addon:rewrite_history (_addon.history.realm)
+				histST:OuroLoot_Refresh()
+				histST:SetData(_addon.history.st)
+			end
+		end)
+		specials:AddChild(b)
 
-			b = mkbutton('hist_clear_old', "Clear Older",
-				[[Preserves only the latest loot entry for each player on the displayed realm, removing all earlier ones.]])
-			b:SetFullWidth(true)
-			b:SetCallback("OnClick", function (_b)
-				local dialog = StaticPopup_Show("OUROL_HIST_PREEN", addon.history.realm)
-				dialog.data = addon
-				dialog.data2 = function(_addon)
-					_addon:preen_history(_addon.history.realm)
-					_addon.hist_clean = nil
-					histST:OuroLoot_Refresh()
-				end
-			end)
-			specials:AddChild(b)
-		end
-		return tabs_OnGroupSelected["hist"](container,specials)
+		b = mkbutton('hist_clear', "Clear Realm History",
+			[[|cffff1010Erases absolutely all> history entries from the displayed realm.]])
+		b:SetFullWidth(true)
+		b:SetCallback("OnClick", function (_b)
+			local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", addon.history.realm)
+			dialog.data = addon
+			dialog.data2 = function(_addon)
+				reset_current_realm(_addon.history.realm)
+			end
+		end)
+		specials:AddChild(b)
+
+		b = mkbutton('hist_clear_all', "Clear All History",
+			[[|cffff1010Erases absolutely all> history entries from ALL realms.]])
+		b:SetFullWidth(true)
+		b:SetCallback("OnClick", function (_b)
+			local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", "ALL realms")
+			dialog.data = addon
+			dialog.data2 = function(_addon)
+				_addon.history_all = {}
+				reset_current_realm()
+			end
+		end)
+		specials:AddChild(b)
+
+		b = mkbutton('hist_clear_old', "Clear Older",
+			[[Preserves only the latest loot entry for each player on the displayed realm, removing all earlier ones.]])
+		b:SetFullWidth(true)
+		b:SetCallback("OnClick", function (_b)
+			local dialog = StaticPopup_Show("OUROL_HIST_PREEN", addon.history.realm)
+			dialog.data = addon
+			dialog.data2 = function(_addon)
+				_addon:preen_history(_addon.history.realm)
+				_addon.hist_clean = nil
+				histST:OuroLoot_Refresh()
+			end
+		end)
+		specials:AddChild(b)
 	end
+	return tabs_OnGroupSelected["hist"](container,specials)
 end
 
+
 -- Tab 5:  Help (content in verbage.lua)
 do
 	local tabs_help_OnGroupSelected_func = function (treeg,event,category)
@@ -1344,6 +1368,7 @@
 	end
 end
 
+
 -- Tab 6:  Options / Advanced
 do
 	local function mkoption (opt, label, width, desc, opt_func)
@@ -1991,8 +2016,6 @@
 	tabs_OnGroupSelected_func (unpack(tabs_OnGroupSelected_func_args))
 end
 
-end -- local 'do' scope
-
 
 ------ Popup dialogs
 -- Callback for each Next/Accept stage of inserting a new loot row via dropdown
@@ -2102,8 +2125,21 @@
 	end,
 }
 
+StaticPopupDialogs["OUROL_HIST_REGEN"] = flib.StaticPopup{
+	-- Concatenate this once at load time.  There is no ITEM_QUALITY_LEGENDARY constant.
+	text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex .. "%s|r, and generate it anew from current loot?",
+	button1 = YES,
+	button2 = NO,
+	OnAccept = function (dialog, addon, data2)
+		data2(addon)
+		addon:Print("%s history has been regenerated.", addon.history.realm)
+		addon:redisplay()
+	end,
+}
+
 StaticPopupDialogs["OUROL_HIST_CLEAR"] = flib.StaticPopup{
-	text = "Erase all history entries from %s?",
+	-- Concatenate this once at load time.  There is no ITEM_QUALITY_LEGENDARY constant.
+	text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex .. "%s|r?",
 	button1 = YES,
 	button2 = NO,
 	OnAccept = function (dialog, addon, data2)
@@ -2114,7 +2150,8 @@
 }
 
 StaticPopupDialogs["OUROL_HIST_PREEN"] = flib.StaticPopup{
-	text = "Erase all but the latest entry for players on %s?",
+	-- Concatenate this once at load time.  There is no ITEM_QUALITY_LEGENDARY constant.
+	text = "Erase all but the latest entry for players on " .. ITEM_QUALITY_COLORS[5].hex .. "%s|r?",
 	button1 = YES,
 	button2 = NO,
 	OnAccept = function (dialog, addon, data2)