306 lines
7.5 KiB
Plaintext
306 lines
7.5 KiB
Plaintext
|
|
||
|
---------------------
|
||
|
namespace settings -- functions to read and write config files (*.ini);
|
||
|
---------------------
|
||
|
|
||
|
export constant version = "4.12.0"
|
||
|
|
||
|
--# EXPORTS
|
||
|
/*
|
||
|
--functions:
|
||
|
settings:Save()
|
||
|
settings:Load()
|
||
|
settings:Add()
|
||
|
|
||
|
-- debug:
|
||
|
-d SETTINGS
|
||
|
*/
|
||
|
|
||
|
include GtkEngine.e
|
||
|
|
||
|
if not equal(version,gtk:version) then
|
||
|
Error(,,"GtkSettings version mismatch","should be version " & gtk:version)
|
||
|
end if
|
||
|
|
||
|
constant fmt = """[].[]=[]"""
|
||
|
|
||
|
------------------------------------------------------------------------
|
||
|
export function Save(sequence inifile, object ctl_list, integer debug=0)
|
||
|
------------------------------------------------------------------------
|
||
|
-- writes an 'ini' type file (file name and extension are up to you)
|
||
|
-- with an entry for each control on ctl_list. The controls MUST have
|
||
|
-- been named, otherwise there's no way to save and retrieve the
|
||
|
-- value/setting for that control.
|
||
|
------------------------------------------------------------------------
|
||
|
object comments = {}
|
||
|
object txt,line
|
||
|
|
||
|
if file_exists(inifile) then
|
||
|
|
||
|
txt = read_lines(inifile)
|
||
|
for i = 1 to length(txt) do -- extract the comments;
|
||
|
line = txt[i]
|
||
|
if match("--",line) = 1
|
||
|
or match("!",line) = 1
|
||
|
or match("+",line) = 1
|
||
|
or equal("\n",line)
|
||
|
or equal({},line) then
|
||
|
comments = append(comments,line)
|
||
|
end if
|
||
|
end for
|
||
|
write_lines(inifile,comments) -- removing everything but the comments;
|
||
|
end if -- file exists
|
||
|
|
||
|
object setting, tmp = 0, pos = {0,0}
|
||
|
object t1, name, prop
|
||
|
atom handle
|
||
|
integer class
|
||
|
|
||
|
atom fn = open(inifile,"a")
|
||
|
|
||
|
for x = 1 to length(ctl_list) do
|
||
|
|
||
|
if string(ctl_list[x]) then
|
||
|
handle = pointer(ctl_list[x])
|
||
|
else
|
||
|
handle = ctl_list[x]
|
||
|
end if
|
||
|
|
||
|
name = get(handle,"name")
|
||
|
class = class_id(handle)
|
||
|
|
||
|
if class=GtkWindow then -- special handling for multiple properties;
|
||
|
printf(fn,"%s\n",{get_setting(handle,"size")})
|
||
|
pos = get(handle,"position")
|
||
|
printf(fn,"%s.position={%d,%d}\n",{name,pos[1],pos[2]})
|
||
|
|
||
|
else
|
||
|
setting = get_setting(handle) -- others have 1 obvious 'saveable' property
|
||
|
if length(setting) < 1 then
|
||
|
continue
|
||
|
end if
|
||
|
|
||
|
if sequence(setting) then
|
||
|
printf(fn,"%s\n",{setting})
|
||
|
end if
|
||
|
end if
|
||
|
end for
|
||
|
|
||
|
flush(fn)
|
||
|
close(fn)
|
||
|
|
||
|
-- if ! exists for this control:property, then ignore the updated setting;
|
||
|
tmp = read_lines(inifile)
|
||
|
for i = 1 to length(tmp) do
|
||
|
if match("--!",tmp[i]) = 1 then
|
||
|
t1 = split(tmp[i],"=")
|
||
|
t1 = t1[1][2..$]
|
||
|
end if
|
||
|
end for
|
||
|
|
||
|
write_lines(inifile,tmp)
|
||
|
|
||
|
return 1
|
||
|
end function
|
||
|
|
||
|
------------------------------------------------------------------------
|
||
|
export function Load(sequence inifile, integer debug=0)
|
||
|
------------------------------------------------------------------------
|
||
|
-- used to restore settings from the specified ini file.
|
||
|
-- this should be called after the controls are 'realized'
|
||
|
|
||
|
object txt, line, obj, prop, val1=0, val2=0, val3=0, val4=0
|
||
|
|
||
|
if not(file_exists(inifile)) then
|
||
|
write_file(inifile,sprintf("--%s\n\n",{inifile}),TEXT_MODE)
|
||
|
display("Creating ini file: []",{inifile})
|
||
|
else
|
||
|
if debug then display("Reading []",{inifile}) end if
|
||
|
end if
|
||
|
|
||
|
txt = read_lines(inifile)
|
||
|
|
||
|
integer err=0
|
||
|
object a,b
|
||
|
|
||
|
for i = 1 to length(txt) do
|
||
|
|
||
|
line = txt[i]
|
||
|
|
||
|
if match("--",line) > 2 then -- strip trailing comments;
|
||
|
line = line[1..match("--",line)-2]
|
||
|
end if
|
||
|
|
||
|
if match("--!",line) = 1 then
|
||
|
line = line[4..$] -- keep it
|
||
|
end if
|
||
|
|
||
|
if match("+",line) = 1 or match("!",line) then
|
||
|
line = line[2..$] -- dito
|
||
|
end if
|
||
|
|
||
|
if match("--",line) or match(";",line)
|
||
|
or match("/*",line) then
|
||
|
continue -- a comment, do nothing with it
|
||
|
end if
|
||
|
|
||
|
if length(line) > 0 then
|
||
|
line = split(line,'=')
|
||
|
a = line[1] b = line[2]
|
||
|
a = split(a,'.')
|
||
|
line = a & {b}
|
||
|
|
||
|
if debug > 1 then display(line) end if
|
||
|
|
||
|
if vlookup(line[1],registry,4,1,-1) = -1 then
|
||
|
err = i
|
||
|
Error(,"Ini Load Error",
|
||
|
sprintf("Invalid object name: %s",{line[1]}),
|
||
|
sprintf("Line #%d of %s",{i,filename(inifile)}))
|
||
|
else
|
||
|
if equal("data",line[2]) then
|
||
|
set(line[1],"data",line[3],line[4])
|
||
|
else
|
||
|
set(line[1],line[2],line[3])
|
||
|
end if
|
||
|
end if
|
||
|
end if
|
||
|
end for
|
||
|
|
||
|
if debug = 1 then
|
||
|
for i = 1 to length(txt) do
|
||
|
if i = err then
|
||
|
display("ERROR:[:3]:[]",{i,txt[i]})
|
||
|
else
|
||
|
display("[:3]:[]",{i,txt[i]})
|
||
|
end if
|
||
|
end for
|
||
|
end if
|
||
|
|
||
|
write_lines(inifile,txt)
|
||
|
|
||
|
return 1
|
||
|
end function
|
||
|
|
||
|
-------------------------------------------------------------------------------------------
|
||
|
export function Add(object ini,object ctl, sequence prop, object v1=0, object v2=0)
|
||
|
-------------------------------------------------------------------------------------------
|
||
|
if atom(ctl) then ctl = get(ctl,"name") end if
|
||
|
|
||
|
Delete(ini,ctl,prop)
|
||
|
|
||
|
if equal("position",prop) or equal("size",prop) then
|
||
|
if string(v1) then v2 = v1[2] v1 = v1[1] end if
|
||
|
end if
|
||
|
|
||
|
if atom(v2) and v2=0 then
|
||
|
writefln("+[].[]=[]",{ctl,prop,v1},{ini,"a"})
|
||
|
else
|
||
|
writefln("+[].[]={[],[]}",{ctl,prop,v1,v2},{ini,"a"})
|
||
|
end if
|
||
|
|
||
|
return 1
|
||
|
end function
|
||
|
|
||
|
--------------------------------------------------------------------
|
||
|
export function Delete(object ini,object ctl, sequence prop)
|
||
|
--------------------------------------------------------------------
|
||
|
if atom(ctl) then ctl = get(ctl,"name") end if
|
||
|
object tmp = read_lines(ini)
|
||
|
object out = {}
|
||
|
object s1 = text:format("[].[]",{ctl,prop})
|
||
|
for i = 1 to length(tmp) do
|
||
|
if match(s1,tmp[i]) then -- skip
|
||
|
else out &= {tmp[i]}
|
||
|
end if
|
||
|
end for
|
||
|
write_lines(ini,out)
|
||
|
return 1
|
||
|
end function
|
||
|
|
||
|
---------------------------------------------------------------------------------
|
||
|
function get_setting(object self, object property = 0)
|
||
|
-- returns the 'important' value from a control
|
||
|
---------------------------------------------------------------------------------
|
||
|
-- returns settings string
|
||
|
-- object must be a named object, e.g. MyButton
|
||
|
|
||
|
-- MyButton.active=1
|
||
|
-- My Calendar.date={YYYY,MM,DD}
|
||
|
|
||
|
object name = 0
|
||
|
object dt
|
||
|
|
||
|
if string(self) then
|
||
|
name = self
|
||
|
self = vlookup(self,registry,4,1)
|
||
|
end if
|
||
|
|
||
|
object val = 0
|
||
|
object txt = {}
|
||
|
|
||
|
integer x = find(self,vslice(registry,1))
|
||
|
|
||
|
ifdef SETTINGS then
|
||
|
display("SELF [] []",{x,self})
|
||
|
display(registry[x])
|
||
|
end ifdef
|
||
|
|
||
|
switch class_id(self) do
|
||
|
-- this decides which value is the important one to save;
|
||
|
-- and stores the control's current value into the registry;
|
||
|
|
||
|
case GtkEntry,GtkEntryBuffer then property = "text"
|
||
|
|
||
|
case GtkCheckButton,GtkRadioButton, GtkToggleButton,
|
||
|
GtkSwitch,GtkComboBox,GtkComboBoxText,
|
||
|
GtkCheckMenuItem,GtkToggleToolButton, GtkSearchEntry
|
||
|
then property = "active"
|
||
|
|
||
|
case GtkPopover then property = "position"
|
||
|
|
||
|
case GtkFontButton then property = "font name"
|
||
|
|
||
|
case GtkAdjustment,GtkSpinButton,GtkScaleButton,GtkVolumeButton,
|
||
|
GtkModelButton,GtkScale
|
||
|
then property = "value"
|
||
|
|
||
|
case GtkEntryCompletion then property = "model"
|
||
|
|
||
|
case GtkLinkButton then property = "uri"
|
||
|
|
||
|
case GtkMenuItem then property = "sensitive"
|
||
|
|
||
|
case GtkPaned then property = "position"
|
||
|
|
||
|
case GtkFileChooser, GtkFileChooserButton, GtkFileChooserWidget, GtkFileChooserDialog
|
||
|
then property = "filename"
|
||
|
|
||
|
case GtkFontChooser, GtkFontChooserWidget, GtkFontChooserDialog then
|
||
|
property = "font"
|
||
|
|
||
|
case GtkCalendar then
|
||
|
dt = get(self,"datetime",0)
|
||
|
registry[x][5] = {"date",dt[1..3]}
|
||
|
txt &= text:format(fmt,{registry[x][4],"date",dt[1..3]})
|
||
|
return txt
|
||
|
|
||
|
case GtkColorButton,GtkColorChooser,GtkColorChooserWidget,
|
||
|
GtkColorChooserDialog then
|
||
|
registry[x][5] = {"rgba",get(self,"rgba",1)}
|
||
|
txt &= text:format(fmt,{registry[x][4],"rgba",get(self,"rgba",1)})
|
||
|
return txt
|
||
|
|
||
|
end switch
|
||
|
|
||
|
if atom(property) then
|
||
|
return txt
|
||
|
end if
|
||
|
|
||
|
val = get(self,property)
|
||
|
registry[x][5] = {property,val}
|
||
|
txt &= text:format(fmt,{registry[x][4],property,val})
|
||
|
|
||
|
return txt
|
||
|
end function
|