It is often desirable to preserve user optional settings between successive runs of a plugin. These ‘sticky’ settings may include the plugin window position and size, default input/output folder, filter options, etc.
Some users run Family Historian on more than one PC and synchronize files across the PC. To support these users, some ‘sticky’ settings, such as window position or default folder, may need to be local to each PC, whereas others need to be global. The local settings are associated with the system ComputerName.
Both the ƒh Version 4 Project structure and Version 3 standalone GEDCOM mode are supported.
This code also illustrates a coding style where:
* global names start with an upper-case letter, e.g. IntOption, StrFolder, DoLoadSettings()
* local names start with a lower-case letter, e.g. tblField, strPublic, strLoadLocal()
* names of data, and functions that return values start with a data type mnemonic:
* Flg or flg for booleans, or alternatively Is or is sometimes works well, e.g. isValidData
* Int or int for integers
* Str or str for strings
* Tbl or tbl for tables
* etc.
Requires: iuplua and lfs and Code Snippets File Exists and Split a Line using a Separator, and Split a String into Numbers using Separators.
Code
-
require "iuplua" -- To access GUI window builder require "lfs" -- To access LUA filing system -- Global Data Contants Definition -- function DoGlobalConstants() StrPlugin = "Plugin Title" -- Plugin title & version StrIssue = " V1.1 " -- Filename Global Constants StrComputerName = os.getenv("COMPUTERNAME") StrStickyFile = fhGetPluginDataFileName() -- Allow plugins with variant filenames to use same plugin data files StrStickyFile = string.gsub(StrStickyFile,"\\"..StrPlugin..".+%.[D,d][A,a][T,t]$","\\"..StrPlugin..".dat") if StrStickyFile == "" then -- Use standalone GEDCOM path & filename..".fh_data\Plugin Data\" as the folder + the Plugin Filename..".dat" StrStickyFile = fhGetContextInfo("CI_GEDCOM_FILE") StrStickyFile = string.gsub(StrStickyFile, "%.[G,g][E,e][D,d]", ".fh_data") lfs.mkdir(StrStickyFile) StrStickyFile = StrStickyFile.."\\Plugin Data" lfs.mkdir(StrStickyFile) StrStickyFile = StrStickyFile.."\\"..StrPlugin..".dat" end -- Plugin data folder path name StrPluginPath = string.gsub(StrStickyFile,"\\"..StrPlugin.."%.[D,d][A,a][T,t]$","") -- other global constants for other purposes may be preset here end -- function DoGlobalConstants -- Reset Sticky Settings to Default Values -- function DoDefaultSettings() IntMainX = iup.CENTER -- GUI Main window position X & Y co-ordinate IntMainY = iup.CENTER IntHelpX = iup.CENTER -- GUI Help window position X & Y co-ordinate IntHelpY = iup.CENTER local strPublic = fhGetContextInfo("CI_PROJECT_PUBLIC_FOLDER") if strPublic == "" then StrFolder = StrPluginPath -- Output folder for standalone Gedcom else StrFolder = strPublic -- Output folder for Project structure end IntOption = 1 -- other option default values should be set here end -- function DoDefaultSettings -- Load Sticky Settings from File -- function DoLoadSettings(strFileName) local tblStickyData = {} -- Load Local Parameter for this PC -- local function strLoadLocal(strParam,strDefault) return tblStickyData[StrComputerName.."-"..strParam] or strDefault end -- Load Global Parameter for all PC -- local function strLoadGlobal(strParam,strDefault) return tblStickyData[strParam] or strDefault end -- Ensure Window Position is on Screen -- local function intintCheckPosition(x,y) local tblScrn = iup.GetGlobal("VIRTUALSCREEN"):SplitNumbers() -- tblScrn[1] = origin x, tblScrn[2] = origin y, tblScrn[3] = width, tblScrn[4] = height if tonumber(x) == nil then x = iup.CENTER elseif tonumber(x) > tblScrn[3] then x = iup.CENTER end if tonumber(y) == nil then y = iup.CENTER elseif tonumber(y) > tblScrn[4] then y = iup.CENTER end return tonumber(x),tonumber(y) end -- local function intintCheckPosition if FileExists(strFileName) then -- Load Settings File in table lines with key & val fields local tblField = {} for strLine in io.lines(strFileName) do tblField = strLine:split("=") tblStickyData[tblField[1]] = tblField[2] end IntMainX = tonumber(strLoadLocal("MainX",IntMainX)) IntMainY = tonumber(strLoadLocal("MainY",IntMainY)) IntHelpX = tonumber(strLoadLocal("HelpX",IntHelpX)) IntHelpY = tonumber(strLoadLocal("HelpY",IntHelpY)) StrFolder = strLoadLocal("Folder",StrFolder) IntOption = tonumber(strLoadGlobal("Option",IntOption)) -- other option default values should be loaded here end IntMainX,IntMainY = intintCheckPosition(IntMainX,IntMainY) IntHelpX,IntHelpY = intintCheckPosition(IntHelpX,IntHelpY) end -- function DoLoadSettings -- Save Sticky Settings to File -- function DoSaveSettings(strFileName) local tblStickyData = {} -- Save Local Parameter for this PC -- local function doSaveLocal(strParam,param) tblStickyData[StrComputerName.."-"..strParam] = param end -- Save Global Parameter for all PC -- local function doSaveGlobal(strParam,param) tblStickyData[strParam] = param end doSaveLocal("MainX",IntMainX) doSaveLocal("MainY",IntMainY) doSaveLocal("HelpX",IntHelpX) doSaveLocal("HelpY",IntHelpY) doSaveLocal("Folder",StrFolder) doSaveGlobal("Option",IntOption) -- other option default values should be saved here local fileHandle, strError = io.open(strFileName,”w”) for strKey,strVal in pairs(tblStickyData) do fileHandle:write(strKey.."="..strVal.."\n") end fileHandle:close() end -- function DoSaveSettings
Usage
-
require "iuplua" -- To access GUI window builder require "lfs" -- To access LUA filing system DoGlobalConstants() -- Preset global data constants DoDefaultSettings() -- Preset default sticky settings DoLoadSettings(StrStickyFile) -- Load sticky data settings -- invoke main plugin functions here DoSaveSettings(StrStickyFile) -- Save sticky data settings