Possible Problem Set Ignore Markers.fh_lua

--[[
@Title: Possible Problem Marker
@Author: Jane Taubman
@LastUpdated: May 2012
@Version: 1.1
@Description: Companion to Possible Problem Marker,  
this allows Events to be marked as "Ignore" so that they are 
not listed on the Possible Problem Report.
]]
require "iuplua"
-- require "_tableloadsave"
--[[
   Save Table to File/Stringtable
   Load Table from File/Stringtable
   v 0.94
   
   Lua 5.1 compatible
   
   Userdata and indices of these are not saved
   Functions are saved via string.dump, so make sure it has no upvalues
   References are saved
   ----------------------------------------------------
   table.save( table [, filename] )
   
   Saves a table so it can be called via the table.load function again
   table must a object of type 'table'
   filename is optional, and may be a string representing a filename or true/1
   
   table.save( table )
      on success: returns a string representing the table (stringtable)
      (uses a string as buffer, ideal for smaller tables)
   table.save( table, true or 1 )
      on success: returns a string representing the table (stringtable)
      (uses io.tmpfile() as buffer, ideal for bigger tables)
   table.save( table, "filename" )
      on success: returns 1
      (saves the table to file "filename")
   on failure: returns as second argument an error msg
   ----------------------------------------------------
   table.load( filename or stringtable )
   
   Loads a table that has been saved via the table.save function
   
   on success: returns a previously saved table
   on failure: returns as second argument an error msg
   ----------------------------------------------------
   
   chillcode, http://lua-users.org/wiki/SaveTableToFile
   Licensed under the same terms as Lua itself.
]]--
do
   -- declare local variables
   --// exportstring( string )
   --// returns a "Lua" portable version of the string
   local function exportstring( s )
      s = string.format( "%q",s )
      -- to replace
      s = string.gsub( s,"\\\n","\\n" )
      s = string.gsub( s,"\r","\\r" )
      s = string.gsub( s,string.char(26),"\"..string.char(26)..\"" )
      return s
   end
--// The Save Function
function table.save(  tbl,filename )
   local charS,charE = "   ","\n"
   local file,err
   -- create a pseudo file that writes to a string and return the string
   if not filename then
      file =  { write = function( self,newstr ) self.str = self.str..newstr end, str = "" }
      charS,charE = "",""
   -- write table to tmpfile
   elseif filename == true or filename == 1 then
      charS,charE,file = "","",io.tmpfile()
   -- write table to file
   -- use io.open here rather than io.output, since in windows when clicking on a file opened with io.output will create an error
   else
      file,err = io.open( filename, "w" )
      if err then return _,err end
   end
   -- initiate variables for save procedure
   local tables,lookup = { tbl },{ [tbl] = 1 }
   file:write( "return {"..charE )
   for idx,t in ipairs( tables ) do
      if filename and filename ~= true and filename ~= 1 then
         file:write( "-- Table: {"..idx.."}"..charE )
      end
      file:write( "{"..charE )
      local thandled = {}
      for i,v in ipairs( t ) do
         thandled[i] = true
         -- escape functions and userdata
         if type( v ) ~= "userdata" then
            -- only handle value
            if type( v ) == "table" then
               if not lookup[v] then
                  table.insert( tables, v )
                  lookup[v] = #tables
               end
               file:write( charS.."{"..lookup[v].."},"..charE )
            elseif type( v ) == "function" then
               file:write( charS.."loadstring("..exportstring(string.dump( v )).."),"..charE )
            else
               local value =  ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
               file:write(  charS..value..","..charE )
            end
         end
      end
      for i,v in pairs( t ) do
         -- escape functions and userdata
         if (not thandled[i]) and type( v ) ~= "userdata" then
            -- handle index
            if type( i ) == "table" then
               if not lookup[i] then
                  table.insert( tables,i )
                  lookup[i] = #tables
               end
               file:write( charS.."[{"..lookup[i].."}]=" )
            else
               local index = ( type( i ) == "string" and "["..exportstring( i ).."]" ) or string.format( "[%d]",i )
               file:write( charS..index.."=" )
            end
            -- handle value
            if type( v ) == "table" then
               if not lookup[v] then
                  table.insert( tables,v )
                  lookup[v] = #tables
               end
               file:write( "{"..lookup[v].."},"..charE )
            elseif type( v ) == "function" then
               file:write( "loadstring("..exportstring(string.dump( v )).."),"..charE )
            else
               local value =  ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
               file:write( value..","..charE )
            end
         end
      end
      file:write( "},"..charE )
   end
   file:write( "}" )
   -- Return Values
   -- return stringtable from string
   if not filename then
      -- set marker for stringtable
      return file.str.."--|"
   -- return stringttable from file
   elseif filename == true or filename == 1 then
      file:seek ( "set" )
      -- no need to close file, it gets closed and removed automatically
      -- set marker for stringtable
      return file:read( "*a" ).."--|"
   -- close file and return 1
   else
      file:close()
      return 1
   end
