List Fact Witness Details.fh_lua

--[[
@Title:			List Fact Witness Details
@Type:				Standard
@Author:			Mike Tate
@Contributors:	Jane Taubman & obstinatesnooper
@Version:			1.1
@Keywords:		
@LastUpdated:	23 Feb 2023
@Licence:			This plugin is copyright (c) 2023 Mike Tate and contributors, and is licensed under the MIT License which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description:	List the Fact Witness details for all Name Only witnesses and selected linked Individuals.
@V1.1:				Fix fault where some Name Only details were listed incorrectly;
@V1.0:				First published in Plugin Store;
]]

local strTitle = "List Fact Witness Details  v1.1"		-- Update when Version changes

function Main()
	local tblIndi = fhPromptUserForRecordSel("INDI")	-- Use Cancel to list just Name Only witnesses
	-- Build List based on record id
	local tblRecord = {}
	for _,ptrIndi in ipairs(tblIndi) do
		tblRecord[fhGetRecordId(ptrIndi)] = ptrIndi:Clone()
	end

	local tblResults = createResultTable()
	-- Define Columns
	tblResults.name = { title="Witness Name"		, width=140 , sort=2 }					-- V1.1
	tblResults.indi = { title="Record"				, width=140 , visibility="buddy" }
	tblResults.wrid = { title="Rec Id"				, width= 34 , align="align_mid" , sort=1 }
	tblResults.role = { title="Role"				, width= 60 }
	tblResults.cite = { title="Source"				, width=100 }
	tblResults.note = { title="Note"				, width=100 }
	tblResults.prin = { title="Fact Principal"	, width=140 }
	tblResults.prid = { title="Rec Id"				, width= 34 , align="align_mid" }
	tblResults.fact = { title="Witnessed Fact"	, width=190 }
	tblResults.link = { title="Witnessed Fact"	, width=190 , visibility="buddy" }

	for ptrItem in allItems("INDI","FAM") do
		local strTag = fhGetTag(ptrItem)
		if strTag:match("^_SHA[NR]$") then
			if strTag == "_SHAR" then			-- Found linked Individual Witness
				local ptrIndi = fhGetValueAsLink(ptrItem)
				local intIndi = fhGetRecordId(ptrIndi)
				if tblRecord[intIndi] then	-- Found their Rec Id in list
					saveColumns(tblResults,ptrItem,fhGetDisplayText(ptrIndi),ptrIndi:Clone(),intIndi)	-- V1.1
				end
			else									-- Found a Name Only witness
				saveColumns(tblResults,ptrItem," Name Only: "..fhGetValueAsText(ptrItem))					-- V1.1
			end
		end
	end
	if tblResults:rowCount() == 0 then
		fhMessageBox("\n No Fact Witnesses found. \n")
	else
		fhOutputResultSetTitles(strTitle, strTitle, "Date: %#x")
		tblResults:outputResults()
	end
end -- function Main

function saveColumns(tblResults,ptrItem,strName,ptrIndi,intIndi)	-- V1.1
	local ptrFact = fhNewItemPtr()
	local ptrPrin = fhNewItemPtr()
	ptrFact:MoveToParentItem(ptrItem)
	ptrPrin:MoveToParentItem(ptrFact)
	tblResults:newRow()							-- Add Row
	tblResults.name:set(strName)
	tblResults.indi:set(ptrIndi or fhNewItemPtr())
	tblResults.wrid:set(intIndi or "")
	tblResults.prin:set(ptrPrin:Clone())
	tblResults.prid:set(fhGetRecordId(ptrPrin))
	tblResults.role:set(fhGetItemPtr(ptrItem,"~.ROLE"))
	tblResults.cite:set(fhGetItemPtr(ptrItem,"~.SOUR"))
	tblResults.note:set(fhGetItemPtr(ptrItem,"~.NOTE2"))
	tblResults.fact:set(fhGetDisplayText(ptrFact))
	tblResults.link:set(ptrFact:Clone())
end -- function saveColumns

function allItems(...)
	local arg = {...}
	arg["n"] = #arg
	local iTypeCount = nil
	local iPos = 1
	local p1 = fhNewItemPtr()
	local p2 = fhNewItemPtr()
	local tblRecTypes = {}

	if arg["n"] == 0 then
		-- No parameter do all Record Types
		iTypeCount = fhGetRecordTypeCount() -- Get Count of Record types
		for i = 1,iTypeCount do
			tblRecTypes[i] = fhGetRecordTypeTag(i)
		end
	else
		-- Got Parameters Process them instead
		tblRecTypes = arg
		iTypeCount = arg["n"]
	end

	p1:MoveToFirstRecord(tblRecTypes[iPos])

	return function()
		repeat
		while p1:IsNotNull() do
			p2:MoveTo(p1)
			p1:MoveNextSpecial()
			if p2:IsNotNull() then
				return p2
			end
		end
		-- Loop through Record Types
		iPos = iPos + 1
		if iPos <= iTypeCount then
			p1:MoveToFirstRecord(tblRecTypes[iPos])
		end
		until iPos > iTypeCount
	end
end -- function allItems

function createResultTable()
	local tblOutput_mt = {} -- create metatable
	local iC = 0 -- Define count of lines
	local tblOutput = {} -- Define Columns Table
	tblOutput_mt.col = 0
	tblOutput_mt.seq = {}
	tblOutput_mt.__newindex =

	function (t,k,v)
		-- Set Values to Defaults if not supplied
		if v.content == nil then v.content = {} end
		if v.title == nil then v.title = k end
		if v.type == nil then v.type = "notset" end
		if v.width == nil then v.width = 140 end
		if v.align == nil then v.align = "align_left" end
		if v.sort == nil then v.sort = 0 end
		if v.sortAscending == nil then v.sortAscending = true end
		if v.sortType == nil then v.sortType = "default" end
		if v.visibility == nil then v. visibility = "show" end
		v.set =

		function(self,value)
			self.content[iC] = value
			if self.type == "notset" then
				if type(value) == "string" then
					self.type = "text"
				elseif type(value) == "number" then
					self.type = "integer"
					self.width = "30"
				else
					self.type = "item"
				end
			end
		end
		rawset(t,k,v) -- update original table
		local m = getmetatable(t)
		m.col = m.col + 1
		table.insert(m.seq,k)
	end
	tblOutput_mt.__call =

	function (t)
		local i = 0
		local m = getmetatable(t)
		local n = #m.seq
		return function ()
			i = i + 1
			if i <= n then
				return t[m.seq[i]]
			end
		end
	end
	tblOutput.newRow = function(t)
		iC = iC + 1
	end
	tblOutput.rowCount = function(t)
		return iC
	end
	tblOutput.outputResults = function(self)
		for l in self() do
			fhOutputResultSetColumn(l.title, l.type, l.content, iC, l.width,l.align,l.sort,l.sortAscending,l.sortType,l.visibility )
		end
	end
	setmetatable(tblOutput, tblOutput_mt)
	return tblOutput
end -- createResultTable

------------------------------------------------------- Run Main

fhInitialise(6,0,0,"save_recommended")											-- Recommend current GEDCOM is saved if outstanding changes

Main()

Source:List-Fact-Witness-Details-1.fh_lua