193 lines
5.9 KiB
Tcl
193 lines
5.9 KiB
Tcl
#!/usr/bin/env tclsh
|
|
package require Tk
|
|
package require json
|
|
package require json::write
|
|
package require inifile
|
|
|
|
# overall vars
|
|
set appdir [ file dirname [ file normalize [ info script ] ] ]
|
|
# check if we're running from a starpack
|
|
if [string match *app-conf $appdir] {
|
|
set appdir [ file normalize [ file join $appdir ".." ".." ".." ] ]
|
|
}
|
|
puts "Working directory: $appdir"
|
|
|
|
set conffile [ file join $appdir "config.json" ]
|
|
set labelfile [ file join $appdir "labels.ini" ]
|
|
|
|
# main configuration read/write procedures
|
|
|
|
proc readrawjson {fname} {
|
|
# read the JSON contents
|
|
set fp [open $fname r]
|
|
set rawdata [read $fp]
|
|
close $fp
|
|
# parse the JSON contents
|
|
set confdict [::json::json2dict $rawdata]
|
|
return $confdict
|
|
}
|
|
|
|
proc readjson {fname} {
|
|
set confdict [readrawjson $fname]
|
|
# update the controls according to the configuration
|
|
dict for {vname vval} $confdict {
|
|
global conf_$vname
|
|
set conf_$vname $vval
|
|
}
|
|
return $confdict
|
|
}
|
|
|
|
proc dict2json {dictToEncode} {
|
|
::json::write object {*}[dict map {k v} $dictToEncode {
|
|
if [string is boolean -strict $v] {
|
|
set v $v
|
|
} elseif [string is integer -strict $v] {
|
|
set v $v
|
|
} else {
|
|
set v [::json::write string $v]
|
|
}
|
|
}]
|
|
}
|
|
|
|
proc writejson {fname} {
|
|
set confdict [readrawjson $fname]
|
|
dict for {vname vval} $confdict {
|
|
global conf_$vname
|
|
dict set confdict $vname [set conf_$vname]
|
|
}
|
|
set fdata [dict2json $confdict]
|
|
set fp [open $fname w]
|
|
puts $fp $fdata
|
|
close $fp
|
|
}
|
|
|
|
# dialog button helpers
|
|
|
|
proc rereadconfig {fname msg} {
|
|
set answer [tk_messageBox -message $msg -icon question -type yesno]
|
|
switch -- $answer {
|
|
yes {readjson $fname}
|
|
no {}
|
|
}
|
|
}
|
|
|
|
proc saveconfig {fname msg} {
|
|
set answer [tk_messageBox -message $msg -icon question -type yesno]
|
|
switch -- $answer {
|
|
yes {writejson $fname}
|
|
no {}
|
|
}
|
|
}
|
|
|
|
proc exitapp {fname msg} {
|
|
saveconfig $fname $msg
|
|
exit
|
|
}
|
|
|
|
# read GUI labels ini file
|
|
set lbls [::ini::open $labelfile r]
|
|
set backends [::ini::value $lbls general backends]
|
|
|
|
# overall provider tab layout
|
|
ttk::notebook .prov
|
|
foreach back $backends {
|
|
set framename .prov.$back
|
|
set tabname [::ini::value $lbls config.gui.$back tabtitle]
|
|
ttk::frame $framename
|
|
.prov add $framename -text $tabname
|
|
}
|
|
|
|
# General controls (need to be hardcoded)
|
|
|
|
set dbglbl [::ini::value $lbls config.gui.general debug]
|
|
set iplbl [::ini::value $lbls config.gui.general server_listen_ip]
|
|
set portlbl [::ini::value $lbls config.gui.general server_port]
|
|
set ualbl [::ini::value $lbls config.gui.general useragent]
|
|
ttk::checkbutton .prov.general.debugchk -text $dbglbl -variable conf_debug -onvalue true -offvalue false
|
|
ttk::label .prov.general.serviplbl -text $iplbl
|
|
ttk::entry .prov.general.serviptxt -textvariable conf_server_listen_ip -width 16
|
|
ttk::label .prov.general.servportlbl -text $portlbl
|
|
ttk::entry .prov.general.servporttxt -textvariable conf_server_port -width 5
|
|
ttk::label .prov.general.ualbl -text $ualbl
|
|
ttk::entry .prov.general.uatxt -textvariable conf_useragent -width 60
|
|
|
|
grid .prov.general.debugchk -column 0 -row 0 -sticky ne -ipadx 5 -ipady 5
|
|
grid .prov.general.serviplbl -column 1 -row 0 -sticky ne -ipadx 5 -ipady 5
|
|
grid .prov.general.serviptxt -column 2 -row 0 -sticky ew -padx 5 -pady 5
|
|
grid .prov.general.servportlbl -column 3 -row 0 -sticky ne -ipadx 5 -ipady 5
|
|
grid .prov.general.servporttxt -column 4 -row 0 -sticky ew -padx 5 -pady 5
|
|
grid .prov.general.ualbl -column 0 -row 2 -sticky ne -ipadx 5 -ipady 5
|
|
grid .prov.general.uatxt -column 1 -row 2 -sticky ew -columnspan 4 -padx 5 -pady 5
|
|
|
|
# backend config controls
|
|
|
|
foreach back $backends {
|
|
if {$back ne "general"} {
|
|
set section config.gui.$back
|
|
set params [::ini::keys $lbls $section]
|
|
set rowidx 1
|
|
foreach key $params {
|
|
if {$key ne "tabtitle"} {
|
|
set lbltext [::ini::value $lbls $section $key]
|
|
set cvarname [string cat conf_ $key]
|
|
set guiname .prov.$back.$key
|
|
if {$key eq [string cat $back _backend_enabled]} {
|
|
set chkname [string cat $guiname chk]
|
|
ttk::checkbutton $chkname -text $lbltext \
|
|
-variable $cvarname -onvalue true -offvalue false
|
|
grid $chkname -column 0 -row 0 -sticky ne -ipadx 5 -ipady 5
|
|
} else {
|
|
set ewidth 40
|
|
set lblname [string cat $guiname lbl]
|
|
set txtname [string cat $guiname txt]
|
|
ttk::label $lblname -text $lbltext
|
|
ttk::entry $txtname -textvariable $cvarname -width $ewidth
|
|
grid $lblname -column 0 -row $rowidx -sticky ne -ipadx 5 -ipady 5
|
|
grid $txtname -column 1 -row $rowidx -sticky ew -padx 5 -pady 5
|
|
}
|
|
incr rowidx
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# lower button row
|
|
foreach lname {reset exit save credits savemodal resetmodal} {
|
|
set vname [string cat $lname lbl]
|
|
set $vname [::ini::value $lbls config.gui.general $lname]
|
|
}
|
|
ttk::frame .btns -padding 4
|
|
ttk::button .btns.reset -text $resetlbl -command {rereadconfig $conffile $resetmodallbl}
|
|
ttk::button .btns.exit -text $exitlbl -command {exitapp $conffile $savemodallbl}
|
|
ttk::button .btns.save -text $savelbl -command {saveconfig $conffile $savemodallbl}
|
|
ttk::label .btns.lbl -text $creditslbl
|
|
pack .btns.save -side right -padx 3 -pady 3
|
|
pack .btns.exit -side right -padx 3 -pady 3
|
|
pack .btns.reset -side right -padx 3 -pady 3
|
|
pack .btns.lbl -side left -padx 3 -pady 3
|
|
|
|
# place the tabs and buttons
|
|
grid .prov -column 0 -row 0 -sticky nsew
|
|
grid .btns -column 0 -row 1 -sticky sew
|
|
|
|
# root grid geometry: don't resize the button row
|
|
grid columnconfigure . 0 -weight 1
|
|
grid rowconfigure . 0 -weight 1
|
|
grid rowconfigure . 1 -weight 0
|
|
|
|
# iterate over available platform-dependent themes, apply "clam" if none found
|
|
ttk::style theme use clam
|
|
catch {ttk::style theme use gtkTtk}
|
|
catch {ttk::style theme use aqua}
|
|
catch {ttk::style theme use winnative}
|
|
catch {ttk::style theme use vista}
|
|
|
|
wm title . "StreamGoose config"
|
|
catch {wm title . [::ini::value $lbls config.gui.general windowtitle]}
|
|
|
|
# stop working with the labels file
|
|
::ini::close $lbls
|
|
|
|
# read the initial config
|
|
readjson $conffile
|