end

--// The Load Function
function table.load( sfile )
   -- catch marker for stringtable
   if string.sub( sfile,-3,-1 ) == "--|" then
      tables,err = loadstring( sfile )
   else
      tables,err = loadfile( sfile )
   end
   if err then return _,err
   end
   tables = tables()
   for idx = 1,#tables do
      local tolinkv,tolinki = {},{}
      for i,v in pairs( tables[idx] ) do
         if type( v ) == "table" and tables[v[1]] then
            table.insert( tolinkv,{ i,tables[v[1]] } )
         end
         if type( i ) == "table" and tables[i[1]] then
            table.insert( tolinki,{ i,tables[i[1]] } )
         end
      end
      -- link values, first due to possible changes of indices
      for _,v in ipairs( tolinkv ) do
         tables[idx][v[1]] = v[2]
      end
      -- link indices
      for _,v in ipairs( tolinki ) do
         tables[idx][v[2]],tables[idx][v[1]] =  tables[idx][v[1]],nil
      end
   end
   return tables[1]
end
-- close do
end
function getAllFacts(ptr)
    local ptrItems = {}
    local dspList = {}
    local markList = {}
	local recordList = {ptr}
    local ptrEvent = fhNewItemPtr()
    local ptrDate = fhNewItemPtr()
	for i,ptr in ipairs(recordList) do
    ptrEvent:MoveToFirstChildItem(ptr)
    while ptrEvent:IsNotNull() do
        if  fhIsFact(ptrEvent) then
			 ptrDate:MoveTo(ptrEvent,'~.DATE')
			 warning = ""
			 if ptrDate:IsNotNull() then
				warning = fhCallBuiltInFunction('GetDataWarning',ptrDate,1)
				if warning ~= "" then 
					warning="   ~~Warning~~" 
				end
			end
            local tblRecord = {recordid=fhGetRecordId(ptr),
								    type=fhGetTag(ptr),
									date=fhGetItemText(ptrEvent,'~.DATE'),
                                plac=fhGetItemText(ptrEvent,'~.PLAC'),
                                tag=fhGetTag(ptrEvent),
                                value=fhGetItemText(ptrEvent,'~')}
            table.insert(ptrItems,tblRecord)
            table.insert(dspList,fhGetDisplayText(ptrEvent)..'('..fhGetTag(ptrEvent)..')'..warning)
            table.insert(markList,checkMark(tblRecord))
        end
		 if fhGetTag(ptrEvent) == 'FAMS' then
			 table.insert(recordList,fhGetValueAsLink(ptrEvent))
		end
        ptrEvent:MoveNext('ANY')
    end
	end
    return ptrItems,dspList,markList
end

function buildIndex(record)
    return (record.type..'|'..record.recordid..'|'..record.tag..'|'..record.date..'|'..record.plac..'|'..record.value)
end
function checkMark(record)
    local mark = 0
    if Settings[buildIndex(record)] ~= nil then
        mark = 1
    end
    return mark
end
--------------------------------------------------------------Main Code
strSettings = fhGetPluginDataFileName()
-- Fix File name
strSettings =strSettings:gsub('Data\\.-\.dat','Data\\Possible Problem Manager.dat')
Settings = table.load(strSettings)
if Settings == nil then Settings = {} end  -- First Run set empty Settings File
    -- Get Current Record abort if none.
    ptrList = fhGetCurrentRecordSel('INDI')
    if ptrList[1] == nil then
        error('No Record - Currently Selected')
    end
    ptrItems,dspList,markList = getAllFacts(ptrList[1])
	table.insert(dspList,1,'Clear All Marks')
	table.insert(markList,1,0)
    error = iup.ListDialog(2,"Mark Events To Be Ignored - Ctrl Click to select more than one",#dspList,dspList,0,40,15,markList)
	bClear = false
    if error == -1 then
		return
    else
        for i,mark in ipairs(markList) do
			 if i == 1 and mark == 1 then
					bClear = true
			 end
			 if i > 1 then
            idx = buildIndex(ptrItems[i-1])
            if (mark == 1) and not(bClear) then
                Settings[idx] = 1
            else
                Settings[idx] = nil
            end
			end
        end
    end
    table.save(Settings,strSettings)

Source:Possible-Problem-Set-Ignore-Markers3.fh_lua