]> git.entuzijast.net Git - imunes.git/commitdiff
Support for oval (circle), rectangle and text annotations.
authormiljenko <miljenko>
Wed, 11 Jul 2007 12:11:12 +0000 (12:11 +0000)
committermiljenko <miljenko>
Wed, 11 Jul 2007 12:11:12 +0000 (12:11 +0000)
Bug found by:
Submitted by:
Reviewed by:
Approved by:
Obtained from:

cfgparse.tcl
editor.tcl
filemgmt.tcl
initgui.tcl

index 80ac5d361266ebc296f9f45bde9e05babf670d16..7fc87729ab0a46339b52aa9ba4e59e18ac845b81 100755 (executable)
@@ -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
 
 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
 }
+
index d408c6e07bad987733aac71cf403ec0b384f4a36..afceb728081d241c55df728190d3b6a3c11e3f64 100755 (executable)
@@ -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\r@[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\r"
+        set labelstr "$labelstr$ifc
+"
     }
     if { $showIfIPaddrs && $ifipv4addr != "" } {
-       set labelstr "$labelstr$ifipv4addr\r"
+        set labelstr "$labelstr$ifipv4addr
+"
     }
     if { $showIfIPv6addrs && $ifipv6addr != "" } {
-       set labelstr "$labelstr$ifipv6addr\r"
+        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]\r"
+    set labelstr "$labelstr[getLinkBandwidthString $link]
+"
     if { "$delstr" != "" } {
-       set labelstr "$labelstr$delstr\r"
+        set labelstr "$labelstr$delstr
+"
     }
     if { "$ber" != "" } {
-       set berstr "ber=$ber"
-       set labelstr "$labelstr$berstr\r"
+        set berstr "ber=$ber"
+        set labelstr "$labelstr$berstr
+"
     }
     if { "$dup" != "" } {
-       set dupstr "dup=$dup%"
-       set labelstr "$labelstr$dupstr\r"
+        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\r"
-           }
-           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 <Key-Escape> "set badentry -1; destroy $wi"
+    bind $wi <Key-Return> "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 <Key-Escape> "destroy $w"
+    bind $w <Key-Return> "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 <Key-Escape> "destroy $w"
+    bind $w <Key-Return> "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 <Key-Escape> "destroy $w"
+    bind $w <Key-Return> "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 <Key-Escape> "destroy $w"
+    bind $w <Key-Return> "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
+}
+
index 81765e21bee59c018357ba808d0960d7bd138d89..f4442df8749617130b8a4fe720ef669dec8935d9 100755 (executable)
@@ -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
+}
+
index 90673fa8d822a90515eb8cf46a025d856ed093ba..f2e9ad493c0c62f76455c879f8412d88f884d05e 100755 (executable)
@@ -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. 
 #****
 
 
-    
 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 . <Control-s> "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 <Any-Enter> ".bottom.textbox config -text {$msg}"
+    bind .left.$b <Any-Leave> ".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 <Any-Enter> ".bottom.textbox config -text {$msg}"
+    bind .left.$b <Any-Leave> ".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 <Double-1> {
            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 <Double-1> "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 <Any-Leave> "anyLeave $c"
 $c bind linklabel <Any-Leave> "anyLeave $c"
 $c bind node <Double-1> "popupConfigDialog $c"
 $c bind nodelabel <Double-1> "popupConfigDialog $c"
+$c bind grid <Double-1> "double1onGrid $c %x %y"
 $c bind link <Double-1> "popupConfigDialog $c"
 $c bind linklabel <Double-1> "popupConfigDialog $c"
+$c bind oval <Double-1> "popupConfigDialog $c"
+$c bind rectangle <Double-1> "popupConfigDialog $c"
+$c bind text <Double-1> "popupConfigDialog $c"
+$c bind text <KeyPress> "textInsert $c %A"
+$c bind text <Return> "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 <Any-Enter> "selectmarkEnter $c %x %y"
+$c bind selectmark <Any-Leave> "selectmarkLeave $c %x %y"
+
 bind $c <1> "button1 $c %x %y none"
 bind $c <Control-Button-1> "button1 $c %x %y ctrl"
 bind $c <B1-Motion> "button1-motion $c %x %y"
@@ -546,6 +630,9 @@ bind . <Left> ".c xview scroll -1 units"
 bind . <Down> ".c yview scroll 1 units"
 bind . <Up> ".c yview scroll -1 units"
 
+# Escape to Select mode
+bind . <Key-Escape> "set activetool select"
+
 #
 # Popup-menu hierarchy
 #