Rich Text Tabulation.fh_lua--[[
@Title: Rich Text Tabulation
@Type: Standard
@Author: Mark Draper
@Version: 1.0
@LastUpdated: 3 Jan 2023
@Licence: This plugin is copyright (c) 2023 Mark Draper and is licensed under the MIT License which
is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Tabulates project fields containing selected Rich Text elements.
]]
--[[
Version 0.1 - 19 Dec 2022
Original FHUG prototype
Version 1.0 - 3 Jan 2023
First Store version
]]
fhInitialise(7)
require('iuplua')
fh = require('fhUtils')
fhfu = require('fhFileUtils')
fh.setIupDefaults()
function main()
local p = fhNewItemPtr()
local pR = fhNewItemPtr()
local tblRecord = {}
local tblText = {}
-- present menu and capture selected options
local tblSelection = MenuOptions()
if tblSelection.End then return end
-- search all records in the project for Rich Text fields
local count = 0
for i = 1, fhGetRecordTypeCount() do
p:MoveToFirstRecord(fhGetRecordTypeTag(i))
while p:IsNotNull() do
if fhGetValueType(p) == 'richtext' then
local rt = fhGetValueAsRichText(p)
if rt:IsRich() then
count = count + 1
if tblSelection.All or SelectField(rt, tblSelection) then
pR:MoveToRecordItem(p)
table.insert(tblRecord, pR:Clone())
table.insert(tblText, p:Clone())
end
end
end
p:MoveNextSpecial()
end
end
if count == 0 then
fhMessageBox('This project does not use Rich Text', 'MB_OK', 'MB_ICONINFORMATION')
return
end
local message = ''
if not tblSelection.All then
message = #tblText .. ' fields containing selected features\n\n'
if #tblText == 1 then message = message:gsub('fields', 'field') end
end
if count == 1 then
message = message .. count .. ' Rich Text field in total'
else
message = message .. count .. ' Rich Text fields in total'
end
fhMessageBox(message, 'MB_OK', 'MB_ICONINFORMATION')
if #tblText > 0 then
fhOutputResultSetTitles('Rich Text')
fhOutputResultSetColumn('Record', 'item', tblRecord, #tblRecord)
fhOutputResultSetColumn('Rich Text', 'item', tblText, #tblText)
end
end
-- ************************************************************************** --
function MenuOptions()
-- create menu
local Options = {} -- toggles in table for easier management
local tblSelection = {}
tblSelection.End = true -- default if not changed
-- define font selection frame using long font name over 2 lines for max size
Options.None = iup.toggle{title = 'None', expand = 'YES'}
Options.Specified = iup.toggle{title = 'Matura MT Script\nCapitals', expand = 'YES'}
Options.Any = iup.toggle{title = 'Any', expand = 'YES'}
local btnSelect = iup.button{title = 'Select', padding = '10x3', tip = 'Select font to locate'}
local vboxFont = iup.vbox{Options.None, Options.Specified, Options.Any; gap = 5, margin = '0x0'}
local radio = iup.radio{vboxFont}
local vboxFS = iup.vbox{radio, btnSelect; gap = 10, margin = '10x10'}
local fraFS = iup.frame{vboxFS; title = 'Font Selection'}
-- define other features
Options.Tables = iup.toggle{title = 'Tables', expand = 'YES'}
Options.Citations = iup.toggle{title = 'Citations', expand = 'YES'}
Options.RecLinks = iup.toggle{title = 'Record Links', expand = 'YES'}
Options.ExtLinks = iup.toggle{title = 'External Links', expand = 'YES'}
local vboxOF = iup.vbox{Options.Tables, Options.Citations, Options.RecLinks, Options.ExtLinks;
gap = 10, margin = '10x10'}
local fraOF = iup.frame{vboxOF; title = 'Other Features'}
-- define custom tag
Options.Custom = iup.toggle{title = '', expand = 'YES'}
local btnDefine = iup.button{title = 'Define', padding = '10x3', tip = 'Define custom Rich Text tag'}
local vboxCF = iup.vbox{Options.Custom, btnDefine; gap = 10, margin = '10x10'}
local fraCF = iup.frame{vboxCF; title = 'Custom Tag'}
-- define main buttons
local btnOK = iup.button{title = 'OK',
tip = 'Locate all record fields containing at least one of the selected Rich Text features'}
local btnAll = iup.button{title = 'All Rich Text', padding = '5x3',
tip = 'Locate all record fields defined as Rich Text'}
local btnHelp = iup.button{title = 'Help', tip = 'Display Plugin Store Help page'}
local btnClose = iup.button{title = 'Close', tip = 'Close plugin'}
local Buttons = iup.hbox{btnOK, btnAll, btnHelp, btnClose; normalizesize = 'BOTH', gap = 25}
-- build form
local Title = iup.label{title = 'List fields containing at least one of the selected Rich Text features',
padding = '10x10'}
local hboxForm = iup.hbox{fraFS, fraOF, fraCF, normalizesize = 'BOTH'}
local vboxForm = iup.vbox{Title, hboxForm, Buttons; alignment = 'ACENTER', gap = 10; margin = '10x10'}
local dialog = iup.dialog{vboxForm; resize = 'NO', minbox = 'NO', maxbox = 'NO', border = 'NO',
title = 'Rich Text Tabulation'}
-- define callbacks
function btnSelect:action()
local fullfont = SelectFont() or ''
Options.Specified.Title = fullfont:match('^[^,]+') or Options.Specified.Title
Options.Specified.Value = 'YES'
Options.Specified.Size = size
end
function btnOK:action()
for k, v in pairs(Options) do
if v.Value == 'ON' then
tblSelection[k] = true
end
end
if Options.Specified.Value == 'ON' then
tblSelection.Specified = Options.Specified.Title
end
if Options.Custom.Value == 'ON' then
tblSelection.Custom = Options.Custom.Title
end
tblSelection.End = nil
return iup.CLOSE
end
function btnAll:action()
tblSelection.All = true
tblSelection.End = nil
return iup.CLOSE
end
function btnHelp:action()
local Cmd = 'https://pluginstore.family-historian.co.uk/page/help/rich-text-tabulation'
fhShellExecute(Cmd)
fhSleep(1000) -- slight pause to suspend immediate redraw
end
function btnDefine:action()
local tag = iup.GetText('Enter custom Rich Text tag', '')
if tag and tag:match('^<.+>$') and not tag:match('\n') then
Options.Custom.Title = tag
Options.Custom.Value = 'ON'
end
end
function btnClose:action()
return iup.CLOSE
end
-- show form
dialog:map()
local size = Options.Specified.Size -- workaround to prevent font option shrinking!
GetOptions(Options) -- populate form with saved values
Options.Specified.Size = size
dialog:show()
iup.MainLoop()
SaveOptions(Options) -- save form configuration
dialog:destroy()
return tblSelection
end
-- ************************************************************************** --
function GetOptions(Options)
-- get options (system level)
local File = 'C:\\ProgramData\\Calico Pie\\Family Historian\\Plugin Data\\Rich Text Tabulation.ini.'
Options.None.Value = fhGetIniFileValue(File, 'Font', 'None', 'text', 'ON')
Options.Specified.Value = fhGetIniFileValue(File, 'Font', 'Specified', 'text', 'OFF')
Options.Specified.Title = fhGetIniFileValue(File, 'Font', 'Font', 'text',
iup.GetGlobal('DEFAULTFONTFACE'):match('^[^",]+'))
Options.Any.Value = fhGetIniFileValue(File, 'Font', 'Any', 'text', 'OFF')
Options.Tables.Value = fhGetIniFileValue(File, 'Other', 'Tables', 'text', 'OFF')
Options.Citations.Value = fhGetIniFileValue(File, 'Other', 'Citations', 'text', 'OFF')
Options.RecLinks.Value = fhGetIniFileValue(File, 'Other', 'RecLinks', 'text', 'OFF')
Options.ExtLinks.Value = fhGetIniFileValue(File, 'Other', 'ExtLinks', 'text', 'OFF')
Options.Custom.Title = fhGetIniFileValue(File, 'Custom', 'Tag', 'text', '')
Options.Custom.Value = fhGetIniFileValue(File, 'Custom', 'Value', 'text', 'OFF')
end
-- ************************************************************************** --
function SaveOptions(Options)
-- save options to disk (system level)
-- create options folder if necessary
local Folder = 'C:\\ProgramData\\Calico Pie\\Family Historian\\Plugin Data'
if not fhfu.folderExists(Folder) then
if not fhfu.createFolder(Folder) then return end
end
-- create and write to options file
local File = Folder .. '\\' .. 'Rich Text Tabulation.ini.'
fhSetIniFileValue(File, 'Font', 'None', 'text', Options.None.Value)
fhSetIniFileValue(File, 'Font', 'Specified', 'text', Options.Specified.Value)
fhSetIniFileValue(File, 'Font', 'Font', 'text', Options.Specified.Title)
fhSetIniFileValue(File, 'Font', 'Any', 'text', Options.Any.Value)
fhSetIniFileValue(File, 'Other', 'Tables', 'text', Options.Tables.Value)
fhSetIniFileValue(File, 'Other', 'Citations', 'text', Options.Citations.Value)
fhSetIniFileValue(File, 'Other', 'RecLinks', 'text', Options.RecLinks.Value)
fhSetIniFileValue(File, 'Other', 'ExtLinks', 'text', Options.ExtLinks.Value)
fhSetIniFileValue(File, 'Custom', 'Tag', 'text', Options.Custom.Title)
fhSetIniFileValue(File, 'Custom', 'Value', 'text', Options.Custom.Value)
end
-- ************************************************************************** --
function SelectFont()
local fontdlg = iup.fontdlg{title='Select Font (Font style, Size and Effects are discarded)'}
fontdlg:popup()
local font = fontdlg.Value
return font
end
-- ************************************************************************** --
function SelectField(rt, tblSelection)
-- returns true if field contains specified Rich Text
local ok = false
local tag = rt:GetText()
if tblSelection.Specified then
local font = tblSelection.Specified
if tag:match('') then ok = true end
end
if tblSelection.Any and tag:match('') then ok = true end
if tblSelection.Citations and tag:match('') then ok = true end
if tblSelection.Custom and tag:match(tblSelection.Custom) then ok = true end
return ok
end
-- ************************************************************************** --
main()
--[[
@Title: Rich Text Tabulation
@Type: Standard
@Author: Mark Draper
@Version: 1.0
@LastUpdated: 3 Jan 2023
@Licence: This plugin is copyright (c) 2023 Mark Draper and is licensed under the MIT License which
is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Tabulates project fields containing selected Rich Text elements.
]]
--[[
Version 0.1 - 19 Dec 2022
Original FHUG prototype
Version 1.0 - 3 Jan 2023
First Store version
]]
fhInitialise(7)
require('iuplua')
fh = require('fhUtils')
fhfu = require('fhFileUtils')
fh.setIupDefaults()
function main()
local p = fhNewItemPtr()
local pR = fhNewItemPtr()
local tblRecord = {}
local tblText = {}
-- present menu and capture selected options
local tblSelection = MenuOptions()
if tblSelection.End then return end
-- search all records in the project for Rich Text fields
local count = 0
for i = 1, fhGetRecordTypeCount() do
p:MoveToFirstRecord(fhGetRecordTypeTag(i))
while p:IsNotNull() do
if fhGetValueType(p) == 'richtext' then
local rt = fhGetValueAsRichText(p)
if rt:IsRich() then
count = count + 1
if tblSelection.All or SelectField(rt, tblSelection) then
pR:MoveToRecordItem(p)
table.insert(tblRecord, pR:Clone())
table.insert(tblText, p:Clone())
end
end
end
p:MoveNextSpecial()
end
end
if count == 0 then
fhMessageBox('This project does not use Rich Text', 'MB_OK', 'MB_ICONINFORMATION')
return
end
local message = ''
if not tblSelection.All then
message = #tblText .. ' fields containing selected features\n\n'
if #tblText == 1 then message = message:gsub('fields', 'field') end
end
if count == 1 then
message = message .. count .. ' Rich Text field in total'
else
message = message .. count .. ' Rich Text fields in total'
end
fhMessageBox(message, 'MB_OK', 'MB_ICONINFORMATION')
if #tblText > 0 then
fhOutputResultSetTitles('Rich Text')
fhOutputResultSetColumn('Record', 'item', tblRecord, #tblRecord)
fhOutputResultSetColumn('Rich Text', 'item', tblText, #tblText)
end
end
-- ************************************************************************** --
function MenuOptions()
-- create menu
local Options = {} -- toggles in table for easier management
local tblSelection = {}
tblSelection.End = true -- default if not changed
-- define font selection frame using long font name over 2 lines for max size
Options.None = iup.toggle{title = 'None', expand = 'YES'}
Options.Specified = iup.toggle{title = 'Matura MT Script\nCapitals', expand = 'YES'}
Options.Any = iup.toggle{title = 'Any', expand = 'YES'}
local btnSelect = iup.button{title = 'Select', padding = '10x3', tip = 'Select font to locate'}
local vboxFont = iup.vbox{Options.None, Options.Specified, Options.Any; gap = 5, margin = '0x0'}
local radio = iup.radio{vboxFont}
local vboxFS = iup.vbox{radio, btnSelect; gap = 10, margin = '10x10'}
local fraFS = iup.frame{vboxFS; title = 'Font Selection'}
-- define other features
Options.Tables = iup.toggle{title = 'Tables', expand = 'YES'}
Options.Citations = iup.toggle{title = 'Citations', expand = 'YES'}
Options.RecLinks = iup.toggle{title = 'Record Links', expand = 'YES'}
Options.ExtLinks = iup.toggle{title = 'External Links', expand = 'YES'}
local vboxOF = iup.vbox{Options.Tables, Options.Citations, Options.RecLinks, Options.ExtLinks;
gap = 10, margin = '10x10'}
local fraOF = iup.frame{vboxOF; title = 'Other Features'}
-- define custom tag
Options.Custom = iup.toggle{title = '', expand = 'YES'}
local btnDefine = iup.button{title = 'Define', padding = '10x3', tip = 'Define custom Rich Text tag'}
local vboxCF = iup.vbox{Options.Custom, btnDefine; gap = 10, margin = '10x10'}
local fraCF = iup.frame{vboxCF; title = 'Custom Tag'}
-- define main buttons
local btnOK = iup.button{title = 'OK',
tip = 'Locate all record fields containing at least one of the selected Rich Text features'}
local btnAll = iup.button{title = 'All Rich Text', padding = '5x3',
tip = 'Locate all record fields defined as Rich Text'}
local btnHelp = iup.button{title = 'Help', tip = 'Display Plugin Store Help page'}
local btnClose = iup.button{title = 'Close', tip = 'Close plugin'}
local Buttons = iup.hbox{btnOK, btnAll, btnHelp, btnClose; normalizesize = 'BOTH', gap = 25}
-- build form
local Title = iup.label{title = 'List fields containing at least one of the selected Rich Text features',
padding = '10x10'}
local hboxForm = iup.hbox{fraFS, fraOF, fraCF, normalizesize = 'BOTH'}
local vboxForm = iup.vbox{Title, hboxForm, Buttons; alignment = 'ACENTER', gap = 10; margin = '10x10'}
local dialog = iup.dialog{vboxForm; resize = 'NO', minbox = 'NO', maxbox = 'NO', border = 'NO',
title = 'Rich Text Tabulation'}
-- define callbacks
function btnSelect:action()
local fullfont = SelectFont() or ''
Options.Specified.Title = fullfont:match('^[^,]+') or Options.Specified.Title
Options.Specified.Value = 'YES'
Options.Specified.Size = size
end
function btnOK:action()
for k, v in pairs(Options) do
if v.Value == 'ON' then
tblSelection[k] = true
end
end
if Options.Specified.Value == 'ON' then
tblSelection.Specified = Options.Specified.Title
end
if Options.Custom.Value == 'ON' then
tblSelection.Custom = Options.Custom.Title
end
tblSelection.End = nil
return iup.CLOSE
end
function btnAll:action()
tblSelection.All = true
tblSelection.End = nil
return iup.CLOSE
end
function btnHelp:action()
local Cmd = 'https://pluginstore.family-historian.co.uk/page/help/rich-text-tabulation'
fhShellExecute(Cmd)
fhSleep(1000) -- slight pause to suspend immediate redraw
end
function btnDefine:action()
local tag = iup.GetText('Enter custom Rich Text tag', '')
if tag and tag:match('^<.+>$') and not tag:match('\n') then
Options.Custom.Title = tag
Options.Custom.Value = 'ON'
end
end
function btnClose:action()
return iup.CLOSE
end
-- show form
dialog:map()
local size = Options.Specified.Size -- workaround to prevent font option shrinking!
GetOptions(Options) -- populate form with saved values
Options.Specified.Size = size
dialog:show()
iup.MainLoop()
SaveOptions(Options) -- save form configuration
dialog:destroy()
return tblSelection
end
-- ************************************************************************** --
function GetOptions(Options)
-- get options (system level)
local File = 'C:\\ProgramData\\Calico Pie\\Family Historian\\Plugin Data\\Rich Text Tabulation.ini.'
Options.None.Value = fhGetIniFileValue(File, 'Font', 'None', 'text', 'ON')
Options.Specified.Value = fhGetIniFileValue(File, 'Font', 'Specified', 'text', 'OFF')
Options.Specified.Title = fhGetIniFileValue(File, 'Font', 'Font', 'text',
iup.GetGlobal('DEFAULTFONTFACE'):match('^[^",]+'))
Options.Any.Value = fhGetIniFileValue(File, 'Font', 'Any', 'text', 'OFF')
Options.Tables.Value = fhGetIniFileValue(File, 'Other', 'Tables', 'text', 'OFF')
Options.Citations.Value = fhGetIniFileValue(File, 'Other', 'Citations', 'text', 'OFF')
Options.RecLinks.Value = fhGetIniFileValue(File, 'Other', 'RecLinks', 'text', 'OFF')
Options.ExtLinks.Value = fhGetIniFileValue(File, 'Other', 'ExtLinks', 'text', 'OFF')
Options.Custom.Title = fhGetIniFileValue(File, 'Custom', 'Tag', 'text', '')
Options.Custom.Value = fhGetIniFileValue(File, 'Custom', 'Value', 'text', 'OFF')
end
-- ************************************************************************** --
function SaveOptions(Options)
-- save options to disk (system level)
-- create options folder if necessary
local Folder = 'C:\\ProgramData\\Calico Pie\\Family Historian\\Plugin Data'
if not fhfu.folderExists(Folder) then
if not fhfu.createFolder(Folder) then return end
end
-- create and write to options file
local File = Folder .. '\\' .. 'Rich Text Tabulation.ini.'
fhSetIniFileValue(File, 'Font', 'None', 'text', Options.None.Value)
fhSetIniFileValue(File, 'Font', 'Specified', 'text', Options.Specified.Value)
fhSetIniFileValue(File, 'Font', 'Font', 'text', Options.Specified.Title)
fhSetIniFileValue(File, 'Font', 'Any', 'text', Options.Any.Value)
fhSetIniFileValue(File, 'Other', 'Tables', 'text', Options.Tables.Value)
fhSetIniFileValue(File, 'Other', 'Citations', 'text', Options.Citations.Value)
fhSetIniFileValue(File, 'Other', 'RecLinks', 'text', Options.RecLinks.Value)
fhSetIniFileValue(File, 'Other', 'ExtLinks', 'text', Options.ExtLinks.Value)
fhSetIniFileValue(File, 'Custom', 'Tag', 'text', Options.Custom.Title)
fhSetIniFileValue(File, 'Custom', 'Value', 'text', Options.Custom.Value)
end
-- ************************************************************************** --
function SelectFont()
local fontdlg = iup.fontdlg{title='Select Font (Font style, Size and Effects are discarded)'}
fontdlg:popup()
local font = fontdlg.Value
return font
end
-- ************************************************************************** --
function SelectField(rt, tblSelection)
-- returns true if field contains specified Rich Text
local ok = false
local tag = rt:GetText()
if tblSelection.Specified then
local font = tblSelection.Specified
if tag:match('') then ok = true end
end
if tblSelection.Any and tag:match('') then ok = true end
if tblSelection.Citations and tag:match('') then ok = true end
if tblSelection.Custom and tag:match(tblSelection.Custom) then ok = true end
return ok
end
-- ************************************************************************** --
main()
Source:Rich-Text-Tabulation.fh_lua