From: miljenko Date: Wed, 11 Jul 2007 12:11:12 +0000 (+0000) Subject: Support for oval (circle), rectangle and text annotations. X-Git-Url: https://git.entuzijast.net/?a=commitdiff_plain;h=56e3c260c2916c7183ac765d664934377cdcfa65;p=imunes.git Support for oval (circle), rectangle and text annotations. Bug found by: Submitted by: Reviewed by: Approved by: Obtained from: --- diff --git a/cfgparse.tcl b/cfgparse.tcl index 80ac5d3..7fc8772 100755 --- a/cfgparse.tcl +++ b/cfgparse.tcl @@ -1,4 +1,4 @@ -# $Id: cfgparse.tcl,v 1.15.2.1 2007/05/07 08:20:09 ana Exp $ +# $Id: cfgparse.tcl,v 1.15.2.2 2007/07/11 12:11:12 miljenko Exp $ # # Copyright 2005 University of Zagreb, Croatia. All rights reserved. # @@ -53,7 +53,7 @@ # Puts a sting to the file or appends the string configuration (used for # undo functions), the choice depends on the value of method parameter. # INPUTS -# * method -- used method. Possiable values are file (if saving the string +# * method -- method used. Possiable values are file (if saving the string # to the file) and string (if appending the string configuration) # * dest -- destination used. File_id for files, and string name for string # configuration @@ -63,14 +63,14 @@ proc dumpputs {method dest string} { switch -exact -- $method { - file { - puts $dest $string - } - string { - global $dest - append $dest "$string + file { + puts $dest $string + } + string { + global $dest + append $dest "$string " - } + } } } @@ -92,72 +92,66 @@ proc dumpCfg {method dest} { global node_list link_list canvas_list global showIfNames showNodeLabels showLinkLabels global showIfIPaddrs showIfIPv6addrs - global showIPsecConfig + global showIPsecConfig + global showBkgImage showGrid showAnnotations + global oval_list rectangle_list text_list foreach node $node_list { - global $node - upvar 0 $node lnode - dumpputs $method $dest "node $node \{" - foreach element $lnode { - if { "[lindex $element 0]" == "network-config" } { - dumpputs $method $dest " network-config \{" - foreach line [lindex $element 1] { - dumpputs $method $dest " $line" - } - dumpputs $method $dest " \}" - } elseif { "[lindex $element 0]" == "custom-config" } { - dumpputs $method $dest " custom-config \{" - foreach line [lindex $element 1] { - if { $line != {} } { - set str [lindex $line 0] - if { $str == "custom-config" } { - dumpputs $method $dest " config \{" - foreach element [lindex $line 1] { - dumpputs $method $dest " $element" - } - dumpputs $method $dest " \}" - } else { - dumpputs $method $dest " $line" - } - } - } - dumpputs $method $dest " \}" - } elseif { "[lindex $element 0]" == "ipsec-config" } { - dumpputs $method $dest " ipsec-config \{" - foreach line [lindex $element 1] { - if { $line != {} } { + global $node + upvar 0 $node lnode + dumpputs $method $dest "node $node \{" + foreach element $lnode { + if { "[lindex $element 0]" == "network-config" } { + dumpputs $method $dest " network-config \{" + foreach line [lindex $element 1] { dumpputs $method $dest " $line" } - } - dumpputs $method $dest " \}" - } else { - dumpputs $method $dest " $element" - } - } - dumpputs $method $dest "\}" - dumpputs $method $dest "" - } - - foreach link $link_list { - global $link - upvar 0 $link llink - dumpputs $method $dest "link $link \{" - foreach element $llink { - dumpputs $method $dest " $element" - } - dumpputs $method $dest "\}" - dumpputs $method $dest "" + dumpputs $method $dest " \}" + } elseif { "[lindex $element 0]" == "custom-config" } { + dumpputs $method $dest " custom-config \{" + foreach line [lindex $element 1] { + if { $line != {} } { + set str [lindex $line 0] + if { $str == "custom-config" } { + dumpputs $method $dest " config \{" + foreach element [lindex $line 1] { + dumpputs $method $dest " $element" + } + dumpputs $method $dest " \}" + } else { + dumpputs $method $dest " $line" + } + } + } + dumpputs $method $dest " \}" + } elseif { "[lindex $element 0]" == "ipsec-config" } { + dumpputs $method $dest " ipsec-config \{" + foreach line [lindex $element 1] { + if { $line != {} } { + dumpputs $method $dest " $line" + } + } + dumpputs $method $dest " \}" + } else { + dumpputs $method $dest " $element" + } + } + dumpputs $method $dest "\}" + dumpputs $method $dest "" } - foreach canvas $canvas_list { - global $canvas - upvar 0 $canvas lcanvas - dumpputs $method $dest "canvas $canvas \{" - foreach element $lcanvas { - dumpputs $method $dest " $element" - } - dumpputs $method $dest "\}" - dumpputs $method $dest "" + foreach obj "rectangle oval text link canvas" { + upvar 0 ${obj}_list obj_list + foreach elem $obj_list { + global $elem + upvar 0 $elem lelem + dumpputs $method $dest "$obj $elem \{" + foreach element $lelem { + dumpputs $method $dest " $element" + } + dumpputs $method $dest "\}" + dumpputs $method $dest "" + } } dumpputs $method $dest "option show \{" @@ -185,6 +179,18 @@ proc dumpCfg {method dest} { dumpputs $method $dest " ipsec_configs no" } else { dumpputs $method $dest " ipsec_configs yes" } + if {$showBkgImage == 0} { + dumpputs $method $dest " background_images no" + } else { + dumpputs $method $dest " background_images yes" } + if {$showAnnotations == 0} { + dumpputs $method $dest " annotations no" + } else { + dumpputs $method $dest " annotations yes" } + if {$showGrid == 0} { + dumpputs $method $dest " grid no" + } else { + dumpputs $method $dest " grid yes" } dumpputs $method $dest "\}" dumpputs $method $dest "" } @@ -205,219 +211,291 @@ proc loadCfg { cfg } { global node_list link_list canvas_list global showIfNames showNodeLabels showLinkLabels global showIfIPaddrs showIfIPv6addrs - global showIPsecConfig + global showIPsecConfig + global showBkgImage showGrid showAnnotations + global oval_list rectangle_list text_list # Cleanup first set node_list {} set link_list {} set canvas_list {} - + set oval_list {} + set rectangle_list {} + set text_list {} set class "" set object "" foreach entry $cfg { - if {"$class" == ""} { - set class $entry - continue - } elseif {"$object" == ""} { - set object $entry - global $object - set $object {} - if {"$class" == "node"} { - lappend node_list $object - } - if {"$class" == "link"} { - lappend link_list $object - } - if {"$class" == "canvas"} { - lappend canvas_list $object - } - if {"$class" == "option"} { + if {"$class" == ""} { + set class $entry + continue + } elseif {"$object" == ""} { + set object $entry + global $object + set $object {} + if {"$class" == "node"} { + lappend node_list $object + } + if {"$class" == "link"} { + lappend link_list $object + } + if {"$class" == "canvas"} { + lappend canvas_list $object + } + if {"$class" == "option"} { # for future use - lappend prefs $object - } - continue - } else { - set line [concat $entry] - while {[llength $line] >= 2} { - set field [lindex $line 0] - if {"$field" == ""} { - set line [lreplace $line 0 0] - continue - } + lappend prefs $object + } + if {"$class" == "rectangle"} { + lappend rectangle_list $object + } + if {"$class" == "oval"} { + lappend oval_list $object + } + if {"$class" == "text"} { + lappend text_list $object + } + continue + } else { + set line [concat $entry] + while {[llength $line] >= 2} { + set field [lindex $line 0] + if {"$field" == ""} { + set line [lreplace $line 0 0] + continue + } - set value [lindex $line 1] - set line [lreplace $line 0 1] + set value [lindex $line 1] + set line [lreplace $line 0 1] - if {"$class" == "node"} { - switch -exact -- $field { - type { - lappend $object "type $value" - } - mirror { - lappend $object "mirror $value" - } - model { - lappend $object "model $value" - } - cpu { - lappend $object "cpu {$value}" - } - interface-peer { - lappend $object "interface-peer {$value}" - } - network-config { - set cfg "" - foreach zline [split $value { + if {"$class" == "node"} { + switch -exact -- $field { + type { + lappend $object "type $value" + } + mirror { + lappend $object "mirror $value" + } + model { + lappend $object "model $value" + } + cpu { + lappend $object "cpu {$value}" + } + interface-peer { + lappend $object "interface-peer {$value}" + } + network-config { + set cfg "" + foreach zline [split $value { }] { - if { [string index "$zline" 0] == " " } { - set zline [string replace "$zline" 0 0] - } - lappend cfg $zline - } - set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] - lappend $object "network-config {$cfg}" - } - custom-enabled { - lappend $object "custom-enabled $value" - } - custom-command { - lappend $object "custom-command {$value}" - } - custom-config { - set cfg "" - - foreach zline [split $value { + if { [string index "$zline" 0] == " " } { + set zline [string replace "$zline" 0 0] + } + lappend cfg $zline + } + set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] + lappend $object "network-config {$cfg}" + } + custom-enabled { + lappend $object "custom-enabled $value" + } + custom-command { + lappend $object "custom-command {$value}" + } + custom-config { + set cfg "" + + foreach zline [split $value { }] { - if { [string index "$zline" 0] == " " } { - set zline [string replace "$zline" 0 0] - } - lappend cfg $zline - } - set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] - lappend $object "custom-config {$cfg}" - } - ipsec-enabled { - lappend $object "ipsec-enabled $value" - } - ipsec-config { - set cfg "" + if { [string index "$zline" 0] == " " } { + set zline [string replace "$zline" 0 0] + } + lappend cfg $zline + } + set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] + lappend $object "custom-config {$cfg}" + } + ipsec-enabled { + lappend $object "ipsec-enabled $value" + } + ipsec-config { + set cfg "" - foreach zline [split $value { + foreach zline [split $value { }] { - if { [string index "$zline" 0] == " " } { - set zline [string replace "$zline" 0 0] - } - lappend cfg $zline - } - set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] - lappend $object "ipsec-config {$cfg}" - } - iconcoords { - lappend $object "iconcoords {$value}" - } - labelcoords { - lappend $object "labelcoords {$value}" - } - canvas { - lappend $object "canvas $value" - } - } - } elseif {"$class" == "link"} { - switch -exact -- $field { - nodes { - lappend $object "nodes {$value}" - } - mirror { - lappend $object "mirror $value" - } - bandwidth { - lappend $object "bandwidth $value" - } - delay { - lappend $object "delay $value" - } - ber { - lappend $object "ber $value" - } - duplicate { - lappend $object "duplicate $value" - } - color { - lappend $object "color $value" - } - width { - lappend $object "width $value" - } - } - } elseif {"$class" == "canvas"} { - switch -exact -- $field { - name { - lappend $object "name {$value}" - } - size { - lappend $object "size {$value}" - } - } - } elseif {"$class" == "option"} { - switch -exact -- $field { - interface_names { + if { [string index "$zline" 0] == " " } { + set zline [string replace "$zline" 0 0] + } + lappend cfg $zline + } + set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]] + lappend $object "ipsec-config {$cfg}" + } + iconcoords { + lappend $object "iconcoords {$value}" + } + labelcoords { + lappend $object "labelcoords {$value}" + } + canvas { + lappend $object "canvas $value" + } + } + } elseif {"$class" == "link"} { + switch -exact -- $field { + nodes { + lappend $object "nodes {$value}" + } + mirror { + lappend $object "mirror $value" + } + bandwidth { + lappend $object "bandwidth $value" + } + delay { + lappend $object "delay $value" + } + ber { + lappend $object "ber $value" + } + duplicate { + lappend $object "duplicate $value" + } + color { + lappend $object "color $value" + } + width { + lappend $object "width $value" + } + } + } elseif {"$class" == "canvas"} { + switch -exact -- $field { + name { + lappend $object "name {$value}" + } + size { + lappend $object "size {$value}" + } + bkgImage { + lappend $object "bkgImage {$value}" + } + } + } elseif {"$class" == "option"} { + switch -exact -- $field { + interface_names { if { $value == "no" } { set showIfNames 0 } elseif { $value == "yes" } { set showIfNames 1 } - } - ip_addresses { + } + ip_addresses { if { $value == "no" } { set showIfIPaddrs 0 } elseif { $value == "yes" } { set showIfIPaddrs 1 } - } - ipv6_addresses { + } + ipv6_addresses { if { $value == "no" } { set showIfIPv6addrs 0 } elseif { $value == "yes" } { set showIfIPv6addrs 1 } - } - node_labels { + } + node_labels { if { $value == "no" } { set showNodeLabels 0 } elseif { $value == "yes" } { set showNodeLabels 1 } - } - link_labels { + } + link_labels { if { $value == "no" } { set showLinkLabels 0 } elseif { $value == "yes" } { set showLinkLabels 1 } - } - ipsec_configs { + } + ipsec_configs { if { $value == "no" } { set showIPsecConfig 0 } elseif { $value == "yes" } { set showIPsecConfig 1 } - } - } + } + background_images { + if { $value == "no" } { + set showBkgImage 0 + } elseif { $value == "yes" } { + set showBkgImage 1 + } + } + annotations { + if { $value == "no" } { + set showAnnotations 0 + } elseif { $value == "yes" } { + set showAnnotations 1 + } + } + grid { + if { $value == "no" } { + set showGrid 0 + } elseif { $value == "yes" } { + set showGrid 1 + } + } + } + } elseif {"$class" == "oval" \ + || "$class" == "rectangle" \ + || "$class" == "text"} { + switch -exact -- $field { + iconcoords { + lappend $object "iconcoords {$value}" + } + color { + lappend $object "color $value" + } + label { + lappend $object "label {$value}" + } + labelcolor { + lappend $object "labelcolor $value" + } + size { + lappend $object "size $value" + } + canvas { + lappend $object "canvas $value" + } + font { + lappend $object "font {$value}" + } + fontfamily { + lappend $object "fontfamily {$value}" + } + fontsize { + lappend $object "fontsize {$value}" + } + effects { + lappend $object "effects {$value}" + } + } } - } - } - set class "" - set object "" + } + } + set class "" + set object "" } # # Hack for comaptibility with old format files (no canvases) # if { $canvas_list == "" } { - set curcanvas [newCanvas ""] - foreach node $node_list { - setNodeCanvas $node $curcanvas - } + set curcanvas [newCanvas ""] + foreach node $node_list { + setNodeCanvas $node $curcanvas + } } } @@ -441,6 +519,7 @@ proc loadCfg { cfg } { proc newObjectId { type } { global node_list link_list canvas_list + global oval_list rectangle_list text_list set mark [string range [set type] 0 0] set id 0 @@ -449,3 +528,4 @@ proc newObjectId { type } { } return $mark$id } + diff --git a/editor.tcl b/editor.tcl index d408c6e..afceb72 100755 --- a/editor.tcl +++ b/editor.tcl @@ -1,4 +1,4 @@ -# $Id: editor.tcl,v 1.62.2.1 2007/05/07 08:20:09 ana Exp $ +# $Id: editor.tcl,v 1.62.2.2 2007/07/11 12:11:12 miljenko Exp $ # # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -50,16 +50,16 @@ proc animateCursor {} { global clock_seconds if { [clock seconds] == $clock_seconds } { - update - return + update + return } set clock_seconds [clock seconds] if { $cursorState } { - .c config -cursor watch - set cursorState 0 + .c config -cursor watch + set cursorState 0 } else { - .c config -cursor pirate - set cursorState 1 + .c config -cursor pirate + set cursorState 1 } update } @@ -86,24 +86,24 @@ proc removeGUILink { link atomic } { set node1 [lindex $nodes 0] set node2 [lindex $nodes 1] if { [nodeType $node1] == "pseudo" } { - removeLink [getLinkMirror $link] - removeLink $link - removeNode [getNodeMirror $node1] - removeNode $node1 - .c delete $node1 + removeLink [getLinkMirror $link] + removeLink $link + removeNode [getNodeMirror $node1] + removeNode $node1 + .c delete $node1 } elseif { [nodeType $node2] == "pseudo" } { - removeLink [getLinkMirror $link] - removeLink $link - removeNode [getNodeMirror $node2] - removeNode $node2 - .c delete $node2 + removeLink [getLinkMirror $link] + removeLink $link + removeNode [getNodeMirror $node2] + removeNode $node2 + .c delete $node2 } else { - removeLink $link + removeLink $link } .c delete $link if { $atomic == "atomic" } { - set changed 1 - updateUndoLog + set changed 1 + updateUndoLog } } @@ -122,13 +122,13 @@ proc removeGUILink { link atomic } { proc removeGUINode { node } { set type [nodeType $node] foreach ifc [ifcList $node] { - set peer [peerByIfc $node $ifc] - set link [lindex [.c gettags "link && $node && $peer"] 1] - removeGUILink $link non-atomic + set peer [peerByIfc $node $ifc] + set link [lindex [.c gettags "link && $node && $peer"] 1] + removeGUILink $link non-atomic } if { $type != "pseudo" } { - removeNode $node - .c delete $node + removeNode $node + .c delete $node } } @@ -146,16 +146,16 @@ proc updateUndoLog {} { global changed undolog undolevel redolevel if { $changed } { - global t_undolog undolog - set t_undolog "" - dumpCfg string t_undolog - incr undolevel - if { $undolevel == 1 } { - .menubar.edit entryconfigure "Undo" -state normal - } - set undolog($undolevel) $t_undolog - set redolevel $undolevel - set changed 0 + global t_undolog undolog + set t_undolog "" + dumpCfg string t_undolog + incr undolevel + if { $undolevel == 1 } { + .menubar.edit entryconfigure "Undo" -state normal + } + set undolog($undolevel) $t_undolog + set redolevel $undolevel + set changed 0 } } @@ -173,14 +173,14 @@ proc undo {} { global undolevel undolog oper_mode if {$oper_mode == "edit" && $undolevel > 0} { - .menubar.edit entryconfigure "Redo" -state normal - incr undolevel -1 - if { $undolevel == 0 } { - .menubar.edit entryconfigure "Undo" -state disabled - } - .c config -cursor watch - loadCfg $undolog($undolevel) - switchCanvas none + .menubar.edit entryconfigure "Redo" -state normal + incr undolevel -1 + if { $undolevel == 0 } { + .menubar.edit entryconfigure "Undo" -state disabled + } + .c config -cursor watch + loadCfg $undolog($undolevel) + switchCanvas none } } @@ -200,16 +200,16 @@ proc redo {} { global undolevel redolevel undolog oper_mode if {$oper_mode == "edit" && $redolevel > $undolevel} { - incr undolevel - if { $undolevel == 1 } { - .menubar.edit entryconfigure "Undo" -state normal - } - if {$redolevel <= $undolevel} { - .menubar.edit entryconfigure "Redo" -state disabled - } - .c config -cursor watch - loadCfg $undolog($undolevel) - switchCanvas none + incr undolevel + if { $undolevel == 1 } { + .menubar.edit entryconfigure "Undo" -state normal + } + if {$redolevel <= $undolevel} { + .menubar.edit entryconfigure "Redo" -state disabled + } + .c config -cursor watch + loadCfg $undolog($undolevel) + switchCanvas none } } @@ -225,66 +225,99 @@ proc redo {} { proc redrawAll {} { global node_list link_list background sizex sizey grid global curcanvas zoom - + global showBkgImage showAnnotations showGrid bkgImage + global oval_list label_list rectangle_list text_list .bottom.zoom config -text "zoom [expr {int($zoom * 100)}]%" set e_sizex [expr {int($sizex * $zoom)}] set e_sizey [expr {int($sizey * $zoom)}] set border 28 .c configure -scrollregion \ - "-$border -$border [expr {$e_sizex + $border}] \ - [expr {$e_sizey + $border}]" + "-$border -$border [expr {$e_sizex + $border}] \ + [expr {$e_sizey + $border}]" .c delete all - set background [.c create rectangle 0 0 $e_sizex $e_sizey \ - -fill white -tags "background"] + + set canvasBkgImage [getCanvasBkg $curcanvas] + if { $showBkgImage == 1 && "$canvasBkgImage" != ""} { + set ret [backgroundImage .c $canvasBkgImage] + if { "$ret" == 2 } { + set background [.c create rectangle 0 0 $e_sizex $e_sizey \ + -fill white -tags "background"] + } else { + set background [.c create rectangle 0 0 $e_sizex $e_sizey \ + -tags "background"] + } + } else { + set background [.c create rectangle 0 0 $e_sizex $e_sizey \ + -fill white -tags "background"] + } + + if { $showAnnotations == 1 } { + foreach rect $rectangle_list { + if { [getNodeCanvas $rect] == $curcanvas } { + drawRect $rect + } + } + foreach oval $oval_list { + if { [getNodeCanvas $oval] == $curcanvas } { + drawOval $oval + } + } + foreach text $text_list { + if { [getNodeCanvas $text] == $curcanvas } { + drawText $text + } + } + } # Grid set e_grid [expr {int($grid * $zoom)}] set e_grid2 [expr {$e_grid * 2}] - if { 1 } { - for { set x $e_grid } { $x < $e_sizex } { incr x $e_grid } { - if { [expr {$x % $e_grid2}] != 0 } { - if { $zoom > 0.5 } { - .c create line $x 1 $x $e_sizey \ - -fill gray -dash {1 7} -tags "background" - } - } else { - .c create line $x 1 $x $e_sizey -fill gray -dash {1 3} \ - -tags "background" - } - } - for { set y $e_grid } { $y < $e_sizey } { incr y $e_grid } { - if { [expr {$y % $e_grid2}] != 0 } { - if { $zoom > 0.5 } { - .c create line 1 $y $e_sizex $y \ - -fill gray -dash {1 7} -tags "background" - } - } else { - .c create line 1 $y $e_sizex $y -fill gray -dash {1 3} \ - -tags "background" - } - } + if { $showGrid } { + for { set x $e_grid } { $x < $e_sizex } { incr x $e_grid } { + if { [expr {$x % $e_grid2}] != 0 } { + if { $zoom > 0.5 } { + .c create line $x 1 $x $e_sizey \ + -fill gray -dash {1 7} -tags "grid" + } + } else { + .c create line $x 1 $x $e_sizey -fill gray -dash {1 3} \ + -tags "grid" + } + } + for { set y $e_grid } { $y < $e_sizey } { incr y $e_grid } { + if { [expr {$y % $e_grid2}] != 0 } { + if { $zoom > 0.5 } { + .c create line 1 $y $e_sizex $y \ + -fill gray -dash {1 7} -tags "grid" + } + } else { + .c create line 1 $y $e_sizex $y -fill gray -dash {1 3} \ + -tags "grid" + } + } } .c lower -withtags background foreach node $node_list { - if { [getNodeCanvas $node] == $curcanvas } { - drawNode $node - } + if { [getNodeCanvas $node] == $curcanvas } { + drawNode $node + } } foreach link $link_list { - set nodes [linkPeers $link] - if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || - [getNodeCanvas [lindex $nodes 1]] != $curcanvas } { - continue - } - drawLink $link - redrawLink $link - updateLinkLabel $link + set nodes [linkPeers $link] + if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || + [getNodeCanvas [lindex $nodes 1]] != $curcanvas } { + continue + } + drawLink $link + redrawLink $link + updateLinkLabel $link } .c config -cursor left_ptr + raiseAll .c } #****f* editor.tcl/drawNode @@ -316,30 +349,31 @@ proc drawNode { node } { set x [expr {[lindex $coords 0] * $zoom}] set y [expr {[lindex $coords 1] * $zoom}] if { [nodeType $node] != "pseudo" } { - set label [.c create text $x $y -fill blue \ + set label [.c create text $x $y -fill blue \ -text "[getNodeName $node]" \ -tags "nodelabel $node"] } else { - set pnode [getNodeName $node] - set pcanvas [getNodeCanvas $pnode] - set ifc [ifcByPeer $pnode [getNodeMirror $node]] - if { $pcanvas != $curcanvas } { - set label [.c create text $x $y -fill blue \ - -text "[getNodeName $pnode]:$ifc @[getCanvasName $pcanvas]" \ - -tags "nodelabel $node" -justify center] - } else { - set label [.c create text $x $y -fill blue \ - -text "[getNodeName $pnode]:$ifc" \ - -tags "nodelabel $node" -justify center] - } + set pnode [getNodeName $node] + set pcanvas [getNodeCanvas $pnode] + set ifc [ifcByPeer $pnode [getNodeMirror $node]] + if { $pcanvas != $curcanvas } { + set label [.c create text $x $y -fill blue \ + -text "[getNodeName $pnode]:$ifc +@[getCanvasName $pcanvas]" \ + -tags "nodelabel $node" -justify center] + } else { + set label [.c create text $x $y -fill blue \ + -text "[getNodeName $pnode]:$ifc" \ + -tags "nodelabel $node" -justify center] + } } if { $showNodeLabels == 0} { - .c itemconfigure $label -state hidden + .c itemconfigure $label -state hidden } # XXX Invisible pseudo-node labels global invisible if { $invisible == 1 && [nodeType $node] == "pseudo" } { - .c itemconfigure $label -state hidden + .c itemconfigure $label -state hidden } } @@ -362,18 +396,18 @@ proc drawLink { link } { set lnode2 [lindex $nodes 1] set lwidth [getLinkWidth $link] if { [getLinkMirror $link] != "" } { - set newlink [.c create line 0 0 0 0 \ - -fill [getLinkColor $link] -width $lwidth \ - -tags "link $link $lnode1 $lnode2" -arrow both] + set newlink [.c create line 0 0 0 0 \ + -fill [getLinkColor $link] -width $lwidth \ + -tags "link $link $lnode1 $lnode2" -arrow both] } else { - set newlink [.c create line 0 0 0 0 \ - -fill [getLinkColor $link] -width $lwidth \ - -tags "link $link $lnode1 $lnode2"] + set newlink [.c create line 0 0 0 0 \ + -fill [getLinkColor $link] -width $lwidth \ + -tags "link $link $lnode1 $lnode2"] } # XXX Invisible pseudo-liks global invisible if { $invisible == 1 && [getLinkMirror $link] != "" } { - .c itemconfigure $link -state hidden + .c itemconfigure $link -state hidden } .c raise $newlink background set newlink [.c create line 0 0 0 0 \ @@ -407,27 +441,27 @@ proc chooseIfName { lnode1 lnode2 } { global $lnode1 $lnode2 switch -exact -- [nodeType $lnode1] { - pc { - return eth - } - host { - return eth - } - hub { - return e - } - lanswitch { - return e - } - frswitch { - return f - } - router { - return eth - } - rj45 { - return - } + pc { + return eth + } + host { + return eth + } + hub { + return e + } + lanswitch { + return e + } + frswitch { + return f + } + router { + return eth + } + rj45 { + return + } } } @@ -450,13 +484,13 @@ proc chooseIfName { lnode1 lnode2 } { proc listLANnodes { l2node l2peers } { lappend l2peers $l2node foreach ifc [ifcList $l2node] { - set peer [logicalPeerByIfc $l2node $ifc] - set type [nodeType $peer] - if { [ lsearch {lanswitch hub} $type] != -1 } { - if { [lsearch $l2peers $peer] == -1 } { - set l2peers [listLANnodes $peer $l2peers] - } - } + set peer [logicalPeerByIfc $l2node $ifc] + set type [nodeType $peer] + if { [ lsearch {lanswitch hub} $type] != -1 } { + if { [lsearch $l2peers $peer] == -1 } { + set l2peers [listLANnodes $peer $l2peers] + } + } } return $l2peers } @@ -479,47 +513,47 @@ proc calcDxDy { lnode } { upvar dy y if { $zoom > 1.0 } { - set x 1 - set y 1 - return + set x 1 + set y 1 + return } switch -exact -- [nodeType $lnode] { - frswitch { - set x [expr {1.8 / $zoom}] - set y [expr {1.8 / $zoom}] - } - hub { - set x [expr {1.5 / $zoom}] - set y [expr {2.6 / $zoom}] - } - lanswitch { - set x [expr {1.5 / $zoom}] - set y [expr {2.6 / $zoom}] - } - router { - set x [expr {1 / $zoom}] - set y [expr {2 / $zoom}] - } - pc { - if { $showIfIPaddrs || $showIfIPv6addrs } { - set x [expr {1.1 / $zoom}] - } else { - set x [expr {1.4 / $zoom}] - } - set y [expr {1.5 / $zoom}] - } - host { - if { $showIfIPaddrs || $showIfIPv6addrs } { - set x [expr {1 / $zoom}] - } else { - set x [expr {1.5 / $zoom}] - } - set y [expr {1.5 / $zoom}] - } - rj45 { - set x [expr {1 / $zoom}] - set y [expr {1 / $zoom}] - } + frswitch { + set x [expr {1.8 / $zoom}] + set y [expr {1.8 / $zoom}] + } + hub { + set x [expr {1.5 / $zoom}] + set y [expr {2.6 / $zoom}] + } + lanswitch { + set x [expr {1.5 / $zoom}] + set y [expr {2.6 / $zoom}] + } + router { + set x [expr {1 / $zoom}] + set y [expr {2 / $zoom}] + } + pc { + if { $showIfIPaddrs || $showIfIPv6addrs } { + set x [expr {1.1 / $zoom}] + } else { + set x [expr {1.4 / $zoom}] + } + set y [expr {1.5 / $zoom}] + } + host { + if { $showIfIPaddrs || $showIfIPv6addrs } { + set x [expr {1 / $zoom}] + } else { + set x [expr {1.5 / $zoom}] + } + set y [expr {1.5 / $zoom}] + } + rj45 { + set x [expr {1 / $zoom}] + set y [expr {1 / $zoom}] + } } } @@ -545,26 +579,29 @@ proc updateIfcLabel { lnode1 lnode2 } { set ifipv4addr [getIfcIPv4addr $lnode1 $ifc] set ifipv6addr [getIfcIPv6addr $lnode1 $ifc] if { $ifc == 0 } { - set ifc "" + set ifc "" } if { [getIfcOperState $lnode1 $ifc] == "down" } { - set labelstr "*" + set labelstr "*" } else { - set labelstr "" + set labelstr "" } if { $showIfNames } { - set labelstr "$labelstr$ifc " + set labelstr "$labelstr$ifc +" } if { $showIfIPaddrs && $ifipv4addr != "" } { - set labelstr "$labelstr$ifipv4addr " + set labelstr "$labelstr$ifipv4addr +" } if { $showIfIPv6addrs && $ifipv6addr != "" } { - set labelstr "$labelstr$ifipv6addr " + set labelstr "$labelstr$ifipv6addr +" } set labelstr \ - [string range $labelstr 0 [expr {[string length $labelstr] - 2}]] + [string range $labelstr 0 [expr {[string length $labelstr] - 2}]] .c itemconfigure "interface && $lnode1 && $link" \ - -text "$labelstr" + -text "$labelstr" } @@ -586,23 +623,27 @@ proc updateLinkLabel { link } { set delstr [getLinkDelayString $link] set ber [getLinkBER $link] set dup [getLinkDup $link] - set labelstr "$labelstr[getLinkBandwidthString $link] " + set labelstr "$labelstr[getLinkBandwidthString $link] +" if { "$delstr" != "" } { - set labelstr "$labelstr$delstr " + set labelstr "$labelstr$delstr +" } if { "$ber" != "" } { - set berstr "ber=$ber" - set labelstr "$labelstr$berstr " + set berstr "ber=$ber" + set labelstr "$labelstr$berstr +" } if { "$dup" != "" } { - set dupstr "dup=$dup%" - set labelstr "$labelstr$dupstr " + set dupstr "dup=$dup%" + set labelstr "$labelstr$dupstr +" } set labelstr \ - [string range $labelstr 0 [expr {[string length $labelstr] - 2}]] + [string range $labelstr 0 [expr {[string length $labelstr] - 2}]] .c itemconfigure "linklabel && $link" -text "$labelstr" if { $showLinkLabels == 0} { - .c itemconfigure "linklabel && $link" -state hidden + .c itemconfigure "linklabel && $link" -state hidden } } @@ -619,12 +660,12 @@ proc redrawAllLinks {} { global link_list curcanvas foreach link $link_list { - set nodes [linkPeers $link] - if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || - [getNodeCanvas [lindex $nodes 1]] != $curcanvas } { - continue - } - redrawLink $link + set nodes [linkPeers $link] + if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || + [getNodeCanvas [lindex $nodes 1]] != $curcanvas } { + continue + } + redrawLink $link } } @@ -665,9 +706,9 @@ proc redrawLink { link } { .c coords "linklabel && $link" $lx $ly set n [expr {sqrt (($x1 - $x2) * ($x1 - $x2) + \ - ($y1 - $y2) * ($y1 - $y2)) * 0.015}] + ($y1 - $y2) * ($y1 - $y2)) * 0.015}] if { $n < 1 } { - set n 1 + set n 1 } calcDxDy $lnode1 @@ -719,11 +760,11 @@ proc splitGUILink { link } { set y2 [lindex [getNodeCoords $orig_node2] 1] setNodeCoords $new_node1 \ - "[expr {($x1 + 0.4 * ($x2 - $x1)) / $zoom}] \ - [expr {($y1 + 0.4 * ($y2 - $y1)) / $zoom}]" + "[expr {($x1 + 0.4 * ($x2 - $x1)) / $zoom}] \ + [expr {($y1 + 0.4 * ($y2 - $y1)) / $zoom}]" setNodeCoords $new_node2 \ - "[expr {($x1 + 0.6 * ($x2 - $x1)) / $zoom}] \ - [expr {($y1 + 0.6 * ($y2 - $y1)) / $zoom}]" + "[expr {($x1 + 0.6 * ($x2 - $x1)) / $zoom}] \ + [expr {($y1 + 0.6 * ($y2 - $y1)) / $zoom}]" setNodeLabelCoords $new_node1 [getNodeCoords $new_node1] setNodeLabelCoords $new_node2 [getNodeCoords $new_node2] @@ -747,11 +788,21 @@ proc splitGUILink { link } { #**** proc selectNode { c obj } { set node [lindex [$c gettags $obj] 1] + $c addtag selected withtag "node && $node" if { [nodeType $node] == "pseudo" } { - set bbox [$c bbox "nodelabel && $node"] + set bbox [$c bbox "nodelabel && $node"] + } elseif { [nodeType $node] == "rectangle" } { + $c addtag selected withtag "rectangle && $node" + set bbox [$c bbox "rectangle && $node"] + } elseif { [nodeType $node] == "text" } { + $c addtag selected withtag "text && $node" + set bbox [$c bbox "text && $node"] + } elseif { [nodeType $node] == "oval" } { + $c addtag selected withtag "oval && $node" + set bbox [$c bbox "oval && $node"] } else { - set bbox [$c bbox "node && $node"] + set bbox [$c bbox "node && $node"] } set bx1 [expr {[lindex $bbox 0] - 2}] set by1 [expr {[lindex $bbox 1] - 2}] @@ -759,19 +810,28 @@ proc selectNode { c obj } { set by2 [expr {[lindex $bbox 3] + 1}] $c delete -withtags "selectmark && $node" $c create line $bx1 $by1 $bx2 $by1 $bx2 $by2 $bx1 $by2 $bx1 $by1 \ - -dash {6 4} -fill black -width 1 -tags "selectmark $node" + -dash {6 4} -fill black -width 1 -tags "selectmark $node" } proc selectNodes { nodelist } { foreach node $nodelist { - selectNode .c [.c find withtag "node && $node"] + selectNode .c [.c find withtag "node && $node"] } } proc selectedNodes {} { set selected {} foreach obj [.c find withtag "node && selected"] { - lappend selected [lindex [.c gettags $obj] 1] + lappend selected [lindex [.c gettags $obj] 1] + } + foreach obj [.c find withtag "oval && selected"] { + lappend selected [lindex [.c gettags $obj] 1] + } + foreach obj [.c find withtag "rectangle && selected"] { + lappend selected [lindex [.c gettags $obj] 1] + } + foreach obj [.c find withtag "text && selected"] { + lappend selected [lindex [.c gettags $obj] 1] } return $selected } @@ -779,12 +839,12 @@ proc selectedNodes {} { proc selectedRealNodes {} { set selected {} foreach obj [.c find withtag "node && selected"] { - set node [lindex [.c gettags $obj] 1] - if { [getNodeMirror $node] != "" || - [nodeType $node] == "rj45" } { - continue - } - lappend selected $node + set node [lindex [.c gettags $obj] 1] + if { [getNodeMirror $node] != "" || + [nodeType $node] == "rj45" } { + continue + } + lappend selected $node } return $selected } @@ -795,15 +855,15 @@ proc selectAdjacent {} { set selected [selectedNodes] set adjacent {} foreach node $selected { - foreach ifc [ifcList $node] { - set peer [peerByIfc $node $ifc] - if { [getNodeMirror $peer] != "" } { - return - } - if { [lsearch $adjacent $peer] < 0 } { - lappend adjacent $peer - } - } + foreach ifc [ifcList $node] { + set peer [peerByIfc $node $ifc] + if { [getNodeMirror $peer] != "" } { + return + } + if { [lsearch $adjacent $peer] < 0 } { + lappend adjacent $peer + } + } } selectNodes $adjacent } @@ -834,10 +894,10 @@ proc button3link { c x y } { set link [lindex [$c gettags {link && current}] 1] if { $link == "" } { - set link [lindex [$c gettags {linklabel && current}] 1] - if { $link == "" } { - return - } + set link [lindex [$c gettags {linklabel && current}] 1] + if { $link == "" } { + return + } } .button3menu delete 0 end @@ -846,40 +906,40 @@ proc button3link { c x y } { # Configure link # .button3menu add command -label "Configure" \ - -command "popupConfigDialog $c" + -command "popupConfigDialog $c" # # Delete link # if { $oper_mode != "exec" } { - .button3menu add command -label "Delete" \ - -command "removeGUILink $link atomic" + .button3menu add command -label "Delete" \ + -command "removeGUILink $link atomic" } else { - .button3menu add command -label "Delete" \ - -state disabled + .button3menu add command -label "Delete" \ + -state disabled } # # Split link # if { $oper_mode != "exec" && [getLinkMirror $link] == "" } { - .button3menu add command -label "Split" \ - -command "splitGUILink $link" + .button3menu add command -label "Split" \ + -command "splitGUILink $link" } else { - .button3menu add command -label "Split" \ - -state disabled + .button3menu add command -label "Split" \ + -state disabled } # # Merge two pseudo nodes / links # if { $oper_mode != "exec" && [getLinkMirror $link] != "" && - [getNodeCanvas [getNodeMirror [lindex [linkPeers $link] 1]]] == - $curcanvas } { - .button3menu add command -label "Merge" \ - -command "mergeGUINode [lindex [linkPeers $link] 1]" + [getNodeCanvas [getNodeMirror [lindex [linkPeers $link] 1]]] == + $curcanvas } { + .button3menu add command -label "Merge" \ + -command "mergeGUINode [lindex [linkPeers $link] 1]" } else { - .button3menu add command -label "Merge" -state disabled + .button3menu add command -label "Merge" -state disabled } set x [winfo pointerx .] @@ -904,37 +964,37 @@ proc movetoCanvas { canvas } { set selected_nodes [selectedNodes] foreach node $selected_nodes { - setNodeCanvas $node $canvas - set changed 1 + setNodeCanvas $node $canvas + set changed 1 } foreach obj [.c find withtag "linklabel"] { - set link [lindex [.c gettags $obj] 1] - set link_peers [linkPeers $link] - set peer1 [lindex $link_peers 0] - set peer2 [lindex $link_peers 1] - set peer1_in_selected [lsearch $selected_nodes $peer1] - set peer2_in_selected [lsearch $selected_nodes $peer2] - if { ($peer1_in_selected == -1 && $peer2_in_selected != -1) || - ($peer1_in_selected != -1 && $peer2_in_selected == -1) } { - if { [nodeType $peer2] == "pseudo" } { - setNodeCanvas $peer2 $canvas - if { [getNodeCanvas [getNodeMirror $peer2]] == $canvas } { - mergeLink $link - } - continue - } - set new_nodes [splitLink $link pseudo] - set new_node1 [lindex $new_nodes 0] - set new_node2 [lindex $new_nodes 1] - setNodeMirror $new_node1 $new_node2 - setNodeMirror $new_node2 $new_node1 - setNodeName $new_node1 $peer2 - setNodeName $new_node2 $peer1 - set link1 [linkByPeers $peer1 $new_node1] - set link2 [linkByPeers $peer2 $new_node2] - setLinkMirror $link1 $link2 - setLinkMirror $link2 $link1 - } + set link [lindex [.c gettags $obj] 1] + set link_peers [linkPeers $link] + set peer1 [lindex $link_peers 0] + set peer2 [lindex $link_peers 1] + set peer1_in_selected [lsearch $selected_nodes $peer1] + set peer2_in_selected [lsearch $selected_nodes $peer2] + if { ($peer1_in_selected == -1 && $peer2_in_selected != -1) || + ($peer1_in_selected != -1 && $peer2_in_selected == -1) } { + if { [nodeType $peer2] == "pseudo" } { + setNodeCanvas $peer2 $canvas + if { [getNodeCanvas [getNodeMirror $peer2]] == $canvas } { + mergeLink $link + } + continue + } + set new_nodes [splitLink $link pseudo] + set new_node1 [lindex $new_nodes 0] + set new_node2 [lindex $new_nodes 1] + setNodeMirror $new_node1 $new_node2 + setNodeMirror $new_node2 $new_node1 + setNodeName $new_node1 $peer2 + setNodeName $new_node2 $peer1 + set link1 [linkByPeers $peer1 $new_node1] + set link2 [linkByPeers $peer2 $new_node2] + setLinkMirror $link1 $link2 + setLinkMirror $link2 $link1 + } } updateUndoLog redrawAll @@ -995,17 +1055,17 @@ proc button3node { c x y } { set node [lindex [$c gettags {node && current}] 1] if { $node == "" } { - set node [lindex [$c gettags {nodelabel && current}] 1] - if { $node == "" } { - return - } + set node [lindex [$c gettags {nodelabel && current}] 1] + if { $node == "" } { + return + } } set mirror_node [getNodeMirror $node] if { [$c gettags "node && $node && selected"] == "" } { - $c dtag node selected - $c delete -withtags selectmark - selectNode $c [$c find withtag "current"] + $c dtag node selected + $c delete -withtags selectmark + selectNode $c [$c find withtag "current"] } .button3menu delete 0 end @@ -1014,22 +1074,22 @@ proc button3node { c x y } { # Select adjacent # if { [nodeType $node] != "pseudo" } { - .button3menu add command -label "Select adjacent" \ - -command "selectAdjacent" + .button3menu add command -label "Select adjacent" \ + -command "selectAdjacent" } else { - .button3menu add command -label "Select adjacent" \ - -command "selectAdjacent" -state disabled + .button3menu add command -label "Select adjacent" \ + -command "selectAdjacent" -state disabled } # # Configure node # if { [nodeType $node] != "pseudo" } { - .button3menu add command -label "Configure" \ - -command "popupConfigDialog $c" + .button3menu add command -label "Configure" \ + -command "popupConfigDialog $c" } else { - .button3menu add command -label "Configure" \ - -command "popupConfigDialog $c" -state disabled + .button3menu add command -label "Configure" \ + -command "popupConfigDialog $c" -state disabled } # @@ -1037,46 +1097,46 @@ proc button3node { c x y } { # .button3menu.connect delete 0 end if { $oper_mode == "exec" || [nodeType $node] == "pseudo" } { - .button3menu add cascade -label "Create link to" \ - -menu .button3menu.connect -state disabled + .button3menu add cascade -label "Create link to" \ + -menu .button3menu.connect -state disabled } else { - .button3menu add cascade -label "Create link to" \ - -menu .button3menu.connect + .button3menu add cascade -label "Create link to" \ + -menu .button3menu.connect } destroy .button3menu.connect.selected menu .button3menu.connect.selected -tearoff 0 .button3menu.connect add cascade -label "Selected" \ - -menu .button3menu.connect.selected + -menu .button3menu.connect.selected .button3menu.connect.selected add command \ - -label "Chain" -command "P \[selectedRealNodes\]" + -label "Chain" -command "P \[selectedRealNodes\]" .button3menu.connect.selected add command \ - -label "Star" \ - -command "Kb \[lindex \[selectedRealNodes\] 0\] \ - \[lrange \[selectedNodes\] 1 end\]" + -label "Star" \ + -command "Kb \[lindex \[selectedRealNodes\] 0\] \ + \[lrange \[selectedNodes\] 1 end\]" .button3menu.connect.selected add command \ - -label "Cycle" -command "C \[selectedRealNodes\]" + -label "Cycle" -command "C \[selectedRealNodes\]" .button3menu.connect.selected add command \ - -label "Clique" -command "K \[selectedRealNodes\]" + -label "Clique" -command "K \[selectedRealNodes\]" .button3menu.connect add separator foreach canvas $canvas_list { - destroy .button3menu.connect.$canvas - menu .button3menu.connect.$canvas -tearoff 0 - .button3menu.connect add cascade -label [getCanvasName $canvas] \ - -menu .button3menu.connect.$canvas + destroy .button3menu.connect.$canvas + menu .button3menu.connect.$canvas -tearoff 0 + .button3menu.connect add cascade -label [getCanvasName $canvas] \ + -menu .button3menu.connect.$canvas } foreach peer_node $node_list { - set canvas [getNodeCanvas $peer_node] - if { $node != $peer_node && [nodeType $node] != "rj45" && - [lsearch {pseudo rj45} [nodeType $peer_node]] < 0 && - [ifcByLogicalPeer $node $peer_node] == "" } { - .button3menu.connect.$canvas add command \ - -label [getNodeName $peer_node] \ - -command "newGUILink $node $peer_node" - } elseif { [nodeType $peer_node] != "pseudo" } { - .button3menu.connect.$canvas add command \ - -label [getNodeName $peer_node] \ - -state disabled - } + set canvas [getNodeCanvas $peer_node] + if { $node != $peer_node && [nodeType $node] != "rj45" && + [lsearch {pseudo rj45} [nodeType $peer_node]] < 0 && + [ifcByLogicalPeer $node $peer_node] == "" } { + .button3menu.connect.$canvas add command \ + -label [getNodeName $peer_node] \ + -command "newGUILink $node $peer_node" + } elseif { [nodeType $peer_node] != "pseudo" } { + .button3menu.connect.$canvas add command \ + -label [getNodeName $peer_node] \ + -state disabled + } } # @@ -1084,42 +1144,42 @@ proc button3node { c x y } { # .button3menu.moveto delete 0 end if { $oper_mode == "exec" || [nodeType $node] == "pseudo" } { - .button3menu add cascade -label "Move to" \ - -menu .button3menu.moveto -state disabled + .button3menu add cascade -label "Move to" \ + -menu .button3menu.moveto -state disabled } else { - .button3menu add cascade -label "Move to" \ - -menu .button3menu.moveto + .button3menu add cascade -label "Move to" \ + -menu .button3menu.moveto } .button3menu.moveto add command -label "Canvas:" -state disabled foreach canvas $canvas_list { - if { $canvas != $curcanvas } { - .button3menu.moveto add command \ - -label [getCanvasName $canvas] \ - -command "movetoCanvas $canvas" - } else { - .button3menu.moveto add command \ - -label [getCanvasName $canvas] -state disabled - } + if { $canvas != $curcanvas } { + .button3menu.moveto add command \ + -label [getCanvasName $canvas] \ + -command "movetoCanvas $canvas" + } else { + .button3menu.moveto add command \ + -label [getCanvasName $canvas] -state disabled + } } # # Merge two pseudo nodes / links # if { $oper_mode != "exec" && [nodeType $node] == "pseudo" && \ - [getNodeCanvas $mirror_node] == $curcanvas } { - .button3menu add command -label "Merge" \ - -command "mergeGUINode $node" + [getNodeCanvas $mirror_node] == $curcanvas } { + .button3menu add command -label "Merge" \ + -command "mergeGUINode $node" } else { - .button3menu add command -label "Merge" -state disabled + .button3menu add command -label "Merge" -state disabled } # # Delete selection # if { $oper_mode != "exec" } { - .button3menu add command -label "Delete" -command deleteSelection + .button3menu add command -label "Delete" -command deleteSelection } else { - .button3menu add command -label "Delete" -state disabled + .button3menu add command -label "Delete" -state disabled } # @@ -1127,18 +1187,18 @@ proc button3node { c x y } { # .button3menu.shell delete 0 end if { $oper_mode == "exec" && [[typemodel $node].layer] == "NETWORK" } { - .button3menu add cascade -label "Shell window" \ - -menu .button3menu.shell - set cmd [[typemodel $node].shellcmd $node] - if { $cmd != "/bin/sh" && $cmd != "" } { - .button3menu.shell add command -label "$cmd" \ - -command "spawnShell $node $cmd" - } - .button3menu.shell add command -label "/bin/sh" \ - -command "spawnShell $node /bin/sh" + .button3menu add cascade -label "Shell window" \ + -menu .button3menu.shell + set cmd [[typemodel $node].shellcmd $node] + if { $cmd != "/bin/sh" && $cmd != "" } { + .button3menu.shell add command -label "$cmd" \ + -command "spawnShell $node $cmd" + } + .button3menu.shell add command -label "/bin/sh" \ + -command "spawnShell $node /bin/sh" } else { - .button3menu add cascade -label "Shell window" \ - -menu .button3menu.shell -state disabled + .button3menu add cascade -label "Shell window" \ + -menu .button3menu.shell -state disabled } # @@ -1146,30 +1206,30 @@ proc button3node { c x y } { # .button3menu.ethereal delete 0 end if { $oper_mode == "exec" && [[typemodel $node].layer] == "NETWORK" } { - .button3menu add cascade -label "Ethereal" \ - -menu .button3menu.ethereal - foreach ifc [ifcList $node] { - set label "$ifc" - if { [getIfcIPv4addr $node $ifc] != "" } { - set label "$label ([getIfcIPv4addr $node $ifc])" - } - if { [getIfcIPv6addr $node $ifc] != "" } { - set label "$label ([getIfcIPv6addr $node $ifc])" - } - .button3menu.ethereal add command -label $label \ - -command "startethereal $node $ifc" - } - .button3menu add command -label Start \ - -command "[typemodel $node].start $eid $node" - .button3menu add command -label Stop \ - -command "[typemodel $node].shutdown $eid $node" + .button3menu add cascade -label "Ethereal" \ + -menu .button3menu.ethereal + foreach ifc [ifcList $node] { + set label "$ifc" + if { [getIfcIPv4addr $node $ifc] != "" } { + set label "$label ([getIfcIPv4addr $node $ifc])" + } + if { [getIfcIPv6addr $node $ifc] != "" } { + set label "$label ([getIfcIPv6addr $node $ifc])" + } + .button3menu.ethereal add command -label $label \ + -command "startethereal $node $ifc" + } + .button3menu add command -label Start \ + -command "[typemodel $node].start $eid $node" + .button3menu add command -label Stop \ + -command "[typemodel $node].shutdown $eid $node" } else { - .button3menu add cascade -label "Ethereal" \ - -menu .button3menu.ethereal -state disabled - .button3menu add command -label start \ - -command "[typemodel $node].start $eid $node" -state disabled - .button3menu add command -label stop \ - -command "[typemodel $node].stop $eid $node" -state disabled + .button3menu add cascade -label "Ethereal" \ + -menu .button3menu.ethereal -state disabled + .button3menu add command -label start \ + -command "[typemodel $node].start $eid $node" -state disabled + .button3menu add command -label stop \ + -command "[typemodel $node].stop $eid $node" -state disabled } # @@ -1203,15 +1263,15 @@ proc spawnShell { node cmd } { nexec vimageShellServer.sh $node_id 1234 $cmd & if { $gui_unix } { exec xterm -sb -rightbar \ - -T "IMUNES: [getNodeName $node] (console)" \ - -e "nc $exec_host 1234" & + -T "IMUNES: [getNodeName $node] (console)" \ + -e "nc $exec_host 1234" & } else { - exec cmd /c nc $exec_host 1234 & + exec cmd /c nc $exec_host 1234 & } } else { - nexec xterm -sb -rightbar \ - -T "IMUNES: [getNodeName $node] (console)" \ - -e "vimage $node_id $cmd" & + nexec xterm -sb -rightbar \ + -T "IMUNES: [getNodeName $node] (console)" \ + -e "vimage $node_id $cmd" & } } @@ -1256,9 +1316,11 @@ proc button1 { c x y button } { global node_list curcanvas zoom global activetool newlink curobj changed def_router_model global router pc host lanswitch frswitch rj45 hub + global oval rectangle text global lastX lastY global background selectbox global defLinkColor defLinkWidth + global resizemode resizeobj set x [$c canvasx $x] set y [$c canvasy $y] @@ -1268,71 +1330,127 @@ proc button1 { c x y button } { set curobj [$c find withtag current] set curtype [lindex [$c gettags current] 0] - if { $curtype == "node" || ( $curtype == "nodelabel" && - [nodeType [lindex [$c gettags $curobj] 1]] == "pseudo") } { - set node [lindex [$c gettags current] 1] - set wasselected \ - [expr {[lsearch [$c find withtag "selected"] \ - [$c find withtag "node && $node"]] > -1}] - if { $button == "ctrl" } { - if { $wasselected } { - $c dtag $node selected - $c delete -withtags "selectmark && $node" - } - } elseif { !$wasselected } { - $c dtag node selected - $c delete -withtags selectmark - } - if { $activetool == "select" && !$wasselected} { - selectNode $c $curobj - } + if { $curtype == "node" || + $curtype == "oval" || $curtype == "rectangle" || $curtype == "text" + || ( $curtype == "nodelabel" && + [nodeType [lindex [$c gettags $curobj] 1]] == "pseudo") } { + set node [lindex [$c gettags current] 1] + set wasselected \ + [expr {[lsearch [$c find withtag "selected"] \ + [$c find withtag "node && $node"]] > -1}] + if { $button == "ctrl" } { + if { $wasselected } { + $c dtag $node selected + $c delete -withtags "selectmark && $node" + } + } elseif { !$wasselected } { + $c dtag node selected + $c delete -withtags selectmark + } + if { $activetool == "select" && !$wasselected} { + selectNode $c $curobj + } + } elseif { $curtype == "selectmark" } { + + set t1 [$c gettags current] + set o1 [lindex $t1 1] + set type1 [nodeType $o1] + + if {$type1== "oval" || $type1== "rectangle"} { + set resizeobj $o1 + set bbox1 [$c bbox $o1] + set x1 [lindex $bbox1 0] + set y1 [lindex $bbox1 1] + set x2 [lindex $bbox1 2] + set y2 [lindex $bbox1 3] + set l 0 ;# left + set r 0 ;# right + set u 0 ;# up + set d 0 ;# down + + if { $x < [expr $x1+($x2-$x1)/8.0]} { set l 1 } + if { $x > [expr $x2-($x2-$x1)/8.0]} { set r 1 } + if { $y < [expr $y1+($y2-$y1)/8.0]} { set u 1 } + if { $y > [expr $y2-($y2-$y1)/8.0]} { set d 1 } + + if {$l==1} { + if {$u==1} { + set resizemode lu + } elseif {$d==1} { + set resizemode ld + } else { + set resizemode l + } + } elseif {$r==1} { + if {$u==1} { + set resizemode ru + } elseif {$d==1} { + set resizemode rd + } else { + set resizemode r + } + } elseif {$u==1} { + set resizemode u + } elseif {$d==1} { + set resizemode d + } else { + set resizemode false + } + } + } elseif { $button != "ctrl" || $activetool != "select" } { - $c dtag node selected - $c delete -withtags selectmark - } - if { [lsearch [.c gettags $curobj] background] != -1 } { - if { [lsearch {select link} $activetool] < 0 } { - set node [newNode $activetool] - setNodeCanvas $node $curcanvas - setNodeCoords $node "[expr {$x / $zoom}] [expr {$y / $zoom}]" - set dy 32 - if { [lsearch {router hub lanswitch rj45} $activetool] >= 0 } { - set dy 24 - } - setNodeLabelCoords $node "[expr {$x / $zoom}] \ - [expr {$y / $zoom + $dy}]" - drawNode $node - selectNode $c [$c find withtag "node && $node"] - set changed 1 - } elseif { $activetool == "select" \ - && $curtype != "node" && $curtype != "nodelabel"} { - $c config -cursor cross - set lastX $x - set lastY $y - if {$selectbox != ""} { - # We actually shouldn't get here! - $c delete $selectbox - set selectbox "" - } - } + $c dtag node selected + $c delete -withtags selectmark + } + if { [lsearch [.c gettags $curobj] background] != -1 || + [lsearch [.c gettags $curobj] grid] != -1 } { + if { [lsearch {select link oval rectangle text} $activetool] < 0 } { + set node [newNode $activetool] + setNodeCanvas $node $curcanvas + setNodeCoords $node "[expr {$x / $zoom}] [expr {$y / $zoom}]" + set dy 32 + if { [lsearch {router hub lanswitch rj45} $activetool] >= 0 } { + set dy 24 + } + setNodeLabelCoords $node "[expr {$x / $zoom}] \ + [expr {$y / $zoom + $dy}]" + drawNode $node + selectNode $c [$c find withtag "node && $node"] + set changed 1 + } elseif { $activetool == "select" \ + && $curtype != "node" && $curtype != "nodelabel"} { + $c config -cursor cross + set lastX $x + set lastY $y + if {$selectbox != ""} { + # We actually shouldn't get here! + $c delete $selectbox + set selectbox "" + } + } elseif { $activetool == "oval" || $activetool == "rectangle" } { + $c config -cursor cross + set lastX $x + set lastY $y + } elseif { $activetool == "text" } { + $c config -cursor xterm + set lastX $x + set lastY $y + } } else { - if {$curtype == "node" || $curtype == "nodelabel"} { - $c config -cursor fleur - } - if {$activetool == "link" && $curtype == "node"} { - $c config -cursor cross - set lastX [lindex [$c coords $curobj] 0] - set lastY [lindex [$c coords $curobj] 1] - set newlink [$c create line $lastX $lastY $x $y \ - -fill $defLinkColor -width $defLinkWidth \ - -tags "link"] - } - } - $c raise link background - $c raise linklabel "link || background" - $c raise interface "linklabel || link || background" - $c raise node "interface || linklabel || link || background" - $c raise nodelabel "node || interface || linklabel || link || background" + if {$curtype == "node" || $curtype == "nodelabel"} { + $c config -cursor fleur + } + if {$activetool == "link" && $curtype == "node"} { + $c config -cursor cross + set lastX [lindex [$c coords $curobj] 0] + set lastY [lindex [$c coords $curobj] 1] + set newlink [$c create line $lastX $lastY $x $y \ + -fill $defLinkColor -width $defLinkWidth \ + -tags "link"] + } + } + + raiseAll $c } @@ -1354,49 +1472,133 @@ proc button1 { c x y button } { proc button1-motion { c x y } { global activetool newlink changed global lastX lastY sizex sizey selectbox background - + global oper_mode newoval newrect resizemode set x [$c canvasx $x] set y [$c canvasy $y] set curobj [$c find withtag current] set curtype [lindex [$c gettags current] 0] if {$activetool == "link" && $newlink != ""} { - $c coords $newlink $lastX $lastY $x $y + $c coords $newlink $lastX $lastY $x $y } elseif { $activetool == "select" && \ - ( $curobj == $selectbox || $curtype == "background" )} { - if {$selectbox == ""} { - set selectbox [$c create line \ - $lastX $lastY $x $lastY $x $y $lastX $y $lastX $lastY \ - -dash {10 4} -fill black -width 1 -tags "selectbox"] - $c raise $selectbox "background || link || linklabel || interface" - } else { - $c coords $selectbox \ - $lastX $lastY $x $lastY $x $y $lastX $y $lastX $lastY - } + ( $curobj == $selectbox || $curtype == "background" || $curtype == "grid")} { + if {$selectbox == ""} { + set selectbox [$c create line \ + $lastX $lastY $x $lastY $x $y $lastX $y $lastX $lastY \ + -dash {10 4} -fill black -width 1 -tags "selectbox"] + $c raise $selectbox "background || link || linklabel || interface" + } else { + $c coords $selectbox \ + $lastX $lastY $x $lastY $x $y $lastX $y $lastX $lastY + } + } elseif { $activetool == "select" && $curtype == "text" } { + $c move $curobj [expr {$x - $lastX}] [expr {$y - $lastY}] + set changed 1 + set lastX $x + set lastY $y + $c delete [$c find withtag "selectmark"] } elseif { $activetool == "select" && $curtype == "nodelabel" \ - && [nodeType [lindex [$c gettags $curobj] 1]] != "pseudo" } { + && [nodeType [lindex [$c gettags $curobj] 1]] != "pseudo" } { $c move $curobj [expr {$x - $lastX}] [expr {$y - $lastY}] set changed 1 set lastX $x set lastY $y + # actually we should check if curobj==bkgImage + } elseif { $activetool == "oval" && \ + ( $curobj == $newoval || $curobj == $background || $curtype == "background" || $curtype == "grid")} { + # Draw a new oval + if {$newoval == ""} { + set newoval [$c create oval $lastX $lastY $x $y \ + -dash {10 4} -width 1 -tags "newoval"] + $c raise $newoval "background || link || linklabel || interface" + } else { + $c coords $newoval \ + $lastX $lastY $x $y + } + # actually we should check if curobj==bkgImage + } elseif { $activetool == "rectangle" && \ + ( $curobj == $newrect || $curobj == $background || $curtype == "background") || $curtype == "grid"} { + # Draw a new rectangle + if {$newrect == ""} { + set newrect [$c create rectangle $lastX $lastY $x $y \ + -outline blue \ + -dash {10 4} -width 1 -tags "newrect"] + $c raise $newrect "oval || background || link || linklabel || interface" + } else { + $c coords $newrect $lastX $lastY $x $y + } + } elseif { $curtype == "selectmark" } { + foreach o [$c find withtag "selected"] { + set node [lindex [$c gettags $o] 1] + set tagovi [$c gettags $o] + set koord [getNodeCoords $node] + + set oldX1 [lindex $koord 0] + set oldY1 [lindex $koord 1] + set oldX2 [lindex $koord 2] + set oldY2 [lindex $koord 3] + switch -exact -- $resizemode { + lu { + set oldX1 $x + set oldY1 $y + } + ld { + set oldX1 $x + set oldY2 $y + } + l { + set oldX1 $x + } + ru { + set oldX2 $x + set oldY1 $y + } + rd { + set oldX2 $x + set oldY2 $y + } + r { + set oldX2 $x + } + u { + set oldY1 $y + } + d { + set oldY2 $y + } + } + if {$selectbox == ""} { + set selectbox [$c create line \ + $oldX1 $oldY1 $oldX2 $oldY1 $oldX2 $oldY2 $oldX1 $oldY2 $oldX1 $oldY1 \ + -dash {10 4} -fill black -width 1 -tags "selectbox"] + $c raise $selectbox "background || link || linklabel || interface" + } else { + $c coords $selectbox \ + $oldX1 $oldY1 $oldX2 $oldY1 $oldX2 $oldY2 $oldX1 $oldY2 $oldX1 $oldY1 + } + } } else { - foreach img [$c find withtag "selected"] { - set node [lindex [$c gettags $img] 1] - set img [$c find withtag "selectmark && $node"] - $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] - set img [$c find withtag "node && $node"] - $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] - set img [$c find withtag "nodelabel && $node"] - $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] - $c addtag need_redraw withtag "link && $node" - } - foreach link [$c find withtag "link && need_redraw"] { - redrawLink [lindex [$c gettags $link] 1] - } - $c dtag link need_redraw - set changed 1 - set lastX $x - set lastY $y + foreach img [$c find withtag "selected"] { + set node [lindex [$c gettags $img] 1] + set img [$c find withtag "selectmark && $node"] + if {$curtype == "oval" || $curtype == "rectangle"} { + $c move $img [expr {($x - $lastX) / 2}] [expr {($y - $lastY) / 2}] + } else { + $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] + set img [$c find withtag "node && $node"] + $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] + set img [$c find withtag "nodelabel && $node"] + $c move $img [expr {$x - $lastX}] [expr {$y - $lastY}] + $c addtag need_redraw withtag "link && $node" + } + } + foreach link [$c find withtag "link && need_redraw"] { + redrawLink [lindex [$c gettags $link] 1] + } + $c dtag link need_redraw + set changed 1 + set lastX $x + set lastY $y } } @@ -1435,23 +1637,23 @@ proc newGUILink { lnode1 lnode2 } { set link [newLink $lnode1 $lnode2] if { $link == "" } { - return + return } if { [getNodeCanvas $lnode1] != [getNodeCanvas $lnode2] } { - set new_nodes [splitLink $link pseudo] - set orig_nodes [linkPeers $link] - set new_node1 [lindex $new_nodes 0] - set new_node2 [lindex $new_nodes 1] - set orig_node1 [lindex $orig_nodes 0] - set orig_node2 [lindex $orig_nodes 1] - set new_link1 [linkByPeers $orig_node1 $new_node1] - set new_link2 [linkByPeers $orig_node2 $new_node2] - setNodeMirror $new_node1 $new_node2 - setNodeMirror $new_node2 $new_node1 - setNodeName $new_node1 $orig_node2 - setNodeName $new_node2 $orig_node1 - setLinkMirror $new_link1 $new_link2 - setLinkMirror $new_link2 $new_link1 + set new_nodes [splitLink $link pseudo] + set orig_nodes [linkPeers $link] + set new_node1 [lindex $new_nodes 0] + set new_node2 [lindex $new_nodes 1] + set orig_node1 [lindex $orig_nodes 0] + set orig_node2 [lindex $orig_nodes 1] + set new_link1 [linkByPeers $orig_node1 $new_node1] + set new_link2 [linkByPeers $orig_node2 $new_node2] + setNodeMirror $new_node1 $new_node2 + setNodeMirror $new_node2 $new_node1 + setNodeName $new_node1 $orig_node2 + setNodeName $new_node2 $orig_node1 + setLinkMirror $new_link1 $new_link2 + setLinkMirror $new_link2 $new_link1 } redrawAll set changed 1 @@ -1479,123 +1681,172 @@ proc button1-release { c x y } { global changed undolog undolevel redolevel selectbox global lastX lastY sizex sizey zoom global autorearrange_enabled + global resizemode resizeobj + set redrawNeeded 0 set x [$c canvasx $x] set y [$c canvasy $y] $c config -cursor left_ptr if {$activetool == "link" && $newlink != ""} { - $c delete $newlink - set newlink "" - set destobj "" - foreach obj [$c find overlapping $x $y $x $y] { - if {[lindex [$c gettags $obj] 0] == "node"} { - set destobj $obj - break - } - } - if {$destobj != "" && $curobj != "" && $destobj != $curobj} { - set lnode1 [lindex [$c gettags $curobj] 1] - set lnode2 [lindex [$c gettags $destobj] 1] - if { [ifcByLogicalPeer $lnode1 $lnode2] == "" } { - set link [newLink $lnode1 $lnode2] - if { $link != "" } { - drawLink $link - redrawLink $link - updateLinkLabel $link - set changed 1 - } - } - } + $c delete $newlink + set newlink "" + set destobj "" + foreach obj [$c find overlapping $x $y $x $y] { + if {[lindex [$c gettags $obj] 0] == "node"} { + set destobj $obj + break + } + } + if {$destobj != "" && $curobj != "" && $destobj != $curobj} { + set lnode1 [lindex [$c gettags $curobj] 1] + set lnode2 [lindex [$c gettags $destobj] 1] + if { [ifcByLogicalPeer $lnode1 $lnode2] == "" } { + set link [newLink $lnode1 $lnode2] + if { $link != "" } { + drawLink $link + redrawLink $link + updateLinkLabel $link + set changed 1 + } + } + } + } elseif {$activetool == "rectangle" } { + popupRectDialog $c 0 "false" "" "" "" + } elseif {$activetool == "oval" } { + popupOvalDialog $c 0 "false" "" "" "" + } elseif {$activetool == "text" } { + textEnter $c $x $y } if { $changed == 1 } { - set regular true - if { [lindex [$c gettags $curobj] 0] == "nodelabel" } { - set node [lindex [$c gettags $curobj] 1] - selectNode $c [$c find withtag "node && $node"] - } - set selected {} - foreach img [$c find withtag "selected"] { - set node [lindex [$c gettags $img] 1] - lappend selected $node - set coords [$c coords $img] - set x [expr {[lindex $coords 0] / $zoom}] - set y [expr {[lindex $coords 1] / $zoom}] - if { $autorearrange_enabled == 0} { - set dx [expr {(int($x / $grid + 0.5) * $grid - $x) * $zoom}] - set dy [expr {(int($y / $grid + 0.5) * $grid - $y) * $zoom}] - $c move $img $dx $dy - set coords [$c coords $img] - set x [expr {[lindex $coords 0] / $zoom}] - set y [expr {[lindex $coords 1] / $zoom}] - } else { - set dx 0 - set dy 0 - } - setNodeCoords $node "$x $y" - if {$x < 0 || $y < 0 || $x > $sizex || $y > $sizey} { - set regular false - } - $c move "nodelabel && $node" $dx $dy - set coords [$c coords "nodelabel && $node"] - set x [expr {[lindex $coords 0] / $zoom}] - set y [expr {[lindex $coords 1] / $zoom}] - setNodeLabelCoords $node "$x $y" - if {$x < 0 || $y < 0 || $x > $sizex || $y > $sizey} { - set regular false - } - $c move "selectmark && $node" $dx $dy - $c addtag need_redraw withtag "link && $node" - } - if {$regular == "true"} { - foreach link [$c find withtag "link && need_redraw"] { - redrawLink [lindex [$c gettags $link] 1] - } - } else { - .c config -cursor watch - loadCfg $undolog($undolevel) - redrawAll - if {$activetool == "select" } { - selectNodes $selected - } - set changed 0 - } - $c dtag link need_redraw - } elseif {$activetool == "select" } { - if {$selectbox == ""} { - set x1 $x - set y1 $y - set autorearrange_enabled 0 - } else { - set coords [$c coords $selectbox] - set x [lindex $coords 0] - set y [lindex $coords 1] - set x1 [lindex $coords 4] - set y1 [lindex $coords 5] - $c delete $selectbox - set selectbox "" - } - set enclosed {} - foreach obj [$c find enclosed $x $y $x1 $y1] { - set tags [$c gettags $obj] - if {[lindex $tags 0] == "node" && [lsearch $tags selected] == -1} { - lappend enclosed $obj - } - } - foreach obj $enclosed { - selectNode $c $obj - } - } - $c raise link background - $c raise linklabel "link || background" - $c raise interface "linklabel || link || background" - $c raise node "interface || linklabel || link || background" - $c raise nodelabel "node || interface || linklabel || link || background" + set regular true + if { [lindex [$c gettags $curobj] 0] == "nodelabel" } { + set node [lindex [$c gettags $curobj] 1] + selectNode $c [$c find withtag "node && $node"] + } + set selected {} + foreach img [$c find withtag "selected"] { + set node [lindex [$c gettags $img] 1] + lappend selected $node + set coords [$c coords $img] + set x [expr {[lindex $coords 0] / $zoom}] + set y [expr {[lindex $coords 1] / $zoom}] + if { $autorearrange_enabled == 0} { + set dx [expr {(int($x / $grid + 0.5) * $grid - $x) * $zoom}] + set dy [expr {(int($y / $grid + 0.5) * $grid - $y) * $zoom}] + $c move $img $dx $dy + set coords [$c coords $img] + set x [expr {[lindex $coords 0] / $zoom}] + set y [expr {[lindex $coords 1] / $zoom}] + } else { + set dx 0 + set dy 0 + } + setNodeCoords $node "$x $y" + if {$x < 0 || $y < 0 || $x > $sizex || $y > $sizey} { + set regular false + } + if { [lindex [$c gettags $node] 0] == "oval" || + [lindex [$c gettags $node] 0] == "rectangle" } { + set bbox [$c bbox "selectmark && $node"] + setNodeCoords $node "$bbox" + set redrawNeeded 1 + } + if {[$c find withtag "nodelabel && $node"] != "" } { + $c move "nodelabel && $node" $dx $dy + set coords [$c coords "nodelabel && $node"] + set x [expr {[lindex $coords 0] / $zoom}] + set y [expr {[lindex $coords 1] / $zoom}] + setNodeLabelCoords $node "$x $y" + if {$x < 0 || $y < 0 || $x > $sizex || $y > $sizey} { + set regular false + } + } + $c move "selectmark && $node" $dx $dy + $c addtag need_redraw withtag "link && $node" + set changed 1 + } ;# end of: foreach img selected + if {$regular == "true"} { + foreach link [$c find withtag "link && need_redraw"] { + redrawLink [lindex [$c gettags $link] 1] + } + } else { + .c config -cursor watch + loadCfg $undolog($undolevel) + redrawAll + if {$activetool == "select" } { + selectNodes $selected + } + set changed 0 + } + $c dtag link need_redraw + + # $changed!=1 + } elseif {$activetool == "select" } { + if {$selectbox == ""} { + set x1 $x + set y1 $y + set autorearrange_enabled 0 + } else { + set coords [$c coords $selectbox] + set x [lindex $coords 0] + set y [lindex $coords 1] + set x1 [lindex $coords 4] + set y1 [lindex $coords 5] + $c delete $selectbox + set selectbox "" + } + + if { $resizemode == "false" } { + set enclosed {} + foreach obj [$c find enclosed $x $y $x1 $y1] { + set tags [$c gettags $obj] + if {[lindex $tags 0] == "node" && [lsearch $tags selected] == -1} { + lappend enclosed $obj + } + if {[lindex $tags 0] == "oval" && [lsearch $tags selected] == -1} { + lappend enclosed $obj + } + if {[lindex $tags 0] == "rectangle" && [lsearch $tags selected] == -1} { + lappend enclosed $obj + } + if {[lindex $tags 0] == "text" && [lsearch $tags selected] == -1} { + lappend enclosed $obj + } + } + foreach obj $enclosed { + selectNode $c $obj + } + } else { + setNodeCoords $resizeobj "$x $y $x1 $y1" + set redrawNeeded 1 + set resizemode false + } + } + + if { $redrawNeeded } { + set redrawNeeded 0 + redrawAll + } else { + raiseAll $c + } update updateUndoLog } +proc raiseAll { c } { + $c raise rectangle background + $c raise oval "rectangle || background" + $c raise grid "oval || rectangle || background" + $c raise link "grid || oval || rectangle || background" + $c raise linklabel "link || grid || oval || rectangle || background" + $c raise interface "linklabel || link || grid || oval || rectangle || background" + $c raise node "interface || linklabel || link || grid || oval || rectangle || background" + $c raise nodelabel "node || interface || linklabel || link || grid || oval || rectangle || background" + $c raise menuBubble "nodelabel || node || interface || linklabel || link || grid || oval || rectangle || background" + $c raise text "menuBubble || nodelabel || node || interface || linklabel || link || grid || oval || rectangle || background" +} #****f* editor.tcl/nodeEnter # NAME @@ -1619,14 +1870,14 @@ proc nodeEnter { c } { set name [getNodeName $node] set model [getNodeModel $node] if { $model != "" } { - set line "{$node} $name ($model):" + set line "{$node} $name ($model):" } else { - set line "{$node} $name:" + set line "{$node} $name:" } if { $type != "rj45" } { - foreach ifc [ifcList $node] { - set line "$line $ifc:[getIfcIPv4addr $node $ifc]" - } + foreach ifc [ifcList $node] { + set line "$line $ifc:[getIfcIPv4addr $node $ifc]" + } } .bottom.textbox config -text "$line" } @@ -1650,7 +1901,7 @@ proc linkEnter {c} { set link [lindex [$c gettags current] 1] if { [lsearch $link_list $link] == -1 } { - return + return } set line "$link: [getLinkBandwidthString $link] [getLinkDelayString $link]" .bottom.textbox config -text "$line" @@ -1692,17 +1943,17 @@ proc anyLeave {c} { #**** proc checkIntRange { str low high } { if { $str == "" } { - return 1 + return 1 } set str [string trimleft $str 0] if { $str == "" } { - set str 0 + set str 0 } if { ![string is integer $str] } { - return 0 + return 0 } if { $str < $low || $str > $high } { - return 0 + return 0 } return 1 } @@ -1729,22 +1980,22 @@ proc focusAndFlash {W {count 9}} { set bg white if { $badentry == -1 } { - return + return } else { - set badentry 1 + set badentry 1 } focus -force $W if {$count<1} { - $W configure -foreground $fg -background $bg - set badentry 0 + $W configure -foreground $fg -background $bg + set badentry 0 } else { - if {$count%2} { - $W configure -foreground $bg -background $fg - } else { - $W configure -foreground $fg -background $bg - } - after 200 [list focusAndFlash $W [expr {$count - 1}]] + if {$count%2} { + $W configure -foreground $bg -background $fg + } else { + $W configure -foreground $fg -background $bg + } + after 200 [list focusAndFlash $W [expr {$count - 1}]] } } @@ -1775,22 +2026,31 @@ proc popupConfigDialog { c } { set tk_type [lindex [$c gettags current] 0] set target [lindex [$c gettags current] 1] if { [lsearch {node nodelabel interface} $tk_type] > -1 } { - set object_type node + set object_type node } if { [lsearch {link linklabel} $tk_type] > -1 } { - set object_type link + set object_type link + } + if { [lsearch {oval} $tk_type] > -1 } { + set object_type oval + } + if { [lsearch {rectangle} $tk_type] > -1 } { + set object_type rectangle + } + if { [lsearch {text} $tk_type] > -1 } { + set object_type text } if { "$object_type" == ""} { - destroy $wi - return + destroy $wi + return } if { $object_type == "link" } { - set n0 [lindex [linkPeers $target] 0] - set n1 [lindex [linkPeers $target] 1] - if { [nodeType $n0] == "rj45" || [nodeType $n1] == "rj45" } { - destroy $wi - return - } + set n0 [lindex [linkPeers $target] 0] + set n1 [lindex [linkPeers $target] 1] + if { [nodeType $n0] == "rj45" || [nodeType $n1] == "rj45" } { + destroy $wi + return + } } $c dtag node selected $c delete -withtags selectmark @@ -1799,268 +2059,284 @@ proc popupConfigDialog { c } { node { set type [nodeType $target] if { $type == "pseudo" } { - # - # Hyperlink to another canvas - # - destroy $wi - set curcanvas [getNodeCanvas [getNodeMirror $target]] - switchCanvas none - return + # + # Hyperlink to another canvas + # + destroy $wi + set curcanvas [getNodeCanvas [getNodeMirror $target]] + switchCanvas none + return } set model [getNodeModel $target] set router_model $model wm title $wi "$type configuration" frame $wi.ftop -borderwidth 4 if { $type == "rj45" } { - label $wi.ftop.name_label -text "Physical interface:" + label $wi.ftop.name_label -text "Physical interface:" } else { - label $wi.ftop.name_label -text "Node name:" + label $wi.ftop.name_label -text "Node name:" } entry $wi.ftop.name -bg white -width 16 \ - -validate focus -invcmd "focusAndFlash %W" + -validate focus -invcmd "focusAndFlash %W" $wi.ftop.name insert 0 [getNodeName $target] pack $wi.ftop.name $wi.ftop.name_label -side right -padx 4 -pady 4 pack $wi.ftop -side top if { $type == "router" } { - frame $wi.model -borderwidth 4 - label $wi.model.label -text "Model:" - if { $oper_mode == "edit" } { - eval tk_optionMenu $wi.model.menu router_model \ - $supp_router_models - } else { - tk_optionMenu $wi.model.menu router_model $model - } - pack $wi.model.menu $wi.model.label -side right -padx 0 -pady 0 - pack $wi.model -side top + frame $wi.model -borderwidth 4 + label $wi.model.label -text "Model:" + if { $oper_mode == "edit" } { + eval tk_optionMenu $wi.model.menu router_model \ + $supp_router_models + } else { + tk_optionMenu $wi.model.menu router_model $model + } + pack $wi.model.menu $wi.model.label -side right -padx 0 -pady 0 + pack $wi.model -side top } if { $type != "rj45" } { - foreach ifc [lsort -ascii [ifcList $target]] { - labelframe $wi.if$ifc -padx 4 -pady 4 - frame $wi.if$ifc.label - label $wi.if$ifc.label.txt -text "Interface $ifc:" - pack $wi.if$ifc.label.txt -side left -anchor w - if {[[typemodel $target].layer] == "NETWORK"} { - global ifoper$ifc - set ifoper$ifc [getIfcOperState $target $ifc] - radiobutton $wi.if$ifc.label.up -text "up" \ - -variable ifoper$ifc -value up - radiobutton $wi.if$ifc.label.down -text "down" \ - -variable ifoper$ifc -value down - label $wi.if$ifc.label.mtul -text "MTU" \ - -anchor e -width 5 - spinbox $wi.if$ifc.label.mtuv -bg white -width 4 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.if$ifc.label.mtuv insert 0 \ - [getIfcMTU $target $ifc] - if {![string first eth $ifc]} { - $wi.if$ifc.label.mtuv configure \ - -from 256 -to 1500 -increment 2 \ - -vcmd {checkIntRange %P 256 1500} - } else { - $wi.if$ifc.label.mtuv configure \ - -from 256 -to 2044 -increment 2 \ - -vcmd {checkIntRange %P 256 2044} - } - pack $wi.if$ifc.label.up $wi.if$ifc.label.down \ - $wi.if$ifc.label.mtul $wi.if$ifc.label.mtuv \ - -side left -anchor w - } - pack $wi.if$ifc.label -side top -anchor w - frame $wi.if$ifc.tab -width 10 - frame $wi.if$ifc.cfg - - # - # Queue config - # - global ifqdisc$ifc ifqdrop$ifc - set ifqdisc$ifc [getIfcQDisc $target $ifc] - set ifqdrop$ifc [getIfcQDrop $target $ifc] - frame $wi.if$ifc.cfg.q - label $wi.if$ifc.cfg.q.l1 -text "Queue" -anchor w - tk_optionMenu $wi.if$ifc.cfg.q.disc ifqdisc$ifc \ - FIFO DRR WFQ - tk_optionMenu $wi.if$ifc.cfg.q.drop ifqdrop$ifc \ - drop-tail drop-head - label $wi.if$ifc.cfg.q.l2 -text "len" \ - -anchor e -width 3 - spinbox $wi.if$ifc.cfg.q.len -bg white -width 4 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.if$ifc.cfg.q.len insert 0 [getIfcQLen $target $ifc] - $wi.if$ifc.cfg.q.len configure \ - -from 5 -to 4096 -increment 1 \ - -vcmd {checkIntRange %P 5 4096} - pack $wi.if$ifc.cfg.q.l1 $wi.if$ifc.cfg.q.disc \ - $wi.if$ifc.cfg.q.drop -side left -anchor w - pack $wi.if$ifc.cfg.q.l2 $wi.if$ifc.cfg.q.len \ - -side left -anchor e - pack $wi.if$ifc.cfg.q -side top -anchor w - - if {[lsearch {router pc host} $type] >= 0} { - # - # IPv4 address - # - frame $wi.if$ifc.cfg.ipv4 - label $wi.if$ifc.cfg.ipv4.addrl -text "IPv4 address" \ - -anchor w - entry $wi.if$ifc.cfg.ipv4.addrv -bg white -width 30 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.if$ifc.cfg.ipv4.addrv insert 0 \ - [getIfcIPv4addr $target $ifc] - $wi.if$ifc.cfg.ipv4.addrv configure \ - -vcmd {checkIPv4Net %P} - pack $wi.if$ifc.cfg.ipv4.addrl \ - $wi.if$ifc.cfg.ipv4.addrv -side left - pack $wi.if$ifc.cfg.ipv4 -side top -anchor w - - # - # IPv6 address - # - frame $wi.if$ifc.cfg.ipv6 - label $wi.if$ifc.cfg.ipv6.addrl -text "IPv6 address" \ - -anchor w - entry $wi.if$ifc.cfg.ipv6.addrv -bg white -width 30 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.if$ifc.cfg.ipv6.addrv insert 0 \ - [getIfcIPv6addr $target $ifc] - $wi.if$ifc.cfg.ipv6.addrv configure -vcmd {checkIPv6Net %P} - pack $wi.if$ifc.cfg.ipv6.addrl \ - $wi.if$ifc.cfg.ipv6.addrv -side left - pack $wi.if$ifc.cfg.ipv6 -side top -anchor w - } - pack $wi.if$ifc.tab $wi.if$ifc.cfg -side left - pack $wi.if$ifc -side top -anchor w -fill both - } + foreach ifc [lsort -ascii [ifcList $target]] { + labelframe $wi.if$ifc -padx 4 -pady 4 + frame $wi.if$ifc.label + label $wi.if$ifc.label.txt -text "Interface $ifc:" + pack $wi.if$ifc.label.txt -side left -anchor w + if {[[typemodel $target].layer] == "NETWORK"} { + global ifoper$ifc + set ifoper$ifc [getIfcOperState $target $ifc] + radiobutton $wi.if$ifc.label.up -text "up" \ + -variable ifoper$ifc -value up + radiobutton $wi.if$ifc.label.down -text "down" \ + -variable ifoper$ifc -value down + label $wi.if$ifc.label.mtul -text "MTU" \ + -anchor e -width 5 + spinbox $wi.if$ifc.label.mtuv -bg white -width 4 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.if$ifc.label.mtuv insert 0 \ + [getIfcMTU $target $ifc] + if {![string first eth $ifc]} { + $wi.if$ifc.label.mtuv configure \ + -from 256 -to 1500 -increment 2 \ + -vcmd {checkIntRange %P 256 1500} + } else { + $wi.if$ifc.label.mtuv configure \ + -from 256 -to 2044 -increment 2 \ + -vcmd {checkIntRange %P 256 2044} + } + pack $wi.if$ifc.label.up $wi.if$ifc.label.down \ + $wi.if$ifc.label.mtul $wi.if$ifc.label.mtuv \ + -side left -anchor w + } + pack $wi.if$ifc.label -side top -anchor w + frame $wi.if$ifc.tab -width 10 + frame $wi.if$ifc.cfg + + # + # Queue config + # + global ifqdisc$ifc ifqdrop$ifc + set ifqdisc$ifc [getIfcQDisc $target $ifc] + set ifqdrop$ifc [getIfcQDrop $target $ifc] + frame $wi.if$ifc.cfg.q + label $wi.if$ifc.cfg.q.l1 -text "Queue" -anchor w + tk_optionMenu $wi.if$ifc.cfg.q.disc ifqdisc$ifc \ + FIFO DRR WFQ + tk_optionMenu $wi.if$ifc.cfg.q.drop ifqdrop$ifc \ + drop-tail drop-head + label $wi.if$ifc.cfg.q.l2 -text "len" \ + -anchor e -width 3 + spinbox $wi.if$ifc.cfg.q.len -bg white -width 4 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.if$ifc.cfg.q.len insert 0 [getIfcQLen $target $ifc] + $wi.if$ifc.cfg.q.len configure \ + -from 5 -to 4096 -increment 1 \ + -vcmd {checkIntRange %P 5 4096} + pack $wi.if$ifc.cfg.q.l1 $wi.if$ifc.cfg.q.disc \ + $wi.if$ifc.cfg.q.drop -side left -anchor w + pack $wi.if$ifc.cfg.q.l2 $wi.if$ifc.cfg.q.len \ + -side left -anchor e + pack $wi.if$ifc.cfg.q -side top -anchor w + + if {[lsearch {router pc host} $type] >= 0} { + # + # IPv4 address + # + frame $wi.if$ifc.cfg.ipv4 + label $wi.if$ifc.cfg.ipv4.addrl -text "IPv4 address" \ + -anchor w + entry $wi.if$ifc.cfg.ipv4.addrv -bg white -width 30 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.if$ifc.cfg.ipv4.addrv insert 0 \ + [getIfcIPv4addr $target $ifc] + $wi.if$ifc.cfg.ipv4.addrv configure \ + -vcmd {checkIPv4Net %P} + pack $wi.if$ifc.cfg.ipv4.addrl \ + $wi.if$ifc.cfg.ipv4.addrv -side left + pack $wi.if$ifc.cfg.ipv4 -side top -anchor w + + # + # IPv6 address + # + frame $wi.if$ifc.cfg.ipv6 + label $wi.if$ifc.cfg.ipv6.addrl -text "IPv6 address" \ + -anchor w + entry $wi.if$ifc.cfg.ipv6.addrv -bg white -width 30 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.if$ifc.cfg.ipv6.addrv insert 0 \ + [getIfcIPv6addr $target $ifc] + $wi.if$ifc.cfg.ipv6.addrv configure -vcmd {checkIPv6Net %P} + pack $wi.if$ifc.cfg.ipv6.addrl \ + $wi.if$ifc.cfg.ipv6.addrv -side left + pack $wi.if$ifc.cfg.ipv6 -side top -anchor w + } + pack $wi.if$ifc.tab $wi.if$ifc.cfg -side left + pack $wi.if$ifc -side top -anchor w -fill both + } } if {[lsearch {router pc host} $type] >= 0} { - # - # Static routes - # - set routes [concat [getStatIPv4routes $target] \ - [getStatIPv6routes $target]] - labelframe $wi.statrt -padx 4 -pady 4 - label $wi.statrt.label -text "Static routes:" - pack $wi.statrt.label -side top -anchor w - frame $wi.statrt.tab -width 10 - frame $wi.statrt.tab1 -width 10 - frame $wi.statrt.cfg - set h [expr {[llength $routes] + 1}] - if { $h < 2 } { - set h 2 - } - text $wi.statrt.cfg.text -font arial -bg white \ - -width 42 -height $h -takefocus 0 - foreach route $routes { - $wi.statrt.cfg.text insert end "$route " - } - pack $wi.statrt.cfg.text -expand yes - pack $wi.statrt.tab $wi.statrt.cfg $wi.statrt.tab1 -side left - pack $wi.statrt -side top -anchor w -fill both + # + # Static routes + # + set routes [concat [getStatIPv4routes $target] \ + [getStatIPv6routes $target]] + labelframe $wi.statrt -padx 4 -pady 4 + label $wi.statrt.label -text "Static routes:" + pack $wi.statrt.label -side top -anchor w + frame $wi.statrt.tab -width 10 + frame $wi.statrt.tab1 -width 10 + frame $wi.statrt.cfg + set h [expr {[llength $routes] + 1}] + if { $h < 2 } { + set h 2 + } + text $wi.statrt.cfg.text -font arial -bg white \ + -width 42 -height $h -takefocus 0 + foreach route $routes { + $wi.statrt.cfg.text insert end "$route +" + } + pack $wi.statrt.cfg.text -expand yes + pack $wi.statrt.tab $wi.statrt.cfg $wi.statrt.tab1 -side left + pack $wi.statrt -side top -anchor w -fill both } if {[lsearch {router pc host} $type] >= 0} { - # - # Custom startup config - # - global customEnabled - labelframe $wi.custom -padx 4 -pady 4 - frame $wi.custom.label - label $wi.custom.label.txt -text "Custom startup config:" - pack $wi.custom.label.txt -side left -anchor w - set customEnabled [getCustomEnabled $target] - radiobutton $wi.custom.label.enabled -text "enabled" \ - -variable customEnabled -value true - radiobutton $wi.custom.label.disabled -text "disabled" \ - -variable customEnabled -value false - pack $wi.custom.label.enabled $wi.custom.label.disabled \ - -side left -anchor w - pack $wi.custom.label -side top -anchor w - frame $wi.custom.cfg - button $wi.custom.cfg.generate -text "Generate" \ - -command "cfgGenerate $target" - button $wi.custom.cfg.edit -text "Edit" \ - -command "editStartupCfg $target 0" - button $wi.custom.cfg.clear -text "Clear" \ - -command "setCustomConfig $target {} {} {} 0" - pack $wi.custom.cfg.generate $wi.custom.cfg.edit \ - $wi.custom.cfg.clear -side left - - pack $wi.custom.label -side top -anchor w - pack $wi.custom.cfg -side top - pack $wi.custom -side top -anchor w -fill both - - # - # IPsec configuration: - # - global ipsecEnabled - global showIPsecConfig - if { $showIPsecConfig == 1 } { - labelframe $wi.ipsec -padx 4 -pady 4 - frame $wi.ipsec.label - label $wi.ipsec.label.txt -text "Manual IPsec configuration:" - pack $wi.ipsec.label.txt -side left -anchor w - set ipsecEnabled [getIpsecEnabled $target] - radiobutton $wi.ipsec.label.enabled -text "enabled" \ - -variable ipsecEnabled -value true - radiobutton $wi.ipsec.label.disabled -text "disabled" \ - -variable ipsecEnabled -value false - pack $wi.ipsec.label.enabled $wi.ipsec.label.disabled \ - -side left -anchor w - pack $wi.ipsec.label -side top -anchor w - frame $wi.ipsec.cfg - set delete "0" - set view "0" - button $wi.ipsec.cfg.add -text "Add SA/SP" \ - -command "viewIpsecCfg $target $delete $view" - set delete "0" - set view "1" - button $wi.ipsec.cfg.view -text "Edit SAs/SPs" \ - -command "viewIpsecCfg $target $delete $view" - pack $wi.ipsec.cfg.add $wi.ipsec.cfg.view -side left - pack $wi.ipsec.label -side top -anchor w - pack $wi.ipsec.cfg -side top - pack $wi.ipsec -side top -anchor w -fill both - } - - # - # CPU scheduling parameters - # - labelframe $wi.cpu -padx 4 -pady 4 - label $wi.cpu.minl -text "CPU min%" -anchor w - spinbox $wi.cpu.mine -bg white -width 3 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.cpu.mine insert 0 [lindex \ - [lsearch -inline [getNodeCPUConf $target] {min *}] 1] - $wi.cpu.mine configure \ - -vcmd {checkIntRange %P 1 90} \ - -from 0 -to 90 -increment 1 - label $wi.cpu.maxl -text " max%" -anchor w - spinbox $wi.cpu.maxe -bg white -width 3 \ - -validate focus -invcmd "focusAndFlash %W" - set cpumax [lindex \ - [lsearch -inline [getNodeCPUConf $target] {max *}] 1] - if { $cpumax == "" } { - set cpumax 100 - } - $wi.cpu.maxe insert 0 $cpumax - $wi.cpu.maxe configure \ - -vcmd {checkIntRange %P 1 100} \ - -from 1 -to 100 -increment 1 - label $wi.cpu.weightl -text " weight" -anchor w - spinbox $wi.cpu.weighte -bg white -width 2 \ - -validate focus -invcmd "focusAndFlash %W" - $wi.cpu.weighte insert 0 [lindex \ - [lsearch -inline [getNodeCPUConf $target] {weight *}] 1] - $wi.cpu.weighte configure \ - -vcmd {checkIntRange %P 1 10} \ - -from 1 -to 10 -increment 1 - pack $wi.cpu.minl $wi.cpu.mine \ - $wi.cpu.maxl $wi.cpu.maxe \ - $wi.cpu.weightl $wi.cpu.weighte -side left - pack $wi.cpu -side top -anchor w -fill both + # + # Custom startup config + # + global customEnabled + labelframe $wi.custom -padx 4 -pady 4 + frame $wi.custom.label + label $wi.custom.label.txt -text "Custom startup config:" + pack $wi.custom.label.txt -side left -anchor w + set customEnabled [getCustomEnabled $target] + radiobutton $wi.custom.label.enabled -text "enabled" \ + -variable customEnabled -value true + radiobutton $wi.custom.label.disabled -text "disabled" \ + -variable customEnabled -value false + pack $wi.custom.label.enabled $wi.custom.label.disabled \ + -side left -anchor w + pack $wi.custom.label -side top -anchor w + frame $wi.custom.cfg + button $wi.custom.cfg.generate -text "Generate" \ + -command "cfgGenerate $target" + button $wi.custom.cfg.edit -text "Edit" \ + -command "editStartupCfg $target 0" + button $wi.custom.cfg.clear -text "Clear" \ + -command "setCustomConfig $target {} {} {} 0" + pack $wi.custom.cfg.generate $wi.custom.cfg.edit \ + $wi.custom.cfg.clear -side left + + pack $wi.custom.label -side top -anchor w + pack $wi.custom.cfg -side top + pack $wi.custom -side top -anchor w -fill both + + # + # IPsec configuration: + # + global ipsecEnabled + global showIPsecConfig + if { $showIPsecConfig == 1 } { + labelframe $wi.ipsec -padx 4 -pady 4 + frame $wi.ipsec.label + label $wi.ipsec.label.txt -text "Manual IPsec configuration:" + pack $wi.ipsec.label.txt -side left -anchor w + set ipsecEnabled [getIpsecEnabled $target] + radiobutton $wi.ipsec.label.enabled -text "enabled" \ + -variable ipsecEnabled -value true + radiobutton $wi.ipsec.label.disabled -text "disabled" \ + -variable ipsecEnabled -value false + pack $wi.ipsec.label.enabled $wi.ipsec.label.disabled \ + -side left -anchor w + pack $wi.ipsec.label -side top -anchor w + frame $wi.ipsec.cfg + set delete "0" + set view "0" + button $wi.ipsec.cfg.add -text "Add SA/SP" \ + -command "viewIpsecCfg $target $delete $view" + set delete "0" + set view "1" + button $wi.ipsec.cfg.view -text "Edit SAs/SPs" \ + -command "viewIpsecCfg $target $delete $view" + pack $wi.ipsec.cfg.add $wi.ipsec.cfg.view -side left + pack $wi.ipsec.label -side top -anchor w + pack $wi.ipsec.cfg -side top + pack $wi.ipsec -side top -anchor w -fill both + } + + # + # CPU scheduling parameters + # + labelframe $wi.cpu -padx 4 -pady 4 + label $wi.cpu.minl -text "CPU min%" -anchor w + spinbox $wi.cpu.mine -bg white -width 3 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.cpu.mine insert 0 [lindex \ + [lsearch -inline [getNodeCPUConf $target] {min *}] 1] + $wi.cpu.mine configure \ + -vcmd {checkIntRange %P 1 90} \ + -from 0 -to 90 -increment 1 + label $wi.cpu.maxl -text " max%" -anchor w + spinbox $wi.cpu.maxe -bg white -width 3 \ + -validate focus -invcmd "focusAndFlash %W" + set cpumax [lindex \ + [lsearch -inline [getNodeCPUConf $target] {max *}] 1] + if { $cpumax == "" } { + set cpumax 100 + } + $wi.cpu.maxe insert 0 $cpumax + $wi.cpu.maxe configure \ + -vcmd {checkIntRange %P 1 100} \ + -from 1 -to 100 -increment 1 + label $wi.cpu.weightl -text " weight" -anchor w + spinbox $wi.cpu.weighte -bg white -width 2 \ + -validate focus -invcmd "focusAndFlash %W" + $wi.cpu.weighte insert 0 [lindex \ + [lsearch -inline [getNodeCPUConf $target] {weight *}] 1] + $wi.cpu.weighte configure \ + -vcmd {checkIntRange %P 1 10} \ + -from 1 -to 10 -increment 1 + pack $wi.cpu.minl $wi.cpu.mine \ + $wi.cpu.maxl $wi.cpu.maxe \ + $wi.cpu.weightl $wi.cpu.weighte -side left + pack $wi.cpu -side top -anchor w -fill both } } + oval { + destroy $wi + annotationConfig $c $target + return + } + rectangle { + destroy $wi + annotationConfig $c $target + return + } + text { + destroy $wi + textConfig $c $target + return + } link { wm title $wi "link configuration" frame $wi.ftop -borderwidth 6 @@ -2120,8 +2396,8 @@ proc popupConfigDialog { c } { frame $wi.color -borderwidth 4 label $wi.color.label -anchor e -text "Color:" set link_color [getLinkColor $target] - tk_optionMenu $wi.color.value link_color \ - Red Green Blue Yellow Magenta Cyan Black + tk_optionMenu $wi.color.value link_color \ + Red Green Blue Yellow Magenta Cyan Black pack $wi.color.value $wi.color.label -side right pack $wi.color -side top -anchor e @@ -2146,8 +2422,10 @@ proc popupConfigDialog { c } { "set badentry -1 ; destroy $wi" pack $wi.butt.cancel $wi.butt.apply -side right pack $wi.butt -side bottom + bind $wi "set badentry -1; destroy $wi" + bind $wi "popupConfigApply $wi $object_type $target 0" after 100 { - grab .popup + grab .popup } } @@ -2165,7 +2443,7 @@ proc popupConfigDialog { c } { # * node_id -- node id #**** proc cfgGenerate { node } { - set id "generic" + set id "generic" set cmd [[typemodel $node].bootcmd $node] set cfg [[typemodel $node].cfggen $node] setCustomConfig $node $id $cmd $cfg 0 @@ -2182,8 +2460,8 @@ proc cfgGenerate { node } { # INPUTS # * node_id -- node id # * deleted -- if deleted is set to 1, editStartupCfg -# has been invoked after deleting custom-config -# with specified custom-config-id. +# has been invoked after deleting custom-config +# with specified custom-config-id. #**** proc editStartupCfg { node deleted } { global viewcustomid @@ -2192,9 +2470,9 @@ proc editStartupCfg { node deleted } { set customCfgList [getCustomConfig $node] set customidlist {} foreach customCfg $customCfgList { - set customid [lindex [lsearch -inline $customCfg \ - "custom-config-id *"] 1] - lappend customidlist $customid + set customid [lindex [lsearch -inline $customCfg \ + "custom-config-id *"] 1] + lappend customidlist $customid } set edit 1 @@ -2203,91 +2481,91 @@ proc editStartupCfg { node deleted } { } if { $customidlist == "" } { - set warning "Custom config list is empty." - tk_messageBox -message $warning -type ok -icon warning \ - -title "Custom configuration warning" + set warning "Custom config list is empty." + tk_messageBox -message $warning -type ok -icon warning \ + -title "Custom configuration warning" } else { - set w .cfgeditor - catch {destroy $w} - toplevel $w -takefocus 1 - grab $w - wm title $w "Custom config $node" - wm iconname $w "$node" - labelframe $w.custom -padx 4 -pady 4 - if { $edit == "1" } { - frame $w.custom.viewid -borderwidth 4 - label $w.custom.viewid.label -text "View custom-config:" - pack $w.custom.viewid.label -side left -anchor w - eval {tk_optionMenu $w.custom.viewid.optmenu viewcustomid} \ - $customidlist - pack $w.custom.viewid.label $w.custom.viewid.optmenu \ - -side left -anchor w - pack $w.custom.viewid -side top -anchor w - button $w.custom.viewid.button -text View \ - -command "editStartupCfg $node 0" - pack $w.custom.viewid.button -side right - - foreach element $customCfgList { - set cid \ - [lindex [lsearch -inline $element "custom-config-id *"] 1] - if { $viewcustomid == $cid } { - set customCfg $element - } - } - } - - frame $w.custom.id -borderwidth 4 - label $w.custom.id.label -text "Custom config id:" - entry $w.custom.id.text -bg white -width 30 - if { $customCfg != {} } { - set ccfg [getConfig $customCfg "custom-config-id"] - } else { - set ccfg "" - } - $w.custom.id.text insert 0 $ccfg - pack $w.custom.id.text $w.custom.id.label -side right -padx 4 -pady 4 - pack $w.custom.id -side top -anchor w - pack $w.custom -side top -anchor w -fill both - - frame $w.ftop -borderwidth 4 - label $w.ftop.label -text "Startup command:" - entry $w.ftop.cmd -bg white -width 64 - if { $customCfg != {} } { - set ccmd [getConfig $customCfg "custom-command"] - } else { - set ccmd "" - } - $w.ftop.cmd insert 0 $ccmd - pack $w.ftop.cmd $w.ftop.label -side right -padx 4 -pady 4 - pack $w.ftop -side top -anchor w - - text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" \ - -setgrid 1 -height 20 -undo 1 -autosep 1 -background white - focus $w.text - scrollbar $w.scroll -command "$w.text yview" - - frame $w.buttons - pack $w.buttons -side bottom - button $w.buttons.apply -text "Apply" \ - -command "customConfigApply $w $node" - button $w.buttons.close -text Close -command "destroy $w" - button $w.buttons.delete -text Delete -command \ - "deleteCustomConfig $w $node $viewcustomid {} {} 1" - pack $w.buttons.apply $w.buttons.close $w.buttons.delete -side left - - pack $w.scroll -side right -fill y - pack $w.text -expand yes -fill both - - if { $customCfg != {} } { - set ccfg [getConfig $customCfg "config"] - } else { - set ccfg "" - } - - foreach line $ccfg { - $w.text insert end "$line\n" - } - $w.text mark set insert 0.0 + set w .cfgeditor + catch {destroy $w} + toplevel $w -takefocus 1 + grab $w + wm title $w "Custom config $node" + wm iconname $w "$node" + labelframe $w.custom -padx 4 -pady 4 + if { $edit == "1" } { + frame $w.custom.viewid -borderwidth 4 + label $w.custom.viewid.label -text "View custom-config:" + pack $w.custom.viewid.label -side left -anchor w + eval {tk_optionMenu $w.custom.viewid.optmenu viewcustomid} \ + $customidlist + pack $w.custom.viewid.label $w.custom.viewid.optmenu \ + -side left -anchor w + pack $w.custom.viewid -side top -anchor w + button $w.custom.viewid.button -text View \ + -command "editStartupCfg $node 0" + pack $w.custom.viewid.button -side right + + foreach element $customCfgList { + set cid \ + [lindex [lsearch -inline $element "custom-config-id *"] 1] + if { $viewcustomid == $cid } { + set customCfg $element + } + } + } + + frame $w.custom.id -borderwidth 4 + label $w.custom.id.label -text "Custom config id:" + entry $w.custom.id.text -bg white -width 30 + if { $customCfg != {} } { + set ccfg [getConfig $customCfg "custom-config-id"] + } else { + set ccfg "" + } + $w.custom.id.text insert 0 $ccfg + pack $w.custom.id.text $w.custom.id.label -side right -padx 4 -pady 4 + pack $w.custom.id -side top -anchor w + pack $w.custom -side top -anchor w -fill both + + frame $w.ftop -borderwidth 4 + label $w.ftop.label -text "Startup command:" + entry $w.ftop.cmd -bg white -width 64 + if { $customCfg != {} } { + set ccmd [getConfig $customCfg "custom-command"] + } else { + set ccmd "" + } + $w.ftop.cmd insert 0 $ccmd + pack $w.ftop.cmd $w.ftop.label -side right -padx 4 -pady 4 + pack $w.ftop -side top -anchor w + + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" \ + -setgrid 1 -height 20 -undo 1 -autosep 1 -background white + focus $w.text + scrollbar $w.scroll -command "$w.text yview" + + frame $w.buttons + pack $w.buttons -side bottom + button $w.buttons.apply -text "Apply" \ + -command "customConfigApply $w $node" + button $w.buttons.close -text Close -command "destroy $w" + button $w.buttons.delete -text Delete -command \ + "deleteCustomConfig $w $node $viewcustomid {} {} 1" + pack $w.buttons.apply $w.buttons.close $w.buttons.delete -side left + + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + if { $customCfg != {} } { + set ccfg [getConfig $customCfg "config"] + } else { + set ccfg "" + } + + foreach line $ccfg { + $w.text insert end "$line\n" + } + $w.text mark set insert 0.0 } } @@ -2311,11 +2589,11 @@ proc customConfigApply { w node } { set newid [$w.custom.id.text get] set newconf [split [$w.text get 0.0 end] "\n"] while { [lindex $newconf end] == {} && $newconf != {} } { - set newconf [lreplace $newconf end end] + set newconf [lreplace $newconf end end] } if { [getCustomCmd $node] != $newcmd || \ - [getCustomConfig $node] != $newconf } { - set changed 1 + [getCustomConfig $node] != $newconf } { + set changed 1 } setCustomConfig $node $newid $newcmd $newconf 0 destroy $w @@ -2347,17 +2625,17 @@ proc popupConfigApply { wi object_type target phase } { global customEnabled ipsecEnabled global eid global showIPsecConfig - + $wi config -cursor watch update if { $phase == 0 } { - set badentry 0 - focus . - after 100 "popupConfigApply $wi $object_type $target 1" - return + set badentry 0 + focus . + after 100 "popupConfigApply $wi $object_type $target 1" + return } elseif { $badentry } { - $wi config -cursor left_ptr - return + $wi config -cursor left_ptr + return } switch -exact -- $object_type { # @@ -2368,45 +2646,45 @@ proc popupConfigApply { wi object_type target phase } { set model [getNodeModel $target] set name [string trim [$wi.ftop.name get]] if { $name != [getNodeName $target] } { - setNodeName $target $name - set changed 1 + setNodeName $target $name + set changed 1 } if { $oper_mode == "edit" && $type == "router" && \ - $router_model != $model } { - setNodeModel $target $router_model - set changed 1 + $router_model != $model } { + setNodeModel $target $router_model + set changed 1 } # # Queue config # foreach ifc [ifcList $target] { - if { [nodeType [peerByIfc $target $ifc]] != "rj45" && \ - [nodeType $target] != "rj45" } { - global ifqdisc$ifc ifqdrop$ifc - set qdisc [subst $[subst ifqdisc$ifc]] - set oldqdisc [getIfcQDisc $target $ifc] - if { $qdisc != $oldqdisc } { - setIfcQDisc $target $ifc $qdisc - set changed 1 - } - set qdrop [subst $[subst ifqdrop$ifc]] - set oldqdrop [getIfcQDrop $target $ifc] - if { $qdrop != $oldqdrop } { - setIfcQDrop $target $ifc $qdrop - set changed 1 - } - set len [$wi.if$ifc.cfg.q.len get] - set oldlen [getIfcQLen $target $ifc] - if { $len != $oldlen } { - setIfcQLen $target $ifc $len - set changed 1 - } - } - } + if { [nodeType [peerByIfc $target $ifc]] != "rj45" && \ + [nodeType $target] != "rj45" } { + global ifqdisc$ifc ifqdrop$ifc + set qdisc [subst $[subst ifqdisc$ifc]] + set oldqdisc [getIfcQDisc $target $ifc] + if { $qdisc != $oldqdisc } { + setIfcQDisc $target $ifc $qdisc + set changed 1 + } + set qdrop [subst $[subst ifqdrop$ifc]] + set oldqdrop [getIfcQDrop $target $ifc] + if { $qdrop != $oldqdrop } { + setIfcQDrop $target $ifc $qdrop + set changed 1 + } + set len [$wi.if$ifc.cfg.q.len get] + set oldlen [getIfcQLen $target $ifc] + if { $len != $oldlen } { + setIfcQLen $target $ifc $len + set changed 1 + } + } + } if {[[typemodel $target].layer] == "NETWORK"} { - foreach ifc [ifcList $target] { + foreach ifc [ifcList $target] { # # Operational state # @@ -2497,9 +2775,9 @@ proc popupConfigApply { wi object_type target phase } { set changed 1 } - if { $showIPsecConfig == 0 } { - set ipsecEnabled 0 - } + if { $showIPsecConfig == 0 } { + set ipsecEnabled 0 + } set oldipsecenabled [getIpsecEnabled $target] if {$oldipsecenabled != $ipsecEnabled} { setIpsecEnabled $target $ipsecEnabled @@ -2534,58 +2812,58 @@ proc popupConfigApply { wi object_type target phase } { set mirror [getLinkMirror $target] set bw [$wi.bandwidth.value get] if { $bw != [getLinkBandwidth $target] } { - setLinkBandwidth $target [$wi.bandwidth.value get] - if { $mirror != "" } { - setLinkBandwidth $mirror [$wi.bandwidth.value get] - } - set changed 1 + setLinkBandwidth $target [$wi.bandwidth.value get] + if { $mirror != "" } { + setLinkBandwidth $mirror [$wi.bandwidth.value get] + } + set changed 1 } set dly [$wi.delay.value get] if { $dly != [getLinkDelay $target] } { - setLinkDelay $target [$wi.delay.value get] - if { $mirror != "" } { - setLinkDelay $mirror [$wi.delay.value get] - } - set changed 1 + setLinkDelay $target [$wi.delay.value get] + if { $mirror != "" } { + setLinkDelay $mirror [$wi.delay.value get] + } + set changed 1 } set ber [$wi.ber.value get] if { $ber != [getLinkBER $target] } { - setLinkBER $target [$wi.ber.value get] - if { $mirror != "" } { - setLinkBER $mirror [$wi.ber.value get] - } - set changed 1 + setLinkBER $target [$wi.ber.value get] + if { $mirror != "" } { + setLinkBER $mirror [$wi.ber.value get] + } + set changed 1 } set dup [$wi.dup.value get] if { $dup != [getLinkDup $target] } { - setLinkDup $target [$wi.dup.value get] - if { $mirror != "" } { - setLinkDup $mirror [$wi.dup.value get] - } - set changed 1 + setLinkDup $target [$wi.dup.value get] + if { $mirror != "" } { + setLinkDup $mirror [$wi.dup.value get] + } + set changed 1 } if { $link_color != [getLinkColor $target] } { - setLinkColor $target $link_color - if { $mirror != "" } { - setLinkColor $mirror $link_color - } - set changed 1 + setLinkColor $target $link_color + if { $mirror != "" } { + setLinkColor $mirror $link_color + } + set changed 1 } set width [$wi.width.value get] if { $width != [getLinkWidth $target] } { - setLinkWidth $target [$wi.width.value get] - if { $mirror != "" } { - setLinkWidth $mirror [$wi.width.value get] - } - set changed 1 + setLinkWidth $target [$wi.width.value get] + if { $mirror != "" } { + setLinkWidth $mirror [$wi.width.value get] + } + set changed 1 + } + if { $changed == 1 && $oper_mode == "exec" } { + execSetLinkParams $eid $target } - if { $changed == 1 && $oper_mode == "exec" } { - execSetLinkParams $eid $target - } } } if { $changed == 1 } { - redrawAll + redrawAll updateUndoLog } destroy $wi @@ -2631,16 +2909,12 @@ proc deleteSelection { } { .c config -cursor watch; update foreach lnode [selectedNodes] { - if { $lnode != "" } { - removeGUINode $lnode - } - set changed 1 + if { $lnode != "" } { + removeGUINode $lnode + } + set changed 1 } - .c raise link background - .c raise linklabel "link || background" - .c raise interface "linklabel || link || background" - .c raise node "interface || linklabel || link || background" - .c raise nodelabel "node || interface || linklabel || link || background" + raiseAll .c updateUndoLog .c config -cursor left_ptr .bottom.textbox config -text "" @@ -2652,29 +2926,29 @@ proc align2grid {} { set node_objects [.c find withtag node] if { [llength $node_objects] == 0 } { - return + return } set step [expr {$grid * 4}] for { set x $step } { $x <= [expr {$sizex - $step}] } { incr x $step } { - for { set y $step } { $y <= [expr {$sizey - $step}] } { incr y $step } { - if { [llength $node_objects] == 0 } { - set changed 1 - updateUndoLog - redrawAll - return - } - set node [lindex [.c gettags [lindex $node_objects 0]] 1] - set node_objects [lreplace $node_objects 0 0] - setNodeCoords $node "$x $y" - set dy 32 - if { [lsearch {router hub lanswitch rj45} \ - [nodeType $node]] >= 0 } { - set dy 24 - } - setNodeLabelCoords $node "$x [expr {$y + $dy}]" - } + for { set y $step } { $y <= [expr {$sizey - $step}] } { incr y $step } { + if { [llength $node_objects] == 0 } { + set changed 1 + updateUndoLog + redrawAll + return + } + set node [lindex [.c gettags [lindex $node_objects 0]] 1] + set node_objects [lreplace $node_objects 0 0] + setNodeCoords $node "$x $y" + set dy 32 + if { [lsearch {router hub lanswitch rj45} \ + [nodeType $node]] >= 0 } { + set dy 24 + } + setNodeLabelCoords $node "$x [expr {$y + $dy}]" + } } } @@ -2700,149 +2974,149 @@ proc rearrange { mode } { .menubar.tools entryconfigure "Auto rearrange selected" -state disabled .bottom.mbuf config -text "autorearrange" if { $mode == "selected" } { - set tagmatch "node && selected" + set tagmatch "node && selected" } else { - set tagmatch "node" + set tagmatch "node" } set otime [clock clicks -milliseconds] while { $autorearrange_enabled } { - set ntime [clock clicks -milliseconds] - if { $otime == $ntime } { - set dt 0.001 - } else { - set dt [expr {($ntime - $otime) * 0.001}] - if { $dt > 0.2 } { - set dt 0.2 - } - set otime $ntime - } - - set objects [.c find withtag $tagmatch] - set peer_objects [.c find withtag node] - foreach obj $peer_objects { - set node [lindex [.c gettags $obj] 1] - set coords [.c coords $obj] - set x [expr {[lindex $coords 0] / $zoom}] - set y [expr {[lindex $coords 1] / $zoom}] - set x_t($node) $x - set y_t($node) $y - - if { $x > 0 } { - set fx [expr {1000 / ($x * $x + 100)}] - } else { - set fx 10 - } - set dx [expr {$sizex - $x}] - if { $dx > 0 } { - set fx [expr {$fx - 1000 / ($dx * $dx + 100)}] - } else { - set fx [expr {$fx - 10}] - } - - if { $y > 0 } { - set fy [expr {1000 / ($y * $y + 100)}] - } else { - set fy 10 - } - set dy [expr {$sizey - $y}] - if { $dy > 0 } { - set fy [expr {$fy - 1000 / ($dy * $dy + 100)}] - } else { - set fy [expr {$fy - 10}] - } - set fx_t($node) $fx - set fy_t($node) $fy - } - - foreach obj $objects { - set node [lindex [.c gettags $obj] 1] - set i [lsearch -exact $peer_objects $obj] - set peer_objects [lreplace $peer_objects $i $i] - set x $x_t($node) - set y $y_t($node) - foreach other_obj $peer_objects { - set other [lindex [.c gettags $other_obj] 1] - set o_x $x_t($other) - set o_y $y_t($other) - set dx [expr {$x - $o_x}] - set dy [expr {$y - $o_y}] - set d [expr {hypot($dx, $dy)}] - set d2 [expr {$d * $d}] - set p_fx [expr {1000.0 * $dx / ($d2 * $d + 100)}] - set p_fy [expr {1000.0 * $dy / ($d2 * $d + 100)}] - if {[linkByPeers $node $other] != ""} { - set p_fx [expr {$p_fx - $dx * $d2 * .0000000005}] - set p_fy [expr {$p_fy - $dy * $d2 * .0000000005}] - } - set fx_t($node) [expr {$fx_t($node) + $p_fx}] - set fy_t($node) [expr {$fy_t($node) + $p_fy}] - set fx_t($other) [expr {$fx_t($other) - $p_fx}] - set fy_t($other) [expr {$fy_t($other) - $p_fy}] - } - - foreach link $link_list { - set nodes [linkPeers $link] - if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || - [getNodeCanvas [lindex $nodes 1]] != $curcanvas || - [getLinkMirror $link] != "" } { - continue - } - set peers [linkPeers $link] - set coords0 [getNodeCoords [lindex $peers 0]] - set coords1 [getNodeCoords [lindex $peers 1]] - set o_x \ - [expr {([lindex $coords0 0] + [lindex $coords1 0]) * .5}] - set o_y \ - [expr {([lindex $coords0 1] + [lindex $coords1 1]) * .5}] - set dx [expr {$x - $o_x}] - set dy [expr {$y - $o_y}] - set d [expr {hypot($dx, $dy)}] - set d2 [expr {$d * $d}] - set fx_t($node) \ - [expr {$fx_t($node) + 500.0 * $dx / ($d2 * $d + 100)}] - set fy_t($node) \ - [expr {$fy_t($node) + 500.0 * $dy / ($d2 * $d + 100)}] - } - } - - foreach obj $objects { - set node [lindex [.c gettags $obj] 1] - if { [catch "set v_t($node)" v] } { - set vx 0.0 - set vy 0.0 - } else { - set vx [lindex $v_t($node) 0] - set vy [lindex $v_t($node) 1] - } - set vx [expr {$vx + 1000.0 * $fx_t($node) * $dt}] - set vy [expr {$vy + 1000.0 * $fy_t($node) * $dt}] - set dampk [expr {0.5 + ($vx * $vx + $vy * $vy) * 0.00001}] - set vx [expr {$vx * exp( - $dampk * $dt)}] - set vy [expr {$vy * exp( - $dampk * $dt)}] - set dx [expr {$vx * $dt}] - set dy [expr {$vy * $dt}] - set x [expr {$x_t($node) + $dx}] - set y [expr {$y_t($node) + $dy}] - set v_t($node) "$vx $vy" - - setNodeCoords $node "$x $y" - set e_dx [expr {$dx * $zoom}] - set e_dy [expr {$dy * $zoom}] - .c move $obj $e_dx $e_dy - set img [.c find withtag "selectmark && $node"] - .c move $img $e_dx $e_dy - set img [.c find withtag "nodelabel && $node"] - .c move $img $e_dx $e_dy - set x [expr {[lindex [.c coords $img] 0] / $zoom}] - set y [expr {[lindex [.c coords $img] 1] / $zoom}] - setNodeLabelCoords $node "$x $y" - .c addtag need_redraw withtag "link && $node" - } - foreach link [.c find withtag "link && need_redraw"] { - redrawLink [lindex [.c gettags $link] 1] - } - .c dtag link need_redraw - update + set ntime [clock clicks -milliseconds] + if { $otime == $ntime } { + set dt 0.001 + } else { + set dt [expr {($ntime - $otime) * 0.001}] + if { $dt > 0.2 } { + set dt 0.2 + } + set otime $ntime + } + + set objects [.c find withtag $tagmatch] + set peer_objects [.c find withtag node] + foreach obj $peer_objects { + set node [lindex [.c gettags $obj] 1] + set coords [.c coords $obj] + set x [expr {[lindex $coords 0] / $zoom}] + set y [expr {[lindex $coords 1] / $zoom}] + set x_t($node) $x + set y_t($node) $y + + if { $x > 0 } { + set fx [expr {1000 / ($x * $x + 100)}] + } else { + set fx 10 + } + set dx [expr {$sizex - $x}] + if { $dx > 0 } { + set fx [expr {$fx - 1000 / ($dx * $dx + 100)}] + } else { + set fx [expr {$fx - 10}] + } + + if { $y > 0 } { + set fy [expr {1000 / ($y * $y + 100)}] + } else { + set fy 10 + } + set dy [expr {$sizey - $y}] + if { $dy > 0 } { + set fy [expr {$fy - 1000 / ($dy * $dy + 100)}] + } else { + set fy [expr {$fy - 10}] + } + set fx_t($node) $fx + set fy_t($node) $fy + } + + foreach obj $objects { + set node [lindex [.c gettags $obj] 1] + set i [lsearch -exact $peer_objects $obj] + set peer_objects [lreplace $peer_objects $i $i] + set x $x_t($node) + set y $y_t($node) + foreach other_obj $peer_objects { + set other [lindex [.c gettags $other_obj] 1] + set o_x $x_t($other) + set o_y $y_t($other) + set dx [expr {$x - $o_x}] + set dy [expr {$y - $o_y}] + set d [expr {hypot($dx, $dy)}] + set d2 [expr {$d * $d}] + set p_fx [expr {1000.0 * $dx / ($d2 * $d + 100)}] + set p_fy [expr {1000.0 * $dy / ($d2 * $d + 100)}] + if {[linkByPeers $node $other] != ""} { + set p_fx [expr {$p_fx - $dx * $d2 * .0000000005}] + set p_fy [expr {$p_fy - $dy * $d2 * .0000000005}] + } + set fx_t($node) [expr {$fx_t($node) + $p_fx}] + set fy_t($node) [expr {$fy_t($node) + $p_fy}] + set fx_t($other) [expr {$fx_t($other) - $p_fx}] + set fy_t($other) [expr {$fy_t($other) - $p_fy}] + } + + foreach link $link_list { + set nodes [linkPeers $link] + if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || + [getNodeCanvas [lindex $nodes 1]] != $curcanvas || + [getLinkMirror $link] != "" } { + continue + } + set peers [linkPeers $link] + set coords0 [getNodeCoords [lindex $peers 0]] + set coords1 [getNodeCoords [lindex $peers 1]] + set o_x \ + [expr {([lindex $coords0 0] + [lindex $coords1 0]) * .5}] + set o_y \ + [expr {([lindex $coords0 1] + [lindex $coords1 1]) * .5}] + set dx [expr {$x - $o_x}] + set dy [expr {$y - $o_y}] + set d [expr {hypot($dx, $dy)}] + set d2 [expr {$d * $d}] + set fx_t($node) \ + [expr {$fx_t($node) + 500.0 * $dx / ($d2 * $d + 100)}] + set fy_t($node) \ + [expr {$fy_t($node) + 500.0 * $dy / ($d2 * $d + 100)}] + } + } + + foreach obj $objects { + set node [lindex [.c gettags $obj] 1] + if { [catch "set v_t($node)" v] } { + set vx 0.0 + set vy 0.0 + } else { + set vx [lindex $v_t($node) 0] + set vy [lindex $v_t($node) 1] + } + set vx [expr {$vx + 1000.0 * $fx_t($node) * $dt}] + set vy [expr {$vy + 1000.0 * $fy_t($node) * $dt}] + set dampk [expr {0.5 + ($vx * $vx + $vy * $vy) * 0.00001}] + set vx [expr {$vx * exp( - $dampk * $dt)}] + set vy [expr {$vy * exp( - $dampk * $dt)}] + set dx [expr {$vx * $dt}] + set dy [expr {$vy * $dt}] + set x [expr {$x_t($node) + $dx}] + set y [expr {$y_t($node) + $dy}] + set v_t($node) "$vx $vy" + + setNodeCoords $node "$x $y" + set e_dx [expr {$dx * $zoom}] + set e_dy [expr {$dy * $zoom}] + .c move $obj $e_dx $e_dy + set img [.c find withtag "selectmark && $node"] + .c move $img $e_dx $e_dy + set img [.c find withtag "nodelabel && $node"] + .c move $img $e_dx $e_dy + set x [expr {[lindex [.c coords $img] 0] / $zoom}] + set y [expr {[lindex [.c coords $img] 1] / $zoom}] + setNodeLabelCoords $node "$x $y" + .c addtag need_redraw withtag "link && $node" + } + foreach link [.c find withtag "link && need_redraw"] { + redrawLink [lindex [.c gettags $link] 1] + } + .c dtag link need_redraw + update } .menubar.tools entryconfigure "Auto rearrange all" -state normal .menubar.tools entryconfigure "Auto rearrange selected" -state normal @@ -2920,10 +3194,10 @@ proc switchCanvas { direction } { set lmargin [expr {[lindex [.hframe.t xview] 0] * $x - 1}] set rmargin [expr {[lindex [.hframe.t xview] 1] * $x + 1}] if { $lborder < $lmargin } { - .hframe.t xview moveto [expr {1.0 * ($lborder - 10) / $x}] + .hframe.t xview moveto [expr {1.0 * ($lborder - 10) / $x}] } if { $rborder > $rmargin } { - .hframe.t xview moveto [expr {1.0 * ($rborder - $width + 10) / $x}] + .hframe.t xview moveto [expr {1.0 * ($rborder - $width + 10) / $x}] } set sizex [lindex [getCanvasSize $curcanvas] 0] @@ -2947,11 +3221,21 @@ proc renameCanvasPopup {} { set w .entry1 catch {destroy $w} toplevel $w -takefocus 1 - update - grab $w + + if { $x == 0 && $y == 0 } { + set screen [wm maxsize .] + set x [expr {[lindex $screen 0] / 2}] + set y [expr {[lindex $screen 1] / 2}] + } else { + set x [expr {$x + 10}] + set y [expr {$y - 90}] + } + wm geometry $w +$x+$y wm title $w "Canvas rename" wm iconname $w "Canvas rename" + update + grab $w label $w.msg -wraplength 5i -justify left -text "Canvas name:" pack $w.msg -side top @@ -2961,6 +3245,9 @@ proc renameCanvasPopup {} { button $w.buttons.cancel -text "Cancel" -command "destroy $w" pack $w.buttons.print $w.buttons.cancel -side left -expand 1 + bind $w "destroy $w" + bind $w "renameCanvasApply $w" + entry $w.e1 -bg white $w.e1 insert 0 [getCanvasName $curcanvas] pack $w.e1 -side top -pady 5 -padx 10 -fill x @@ -2985,20 +3272,22 @@ proc resizeCanvasPopup {} { button $w.buttons.print -text "Apply" -command "resizeCanvasApply $w" button $w.buttons.cancel -text "Cancel" -command "destroy $w" pack $w.buttons.print $w.buttons.cancel -side left -expand 1 + bind $w "destroy $w" + bind $w "resizeCanvasApply $w" frame $w.size pack $w.size -side top -fill x -pady 2m spinbox $w.size.x -bg white -width 4 \ - -validate focus -invcmd "focusAndFlash %W" + -validate focus -invcmd "focusAndFlash %W" $w.size.x insert 0 [lindex [getCanvasSize $curcanvas] 0] $w.size.x configure -from 800 -to 4096 -increment 2 \ - -vcmd {checkIntRange %P 800 4096} + -vcmd {checkIntRange %P 800 4096} label $w.size.label -text "*" spinbox $w.size.y -bg white -width 4 \ - -validate focus -invcmd "focusAndFlash %W" + -validate focus -invcmd "focusAndFlash %W" $w.size.y insert 0 [lindex [getCanvasSize $curcanvas] 1] $w.size.y configure -from 600 -to 4096 -increment 2 \ - -vcmd {checkIntRange %P 600 4096} + -vcmd {checkIntRange %P 600 4096} pack $w.size.x $w.size.label $w.size.y -side left -pady 5 -padx 2 -fill x } @@ -3020,7 +3309,7 @@ proc renameCanvasApply { w } { set newname [$w.e1 get] destroy $w if { $newname != [getCanvasName $curcanvas] } { - set changed 1 + set changed 1 } setCanvasName $curcanvas $newname switchCanvas none @@ -3034,7 +3323,7 @@ proc resizeCanvasApply { w } { set y [$w.size.y get] destroy $w if { "$x $y" != [getCanvasSize $curcanvas] } { - set changed 1 + set changed 1 } setCanvasSize $curcanvas $x $y switchCanvas none @@ -3056,13 +3345,13 @@ proc animate {} { .c itemconfigure "selectmark || selectbox" -dashoffset $animatephase incr animatephase 2 if { $animatephase == 100 } { - set animatephase 0 + set animatephase 0 } if { $oper_mode == "edit" } { - after 250 animate + after 250 animate } else { - after 1500 animate + after 1500 animate } } @@ -3197,7 +3486,7 @@ proc configRemoteHosts {} { enable_disable $wi after 100 { - grab .popup + grab .popup } ;# Apply and Cancel explicitly destroy $wi vwait forever @@ -3285,19 +3574,171 @@ proc zoom { dir } { global zoom set stops ".25 .5 .75 1.0 1.5 2.0 4.0" - set i [lsearch $stops $zoom] + # set i [lsearch $stops $zoom] + set minzoom [lindex $stops 0] + set maxzoom [lindex $stops [expr [llength $stops] - 1]] switch -exact -- $dir { - "down" { - if { $i >0 } { - set zoom [lindex $stops [expr $i - 1]] - redrawAll - } - } - "up" { - if { $i < [expr [llength $stops] - 1] } { - set zoom [lindex $stops [expr $i + 1]] - redrawAll - } - } + "down" { + if {$zoom > $maxzoom} { + set zoom $maxzoom + } elseif {$zoom < $minzoom} { + ; # leave it unchanged + } else { + set newzoom $minzoom + foreach z $stops { + if {$zoom <= $z} { + break + } else { + set newzoom $z + } + } + set zoom $newzoom + } + redrawAll + } + "up" { + if {$zoom < $minzoom} { + set zoom $minzoom + } elseif {$zoom > $maxzoom} { + ; # leave it unchanged + } else { + foreach z [lrange $stops 1 end] { + set newzoom $z + if {$zoom < $z} { + break + } + } + set zoom $newzoom + } + redrawAll + } + default { + if { $i < [expr [llength $stops] - 1] } { + set zoom [lindex $stops [expr $i + 1]] + redrawAll + } + } } } + + +#****h* editor.tcl/double1onGrid +# NAME +# double1onGrid.tcl -- called on Double-1 click on grid (bind command) +# SYNOPSIS +# double1onGrid $c %x %y +# FUNCTION +# As grid is layered above annotations this procedure is used to find +# annotation object closest to cursor +#**** + +proc double1onGrid { c x y } { + set obj [$c find closest $x $y] + set tags [$c gettags $obj] + set node [lindex $tags 1] + if {[lsearch $tags grid] != -1 || [lsearch $tags background] != -1} { + return + } + # Is this really necessary? + set coords [getNodeCoords $node] + set x1 [lindex $coords 0] + set y1 [lindex $coords 1] + set x2 [lindex $coords 2] + set y2 [lindex $coords 3] + if {$x < $x1 || $x > $x2 || $y < $y1 || $y > $y2} { + # cursor is not ON the closest object + return + } else { + annotationConfig $c $node + } +} + +proc setZoom { x y } { + global curcanvas + global zoom + + set w .entry1 + catch {destroy $w} + toplevel $w -takefocus 1 + + if { $x == 0 && $y == 0 } { + set screen [wm maxsize .] + set x [expr {[lindex $screen 0] / 2}] + set y [expr {[lindex $screen 1] / 2}] + } else { + set x [expr {$x + 10}] + set y [expr {$y - 90}] + } + wm geometry $w +$x+$y + wm title $w "Set zoom %" + wm iconname $w "Set zoom %" + + update + grab $w + label $w.msg -wraplength 5i -justify left -text "Zoom percentage:" + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.print -text "Apply" -command "setZoomApply $w" + button $w.buttons.cancel -text "Cancel" -command "destroy $w" + pack $w.buttons.print $w.buttons.cancel -side left -expand 1 + + bind $w "destroy $w" + bind $w "setZoomApply $w" + + entry $w.e1 -bg white + $w.e1 insert 0 [expr {int($zoom * 100)}] + pack $w.e1 -side top -pady 5 -padx 10 -fill x +} + +proc setZoomApply { w } { + global zoom changed + + set newzoom [expr [$w.e1 get] / 100.0] + if { $newzoom != $zoom } { + set zoom $newzoom + redrawAll + } + destroy $w +} + +proc selectZoom { x y } { + global curcanvas + global zoom + + set stops ".25 .5 .75 1.0 1.5 2.0 4.0" + + set w .entry1 + catch {destroy $w} + toplevel $w -takefocus 1 + + if { $x == 0 && $y == 0 } { + set screen [wm maxsize .] + set x [expr {[lindex $screen 0] / 2}] + set y [expr {[lindex $screen 1] / 2}] + } else { + set x [expr {$x + 10}] + set y [expr {$y - 90}] + } + wm geometry $w +$x+$y + wm title $w "Select zoom %" + wm iconname $w "Select zoom %" + + update + grab $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.print -text "Apply" -command "setZoomApply $w" + button $w.buttons.cancel -text "Cancel" -command "destroy $w" + pack $w.buttons.print $w.buttons.cancel -side left -expand 1 + + bind $w "destroy $w" + bind $w "setZoomApply $w" + + entry $w.e1 -bg white + $w.e1 insert 0 [expr {int($zoom * 100)}] + pack $w.e1 -side top -pady 5 -padx 10 -fill x +} + diff --git a/filemgmt.tcl b/filemgmt.tcl index 81765e2..f4442df 100755 --- a/filemgmt.tcl +++ b/filemgmt.tcl @@ -1,4 +1,4 @@ -# $Id: filemgmt.tcl,v 1.7.2.1 2007/05/07 08:20:09 ana Exp $ +# $Id: filemgmt.tcl,v 1.7.2.2 2007/07/11 12:11:12 miljenko Exp $ # # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -135,7 +135,7 @@ proc openFile {} { loadCfg $cfg set curcanvas [lindex $canvas_list 0] switchCanvas none - redrawAll + # already called from switchCanvas: redrawAll set undolevel 0 set redolevel 0 set undolog(0) $cfg @@ -307,3 +307,63 @@ proc readConfigFile {} { } } +# Currently not used +#proc checkBkgImageFilenames {} { +# global canvas_list +# foreach canvas $canvas_list { +# global $canvas +# puts [set $canvas] +# set i [lsearch [set $canvas] "bkgImage *"] +# if { $i >= 0 } { +# set oldname [getCanvasBkg $canvas] +# set newname [relpath $oldname] +# puts "Staro ime: $oldname novo ime: $newname" +# set $canvas [lreplace [set $canvas] $i $i "bkgImage {$newname}"] +# } +# } +#} + + +#****f* filemgmt.tcl/relpath +# NAME +# relpath -- return background image filename relative to configuration file +# SYNOPSIS +# relpath bkgImageFilename +# FUNCTION +# Returns relative pathname +# +#*** +##### +# Some examples +# puts [relpath /root/imunes/labos.imn /root/EXAMPLES/labos.gif] +# ../EXAMPLES/labos.gif +# puts [relpath /root/EXAMPLES/labos.imn /root/EXAMPLES/labos.gif] +# ./labos.gif + +;#proc relpath {basedir target} { +proc relpath {target} { + global currentFile + set basedir $currentFile + # Try and make a relative path to a target file/dir from base directory + set bparts [file split [file normalize $basedir]] + set tparts [file split [file normalize $target]] + + if {[lindex $bparts 0] eq [lindex $tparts 0]} { + # If the first part doesn't match - there is no good relative path + set blen [expr {[llength $bparts] - 1}] + set tlen [llength $tparts] + for {set i 1} {$i < $blen && $i < $tlen} {incr i} { + if {[lindex $bparts $i] ne [lindex $tparts $i]} { break } + } + set path [lrange $tparts $i end] + for {} {$i < $blen} {incr i} { + set path [linsert $path 0 ..] + } + # Full name: + # [file normalize [join $path [file separator]]] + # Relative file name: + return [join $path [file separator]] + } + return $target +} + diff --git a/initgui.tcl b/initgui.tcl index 90673fa..f2e9ad4 100755 --- a/initgui.tcl +++ b/initgui.tcl @@ -1,4 +1,4 @@ -# $Id: initgui.tcl,v 1.34.2.1 2007/05/07 08:20:09 ana Exp $ +# $Id: initgui.tcl,v 1.34.2.2 2007/07/11 12:11:12 miljenko Exp $ # # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -38,7 +38,7 @@ # NAME # initgui.tcl # FUNCTION -# Initialize GUI. Not included in imunes when opearting in batch mode. +# Initialize GUI. Not included when operating in batch mode. #**** @@ -56,7 +56,7 @@ # link currently created, this value is set to an empty string. # * selectbox -- the value of the box representing all the selected items # * selected -- containes the list of node_id's of all selected nodes. -# * newCanves -- +# * newCanvas -- # # * animatephase -- starting dashoffset. With this value the effect of # rotating line around selected itme is achived. @@ -101,7 +101,6 @@ #**** - set newlink "" set selectbox "" set selected "" @@ -117,10 +116,14 @@ set cursorState 0 set clock_seconds 0 set oper_mode edit set grid 24 +set showGrid 1 set zoom 1.0 set curcanvas [lindex $canvas_list 0] set autorearrange_enabled 0 +# resize Oval/Rectangle, "false" or direction: north/west/east/... +set resizemode false + # # Initialize a few variables to default values # @@ -130,6 +133,17 @@ set defEthBandwidth 100000000 set defSerBandwidth 2048000 set defSerDelay 2500 +set newoval "" +set defOvalColor #CFCFFF +set defOvalLabelFont "Arial 12" +set newrect "" +set defRectColor #C0C0FF +set defRectLabelFont "Arial 12" +set defTextFont "Arial 12" +set defTextFontFamily "Arial" +set defTextFontSize 12 +set defTextColor #000000 + set showIfNames 0 set showIfIPaddrs 0 set showIfIPv6addrs 0 @@ -137,6 +151,9 @@ set showNodeLabels 1 set showLinkLabels 0 set showIPsecConfig 1 +set showBkgImage 0 +set showAnnotations 1 + set supp_router_models "xorp quagga static" set def_router_model quagga @@ -146,7 +163,7 @@ set def_router_model quagga # wm minsize . 640 400 -wm geometry . 1016x716 +wm geometry . 1016x716-30+30 wm title . IMUNES menu .menubar @@ -204,6 +221,7 @@ bind . "fileSaveDialogBox" $w.e1 insert 0 "lpr" pack $w.e1 -side top -pady 5 -padx 10 -fill x } + .menubar.file add separator .menubar.file add command -label Quit -underline 0 -command { exit } @@ -245,7 +263,7 @@ menu .menubar.canvas -tearoff 0 set changed 1 updateUndoLog } -.menubar.canvas add command -label "Rename" -command renameCanvasPopup +.menubar.canvas add command -label "Rename" -command { renameCanvasPopup 0 0 } .menubar.canvas add command -label "Delete" -command { if { [llength $canvas_list] == 1 } { return @@ -266,6 +284,11 @@ menu .menubar.canvas -tearoff 0 } .menubar.canvas add separator .menubar.canvas add command -label "Resize" -command resizeCanvasPopup + +# There are unresolved scale issues for Background images +# .menubar.canvas add command -label "Background Image" -underline 0 \ +# -command { selectBkgImage } + .menubar.canvas add separator .menubar.canvas add command -label "Previous" -accelerator "PgUp" \ -command { switchCanvas prev } @@ -357,6 +380,16 @@ menu .menubar.view -tearoff 0 } } } +# .menubar.view add checkbutton -label "Show Background Image" \ +# -underline 5 -variable showBkgImage \ +# -command { redrawAll } +.menubar.view add checkbutton -label "Show Annotations" \ + -underline 5 -variable showAnnotations \ + -command { redrawAll } +.menubar.view add checkbutton -label "Show Grid" \ + -underline 5 -variable showGrid \ + -command { redrawAll } + .menubar.view add command -label "Show All" \ -underline 5 -command { set showIfNames 1 @@ -443,13 +476,47 @@ foreach b {select link hub lanswitch router host pc rj45} { } } pack .left.$b -side top + # hover status line + switch -exact -- $b { + select { set msg "Select tool" } + link { set msg "Create link" } + hub { set msg "Add new Hub" } + lanswitch { set msg "Add new LAN switch" } + router { set msg "Add new Router" } + host { set msg "Add new Host" } + pc { set msg "Add new PC" } + rj45 { set msg "Add new external interface" } + default { set msg "" } + } + bind .left.$b ".bottom.textbox config -text {$msg}" + bind .left.$b ".bottom.textbox config -text {}" } + +foreach b {rectangle oval text} { + set image [image create photo -file $ROOTDIR/$LIBDIR/icons/tiny/$b.gif] + radiobutton .left.$b -indicatoron 0 \ + -variable activetool -value $b -selectcolor [.left cget -bg] \ + -width 32 -height 32 -activebackground gray -image $image \ + -command { + global activetool + } + pack .left.$b -side bottom + # hover status line + switch -exact -- $b { + rectangle { set msg "Rectangle" } + oval { set msg "Oval" } + text { set msg "Text" } + default { set msg "" } + } + bind .left.$b ".bottom.textbox config -text {$msg}" + bind .left.$b ".bottom.textbox config -text {}" +} + + foreach b {router host pc hub lanswitch frswitch rj45} { set $b [image create photo -file $ROOTDIR/$LIBDIR/icons/normal/$b.gif] } set pseudo [image create photo] -set text [image create photo] - . configure -background #808080 frame .grid @@ -459,6 +526,7 @@ set c [canvas .c -bd 0 -relief sunken -highlightthickness 0\ -background gray \ -xscrollcommand ".hframe.scroll set" \ -yscrollcommand ".vframe.scroll set"] + canvas .hframe.t -width 300 -height 18 -bd 0 -highlightthickness 0 \ -background gray \ -xscrollcommand ".hframe.ts set" @@ -476,7 +544,7 @@ bind .hframe.t { set curcanvas $canvas switchCanvas none } else { - renameCanvasPopup + renameCanvasPopup %X %Y } } } @@ -503,6 +571,8 @@ frame .bottom pack .bottom -side bottom -fill x label .bottom.textbox -relief sunken -bd 1 -anchor w -width 999 label .bottom.zoom -relief sunken -bd 1 -anchor w -width 10 +bind .bottom.zoom "setZoom %X %Y" +bind .bottom.zoom <3> "selectZoom %X %Y" label .bottom.cpu_load -relief sunken -bd 1 -anchor w -width 9 label .bottom.mbuf -relief sunken -bd 1 -anchor w -width 15 label .bottom.oper_mode -relief sunken -bd 1 -anchor w -width 9 @@ -523,12 +593,26 @@ $c bind link "anyLeave $c" $c bind linklabel "anyLeave $c" $c bind node "popupConfigDialog $c" $c bind nodelabel "popupConfigDialog $c" +$c bind grid "double1onGrid $c %x %y" $c bind link "popupConfigDialog $c" $c bind linklabel "popupConfigDialog $c" +$c bind oval "popupConfigDialog $c" +$c bind rectangle "popupConfigDialog $c" +$c bind text "popupConfigDialog $c" +$c bind text "textInsert $c %A" +$c bind text "textInsert $c \\n" $c bind node <3> "button3node $c %x %y" $c bind nodelabel <3> "button3node $c %x %y" $c bind link <3> "button3link $c %x %y" $c bind linklabel <3> "button3link $c %x %y" + +$c bind oval <3> "button3annotation oval $c %x %y" +$c bind rectangle <3> "button3annotation rectangle $c %x %y" +$c bind text <3> "button3annotation text $c %x %y" + +$c bind selectmark "selectmarkEnter $c %x %y" +$c bind selectmark "selectmarkLeave $c %x %y" + bind $c <1> "button1 $c %x %y none" bind $c "button1 $c %x %y ctrl" bind $c "button1-motion $c %x %y" @@ -546,6 +630,9 @@ bind . ".c xview scroll -1 units" bind . ".c yview scroll 1 units" bind . ".c yview scroll -1 units" +# Escape to Select mode +bind . "set activetool select" + # # Popup-menu hierarchy #