# # Copyright 2010-2013 the Boeing Company. # See the LICENSE file included in this distribution. # # author: Jeff Ahrenholz # # GUI support for managing CORE node services. # # # Popup a services configuration dialog box. Similar to popupCapabilityConfig # but customized for configuring node services. This dialog has two uses: # (1) selecting the default services for a node type (when session != ""), and # (2) selecting/customizing services for a certain node # proc popupServicesConfig { channel node types values captions possible_values groups session } { global plugin_img_edit global g_service_ctls global g_sent_nodelink_definitions set wi .popupServicesConfig catch {destroy $wi} toplevel $wi # instead of using vals, the activated services are stored in this list set activated "" if { $session != "" } { global g_node_type_services_hint if { ![info exists g_node_type_services_hint] } { set g_node_type_services_hint "router" } set title "Default services" set toptitle "Default services for node type $g_node_type_services_hint" set activated [getNodeTypeServices $g_node_type_services_hint] set parent .nodesConfig } else { set title "Node [getNodeName $node] ($node) services" set toptitle $title set activated [getNodeServices $node true] set parent .popup } if { ![winfo exists $parent] } { set parent "." } wm title $wi $title wm transient $wi $parent label $wi.top -text $toptitle pack $wi.top -side top -padx 4 -pady 4 frame $wi.vals -relief raised -borderwidth 1 set g_sent_nodelink_definitions 0 ;# only send node/link defs once set g_service_ctls {} ;# list of checkboxes set n 0 set gn 0 set lastgn -1 foreach type $types { # group values into frames based on groups TLV set groupinfo [popupCapabilityConfigGroup $groups [expr {$n + 1}]] set gn [lindex $groupinfo 0] set groupcaption [lindex $groupinfo 1] if { $lastgn != $gn } { labelframe $wi.vals.$gn -text $groupcaption \ -borderwidth 1 -padx 4 -pady 4 } frame $wi.vals.$gn.item$n if {$type != 11} { ;# boolean value puts "warning: skipping service config [lindex $captions $n]" incr n continue } set servicename [lindex $captions $n] global $wi.vals.$gn.item$n.entval checkbutton $wi.vals.$gn.item$n.ent -width 12 -wraplength 90 \ -variable $wi.vals.$gn.item$n.entval -text $servicename \ -offrelief flat -indicatoron false -overrelief raised lappend g_service_ctls $wi.vals.$gn.item$n.ent if { [lsearch -exact $activated [lindex $captions $n]] == -1 } { set value 0 ;# not in the activated list } else { set value 1 } set $wi.vals.$gn.item$n.entval $value if { $session == "" } { set needcustom false if { $n < [llength $possible_values] } { if { [lindex $possible_values $n] == 1 } { set needcustom true } } set btn $wi.vals.$gn.item$n.custom button $btn -image $plugin_img_edit \ -command "customizeService $wi $node $servicename $btn" setCustomButtonColor $btn $node $servicename $needcustom pack $wi.vals.$gn.item$n.custom -side right -padx 4 -pady 4 # this causes the button for services that require customization to # turn yellow when the service is selected $wi.vals.$gn.item$n.ent configure -command \ "setCustomButtonColor $btn $node $servicename $needcustom" } pack $wi.vals.$gn.item$n.ent -side right -padx 4 -pady 4 pack $wi.vals.$gn.item$n -side top -anchor e if { $lastgn != $gn } { pack $wi.vals.$gn -side left -anchor n -fill both set lastgn $gn } incr n }; # end foreach pack $wi.vals.$gn -side left -anchor n -fill both pack $wi.vals -side top -padx 4 -pady 4 # Apply / Cancel buttons set apply_cmd "popupServicesConfigApply $wi $channel $node {$session}" set cancel_cmd "destroy $wi" frame $wi.btn button $wi.btn.apply -text "Apply" -command $apply_cmd button $wi.btn.def -text "Defaults" -command \ "popupServicesConfigDefaults $wi $node {$types} {$captions} {$groups}" button $wi.btn.cancel -text "Cancel" -command $cancel_cmd set buttons [list $wi.btn.apply $wi.btn.cancel] if { $session == "" } { set buttons [linsert $buttons 1 $wi.btn.def] } foreach b $buttons { pack $b -side left -padx 4 -pady 4 } pack $wi.btn -side bottom bind $wi $apply_cmd bind $wi $cancel_cmd } # # Save the selection of activated services with the node or in the g_node_types # array when configuring node type defaults. # proc popupServicesConfigApply { wi channel node session } { set vals [getSelectedServices] # save default services for a node type into the g_node_types array if { $session != "" } { global g_node_types g_node_type_services_hint set type $g_node_type_services_hint set idx [getNodeTypeIndex $type] if { $idx < 0 } { puts "warning: skipping unknown node type $type" } else { set typedata $g_node_types($idx) set typedata [lreplace $typedata 3 3 $vals] array set g_node_types [list $idx $typedata] } # save the services configured for a specific node } else { setNodeServices $node $vals } destroy $wi } # load the default set of services for this node type proc popupServicesConfigDefaults { wi node types captions groups } { set type [getNodeModel $node] set defaults [getNodeTypeServices $type] for { set n 0 } { $n < [llength $types] } { incr n } { set groupinfo [popupCapabilityConfigGroup $groups [expr {$n + 1}]] set gn [lindex $groupinfo 0] set val 0 set valname [lindex $captions $n] if { [lsearch $defaults $valname] != -1 } { set val 1 } global $wi.vals.$gn.item$n.entval set $wi.vals.$gn.item$n.entval $val } } # # Popup a service customization dialog for a given service on a node # The customize/edit button next to a service has been pressed # proc customizeService { wi node service btn } { global g_sent_nodelink_definitions global plugin_img_add plugin_img_del plugin_img_folder global plugin_img_open plugin_img_save global eventtypes set selected [getSelectedServices] # if service is not enabled, enable it here if { [lsearch -exact $selected $service] == -1 } { set i [string last ".custom" $btn] set entval [string replace $btn $i end ".entval"] global $entval set $entval 1 lappend selected $service } # inform the CORE services about all nodes and links, so it can build # custom configurations for services if { $g_sent_nodelink_definitions == 0 } { set g_sent_nodelink_definitions 1 set sock [lindex [getEmulPlugin $node] 2] sendEventMessage $sock $eventtypes(definition_state) -1 "" "" 0 sendNodeLinkDefinitions $sock } set w .popupServicesCustomize catch {destroy $w} toplevel $w wm transient $w .popupServicesConfig wm title $w "$service on node [getNodeName $node] ($node)" ttk::frame $w.top ttk::label $w.top.lab -text "$service service" ttk::frame $w.top.meta ttk::label $w.top.meta.lab -text "Meta-data" ttk::entry $w.top.meta.ent -width 40 pack $w.top.lab -side top pack $w.top.meta.lab -side left -padx 4 -pady 4 pack $w.top.meta.ent -fill x -side left -padx 4 -pady 4 pack $w.top.meta -side top pack $w.top -side top -padx 4 -pady 4 ttk::notebook $w.note pack $w.note -fill both -expand true -padx 4 -pady 4 ttk::notebook::enableTraversal $w.note set enableapplycmd "$w.btn.apply configure -state normal" ### Custom ### # services may define custom popup configuration dialogs invoked here set custom_popup "popupServiceConfig_$service" if { [info commands $custom_popup] == $custom_popup } { $custom_popup $wi $w $node $service $btn } ### Files ### ttk::frame $w.note.files set fileshelp "Config files and scripts that are generated for this" set fileshelp "$fileshelp service." ttk::label $w.note.files.help -text $fileshelp pack $w.note.files.help -side top -anchor w -padx 4 -pady 4 $w.note add $w.note.files -text "Files" -underline 0 ttk::frame $w.note.files.name ttk::label $w.note.files.name.lab -text "File name:" set combo $w.note.files.name.combo ttk::combobox $combo -width 30 set helpercmd "customizeServiceFileHelper $w" ttk::button $w.note.files.name.add -image $plugin_img_add \ -command "listboxAddDelHelper add $combo $combo true; $helpercmd false" ttk::button $w.note.files.name.del -image $plugin_img_del \ -command "listboxAddDelHelper del $combo $combo true; $helpercmd true" pack $w.note.files.name.lab -side left pack $w.note.files.name.combo -side left -fill x -expand true foreach c [list add del] { pack $w.note.files.name.$c -side left } pack $w.note.files.name -side top -anchor w -padx 4 -pady 4 -fill x # copy source file global g_service_configs_opt set g_service_configs_opt "use" set f ${w}.note.files.copy ttk::frame $f ttk::radiobutton $f.opt -text "Copy this source file: " \ -value "copy" -variable g_service_configs_opt \ -command "customizeServiceFileOpt $w copy true" ttk::entry $f.name -width 45 ttk::button $f.btn -image $plugin_img_open -command \ "customizeServiceFileOpt $w copy true; fileButtonPopup $f.name {}" pack $f.opt $f.name $f.btn -side left -anchor w pack $f -side top -anchor w -padx 4 -pady 4 -fill x bind $f.btn