home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / angela-1.28-BETA-bin-Linux-i586.tar.gz / angela-1.28-BETA-bin-Linux-i586.tar / angela-1.28-BETA / angela next >
Text File  |  1998-05-05  |  91KB  |  3,212 lines

  1. #!/bin/sh
  2. # This line is to tell emacs to load tcl mode: -*- Mode: Tcl -*-
  3.  
  4. # If this file doesn't execute properly, check if the
  5. # tixwish4.1.8.0 binary is on the current path. If not,
  6. # make the required changes.
  7.  
  8. # The next line will be executed using the shell 
  9. # and ignored by Tcl because of the trailing backslash \
  10. exec tixwish4.1.8.0 -f "$0" ${1+"$@"}
  11.  
  12. # Please read file LICENSE for licensing informations.
  13. # If this file was not included with your distribution, please
  14. # email pabst@mpi-sb.mpg.de to receive one copy.
  15.  
  16. # To report bug reports or other comments, please use the
  17. # bug report generator in the file menu. This will include some
  18. # precious informations about the Tcl/Tk context you are 
  19. # using. The generated text file can be send with any mail
  20. # editor.
  21.  
  22. ################################################################
  23. ################################################################
  24. ################################################################
  25. ##
  26. ## Constants and Variable set
  27. ##
  28. ################################################################
  29. ################################################################
  30. ################################################################
  31.  
  32. set angela_selected_nodes ""
  33. set angela_state NORMAL
  34. set angela_dragflag 0
  35. set angela_lasthighlight ""
  36. set angela_nodes ""
  37. set angela_edges ""
  38. set angela_debug 0
  39. set angela_version ""
  40.  
  41. ################################################################
  42. ################################################################
  43. ################################################################
  44. ##
  45. ## Procedures 
  46. ##
  47. ################################################################
  48. ################################################################
  49. ################################################################
  50.  
  51. ################################################################
  52. #
  53. # Module Management
  54. #
  55. ################################################################
  56.  
  57. proc angela:mod:manager:browse { tree path action args } {
  58.  
  59.     set module [lindex $action 1]
  60.  
  61.     if { $module == "" } {
  62.     set ok 0
  63.     } else {
  64.     set ok 1 
  65.     }
  66.  
  67.     foreach { widget command } \
  68.     { \
  69.           algname algorithm_name \
  70.           alglongname algorithm_longname \
  71.           algauthor algorithm_author \
  72.           algversion algorithm_version \
  73.           implname implementation_name \
  74.           impllongname implementation_longname \
  75.           implauthor implementation_author \
  76.           implversion implementation_version \
  77.           type type \
  78.           subtype subtype \
  79.       } {
  80.           [ $path.top.b.$widget subwidget entry] \
  81.           delete 0 end
  82.           if { $ok } {
  83.           [ $path.top.b.$widget subwidget entry] \
  84.               insert end \
  85.               [angela:mod:info:$command $module]
  86.           }
  87.       }
  88.  
  89. proc angela:mod:manager:run { tree path action args } {
  90.  
  91.     angela:mod:manager:browse $tree $path $action $args
  92.  
  93. }
  94.  
  95. proc angela:mod:manager { w } {
  96. global angela_mod_list
  97.     
  98.     catch { destroy $w }
  99.     toplevel $w
  100.     wm title $w "angela!:Module Browser"
  101.  
  102.     angela:prefs:window $w ModuleBrowser
  103.  
  104.     frame $w.top -relief raised -bd 1
  105.  
  106.     # Create a TixTree widget to display the module hierarchy
  107.     # 
  108.     #
  109.     tixTree $w.top.a -options {
  110.     separator "/"
  111.     hlist.selectMode single
  112.     }
  113.  
  114.     $w.top.a config \
  115.      -browsecmd "angela:mod:manager:browse $w.top.a $w" \
  116.      -command   "angela:mod:manager:run $w.top.a $w"
  117.  
  118.     frame $w.top.b
  119.  
  120.     pack $w.top.a $w.top.b -expand yes -fill both -padx 10 \
  121.     -pady 10 -side left
  122.  
  123.     foreach { name string } \
  124.     { \
  125.       algname "Algorithm name" \
  126.       alglongname "Algorithm long name" \
  127.       algauthor "Algorithm author" \
  128.       algversion "Algorithm version" \
  129.       implname "Implementation name" \
  130.       impllongname "Implementation long name" \
  131.       implauthor "Implementation author" \
  132.       implversion "Implementation version" \
  133.       type "Module type" \
  134.       subtype "Module subtype"
  135.     } {
  136.     
  137.     tixLabelEntry $w.top.b.$name -label $string: \
  138.         -options {
  139.         -anchor e
  140.         label.width 26
  141.         entry.width 30
  142.         }
  143.     
  144.     pack $w.top.b.$name -fill x -expand yes
  145.     }
  146.     
  147.     set tree $w.top.a 
  148.     set hlist [$w.top.a subwidget hlist]
  149.  
  150.     # STEP (1) Add the entries
  151.  
  152.     $hlist add object -itemtype imagetext \
  153.          -text object -image [tix getimage folder]
  154.  
  155.     $hlist add filter_out -itemtype imagetext \
  156.          -text filter_out -image [tix getimage folder]
  157.  
  158.     $hlist add filter_in -itemtype imagetext \
  159.          -text filter_in -image [tix getimage folder]
  160.  
  161.     $hlist add filter_exec -itemtype imagetext \
  162.          -text filter_exec -image [tix getimage folder]
  163.  
  164.     $hlist add AGD -itemtype imagetext \
  165.     -text AGD -image [tix getimage folder]
  166.  
  167.     $hlist add LEDA -itemtype imagetext \
  168.     -text LEDA -image [tix getimage folder]
  169.  
  170.     foreach i $angela_mod_list {
  171.  
  172.     set name [angela:mod:info:algorithm_name $i]
  173.     set type \
  174.         "[angela:mod:info:type $i]/[angela:mod:info:subtype $i] $i"
  175.  
  176.     $hlist add $type -itemtype imagetext \
  177.         -text $name -image [tix getimage folder]
  178.  
  179.     }
  180.  
  181.     # STEP (2) Use the "autosetmode" method of TixTree to indicate 
  182.     #           which entries can be opened or closed. The
  183.     #           "autosetmode" command will call the "setmode" method
  184.     #           to set the mode of each entry to the following:
  185.     #
  186.     #        "open" : the entry has some children and the children are
  187.     #             currently visible
  188.     #        "close": the entry has some children and the children are
  189.     #             currently INvisible
  190.     #        "none": the entry does not have children.
  191.     #
  192.     #    If you don't like the "autosetmode" method, you can always call
  193.     #    "setmode" yourself, but that takes more work.
  194.     
  195.     $tree autosetmode
  196.  
  197.     # Use a ButtonBox to hold the buttons.
  198.     #
  199.     tixButtonBox $w.box -orientation horizontal
  200.     $w.box add ok     -text Done   -underline 0 \
  201.     -command "angela:prefs:window:save $w ModuleBrowser" \
  202.     -width 6
  203.     $w.box add load -text "Load..." -underline 0 \
  204.     -command "angela:prefs:window:save $w ModuleBrowser" \
  205.     -width 6 -state disabled
  206.     $w.box add unload -text "Unload..." -underline 0 \
  207.     -command "angela:prefs:window:save $w ModuleBrowser" \
  208.          -width 6 -state disabled
  209.  
  210.     pack $w.box -side bottom -fill x
  211.     pack $w.top -side top -fill both -expand yes
  212.  
  213. }
  214.  
  215. proc angela:mod:info:algorithm_name { module } {
  216.     return [angela:mod:info $module 0]
  217. }
  218.  
  219. proc angela:mod:info:algorithm_longname { module } {
  220.     return [angela:mod:info $module 1]
  221. }
  222.  
  223. proc angela:mod:info:algorithm_author { module } {
  224.     return [angela:mod:info $module 2]
  225. }
  226.  
  227. proc angela:mod:info:algorithm_version { module } {
  228.     return [angela:mod:info $module 3]
  229. }
  230.  
  231. proc angela:mod:info:implementation_name { module } {
  232.     return [angela:mod:info $module 4]
  233. }
  234.  
  235. proc angela:mod:info:implementation_longname { module } {
  236.     return [angela:mod:info $module 5]
  237. }
  238.  
  239. proc angela:mod:info:implementation_author { module } {
  240.     return [angela:mod:info $module 6]
  241. }
  242.  
  243. proc angela:mod:info:implementation_version { module } {
  244.     return [angela:mod:info $module 7]
  245. }
  246.  
  247. proc angela:mod:info:type { module } {
  248.     return [angela:mod:info $module 8]
  249. }
  250.  
  251. proc angela:mod:info:subtype { module } {
  252.     return [angela:mod:info $module 9]
  253. }
  254.  
  255. proc angela:mod:info { module id } {
  256.     set command [ format "%s long_info" $module ]
  257.     return [string trim [ lindex [ eval $command ] $id ] ]
  258. }
  259.  
  260. proc angela:mod:scan { modules tag value } {
  261.     set result ""
  262.     foreach i $modules {
  263.     if { [angela:mod:info:$tag $i] == $value } {
  264.         lappend result $i
  265.     }
  266.     }
  267.     return $result
  268. }
  269.  
  270. proc angela:mod:scan:type { type subtype } {
  271. global angela_mod_list
  272.     set fromtype [angela:mod:scan $angela_mod_list type $type]
  273.     return [angela:mod:scan $fromtype subtype $subtype]
  274. }
  275.  
  276. proc angela:mod:register { name } {
  277. global angela_mod_list
  278.     
  279.     lappend angela_mod_list $name
  280.  
  281. }
  282.  
  283. proc angela:mod:load:dll { name module } {
  284. global angela_root
  285.  
  286.     debug "Load DLL $name=$module"
  287.  
  288.     if { ![file exists $angela_root/$module] } {
  289.     fatal \
  290.         "Cannot load $angela_root/$module as DLL. Check configuration."
  291.     }
  292.  
  293.     load $angela_root/$module
  294.  
  295.     angela:mod:register $name
  296.  
  297. }
  298.  
  299. proc angela:mod:load:tcl { name module } {
  300. global angela_root 
  301.  
  302.     debug "Load TCL $name=$module"
  303.  
  304.     if { ![file exists $angela_root/$module] } {
  305.     fatal \
  306.         "Cannot load $angela_root/$module as TCL. Check configuration."
  307.     }
  308.  
  309.     source $angela_root/$module
  310.  
  311.     angela:mod:register $name
  312.     $name init
  313. }
  314.  
  315. proc angela:mod:load { name module type } {
  316.     switch $type {
  317.     dll
  318.     {
  319.         angela:mod:load:dll $name $module
  320.     }
  321.     tcl
  322.     {
  323.         angela:mod:load:tcl $name $module
  324.     }
  325.     }
  326. }
  327.  
  328. proc angela:mod:init { } {
  329. global angela_mod_list angela_option
  330.     debug "Initializing module engine..."
  331.     set angela_mod_list ""
  332.     foreach {name module type} $angela_option(modules:startup) {
  333.         angela:mod:load $name $module $type
  334.     }
  335. }
  336.  
  337. ################################################################
  338. #
  339. # Preferences Management
  340. #
  341. ################################################################
  342.  
  343. proc angela:prefs:write { key value } {
  344. global angela_prefs
  345.  
  346.     if { [file exists $angela_prefs] == 0 } {
  347.         
  348.         set handle [open $angela_prefs "w"]
  349.         puts $handle "$key=$value"
  350.         close $handle
  351.         return
  352.     }
  353.  
  354.     set handle [open $angela_prefs "r"]
  355.     set handle2 [open "$angela_prefs.tmp" "w"]
  356.     set updated 0
  357.  
  358.     while { ! [eof $handle] } {
  359.  
  360.         set line [gets $handle]
  361.         set newline [ split $line = ]
  362.         if { $line!="" } {
  363.             if { [lindex $newline 0] == $key } {
  364.                 puts $handle2 "$key=$value"
  365.                 set updated 1
  366.             } else {
  367.                 puts $handle2 $line
  368.             }
  369.         }
  370.     }
  371.  
  372.     close $handle
  373.  
  374.     if { ! $updated } {
  375.         
  376.         puts $handle2 "$key=$value"
  377.         
  378.     }
  379.  
  380.     close $handle2
  381.  
  382.     file delete $angela_prefs
  383.     file rename "$angela_prefs.tmp" $angela_prefs
  384.  
  385. }
  386.  
  387. proc angela:prefs:read { key } {
  388. global angela_prefs
  389.  
  390.     if { [file exists $angela_prefs] == 0 } {
  391.         return ""
  392.     }
  393.  
  394.     set handle [open $angela_prefs "r"]
  395.  
  396.     while { ! [eof $handle] } {
  397.  
  398.         set line [ gets $handle ]
  399.         set line [ split $line = ]
  400.         
  401.         if { [lindex $line 0 ] == $key } {
  402.             close $handle
  403.             return [lindex $line 1]
  404.         }
  405.     }
  406.  
  407.     close $handle
  408.  
  409.     return ""
  410. }
  411.  
  412. proc angela:prefs:window { path windowname } {
  413.  
  414.     # Read preference, if exist
  415.     set placement [angela:prefs:read $windowname]
  416.  
  417.     if { $placement != "" } {
  418.     wm geometry $path $placement
  419.     wm protocol $path WM_DELETE_WINDOW \
  420.         "angela:prefs:window:save $path $windowname"
  421.     }
  422.  
  423. }
  424.  
  425. proc angela:prefs:window:save { path windowname } {
  426.  
  427.     set placement [wm geometry $path]
  428.     angela:prefs:write $windowname $placement
  429.     destroy $path
  430.  
  431. }
  432.  
  433. ################################################################
  434. #
  435. # Configuration Management
  436. #
  437. ################################################################
  438.  
  439. proc angela:conf:write { } {
  440. global \
  441.     angela_option \
  442.     angela_cap_value \
  443.     angela_root \
  444.     angela_prefs \
  445.     angela_user
  446.     
  447.     # Write into configuration file the current settings.
  448.  
  449.     set handle [open $angela_user w]
  450.  
  451.     puts $handle "# This configuration file is part of angela!"
  452.     puts $handle "# angela! is located in $angela_root"
  453.     puts $handle "# Please do not edit this file manually unless"
  454.     puts $handle "# you know what you are doing!"
  455.  
  456.     puts $handle ""
  457.  
  458.     foreach i [array names angela_option] {
  459.     puts $handle "set angela_option($i)\t\t\t\"$angela_option($i)\""
  460.     }
  461.  
  462.     foreach i [array names angela_cap_value] {
  463.     puts $handle "set angela_cap_value($i)\t\t\t\"$angela_cap_value($i)\""
  464.     }
  465.  
  466.     close $handle
  467. }
  468.  
  469. proc angela:conf:setup { } {
  470. global \
  471.     angela_option \
  472.     angela_cap_value \
  473.     angela_root \
  474.     angela_prefs \
  475.     angela_user
  476.  
  477.     set system \
  478.     [format "%s/angela.rc" $angela_root]
  479.  
  480.     set user "~/angela.rc"
  481.     set angela_user $user
  482.  
  483.     set forced \
  484.     [format "%s/angela.forced.rc" $angela_root]
  485.  
  486.     set angela_prefs "~/.angela.runtime"
  487.  
  488.     if { [file exists $system] } {
  489.     debug "Loading system configuration in $system"
  490.     source $system
  491.     }
  492.  
  493.     if { [file exists $user] } {
  494.     debug "Loading user configuration in $user"
  495.     source $user
  496.     }
  497.  
  498.     if { [file exists $forced] } {
  499.     debug "Loading forced configuration in $forced"
  500.     source $forced
  501.     }
  502.  
  503. }
  504.  
  505. ################################################################
  506. #
  507. # Realtime Management
  508. #
  509. ################################################################
  510.  
  511. proc angela:realtime:start { } {
  512.     after idle angela:realtime:idle
  513. }
  514.  
  515. proc angela:realtime:idle { } {
  516.     angela:realtime:task
  517.     after 50 angela:realtime:idle
  518. }
  519.  
  520. proc angela:realtime:task { } {
  521. global angela_edges angela_canvas
  522.  
  523.     foreach e $angela_edges {
  524.     $e spring_visc
  525.     }
  526.  
  527.     foreach e $angela_edges {
  528.     $e spring_calculate 0.5
  529.     }
  530.  
  531.     foreach e $angela_edges {
  532.     set n1 [$e export -node1]
  533.     set n2 [$e export -node2]
  534.     $n1 spring_update $angela_canvas 0.5
  535.     $n2 spring_update $angela_canvas 0.5
  536.     $e update $angela_canvas
  537.     }
  538. }
  539.  
  540. ################################################################
  541. #
  542. # Printing
  543. #
  544. ################################################################
  545.  
  546. proc angela:print { path } {
  547. global angela_option
  548.  
  549.     set w .print
  550.     catch { destroy $w }
  551.     toplevel $w
  552.     wm title $w "angela!:Print"
  553.  
  554.     angela:prefs:window $w Print
  555.  
  556.     # Create the notebook widget and set its backpagecolor to gray.
  557.     # Note that the -backpagecolor option belongs to the "nbframe"
  558.     # subwidget.
  559.     tixNoteBook $w.nb -ipadx 6 -ipady 6
  560.     $w config -bg gray
  561.     $w.nb subwidget nbframe config -backpagecolor gray
  562.  
  563.     # Create the two tabs on the notebook. The -underline option
  564.     # puts a underline on the first character of the labels of the tabs.
  565.     # Keyboard accelerators will be defined automatically according
  566.     # to the underlined character.    
  567.     #
  568.     $w.nb add area -label "Area" -underline 0
  569.     pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top
  570.     
  571.     #----------------------------------------
  572.     # Create the area page
  573.     #----------------------------------------
  574.     set f [$w.nb subwidget area]
  575.  
  576.     # Create two frames: one for the common buttons, one for the
  577.     # other widgets
  578.     #
  579.     frame $f.f
  580.     frame $f.common
  581.     pack $f.f      -side left  -padx 2 -pady 2 -fill both -expand yes
  582.     pack $f.common -side right -padx 2 -pady 2 -fill y
  583.  
  584.     # Create the controls that only belong to this page
  585.     #
  586.  
  587.     frame $f.f.left
  588.     frame $f.f.right
  589.     pack $f.f.left $f.f.right -side left -fill both -expand yes
  590.  
  591.     canvas $f.f.left.c -width 155 -height 155 -background gray \
  592.     -borderwidth 0 -relief sunken
  593.  
  594.     button $f.f.left.update -text "Refresh preview" \
  595.     -command "angela:print:refresh $f.f.left.c $path" \
  596.         -pady 5
  597.  
  598.     pack $f.f.left.c $f.f.left.update -side top
  599.  
  600.     tixLabelEntry $f.f.right.paperheight -label "Paper height:" \
  601.     -options {
  602.     entry.width 10
  603.     label.width 15
  604.     label.anchor e
  605.     entry.textVariable angela_option(print:paper:height)
  606.     }
  607.  
  608.     tixLabelEntry $f.f.right.paperwidth -label "Paper width:" \
  609.     -options {
  610.     entry.width 10
  611.     label.width 15
  612.     label.anchor e
  613.     entry.textVariable angela_option(print:paper:width)
  614.     }
  615.  
  616.     tixLabelEntry $f.f.right.paperleft -label "Left margin:" \
  617.     -options {
  618.     entry.width 10
  619.     label.width 15
  620.     label.anchor e
  621.     entry.textVariable angela_option(print:paper:left)
  622.     }
  623.  
  624.     tixLabelEntry $f.f.right.paperright -label "Right margin:" \
  625.     -options {
  626.     entry.width 10
  627.     label.width 15
  628.     label.anchor e
  629.     entry.textVariable angela_option(print:paper:right)
  630.     }
  631.  
  632.     tixLabelEntry $f.f.right.papertop -label "Top margin:" \
  633.     -options {
  634.     entry.width 10
  635.     label.width 15
  636.     label.anchor e
  637.     entry.textVariable angela_option(print:paper:top)
  638.     }
  639.  
  640.     tixLabelEntry $f.f.right.paperbottom -label "Paper bottom:" \
  641.     -options {
  642.     entry.width 10
  643.     label.width 15
  644.     label.anchor e
  645.     entry.textVariable angela_option(print:paper:bottom)
  646.     }
  647.  
  648.     frame $f.f.right.rotate
  649.  
  650.     radiobutton $f.f.right.rotate.portrait -text "Portrait" \
  651.     -variable angela_paperportrait -value 1
  652.     
  653.     radiobutton $f.f.right.rotate.landscape -text "Landscape" \
  654.     -variable angela_paperportrait -value 0
  655.  
  656.     pack $f.f.right.rotate.portrait $f.f.right.rotate.landscape \
  657.     -side left -fill both -expand yes
  658.  
  659.     pack $f.f.right.paperheight $f.f.right.paperwidth \
  660.     $f.f.right.paperleft $f.f.right.paperright \
  661.     $f.f.right.papertop $f.f.right.paperbottom \
  662.     $f.f.right.rotate \
  663.     -side top -fill x -expand yes
  664.  
  665.     # Create the common buttons
  666.     #
  667.     angela:print:CreateCommonButtons $w $f.common $f.f.left.c $path
  668.  
  669.     angela:print:refresh $f.f.left.c $path
  670.     
  671. }
  672.  
  673. proc angela:print:CreateCommonButtons {w f canvas path} {
  674.  
  675.     button $f.printfile -text "Print to file..."  -width 10 \
  676.     -command "angela:prefs:window:save $w Print"
  677.     button $f.print -text "Print"  -width 10 \
  678.     -command "angela:prefs:window:save $w Print"
  679.     button $f.cancel -text Cancel -width 10 \
  680.     -command "angela:prefs:window:save $w Print"
  681.  
  682.     pack $f.printfile $f.print $f.cancel -side top -padx 2 -pady 2
  683. }
  684.  
  685. proc angela:print:refresh { canvas realcanvas} {
  686. global angela_option
  687.     
  688.     angela:msg GRAPH:CLEANUP
  689.  
  690.     set previewwidth 150.0
  691.     set previewheight 150.0
  692.     set previewx 2
  693.     set previewy 2
  694.  
  695.     set posterx 1
  696.     set postery 1
  697.     set paperwp 100
  698.     set paperhp 100
  699.  
  700.     set paperwidth  [winfo fpixels . $angela_option(print:paper:width)]
  701.     set paperheight [winfo fpixels . $angela_option(print:paper:height)]
  702.     set paperleft   [winfo fpixels . $angela_option(print:paper:left)]
  703.     set paperright  [winfo fpixels . $angela_option(print:paper:right)]
  704.     set papertop    [winfo fpixels . $angela_option(print:paper:top)]
  705.     set paperbottom [winfo fpixels . $angela_option(print:paper:bottom)]
  706.  
  707.     set printmaxwidth  [expr $paperwidth-$paperleft-$paperright]
  708.     set printmaxheight [expr $paperheight-$papertop-$paperbottom]
  709.  
  710.     set bbox [$realcanvas bbox all]
  711.     set realx [lindex $bbox 0]
  712.     set realy [lindex $bbox 1]
  713.     set realwidth  [expr [lindex $bbox 2]-$realx]
  714.     set realheight [expr [lindex $bbox 3]-$realy]
  715.  
  716.     set realprintscalex [expr 1/(($realwidth/$posterx)/$printmaxwidth)]
  717.     set realprintscaley [expr 1/(($realheight/$postery)/$printmaxheight)]
  718.  
  719.     # Set the scales to the minimum value
  720.     
  721.     if { $realprintscalex < $realprintscaley } {
  722.     set realprintscaley $realprintscalex
  723.     } else {
  724.     set realprintscalex $realprintscaley
  725.     }
  726.  
  727.     set realprintscalex [expr $realprintscalex*$paperwp/100]
  728.     set realprintscaley [expr $realprintscaley*$paperhp/100]
  729.  
  730.     set printwidth  [expr ($realwidth/$posterx)*$realprintscalex]
  731.     set printheight [expr ($realheight/$postery)*$realprintscaley]
  732.  
  733.     set pagecenterx [expr $printmaxwidth/2+$paperleft]
  734.     set pagecentery [expr $printmaxheight/2+$papertop]
  735.  
  736.     set printx [expr $pagecenterx-($printwidth/2)]
  737.     set printy [expr $pagecentery-($printheight/2)]
  738.  
  739.     # Compute values for preview display
  740.     set paperpreviewscalex [expr 1/($paperwidth/$previewwidth)]
  741.     set paperpreviewscaley [expr 1/($paperheight/$previewheight)]
  742.  
  743.     if { $paperpreviewscalex > $paperpreviewscaley } {
  744.     set paperpreviewscalex $paperpreviewscaley
  745.     } else {
  746.     set paperpreviewscaley $paperpreviewscalex
  747.     }
  748.  
  749.     set previewpaperwidth [expr $paperwidth*$paperpreviewscalex]
  750.     set previewpaperheight [expr $paperheight*$paperpreviewscaley]
  751.  
  752.     set previeworiginx [expr $previewwidth/2-($paperwidth/2*$paperpreviewscalex)+2]
  753.     set previeworiginy [expr $previewheight/2-($paperheight/2*$paperpreviewscaley)+2]
  754.  
  755.     set previewtop    [expr $papertop*$paperpreviewscaley]
  756.     set previewbottom [expr $paperbottom*$paperpreviewscaley]
  757.     set previewleft   [expr $paperleft*$paperpreviewscalex]
  758.     set previewright  [expr $paperright*$paperpreviewscalex]
  759.     
  760.     set previewprintx [expr $printx*$paperpreviewscalex]
  761.     set previewprinty [expr $printy*$paperpreviewscaley]
  762.  
  763.     set previewprintheight [expr $printheight*$paperpreviewscaley]
  764.     set previewprintwidth  [expr $printwidth*$paperpreviewscalex]
  765.  
  766.     foreach i { \
  767.             previeworiginx previeworiginy \
  768.             paperpreviewscalex paperpreviewscaley \
  769.             previewpaperwidth previewpaperheight previewtop previewbottom \
  770.             previewleft previewright previewprintx previewprinty \
  771.             previewprintheight previewprintwidth \
  772.             realx realy realheight realwidth paperheight paperwidth \
  773.             papertop paperbottom paperleft paperright paperwp paperhp \
  774.             posterx postery printx printy printwidth printheight \
  775.             realprintscalex realprintscaley pagecenterx pagecentery } {
  776.     debug "$i=[set $i]"
  777.     }
  778.  
  779.     # Delete old objects
  780.     $canvas delete all
  781.     
  782.     # Draw sheet
  783.     $canvas create rectangle $previeworiginx $previeworiginy \
  784.     [expr $previeworiginx+$previewpaperwidth] \
  785.     [expr $previeworiginy+$previewpaperheight] \
  786.     -fill white -outline black -width 1 -tags sheet
  787.  
  788.     # Draw margins
  789.     $canvas create line \
  790.     [expr $previeworiginx+$previewleft] \
  791.     $previeworiginy \
  792.     [expr $previeworiginx+$previewleft] \
  793.     [expr $previeworiginy+$previewpaperheight] \
  794.     -fill gray -width 1 -tags marginleft
  795.  
  796.     $canvas create line \
  797.     [expr $previeworiginx+$previewpaperwidth-$previewright] \
  798.     $previeworiginy \
  799.     [expr $previeworiginx+$previewpaperwidth-$previewright] \
  800.     [expr $previeworiginy+$previewpaperheight] \
  801.     -fill gray -width 1 -tags marginright
  802.  
  803.     $canvas create line \
  804.     $previeworiginx \
  805.     [expr $previeworiginy+$previewtop] \
  806.     [expr $previeworiginx+$previewpaperwidth] \
  807.     [expr $previeworiginy+$previewtop] \
  808.     -fill gray -width 1 -tags margintop
  809.  
  810.     $canvas create line \
  811.     $previeworiginx \
  812.     [expr $previeworiginy+$previewpaperheight-$previewbottom] \
  813.     [expr $previeworiginx+$previewpaperwidth] \
  814.     [expr $previeworiginy+$previewpaperheight-$previewbottom] \
  815.     -fill gray -width 1 -tags marginbottom
  816.  
  817.     # Draw to-print area
  818.     $canvas create rectangle \
  819.     [expr $previeworiginx+$previewprintx] \
  820.     [expr $previeworiginy+$previewprinty] \
  821.     [expr $previeworiginx+$previewprintx+$previewprintwidth] \
  822.     [expr $previeworiginy+$previewprinty+$previewprintheight] \
  823.     -fill steelblue -outline black -width 1 -tags area
  824.  
  825.     $realcanvas postscript -file print.ps\
  826.     -width  $realwidth\
  827.     -height $realheight\
  828.     -x $realx\
  829.     -y $realy\
  830.     -pageanchor sw \
  831.     -pagewidth [expr $paperwidth-$printx]\
  832.     -pageheight [expr $paperheight-$printy]\
  833.     -pagex $printx\
  834.     -pagey [expr $realheight-$printy]
  835.  
  836. }
  837.  
  838. ################################################################
  839. #
  840. # Capabilities Management
  841. #
  842. ################################################################
  843.  
  844. proc angela:capabilities:scan { what type subtype } {
  845. global angela_cap angela_cap_value \
  846.     angela_allcap angela_allcap_value
  847.  
  848.     set module [angela:mod:scan:type $type $subtype]
  849.  
  850.     if { $module == "" } {
  851.     debug "No module for $type/$subtype found!"
  852.     return
  853.     }
  854.  
  855.     if { [llength $module] > 1 } {
  856.     debug "More than one module for $type/$subtype"
  857.     set module [lindex $module 0]
  858.     }
  859.  
  860.     set cap [$module attributes]
  861.     set angela_cap($what) $cap
  862.     foreach i $cap {
  863.     if { [lsearch [array names angela_cap_value] $what:$i] == -1 } {
  864.         set angela_cap_value($what:$i) "0"
  865.     }
  866.     }
  867.  
  868.     set allcap [$module all_attributes]
  869.     set angela_allcap($what) $allcap
  870.     foreach i $allcap {
  871.     if { [lsearch [array names angela_allcap_value] $what:$i] == -1 } {
  872.         set angela_allcap_value($what:$i) "0"
  873.     }
  874.     }
  875. }
  876.  
  877. proc angela:capabilities:get:all { command classes destcap destcap_value } {
  878.     global $destcap $destcap_value angela_allcap angela_allcap_value
  879.  
  880.     catch { unset $destcap }
  881.     catch { unset $destcap_value }
  882.  
  883.     foreach { class cmd } $classes {
  884.     foreach i $angela_allcap($class) {
  885.         set value [$cmd export -$i]
  886.         if { $value == "" } { set value "{}" }
  887.         eval [format "set %s(%s:%s) $value" \
  888.               $destcap_value $class $i]
  889.         eval [format "lappend %s(%s) $i" \
  890.               $destcap $class $i]
  891.     }
  892.     }
  893. }
  894.  
  895. proc angela:capabilities:get:user { command classes destcap destcap_value } {
  896.     global $destcap $destcap_value angela_cap angela_cap_value
  897.  
  898.     catch { unset $destcap }
  899.     catch { unset $destcap_value }
  900.  
  901.     foreach { class cmd } $classes {
  902.     foreach i $angela_cap($class) {
  903.         set value [$cmd export -$i]
  904.         if { $value == "" } { set value "{}" }
  905.         eval [format "set %s(%s:%s) $value" \
  906.               $destcap_value $class $i]
  907.         eval [format "lappend %s(%s) $i" \
  908.               $destcap $class $i]
  909.     }
  910.     }
  911. }
  912.  
  913. proc angela:capabilities:synonym { value } {
  914. global angela_option
  915.  
  916.     set retval $value
  917.     if { [lsearch [array names angela_option] synonym:$value] != -1 } {
  918.     set retval $angela_option(synonym:$value)
  919.     }
  920.     return $retval
  921.     
  922. }
  923.  
  924. proc angela:capabilities:manager { classes cap cap_value { command "" } } {
  925. #global angela_cap angela_cap_value \
  926. #    angela_capfont
  927. global angela_option $cap $cap_value
  928.  
  929.     array set newcap [array get $cap]
  930.     array set newcap_value [array get $cap_value]
  931.  
  932.     set w .cap
  933.     
  934.     catch { destroy $w }
  935.     toplevel $w
  936.     wm title $w "Capabilities"
  937.  
  938.     angela:prefs:window $w Capabilities
  939.  
  940.     # Create the notebook widget and set its backpagecolor to gray.
  941.     # Note that the -backpagecolor option belongs to the "nbframe"
  942.     # subwidget.
  943.     tixNoteBook $w.nb -ipadx 6 -ipady 6
  944.     $w config 
  945.     $w.nb subwidget nbframe config 
  946.  
  947.     # Create the two tabs on the notebook. The -underline option
  948.     # puts a underline on the first character of the labels of the tabs.
  949.     # Keyboard accelerators will be defined automatically according
  950.     # to the underlined character.    
  951.     #
  952.     
  953.     foreach class $classes {
  954.     $w.nb add $class -label $class
  955.     }
  956.     pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top
  957.     
  958.     foreach class $classes {
  959.  
  960.     set f [$w.nb subwidget $class]
  961.  
  962.     # Create two frames: one for the common buttons, one for the
  963.     # other widgets
  964.     #
  965.     frame $f.f
  966.     frame $f.common
  967.     pack $f.f      -side top  -padx 2 -pady 2 -fill both -expand yes
  968.     pack $f.common -side bottom -padx 2 -pady 2 -fill x
  969.     
  970.     # Create the controls that only belong to this page
  971.     #
  972.     foreach i $newcap($class) {
  973.         frame $f.f.$i
  974.         pack $f.f.$i -fill both -expand yes
  975.         label $f.f.$i.l -text [angela:capabilities:synonym $class:$i]: \
  976.         -font $angela_option(gui:font:cap) \
  977.         -width 15 -anchor e
  978.  
  979.         button $f.f.$i.b -text $newcap_value($class:$i) \
  980.         -command "angela:capabilities:manager:edit $f.f.$i.b\
  981.                           $class $i $cap $cap_value \"$command\"" \
  982.         -font $angela_option(gui:font:cap) -borderwidth 1 \
  983.         -background white
  984.  
  985.         pack $f.f.$i.l $f.f.$i.b -side left -fill x
  986.     }
  987.     }
  988.  
  989. frame $w.common -background gray -border 4
  990.  
  991. set majorclass ""
  992. set first 1
  993. foreach class $classes {
  994.     if { ! $first } {
  995.     set majorclass "$majorclass:$class"
  996.     } else {
  997.     set majorclass $class
  998.     set first 0
  999.     }
  1000. }
  1001.  
  1002. tixComboBox $w.common.select -label "Style:" -dropdown true \
  1003.     -editable true -fancy true \
  1004.     -command "angela:capabilities:manager:style:do $majorclass \
  1005.               $cap $cap_value \"$command\" $w.nb" \
  1006.     -options {
  1007.     listbox.height 10
  1008.     label.with 5
  1009.     label.anchor e
  1010.     entry.width 30
  1011.     }
  1012.  
  1013. # Parse and register the styles
  1014.  
  1015. if { [lsearch [array names angela_option] style:$majorclass] != -1 } {
  1016.     foreach style $angela_option(style:$majorclass) {
  1017.     $w.common.select insert end [lindex $style 0]
  1018.     }
  1019. }
  1020.  
  1021. pack $w.common.select -fill both -expand yes
  1022. button $w.common.close -text Close -width 6 \
  1023.     -command "angela:prefs:window:save $w Capabilities" \
  1024.     -font $angela_option(gui:font:cap)
  1025.  
  1026. pack $w.common.close -side bottom -fill both
  1027. pack $w.common -fill x -expand yes
  1028. }
  1029.  
  1030. proc angela:capabilities:manager:update { majorclass path cap cap_value } {
  1031. global $cap $cap_value
  1032.  
  1033.     array set newcap [array get $cap]
  1034.     array set newcap_value [array get $cap_value]
  1035.  
  1036.     set classes [split $majorclass :]
  1037.  
  1038.     foreach class $classes {
  1039.     set f [$path subwidget $class]
  1040.     foreach i $newcap($class) {
  1041.         $f.f.$i.b configure -text $newcap_value($class:$i)
  1042.     }
  1043.     }
  1044. }
  1045.  
  1046. proc angela:capabilities:manager:style:do \
  1047.     { majorclass cap cap_value command path arg } {
  1048. global $cap $cap_value angela_option
  1049.  
  1050.     array set newcap_value [array get $cap_value]
  1051.  
  1052.     set found 0
  1053.     foreach style $angela_option(style:$majorclass) {
  1054.     if { [lindex $style 0] == $arg } {
  1055.         set found 1
  1056.         break
  1057.     }
  1058.     }
  1059.     
  1060.     if { $found } {
  1061.     set style [lrange $style 1 end]
  1062.     foreach { attribute value } $style {
  1063.         angela:capabilities:manager:edit:newval \
  1064.         $cap_value $attribute $command $value
  1065.     }
  1066.     angela:capabilities:manager:update \
  1067.         $majorclass $path $cap $cap_value
  1068.     }
  1069. }
  1070.  
  1071. proc angela:capabilities:manager:edit \
  1072.     {path class attribute cap cap_value { cmd "" } } {
  1073. global angela_cap_value angela_option $cap $cap_value
  1074.  
  1075.     array set newcap [array get $cap]
  1076.     array set newcap_value [array get $cap_value]
  1077.  
  1078.     catch { destroy .capedit }
  1079.     toplevel .capedit
  1080.     wm title .capedit "angela!:Edit attribute"
  1081.  
  1082.     set w .capedit
  1083.  
  1084.     angela:prefs:window $w CapabilitiesEdit
  1085.  
  1086.     frame $w.top -border 1 -relief raised
  1087.  
  1088.     # $w.top.a is a drop-down combo box. It is not editable -- who wants
  1089.     # to invent new months?
  1090.     #
  1091.     # [Hint] The -options switch sets the options of the subwidgets.
  1092.     # [Hint] We set the label.width subwidget option of both comboboxes to 
  1093.     #        be 10 so that their labels appear to be aligned.
  1094.     #
  1095.     # newcap_value($class:$attribute) \    
  1096.  
  1097.     tixComboBox $w.top.a \
  1098.         -label "[angela:capabilities:synonym $class:$attribute]= " \
  1099.     -dropdown true \
  1100.     -editable true \
  1101.         -command "angela:capabilities:manager:edit:newval \
  1102.                   $cap_value \
  1103.                   $class:$attribute \"$cmd\"" \
  1104.         -history 1 \
  1105.         -fancy 1 \
  1106.         -options {
  1107.         listbox.height 6
  1108.         label.width 20
  1109.         label.anchor e
  1110.     }
  1111.  
  1112.     $w.top.a subwidget entry insert end $newcap_value($class:$attribute)
  1113.     focus [$w.top.a subwidget entry]
  1114.  
  1115.     pack $w.top.a -side top -anchor e
  1116.  
  1117.     if { [lsearch [array names angela_option] choice:$class:$attribute] == -1 } {
  1118.     # Insert the choices into the combo boxes
  1119.     #
  1120.     $w.top.a insert end 1
  1121.     $w.top.a insert end 5
  1122.     $w.top.a insert end 10
  1123.     $w.top.a insert end 20
  1124.     $w.top.a insert end White
  1125.     $w.top.a insert end Black
  1126.     $w.top.a insert end Green
  1127.     $w.top.a insert end SteelBlue
  1128.     $w.top.a insert end { Arial 8 }
  1129.     $w.top.a insert end { Arial 20 }
  1130.     } else {
  1131.     foreach element $angela_option(choice:$class:$attribute) {
  1132.         $w.top.a insert end $element
  1133.     }
  1134.     }
  1135.     # Use a ButtonBox to hold the buttons.
  1136.     #
  1137.     tixButtonBox $w.box -orientation horizontal
  1138.     $w.box add ok     -text Done   -underline 0 \
  1139.     -command "angela:capabilities:manager:edit:okcmd $path $w $class $attribute $cap $cap_value" \
  1140.         -width 6
  1141. #    $w.box add cancel -text Cancel -underline 0 \
  1142. #    -command "angela:prefs:window:save $w CapabilitiesEdit" \
  1143. #    -width 6
  1144.  
  1145.     pack $w.box -side bottom -fill x
  1146.     pack $w.top -side top -fill both -expand yes
  1147. }
  1148.  
  1149. proc angela:capabilities:manager:edit:newval \
  1150.     { \
  1151.       cap_value attribute command value } \
  1152.     {
  1153.     global $cap_value
  1154.  
  1155.     #set value [$path subwidget entry get]
  1156.     eval set [format "%s(%s)" $cap_value $attribute] \"$value\"
  1157.     if { $command != "" } { eval $command }
  1158.     }
  1159.  
  1160. proc angela:capabilities:manager:edit:okcmd {path w class attribute cap cap_value} {
  1161. global angela_cap_value $cap $cap_value
  1162.     
  1163.     array set newcap [array get $cap]
  1164.     array set newcap_value [array get $cap_value]
  1165.  
  1166.     $path configure -text $newcap_value($class:$attribute)
  1167.     destroy $w
  1168. }
  1169.  
  1170. ################################################################
  1171. #
  1172. # Workspace Management
  1173. #
  1174. ################################################################
  1175.  
  1176. proc angela:ws:title:init { path } {
  1177. global angela_filename
  1178.  
  1179.     wm title $path "angela!([angela:msg VERSION]):Workspace:$angela_filename"
  1180.  
  1181. }
  1182.  
  1183. proc angela:ws:menubar:init { path } { 
  1184.  
  1185.     menubutton $path.file    -text "File"  -underline 0 \
  1186.     -menu $path.file.m -borderwidth 1
  1187.     menubutton $path.edit    -text "Edit"  -underline 0 \
  1188.     -menu $path.edit.m -borderwidth 1
  1189.     menubutton $path.tools   -text "Tools" -underline 0 \
  1190.     -menu $path.tools.m -borderwidth 1
  1191.     menubutton $path.help    -text "Help"  -underline 0 \
  1192.     -menu $path.help.m -state disabled -borderwidth 1
  1193.  
  1194.     pack $path.file  -side left
  1195.     pack $path.edit  -side left
  1196.     pack $path.tools -side left
  1197.  
  1198.     pack $path.help  -side right
  1199.  
  1200.     angela:ws:menubar:set $path
  1201.  
  1202. }
  1203.  
  1204. proc angela:ws:menubar:set { path } {
  1205.  
  1206.     menu $path.file.m -tearoff 0 -borderwidth 1
  1207.     $path.file.m add command -label "New Graph" \
  1208.     -underline 0 -command "angela:msg GRAPH:NEW"
  1209.     $path.file.m add command -label "Open Graph..." \
  1210.     -underline 0 -command "angela:msg GRAPH:OPEN"
  1211.     $path.file.m add command -label "Save Graph" \
  1212.     -underline 0 -command "angela:msg GRAPH:SAVE"
  1213.     $path.file.m add command -label "Save Graph As..." \
  1214.     -underline 0 -command "angela:msg GRAPH:SAVEAS"
  1215.     $path.file.m add separator
  1216.     $path.file.m add command -label "Print..." \
  1217.     -underline 0 -command "angela:msg GRAPH:PRINT"
  1218.     $path.file.m add separator
  1219.     $path.file.m add command -label "Properties..." \
  1220.     -underline 0 -command "angela:msg GRAPH:PROPERTIES"
  1221.     $path.file.m add command -label "Save configuration" \
  1222.     -underline 5 -command "angela:conf:write"
  1223.     $path.file.m add separator
  1224.     $path.file.m add command -label "Tcl command..." \
  1225.     -underline 0 -command "angela:tcl"
  1226.     $path.file.m add command -label "Bug Report..." \
  1227.     -underline 0 -command "angela:msg BUG"
  1228.     $path.file.m add separator
  1229.     $path.file.m add command -label "Quit" \
  1230.     -underline 0 -accelerator "Alt-F4" \
  1231.     -command "angela:msg QUIT"
  1232.  
  1233.     menu $path.edit.m -tearoff 0 -borderwidth 1
  1234.     $path.edit.m add command -label "Undo" \
  1235.     -underline 0 -command "angela:msg UNDO" -state disabled
  1236.     $path.edit.m add command -label "Redo" \
  1237.     -underline 0 -command "angela:msg REDO" -state disabled
  1238.     $path.edit.m add separator
  1239.     $path.edit.m add command -label "Copy" \
  1240.     -underline 0 -command "angela:msg COPY" -state disabled
  1241.     $path.edit.m add command -label "Cut" \
  1242.     -underline 2 -command "angela:msg CUT"
  1243.     $path.edit.m add command -label "Paste" \
  1244.     -underline 0 -command "angela:msg PASTE" -state disabled
  1245.  
  1246.     menu $path.tools.m -tearoff 0 -borderwidth 1
  1247.     $path.tools.m add command -label "Modules..." \
  1248.     -command "angela:msg MODULES"
  1249.     $path.tools.m add separator
  1250.     $path.tools.m add command -label "Create node" \
  1251.     -command "angela:msg TOOL:NODE"
  1252.     $path.tools.m add command -label "Create edge" \
  1253.     -command "angela:msg TOOL:EDGE"
  1254.     $path.tools.m add command -label "Edit Object" \
  1255.     -command "angela:msg TOOL:EDIT"
  1256.     $path.tools.m add separator
  1257.  
  1258. }
  1259.  
  1260. proc angela:ws:actionbar:init { path } { 
  1261. global angela_option
  1262.  
  1263. #     button $path.node -text "Create node" -borderwidth 1 \
  1264. #     -command "angela:msg TOOL:NODE"
  1265. #     button $path.edge -text "Create edge" -borderwidth 1 \
  1266. #     -command "angela:msg TOOL:EDGE"
  1267. #     button $path.edit -text "Edit"        -borderwidth 1 \
  1268. #     -command "angela:msg TOOL:EDIT"\
  1269.  
  1270. #     pack $path.node -side top -fill x
  1271. #     pack $path.edge -side top -fill x
  1272. #     pack $path.edit -side top -fill x
  1273.  
  1274.     tixSelect $path.sel \
  1275.     -radio true -orientation vertical
  1276.     $path.sel add node -text "Create node" \
  1277.     -command "angela:msg TOOL:NODE" \
  1278.         -font $angela_option(gui:font:tool) -borderwidth 1
  1279.     $path.sel add edge -text "Create edge" \
  1280.     -command "angela:msg TOOL:EDGE" \
  1281.         -font $angela_option(gui:font:tool) -borderwidth 1
  1282.     $path.sel add edit -text "Edit object" \
  1283.     -command "angela:msg TOOL:EDIT" \
  1284.         -font $angela_option(gui:font:tool) -borderwidth 1
  1285.  
  1286.     .balloon bind $path.sel -balloonmsg "Choose Action" \
  1287.     -statusmsg "Choose the action you will execute."
  1288.  
  1289.     pack $path.sel -side top -fill x
  1290.  
  1291. }
  1292.  
  1293. proc angela:ws:statusbar:init { path } { 
  1294. global angela_option
  1295.  
  1296.     label $path.statusbar -font $angela_option(gui:font:status)
  1297.  
  1298.     pack $path.statusbar -fill x -expand no
  1299.  
  1300. }
  1301.  
  1302. proc angela:ws:statusbar:set { path text } {
  1303.  
  1304.     $path.statusbar configure -text $text
  1305.     update
  1306. }
  1307.  
  1308. proc angela:ws:statusbuttons:init { path } { 
  1309. global angela_option
  1310.  
  1311.     label $path.statusbuttons -font $angela_option(gui:font:status)
  1312.  
  1313.     pack $path.statusbuttons -fill x -expand no
  1314.  
  1315. }
  1316.  
  1317. proc angela:ws:statusbuttons:set { path text } {
  1318.  
  1319.     $path.statusbuttons configure -text $text
  1320.  
  1321. }
  1322.  
  1323. proc angela:ws:statusdebug:init { path } { 
  1324. global angela_option
  1325.  
  1326.     label $path.statusdebug -font $angela_option(gui:font:status) \
  1327.     -background black -foreground white
  1328.  
  1329.     .balloon bind $path.statusdebug -balloonmsg "Debugging info"
  1330.  
  1331.     pack $path.statusdebug -fill x -expand no
  1332.  
  1333. }
  1334.  
  1335. proc angela:ws:statusdebug:set { path text } {
  1336. global angela_debug argv0
  1337.  
  1338.     if { $angela_debug } {
  1339.     puts stderr "$argv0:dbg:$text"
  1340.     }
  1341. }
  1342.  
  1343. proc debug { text } {
  1344.     angela:ws:statusdebug:set .statusdebug $text
  1345. }
  1346.  
  1347. proc status { text } {
  1348.     angela:ws:statusbar:set .statusbar $text
  1349. }
  1350.  
  1351. proc angela:ws:buttonbar:init { path } { 
  1352. global angela_option
  1353.  
  1354.     button $path.new -text "NEW" -font $angela_option(gui:font:tool) \
  1355.     -command "angela:msg GRAPH:NEW" \
  1356.     -borderwidth 1
  1357.  
  1358.     .balloon bind $path.new -balloonmsg "Start a new graph" \
  1359.     -statusmsg "Press this to start a new graph"
  1360.  
  1361.     button $path.open -text "OPEN" -font $angela_option(gui:font:tool) \
  1362.     -command "angela:msg GRAPH:OPEN" \
  1363.     -borderwidth 1
  1364.  
  1365.     .balloon bind $path.open -balloonmsg "Open a graph" \
  1366.     -statusmsg "Press this to open a graph"
  1367.  
  1368.     button $path.save -text "SAVE" -font $angela_option(gui:font:tool) \
  1369.     -command "angela:msg GRAPH:SAVE" \
  1370.     -borderwidth 1
  1371.  
  1372.     .balloon bind $path.save -balloonmsg "Save the graph" \
  1373.     -statusmsg "Press this to save the graph"
  1374.  
  1375.     button $path.quit -text "QUIT" -font $angela_option(gui:font:tool) \
  1376.     -command "angela:msg QUIT" \
  1377.     -borderwidth 1
  1378.  
  1379.     .balloon bind $path.quit -balloonmsg "Quit angela!" \
  1380.     -statusmsg "Press this to quit angela!"
  1381.  
  1382.     pack \
  1383.     $path.new \
  1384.     $path.open \
  1385.     $path.save \
  1386.     $path.quit \
  1387.     -side left -fill none -expand no
  1388.  
  1389. }
  1390.  
  1391. proc angela:ws:canvas:init { path } { 
  1392. global angela_canvas
  1393.  
  1394.     canvas $path.c -background white \
  1395.     -xscrollcommand "$path.horiz set" \
  1396.     -yscrollcommand "$path.vert  set" \
  1397.     -borderwidth 2
  1398.     
  1399.     scrollbar $path.horiz -orient horiz \
  1400.     -command "$path.c xview"
  1401.     scrollbar $path.vert  -orient vert \
  1402.     -command "$path.c yview"
  1403.  
  1404.     pack $path.horiz -side bottom -fill x    -expand no
  1405.     pack $path.vert  -side right  -fill y    -expand no
  1406.     pack $path.c     -side top    -fill both -expand yes
  1407.  
  1408.     angela:ws:canvas:grid:draw $path.c
  1409.  
  1410.     set angela_canvas $path.c
  1411.  
  1412. #     bind $path.c <Configure> \
  1413. #     "angela:ws:canvas:resize $path %w %h"
  1414.     
  1415. }
  1416.  
  1417. proc angela:ws:canvas:resize { path width height } {
  1418.  
  1419.     # Terrible hack here. Don't know why there is a difference 
  1420.     # of 6 units.
  1421.     # Should find a way to expand canvas to minimum of window size.
  1422.  
  1423.     incr width -6
  1424.     incr height -6
  1425.  
  1426.     set w [$path.c cget -width]
  1427.     set h [$path.c cget -height]
  1428.  
  1429.     if { $w < $width } {
  1430.     $path.c configure -width $width
  1431.     }
  1432.  
  1433.     if { $h < $height } {
  1434.     $path.c configure -height $height
  1435.     }
  1436.  
  1437.     angela:ws:canvas:refresh $path
  1438.     
  1439. }
  1440.  
  1441. proc angela:ws:canvas:refresh { path } {
  1442.  
  1443.     $path.c configure -scrollregion [$path.c bbox all]
  1444.     angela:ws:canvas:grid:refresh $path.c
  1445.     
  1446. }
  1447.  
  1448. proc angela:ws:canvas:grid:draw { path } {
  1449. global angela_option
  1450.  
  1451. #     set width  [$path cget -width]
  1452. #     set height [$path cget -height]
  1453.  
  1454. #     for { set i 0 } { $i < $width } { incr i $angela_gridx } {
  1455. #     for { set j 0 } { $j < $height } { incr j $angela_gridy } {
  1456. #         $path create line $i [expr $j-1] $i [expr $j+1] \
  1457. #         -fill gray60 -tag grid
  1458. #         $path create line [expr $i-1] $j [expr $i+1] $j\
  1459. #         -fill gray60 -tag grid
  1460. #     }
  1461. #     }
  1462. #     $path lower grid
  1463.  
  1464. }
  1465.  
  1466. proc angela:ws:canvas:grid:refresh { path } {
  1467.  
  1468.     $path delete grid
  1469.     angela:ws:canvas:grid:draw $path
  1470.     
  1471. }
  1472.  
  1473. proc angela:ws:init { } {
  1474.  
  1475.     angela:ws:title:init .
  1476.  
  1477.     angela:prefs:window . MainWindow
  1478.  
  1479.     frame .menubar
  1480.     frame .buttonbar -relief ridge -borderwidth 1
  1481.     frame .middle
  1482.     frame .statusbar -relief sunken -borderwidth 1
  1483.     frame .statusbuttons -relief sunken -borderwidth 1
  1484.     frame .statusdebug -relief sunken -borderwidth 1
  1485.  
  1486.     pack .menubar -side top -fill x -expand no
  1487.     pack .buttonbar -fill x -expand no
  1488.     pack .middle -fill both -expand yes
  1489.     pack .statusbar -fill x -expand no
  1490.     pack .statusdebug -fill x -expand no \
  1491.     -in .statusbar -side right
  1492.     pack .statusbuttons -fill x -expand no \
  1493.     -in .statusbar -side right
  1494.  
  1495.     frame .middle.actionbar
  1496.     frame .middle.canvas
  1497.  
  1498.     pack .middle.actionbar -side left -expand no -fill y
  1499.     pack .middle.canvas -side right -expand yes -fill both
  1500.  
  1501.     tixBalloon .balloon -statusbar .statusbar.statusbar
  1502.  
  1503.     angela:ws:menubar:init       .menubar
  1504.     angela:ws:actionbar:init     .middle.actionbar
  1505.     angela:ws:statusbar:init     .statusbar
  1506.     angela:ws:statusbuttons:init .statusbuttons
  1507.     angela:ws:statusdebug:init   .statusdebug
  1508.     angela:ws:buttonbar:init     .buttonbar
  1509.     angela:ws:canvas:init        .middle.canvas
  1510.  
  1511.     angela:ws:statusbar:set .statusbar "Welcome to angela!"
  1512.     angela:ws:statusbuttons:set .statusbuttons "ready"
  1513.     angela:ws:statusdebug:set .statusdebug "angela! welcomes you"
  1514.  
  1515. }
  1516.  
  1517. ################################################################
  1518. #
  1519. # Properties Management
  1520. #
  1521. ################################################################
  1522.  
  1523. proc angela:properties { } {
  1524. global angela_option
  1525.  
  1526.     set w .properties
  1527.  
  1528.     catch { destroy $w }
  1529.     toplevel $w
  1530.     wm title $w "angela!:Properties"
  1531.  
  1532.     angela:prefs:window $w Properties
  1533.  
  1534.     tixNoteBook $w.nb -ipadx 6 -ipady 6
  1535.     $w config
  1536.     $w.nb subwidget nbframe config
  1537.  
  1538.     $w.nb add general -label General
  1539.     $w.nb add grid    -label Grid
  1540.     $w.nb add print   -label Printing
  1541.     pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top
  1542.  
  1543.     # General properties
  1544.     set f [$w.nb subwidget general]
  1545.  
  1546.     set index 0
  1547.     foreach { label variable } \
  1548.     { "Font for tools"        angela_option(gui:font:tool) \
  1549.       "Font for status bar"   angela_option(gui:font:status) \
  1550.       "Font for capabilities" angela_option(gui:font:cap) } \
  1551.     {
  1552.     tixLabelEntry $f.$index -label "$label:" \
  1553.         -options {
  1554.         entry.width 30
  1555.         label.width 20
  1556.         label.anchor w
  1557.         }
  1558.     $f.$index subwidget entry configure -textvariable $variable
  1559.     pack $f.$index
  1560.     incr index
  1561.     }
  1562.  
  1563.     # Grid properties
  1564.     set f [$w.nb subwidget grid]
  1565.  
  1566.     set index 0
  1567.     foreach { label variable } \
  1568.     { "Grid X-resolution"     angela_option(gui:grid:x) \
  1569.       "Grid Y-resolution"     angela_option(gui:grid:y) } \
  1570.     {
  1571.     tixLabelEntry $f.$index -label "$label:" \
  1572.         -options {
  1573.         entry.width 30
  1574.         label.width 20
  1575.         label.anchor w
  1576.         }
  1577.     $f.$index subwidget entry configure -textvariable $variable
  1578.     pack $f.$index
  1579.     incr index
  1580.     }
  1581.  
  1582.     # Print properties
  1583.     set f [$w.nb subwidget print]
  1584.  
  1585.     set index 0
  1586.     foreach { label variable } \
  1587.     { "Paper width"         angela_option(print:paper:width) \
  1588.       "Paper height"        angela_option(print:paper:height) \
  1589.       "Paper margin left"   angela_option(print:paper:left) \
  1590.       "Paper margin right"  angela_option(print:paper:right) \
  1591.       "Paper margin top"    angela_option(print:paper:top) \
  1592.       "Paper margin bottom" angela_option(print:paper:bottom) \
  1593.       } \
  1594.     {
  1595.     tixLabelEntry $f.$index -label "$label:" \
  1596.         -options {
  1597.         entry.width 30
  1598.         label.width 20
  1599.         label.anchor w
  1600.         }
  1601.     $f.$index subwidget entry configure -textvariable $variable
  1602.     pack $f.$index
  1603.     incr index
  1604.     }
  1605.  
  1606.     set box [tixButtonBox $w.b -bd 1 -relief raised]
  1607.     pack $box -side bottom -fill both
  1608.     $box add done -text Done \
  1609.       -command "angela:prefs:window:save $w Properties" -width 6
  1610.  
  1611. }
  1612.  
  1613. ################################################################
  1614. #
  1615. # Tool Management
  1616. #
  1617. ################################################################
  1618.  
  1619. proc angela:tool:add:cascade { path name command } {
  1620.  
  1621.     set index 0
  1622.     while { 1 } {
  1623.     set newmenu $path.cascade$index
  1624.     if { [lsearch [winfo children $path] $newmenu] != -1 } {
  1625.         incr index
  1626.     } else {
  1627.         break
  1628.     }
  1629.     }
  1630.     $path add cascade -label "$name" -menu $newmenu
  1631. #    -command "$command angela:msg"
  1632.  
  1633.     menu $newmenu -tearoff 0
  1634.  
  1635.     return $newmenu
  1636.  
  1637. }
  1638.  
  1639. proc angela:tool:node { } {
  1640. global angela_canvas angela_state
  1641.  
  1642.     bind $angela_canvas <B1-ButtonRelease> \
  1643.     "angela:msg NODE:CREATE %x %y"
  1644.  
  1645.     bind $angela_canvas <B1-Motion> \
  1646.        ""
  1647.     angela:capabilities:manager "node shape text" \
  1648.       angela_cap angela_cap_value
  1649.  
  1650.     set angela_state NODE
  1651.  
  1652.     .middle.actionbar.sel subwidget node configure -state disabled
  1653.     .middle.actionbar.sel subwidget edge configure -state normal
  1654.     .middle.actionbar.sel subwidget edit configure -state normal
  1655. }
  1656.  
  1657. proc angela:tool:edge { } {
  1658. global angela_canvas angela_state
  1659.  
  1660.     bind $angela_canvas <B1-ButtonRelease> \
  1661.        ""
  1662.  
  1663.     bind $angela_canvas <B1-Motion> \
  1664.        ""
  1665.     
  1666.     angela:capabilities:manager "edge line" \
  1667.        angela_cap angela_cap_value
  1668.  
  1669.     set angela_state EDGE
  1670.  
  1671.     .middle.actionbar.sel subwidget node configure -state normal
  1672.     .middle.actionbar.sel subwidget edge configure -state disabled
  1673.     .middle.actionbar.sel subwidget edit configure -state normal
  1674. }
  1675.  
  1676. proc angela:tool:edit { } {
  1677. global angela_canvas angela_state
  1678.  
  1679.     # Destroy capabilities window
  1680.     catch { destroy .cap }
  1681.     
  1682.     bind $angela_canvas <B1-ButtonRelease> \
  1683.        ""
  1684.  
  1685.     bind $angela_canvas <B1-Motion> \
  1686.        ""
  1687.     
  1688.     set angela_state EDIT
  1689.  
  1690.     .middle.actionbar.sel subwidget node configure -state normal
  1691.     .middle.actionbar.sel subwidget edge configure -state normal
  1692.     .middle.actionbar.sel subwidget edit configure -state disabled
  1693. }
  1694.  
  1695. ################################################################
  1696. #
  1697. # Edges
  1698. #
  1699. ################################################################
  1700.  
  1701. proc angela:edge:create { canvas node1 node2 } {
  1702.  
  1703.     angela:msg \
  1704.     EDGE:CREATE:DRAW \
  1705.     $node1 $node2 \
  1706.     angela_cap angela_cap_value "edge line"
  1707.  
  1708. }
  1709.  
  1710. proc angela:edge:create:direct { canvas node1 node2 cap capvalue } {
  1711. global thiscap thiscapvalue
  1712.  
  1713.     array set thiscap $cap
  1714.     array set thiscapvalue $capvalue
  1715.  
  1716.     # This is the high-level code for creating a node
  1717.  
  1718.     angela:msg \
  1719.     EDGE:CREATE:DRAW \
  1720.     $node1 $node2 \
  1721.     thiscap thiscapvalue "edge line"
  1722.  
  1723. }
  1724.  
  1725. proc angela:edge:create:draw { canvas node1 node2 cap \
  1726.                    cap_value classes } {
  1727. global $cap $cap_value angela_edges
  1728.     
  1729.     array set newcap [array get $cap]
  1730.     array set newcap_value [array get $cap_value]
  1731.  
  1732.     set edgecmd [angela:mod:scan:type object edge]
  1733.  
  1734.     foreach type $classes {
  1735.     set attr$type ""
  1736.     foreach a $newcap($type) {
  1737.         set attr$type \
  1738.         "[set attr$type] -$a \"$newcap_value($type:$a)\" "
  1739.     }
  1740.     }
  1741.  
  1742.     set edge [$edgecmd create $node1 $node2]
  1743.     set line [$edge line]
  1744.  
  1745.     eval "$edge update [set attredge]"
  1746.     eval "$line update $canvas [set attrline]"
  1747.  
  1748.     $edge update $canvas
  1749.  
  1750.     lappend angela_edges $edge
  1751.  
  1752.     set carriage [lindex [$node1 export -carriage] 0]
  1753.     if { [lsearch $carriage $edge] == -1 } {
  1754.     lappend carriage $edge
  1755.     $node1 update -carriage $carriage
  1756.     }
  1757.  
  1758.     set carriage [lindex [$node2 export -carriage] 0]
  1759.     if { [lsearch $carriage $edge] == -1 } {
  1760.     lappend carriage $edge
  1761.     $node2 update -carriage $carriage
  1762.     }
  1763.  
  1764.     $edge bind $canvas <Any-Enter> "angela:msg EDGE:ENTER $edge"
  1765.     $edge bind $canvas <B1-ButtonRelease> \
  1766.          "angela:msg EDGE:SPLIT $edge %x %y"
  1767.     $edge bind $canvas <Double-B1-ButtonRelease> \
  1768.          "angela:msg EDGE:EDIT $edge"
  1769.     $edge bind $canvas <B3-ButtonRelease> \
  1770.          "angela:msg EDGE:CONTEXT $edge %x %y"
  1771.  
  1772. }
  1773.  
  1774. proc angela:edge:delete { canvas edge } {
  1775. global angela_edges angela_nodes
  1776.  
  1777.     # Search all nodes to find dependencies
  1778.  
  1779.     foreach node $angela_nodes {
  1780.     set carriage [lindex [$node export -carriage] 0]
  1781.     set index [lsearch $carriage $edge]
  1782.  
  1783.     if { $index != -1 } {
  1784.         set carriage [lreplace $carriage $index $index]
  1785.         $node update -carriage $carriage
  1786.     }
  1787.     }
  1788.  
  1789.     [$edge line] delete $canvas
  1790.     $edge delete
  1791.  
  1792.     set index [lsearch $angela_edges $edge]
  1793.     set angela_edges [lreplace $angela_edges $index $index]
  1794.  
  1795. }
  1796.  
  1797. proc angela:edge:highlight { canvas edge } {
  1798. global angela_lasthighlight angela_option
  1799.  
  1800. #    debug "edge:highlight $canvas $edge$"
  1801.     if { $angela_lasthighlight == $edge } { return }
  1802.  
  1803.     set angela_lasthighlight $edge
  1804.  
  1805.     angela:msg EDGE:SPLIT:NONE
  1806.  
  1807.     set line [$edge line]
  1808.     set coords [lindex [$line export -coords] 0]
  1809.     set length [llength $coords]
  1810.     set length [expr ($length-1)/2]
  1811.     set which 0
  1812.     foreach { x y } $coords {
  1813.     if { $which != 0 && $which != $length } {
  1814.         $canvas create rectangle \
  1815.         [expr $x-4] [expr $y-4] [expr $x+4] [expr $y+4] \
  1816.         -fill black -outline white -width 1 \
  1817.         -tags "eh hl$edge $edge $line eh$which"
  1818.     }
  1819.     if { $which != 0 && $which != $length } {
  1820.         $canvas bind eh$which <B1-Motion> \
  1821.         "angela:msg EDGE:SPLIT:MOVE $edge $which eh$which %x %y"
  1822. #        "angela:edge:split:move:grid $canvas $edge $which eh$which %x %y"
  1823.         $canvas bind eh$which <B1-ButtonRelease> \
  1824.         "angela:msg EDGE:SPLIT:MOVE:END $edge"
  1825.     }
  1826.     incr which
  1827.     }
  1828. }
  1829.  
  1830. proc angela:edge:lowlight { canvas { edge "" } } {
  1831.  
  1832. #    debug "edge:lowlight $canvas $edge"
  1833.     if { $edge == "" } {
  1834.     $canvas delete eh
  1835.     } else {
  1836.     $canvas delete hl$edge
  1837.     }
  1838. }
  1839.  
  1840. proc angela:edge:split:distance { x1 y1 x2 y2 } {
  1841.     set distance [expr sqrt( pow($x1-$x2,2) + pow($y1-$y2,2) )]
  1842.     return $distance
  1843. }
  1844.  
  1845. proc angela:edge:split:add { canvas edge x y } {
  1846. global angela_lasthighlight
  1847.  
  1848. #    debug "split:add $canvas $edge $x $y"
  1849.     set line [$edge line]
  1850.     set coords [lindex [$line export -coords] 0]
  1851.     set origcoords $coords
  1852.  
  1853.     angela:edge:lowlight $canvas $edge
  1854.  
  1855.     # Scans for minimal distance
  1856.     set found 0
  1857.     for { set i 0 } { $i < [expr [llength $coords]-2] } { incr i 2 } {
  1858.     set xa [lindex $coords $i]
  1859.     set ya [lindex $coords [expr $i+1]]
  1860.     set xb [lindex $coords [expr $i+2]]
  1861.     set yb [lindex $coords [expr $i+3]]
  1862.  
  1863.     if { [expr abs(([angela:edge:split:distance $xa $ya $x $y] + \
  1864.                 [angela:edge:split:distance $xb $yb $x $y]) - \
  1865.                [angela:edge:split:distance $xa $ya $xb $yb])] <= 1 } {
  1866.         set found 1
  1867.         break
  1868.     }
  1869.     }
  1870.     
  1871.     set i [expr $i/2]
  1872.  
  1873.     # Set the beginning of the coords
  1874.     set newcoords "[lrange $coords 0 1]"
  1875.     set coords [lreplace $coords 0 1]
  1876.     
  1877.     while { $i > 0 } {
  1878.     # Get the next two coords
  1879.     set newcoords "$newcoords [lrange $coords 0 1] "
  1880.     set coords [lreplace $coords 0 1]
  1881.     incr i -1
  1882.     }
  1883.  
  1884.     set newcoords "$newcoords $x $y $coords"
  1885.     $line update $canvas -coords $newcoords
  1886.     set angela_lasthighlight ""
  1887.     angela:edge:highlight $canvas $edge
  1888. }
  1889.  
  1890. # proc angela:edge:split:move:grid { path edge id tag x y } {
  1891. # global angela_gridx angela_gridy
  1892.  
  1893. #     angela:edge:split:move $path $edge $id $tag \
  1894. #     [$path canvasx $x $angela_gridx] \
  1895. #     [$path canvasy $y $angela_gridy]
  1896.  
  1897. # }
  1898.  
  1899. proc angela:edge:split:move { path edge id tag x y } {
  1900.  
  1901. #    debug "split:move $path $edge $id $tag $x $y"
  1902.     $path coords $tag [expr $x-4] [expr $y-4] [expr $x+4] [expr $y+4]
  1903.     # Set leaf $id of edge $edgeid to $x,$y
  1904.     set line [$edge line]
  1905.     set coords [lindex [$line export -coords] 0]
  1906.     set coords [lreplace $coords [expr $id*2] [expr $id*2] "$x"]
  1907.     set coords [lreplace $coords [expr $id*2+1] [expr $id*2+1] "$y"]
  1908.     $line update $path -coords $coords
  1909. #    $edge update $path
  1910.  
  1911. }
  1912.  
  1913. proc angela:edge:split:move:end { path edge } {
  1914.  
  1915.     $edge update $path
  1916.  
  1917. }
  1918.  
  1919. proc angela:edge:set { canvas edge cap cap_value } {
  1920. global edgecap edgecap_value
  1921.  
  1922. #    debug "edge:set $canvas $edge ..."
  1923.     foreach i $edgecap(edge) {
  1924.     $edge update -$i $edgecap_value(edge:$i)
  1925.     }
  1926.  
  1927.     foreach i $edgecap(line) {
  1928.     [$edge line] update $canvas -$i $edgecap_value(line:$i)
  1929.     }
  1930.  
  1931. }
  1932.  
  1933. proc angela:edge:update { canvas edge } {
  1934. global edgecap edgecap_value
  1935.  
  1936. #    debug "edge:update $canvas $edge"
  1937.     angela:edge:set $canvas $edge edgecap edgecap_value
  1938. }
  1939.  
  1940. proc angela:edge:edit { canvas edge } {
  1941. global angela_cap angela_cap_value edgecap edgecap_value
  1942.  
  1943. #    debug "edge:edit $canvas $edge"
  1944.     angela:capabilities:get:user $edge \
  1945.     " edge $edge line [$edge line] " \
  1946.     edgecap edgecap_value
  1947.  
  1948.     angela:capabilities:manager "edge line" \
  1949.     edgecap edgecap_value "angela:edge:update $canvas $edge"
  1950.  
  1951. }
  1952. proc angela:edge:context { path edge x y } {
  1953. global angela_option
  1954.  
  1955.     catch { $path delete contextmenu }
  1956.     catch { destroy .contextmenu }
  1957.     
  1958.     menu .contextmenu -tearoff 0 -font $angela_option(gui:font:cap) \
  1959.     -borderwidth 1
  1960.  
  1961.     .contextmenu add command -label "Delete Edge" \
  1962.     -command "angela:msg EDGE:DELETE $edge;\
  1963.               $path delete contextmenu;destroy .contextmenu"
  1964.  
  1965.     tk_popup .contextmenu [winfo pointerx .] [winfo pointery .]
  1966.  
  1967. }
  1968.  
  1969. ################################################################
  1970. #
  1971. # Nodes
  1972. #
  1973. ################################################################
  1974.  
  1975. proc angela:node:create { canvas x y } {
  1976. global angela_option
  1977.  
  1978.     # This is the high-level code for creating a node
  1979.  
  1980.     return [angela:msg \
  1981.         NODE:CREATE:DRAW \
  1982.         [$canvas canvasx $x $angela_option(gui:grid:x)] \
  1983.         [$canvas canvasy $y $angela_option(gui:grid:y)] \
  1984.         angela_cap angela_cap_value "node shape text"]
  1985.  
  1986. }
  1987. proc angela:node:create:direct { canvas x y cap capvalue} {
  1988. global thiscap thiscapvalue
  1989.  
  1990.     array set thiscap $cap
  1991.     array set thiscapvalue $capvalue
  1992.  
  1993.     # This is the high-level code for creating a node
  1994.  
  1995.     return [angela:msg \
  1996.         NODE:CREATE:DRAW \
  1997.         $x \
  1998.         $y \
  1999.         thiscap thiscapvalue "node shape text"]
  2000.  
  2001. }
  2002.  
  2003. proc angela:node:create:draw { canvas x y cap cap_value classes } {
  2004. global $cap $cap_value angela_nodes
  2005.  
  2006.     # This is the low-level code for creating a node
  2007.     # This is hard-coded into node/shape/text
  2008.  
  2009.     # Copy the capabilities into new variables
  2010.     array set newcap [array get $cap]
  2011.     array set newcap_value [array get $cap_value]
  2012.     
  2013.     set nodecmd  [angela:mod:scan:type object node]
  2014.     set shapecmd [angela:mod:scan:type object shape]
  2015.     set textcmd  [angela:mod:scan:type object text]
  2016.  
  2017.     set newcap_value(node:x) $x
  2018.     set newcap_value(node:y) $y
  2019.     set newcap_value(shape:x) $x
  2020.     set newcap_value(shape:y) $y
  2021.     set newcap_value(shape:coords) "$x $y"
  2022.     set newcap_value(text:coords) "$x $y"
  2023.  
  2024.     foreach type $classes {
  2025.     set attr$type ""
  2026.     foreach a $newcap($type) {
  2027.         set attr$type \
  2028.         "[set attr$type] -$a \"$newcap_value($type:$a)\" "
  2029.     }
  2030.     }
  2031.  
  2032.     set node [$nodecmd create]
  2033.     set shape [$node shape]
  2034.     set text [$node text]
  2035.     
  2036.     eval "$node update [set attrnode]"
  2037.     eval "$shape update $canvas [set attrshape]"
  2038.     eval "$text update $canvas [set attrtext]"
  2039.  
  2040.     lappend angela_nodes $node
  2041.     angela:ws:canvas:refresh .middle.canvas
  2042.  
  2043.     $node bind $canvas <B1-ButtonRelease> \
  2044.          "angela:msg NODE:MOTION:END $node"
  2045.     $node bind $canvas <Double-B1-ButtonRelease> \
  2046.          "angela:msg NODE:EDIT $node"
  2047.     $node bind $canvas <B1-Motion> \
  2048.          "angela:msg NODE:MOTION $node %x %y"
  2049.     $node bind $canvas <Shift-B1-ButtonRelease> \
  2050.          "debug sB1rel$node"
  2051.     $node bind $canvas <Alt-B1-ButtonRelease> \
  2052.          "debug aB1rel$node"
  2053.     $node bind $canvas <Control-B1-ButtonRelease> \
  2054.          "angela:msg NODE:SWITCH $node"
  2055.     $node bind $canvas <B2-ButtonRelease> \
  2056.          "angela:msg NODE:SWITCH $node"
  2057.     $node bind $canvas <B3-ButtonRelease> \
  2058.          "angela:msg NODE:CONTEXT $node %x %y"
  2059.  
  2060.     return $node
  2061. }
  2062.  
  2063. proc angela:node:delete { canvas node } {
  2064. global angela_nodes angela_selected_nodes
  2065.  
  2066.     angela:node:unselect $canvas $node
  2067.  
  2068.     # Destroy all related edges
  2069.  
  2070.     foreach edge [lindex [$node export -carriage] 0] {
  2071.  
  2072.     angela:edge:delete $canvas $edge
  2073.  
  2074.     }
  2075.  
  2076.     # Destroy the node
  2077.     
  2078.     [$node shape] delete $canvas
  2079.     [$node text] delete $canvas
  2080.     $node delete
  2081.  
  2082.     # Remove the node from the node list
  2083.     
  2084.     set index [lsearch $angela_nodes $node]    
  2085.     set angela_nodes [lreplace $angela_nodes $index $index]
  2086.     
  2087. }
  2088.  
  2089. proc angela:node:highlight { canvas node } {
  2090.  
  2091.     set shape [$node shape]
  2092.     eval "$canvas create rectangle [$canvas bbox $shape] \
  2093.     -tags \"hl hl$node $node\" -width 2 -outline red"
  2094.  
  2095. }
  2096.  
  2097. proc angela:node:lowlight { canvas node } {
  2098.  
  2099.     $canvas delete hl$node
  2100.  
  2101. }
  2102.  
  2103. proc angela:node:select { canvas node } {
  2104. global angela_selected_nodes
  2105.  
  2106.     angela:node:highlight $canvas $node
  2107.     lappend angela_selected_nodes $node
  2108. }
  2109.  
  2110. proc angela:node:unselect { canvas node } {
  2111. global angela_selected_nodes
  2112.     set index [lsearch $angela_selected_nodes $node]
  2113.     if { $index != -1 } {
  2114.     angela:node:lowlight $canvas $node
  2115.     set angela_selected_nodes \
  2116.         [lreplace $angela_selected_nodes $index $index]
  2117.     }
  2118. }
  2119.  
  2120. proc angela:node:switch { canvas node } {
  2121. global angela_selected_nodes
  2122.     set index [lsearch $angela_selected_nodes $node]
  2123.     if { $index == -1 } {
  2124.     angela:node:select $canvas $node
  2125.     } else {
  2126.     angela:node:unselect $canvas $node
  2127.     }
  2128. }
  2129.  
  2130. proc angela:node:move { canvas node dx dy } {
  2131.     $node move $canvas $dx $dy
  2132.     foreach e [lindex [$node export -carriage] 0] {
  2133.     $e update $canvas
  2134.     }    
  2135. }
  2136.  
  2137. proc angela:node:drag:end { canvas } {
  2138. global angela_dragflag
  2139.  
  2140.     set angela_dragflag 0
  2141. }
  2142.  
  2143. proc angela:node:drag { canvas node x y } {
  2144. global angela_dragflag angela_posx angela_posy angela_selected_nodes
  2145.  
  2146.     set nodes $angela_selected_nodes
  2147.  
  2148.     if { [lsearch $nodes $node] == -1 } {
  2149.     lappend nodes $node
  2150.     }
  2151.     if { !$angela_dragflag } {
  2152.     # Starting with drag
  2153.     set angela_dragflag 1
  2154.     set angela_posx $x
  2155.     set angela_posy $y    
  2156.     } else {
  2157.     # I am currently dragging
  2158.     # Move to current position
  2159.     set dx [expr $x-$angela_posx]
  2160.     set dy [expr $y-$angela_posy]
  2161.     foreach n $nodes {
  2162.         angela:node:move $canvas $n $dx $dy
  2163.     }
  2164.     set angela_posx $x
  2165.     set angela_posy $y    
  2166.     }
  2167. }
  2168.  
  2169. proc angela:node:set { canvas node cap cap_value } {
  2170. global nodecap nodecap_value
  2171.  
  2172.     foreach i $nodecap(node) {
  2173.     $node update -$i $nodecap_value(node:$i)
  2174.     }
  2175.  
  2176.     foreach i $nodecap(shape) {
  2177.     [$node shape] update $canvas -$i $nodecap_value(shape:$i)
  2178.     }
  2179.  
  2180.     foreach i $nodecap(text) {
  2181.     [$node text] update $canvas -$i $nodecap_value(text:$i)
  2182.     }
  2183.  
  2184.     [$node text] raise $canvas [$node shape]
  2185. }
  2186.  
  2187. proc angela:node:update { canvas node } {
  2188. global nodecap nodecap_value
  2189.  
  2190.     angela:node:set $canvas $node nodecap nodecap_value
  2191. }
  2192.  
  2193. proc angela:node:edit { canvas node } {
  2194. global angela_cap angela_cap_value nodecap nodecap_value
  2195.  
  2196.     angela:capabilities:get:user $node \
  2197.     " node $node shape [$node shape] text [$node text] " \
  2198.     nodecap nodecap_value
  2199.  
  2200. #    foreach class { node shape text } {
  2201. #    foreach i $nodecap($class) {
  2202. #        debug "Cap $i=$nodecap_value($class:$i)"
  2203. #    }
  2204. #    }
  2205.  
  2206.     angela:capabilities:manager "node shape text" \
  2207.     nodecap nodecap_value "angela:node:update $canvas $node"
  2208.  
  2209. }
  2210.  
  2211. proc angela:node:context { path node x y } {
  2212. global angela_option
  2213.  
  2214.     catch { $path delete contextmenu }
  2215.     catch { destroy .contextmenu }
  2216.     
  2217.     menu .contextmenu -tearoff 0 -font $angela_option(gui:font:cap) \
  2218.     -borderwidth 1
  2219.  
  2220.     .contextmenu add command -label "Switch node" \
  2221.     -command "angela:msg NODE:SWITCH $node;\
  2222.               $path delete contextmenu;destroy .contextmenu"
  2223.  
  2224.     .contextmenu add separator
  2225.  
  2226.     .contextmenu add command -label "Delete node" \
  2227.     -command "angela:msg NODE:DELETE $node;\
  2228.               $path delete contextmenu;destroy .contextmenu"
  2229.  
  2230.     tk_popup .contextmenu [winfo pointerx .] [winfo pointery .]
  2231.  
  2232.  
  2233. }
  2234.  
  2235. ################################################################
  2236. #
  2237. # Bug Management
  2238. #
  2239. ################################################################
  2240.  
  2241. proc angela:bug { } {
  2242. global tcl_platform \
  2243.     bugreport_name \
  2244.     bugreport_source \
  2245.     bugreport_system \
  2246.     bugreport_install \
  2247.     bugreport_motivation
  2248.  
  2249.     set w .bugreport
  2250.     catch { destroy $w }
  2251.     toplevel $w
  2252.     wm title $w "angela!:Bug Report generator"
  2253.  
  2254.     angela:prefs:window $w BugReport
  2255.  
  2256.     # Create the notebook widget
  2257.     tixNoteBook $w.nb -ipadx 6 -ipady 6
  2258.     $w config -bg gray
  2259.     $w.nb subwidget nbframe configure -backpagecolor gray
  2260.  
  2261.     # Create the tabs in the notebook
  2262.     $w.nb add general -label "General" -underline 0
  2263.     pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top
  2264.  
  2265.     # Create the general page
  2266.     set f [$w.nb subwidget general]
  2267.  
  2268.     label $f.head -text \
  2269.     "This generates a file you can send to the author via your mail tool."
  2270.  
  2271.     frame $f.f
  2272.     frame $f.common
  2273.     pack $f.head $f.f -side top -padx 2 -pady 2 -fill both -expand yes
  2274.     pack $f.common -side bottom -padx 2 -pady 2 -fill x
  2275.  
  2276.     tixLabelEntry $f.f.name -label "Your name: " \
  2277.     -options {
  2278.         entry.width 50
  2279.         label.width 25
  2280.         label.anchor e
  2281.         entry.textVariable bugreport_name
  2282.     }
  2283.  
  2284.     tixComboBox $f.f.source -label "Where did you get angela!: " -dropdown true \
  2285.     -editable true -variable bugreport_source \
  2286.     -options {
  2287.         listbox.height 5
  2288.         label.width 25
  2289.         label.anchor e
  2290.         entry.width 50
  2291.     }
  2292.     
  2293.     $f.f.source insert end "Official Homepage of angela!"
  2294.     $f.f.source insert end "Official FTP-Server"
  2295.     $f.f.source insert end "Local FTP-Server"
  2296.     $f.f.source insert end "Magazine's CD-ROM (Name: xyz)"
  2297.     $f.f.source insert end "Local grocery"
  2298.     $f.f.source insert end "My Milkman deposited it here!"
  2299.  
  2300.     tixLabelEntry $f.f.system -label "Your system: " \
  2301.     -options {
  2302.         entry.width 50
  2303.         label.width 25
  2304.         label.anchor e
  2305.         entry.textVariable bugreport_system
  2306.     }
  2307.  
  2308.     set newval ""
  2309.     foreach i [array names tcl_platform] {
  2310.     append newval $tcl_platform($i) " "
  2311.     }
  2312.  
  2313.     uplevel #0 set bugreport_system \"$newval\"
  2314.  
  2315.     tixComboBox $f.f.install -label "Difficult to install ?: " -dropdown true \
  2316.     -editable true -variable bugreport_install \
  2317.     -options {
  2318.         listbox.height 5
  2319.         label.width 25
  2320.         label.anchor e
  2321.         entry.width 50
  2322.     }
  2323.  
  2324.     $f.f.install insert end "No, it was not difficult! (no major changes made)"
  2325.     $f.f.install insert end "Yes, it was difficult! (major changes made)"
  2326.     $f.f.install insert end "I used the binary version."
  2327.     $f.f.install insert end "Our sysadmin made the installation!"
  2328.     $f.f.install insert end "I didn't manage to get it work! (huh!)"
  2329.  
  2330.     tixComboBox $f.f.motivation -label "Overall opinion ?: " -dropdown true \
  2331.     -editable true -variable bugreport_motivation \
  2332.     -options {
  2333.         listbox.height 5
  2334.         label.width 25
  2335.         label.anchor e
  2336.         entry.width 50
  2337.     }
  2338.  
  2339.     $f.f.motivation insert end "Continue improving angela!"
  2340.     $f.f.motivation insert end "angela! will end in a dead-project!"
  2341.     $f.f.motivation insert end "I am enjoying using angela!"
  2342.     $f.f.motivation insert end "I cannot imagine working without angela! (really thanks)"
  2343.  
  2344.     label $f.f.contexttext -text "Describe the context as the bug occured:"
  2345.     tixScrolledText $f.f.context -height 60
  2346.  
  2347.     label $f.f.actiontext -text "Describe the action you were doing (or wanted to do):"
  2348.     tixScrolledText $f.f.action -height 60
  2349.  
  2350.     label $f.f.changetext -text "Describe the change you would like to see:"
  2351.     tixScrolledText $f.f.change -height 60
  2352.  
  2353.     pack \
  2354.     $f.f.name \
  2355.     $f.f.source \
  2356.         $f.f.system \
  2357.         $f.f.install \
  2358.         $f.f.motivation \
  2359.         $f.f.contexttext \
  2360.         $f.f.context \
  2361.         $f.f.actiontext \
  2362.         $f.f.action \
  2363.         $f.f.changetext \
  2364.         $f.f.change \
  2365.     -side top -fill x -expand yes
  2366.  
  2367.     # Create the common buttons
  2368.     angela:bug:CreateCommonButtons $w $f.common $f
  2369. }
  2370.  
  2371. proc angela:bug:CreateCommonButtons {w f realf} {
  2372.  
  2373.     button $f.ok -text "Save to bugreport.txt" \
  2374.     -command "angela:bug:okcmd $w $realf;\
  2375.                   angela:prefs:window:save $w BugReport"
  2376.     button $f.cancel -text Cancel -width 6 \
  2377.     -command "angela:prefs:window:save $w BugReport"
  2378.  
  2379.     pack $f.ok $f.cancel -side left -padx 2 -pady 2
  2380.  
  2381. }
  2382.  
  2383. proc angela:bug:okcmd {w f} {
  2384. global \
  2385.     bugreport_name \
  2386.     bugreport_source \
  2387.     bugreport_system \
  2388.     bugreport_install \
  2389.     bugreport_motivation
  2390.  
  2391.     if { [catch { set handle [open "bugreport.txt" w] }] } {
  2392.  
  2393.     angela:dlg "Cannot open bugreport.txt file!!! Aborting."
  2394.     return
  2395.  
  2396.     }
  2397.  
  2398.     puts $handle "Subject: \[angela! BR\]"
  2399.     puts $handle ""
  2400.     puts $handle "Bug report for angela! Send this file to angela@itm.uni-sb.de"
  2401.     puts $handle "using your conventional and preferred mail tool."
  2402.     puts $handle "Please make sure, that the subject line contains the content"
  2403.     puts $handle "of the first line (without the Subject: prefix, of course)."
  2404.     puts $handle ""
  2405.     puts $handle "-------------------------------------------------------------"
  2406.     puts $handle "     Name of user: $bugreport_name"
  2407.     puts $handle "Source of angela!: $bugreport_source"
  2408.     puts $handle "     Local system: $bugreport_system"
  2409.     puts $handle "Installation deg.: $bugreport_install"
  2410.     puts $handle "       Motivation: $bugreport_motivation"
  2411.     puts $handle ""
  2412.     puts $handle "-------------------------------------------------------------"
  2413.     puts $handle "Tcl/Tk infos:"
  2414.     puts $handle "     Command count: [info cmdcount]"
  2415.     puts $handle "  Loaded libraries: [info loaded]"
  2416.     puts $handle "    Called library: [info library]"
  2417.     puts $handle "        Executable: [info nameofexecutable]"
  2418.     puts $handle "        Patchlevel: [info patchlevel]"
  2419.     puts $handle ""
  2420.     puts $handle "-------------------------------------------------------------"
  2421.     puts $handle "Context of problem:"
  2422.     puts $handle "[$f.f.context subwidget text get 1.0 end]"
  2423.     puts $handle ""
  2424.     puts $handle "-------------------------------------------------------------"
  2425.     puts $handle "Action trigerring the problem:"
  2426.     puts $handle "[$f.f.action subwidget text get 1.0 end]"
  2427.     puts $handle ""
  2428.     puts $handle "-------------------------------------------------------------"
  2429.     puts $handle "Change requested:"
  2430.     puts $handle "[$f.f.change subwidget text get 1.0 end]"
  2431.     puts $handle ""
  2432.     puts $handle "-------------------------------------------------------------"
  2433.     puts $handle "End of bug report. Append your comments below this line."
  2434.  
  2435.     close $handle
  2436. }
  2437.  
  2438. ################################################################
  2439. #
  2440. # Load
  2441. #
  2442. ################################################################
  2443.  
  2444. proc angela:load { { filename "" } } {
  2445. global angela_mod_list angela_filename
  2446.  
  2447.     set defaultextension ""
  2448.  
  2449.     if { $filename == "" || ![file exists $filename]} {
  2450.  
  2451.     # Scan all filter_in modules to produce extension list.
  2452.     set extensions " { \"All files\" * } "
  2453.     set modules [angela:mod:scan $angela_mod_list type "filter_in"]
  2454.     
  2455.     foreach i $modules {
  2456.         set extensions "$extensions { \
  2457.                         \"[angela:mod:info:algorithm_name $i]\" \
  2458.                         \"[$i extension]\" }"
  2459.         set defaultextension [$i extension]
  2460.     }
  2461.     
  2462.     set initialdir [angela:prefs:read LoadPath]
  2463.     if { $initialdir == "" || ![file exists $initialdir] } { 
  2464.         set initialdir ./ 
  2465.     }
  2466.  
  2467.     set file [ tk_getOpenFile -filetypes $extensions -parent . \
  2468.                -initialdir $initialdir \
  2469.                -defaultextension $defaultextension ]
  2470.     
  2471.     if { $file != "" } {
  2472.         angela:prefs:write LoadPath [file dirname $file]
  2473.         angela:load $file
  2474.     }
  2475.  
  2476.     } else {
  2477.     
  2478.     set extension [file ext $filename]
  2479.     set modules [angela:mod:scan $angela_mod_list type "filter_in"]
  2480.     set module ""
  2481.     foreach i $modules {
  2482.         if { [$i extension]==$extension } {
  2483.         set module $i
  2484.         break
  2485.         }
  2486.     }
  2487.     if { $module == "" } {
  2488.         debug "Did not found any module for file $filename"
  2489.     }
  2490.     debug "Filetype according to extension is $module"
  2491.     angela:load:module $filename $module
  2492.  
  2493.     }
  2494. }
  2495.  
  2496. proc angela:load:module { filename module } {
  2497. global angela_filename
  2498.  
  2499.     # first delete the current graph
  2500.     angela:msg GRAPH:NEW
  2501.     # open the file and read the graph
  2502.     set handle [open $filename r]
  2503.     angela:load:module:do $handle $module
  2504.     close $handle
  2505.     # update file filename information in editor
  2506.     set angela_filename $filename
  2507.     angela:ws:title:init .
  2508.     angela:msg TOOL:EDIT
  2509. }
  2510.  
  2511. proc angela:load:module:do { handle module } {
  2512. global angela_nodes angela_edges
  2513.     $module load $handle angela:msg $angela_nodes $angela_edges
  2514. }
  2515.  
  2516. ################################################################
  2517. #
  2518. # Save
  2519. #
  2520. ################################################################
  2521.  
  2522. proc angela:save:as { { file "" } } {
  2523. global angela_mod_list
  2524.  
  2525.     if { $file != "" } {
  2526.     angela:save $file
  2527.     return
  2528.     }
  2529.  
  2530.     # Scan all filter_out modules to produce extension list.
  2531.     set extensions " { \"All files\" * } "
  2532.     set modules \
  2533.       [angela:mod:scan $angela_mod_list type "filter_out"]
  2534.  
  2535.     set defaultextension ""
  2536.     
  2537.     foreach i $modules {
  2538.     set extensions "$extensions { \
  2539.                         \"[angela:mod:info:algorithm_name $i]\" \
  2540.                         \"[$i extension]\" }"
  2541.     set defaultextension [$i extension]
  2542.     }
  2543.  
  2544.     set initialdir [angela:prefs:read SavePath]
  2545.     if { $initialdir == "" || ![file exists $initialdir] } {
  2546.     set initialdir [pwd]
  2547.     }
  2548.  
  2549.     set file [ tk_getSaveFile -filetypes $extensions -parent . \
  2550.           -initialfile Untitled -initialdir $initialdir \
  2551.           -defaultextension $defaultextension]
  2552.     
  2553.     if { $file != "" } {
  2554.     angela:prefs:write SavePath [file dirname $file]
  2555.     angela:save $file
  2556.     }
  2557.  
  2558. }
  2559.  
  2560. proc angela:save { filename } {
  2561. global angela_mod_list
  2562.  
  2563.     set extension [file ext $filename]
  2564.     set modules [angela:mod:scan $angela_mod_list type "filter_out"]
  2565.     set module ""
  2566.     foreach i $modules {
  2567.     if { [$i extension]==$extension } {
  2568.         set module $i
  2569.         break
  2570.     }
  2571.     }
  2572.     if { $module == "" } {
  2573.     debug "Did not found any module for file $filename"
  2574.     }
  2575.     debug "Filetype according to extension is $module"
  2576.     angela:save:module $filename $module
  2577. }
  2578.  
  2579. proc angela:save:module { filename module } {
  2580. global angela_filename
  2581.     # Must save graph using filename and module
  2582.  
  2583.     set handle [open $filename w]
  2584.     angela:save:module:do $handle $module
  2585.     close $handle
  2586.  
  2587.     set angela_filename $filename
  2588.     angela:ws:title:init .
  2589. }
  2590.  
  2591. proc angela:save:module:do { handle module } {
  2592. global angela_nodes angela_edges
  2593.     
  2594.     $module save $handle angela:msg $angela_nodes $angela_edges
  2595.     
  2596. }
  2597.  
  2598. ################################################################
  2599. #
  2600. # Niou
  2601. #
  2602. ################################################################
  2603.  
  2604. proc angela:new { } {
  2605. global angela_nodes angela_edges angela_canvas angela_filename
  2606.  
  2607.     foreach i $angela_edges {
  2608.     [$i line] delete $angela_canvas
  2609.     $i delete
  2610.     }
  2611.  
  2612.     foreach i $angela_nodes {
  2613.     [$i shape] delete $angela_canvas
  2614.     [$i text] delete $angela_canvas
  2615.     $i delete
  2616.     }
  2617.  
  2618.     set angela_nodes ""
  2619.     set angela_edges ""
  2620.     set angela_filename ""
  2621.  
  2622.     angela:ws:title:init .
  2623. }
  2624.  
  2625. ################################################################
  2626. #
  2627. # Clipboard Management
  2628. #
  2629. ################################################################
  2630.  
  2631. proc angela:clipboard:cut { } {
  2632. global angela_selected_nodes
  2633.  
  2634.     # Scan which nodes I have to cut...
  2635.     foreach node $angela_selected_nodes {
  2636.     angela:msg NODE:SWITCH $node
  2637.     angela:msg NODE:DELETE $node
  2638.     }
  2639.  
  2640.     set angela_selected_nodes ""
  2641.  
  2642. }
  2643.  
  2644. ################################################################
  2645. #
  2646. # Message Management
  2647. #
  2648. ################################################################
  2649.  
  2650. proc angela:msg \
  2651.     { \
  2652.       message \
  2653.       { arg1 "" } \
  2654.       { arg2 "" } \
  2655.       { arg3 "" } \
  2656.       { arg4 "" } \
  2657.       { arg5 "" } } {
  2658.  
  2659. global angela_canvas angela_state angela_option angela_edgemem \
  2660.     temp_cap temp_capvalue angela_filename
  2661.  
  2662.           #debug "msg:$message $arg1 $arg2 $arg3 $arg4 $arg5"
  2663.           
  2664.           switch $message {
  2665.  
  2666.           CANVAS
  2667.           {
  2668.               return $angela_canvas
  2669.           }
  2670.  
  2671.           VERSION
  2672.           {
  2673.               set Revision "\$Revision"
  2674.               set version "$Revision: 1.28 $"
  2675.               set version [split $version :]
  2676.               set version [string trim [lindex [lindex $version 1] 0] 0]
  2677.               return $version
  2678.           }
  2679.  
  2680.           BUG 
  2681.           {
  2682.               angela:bug
  2683.           }
  2684.  
  2685.           CUT
  2686.           {
  2687.               angela:clipboard:cut
  2688.           }
  2689.  
  2690.           MODULES
  2691.           {
  2692.               angela:mod:manager .modules
  2693.           }
  2694.           
  2695.           QUIT
  2696.           {
  2697.               angela:quit
  2698.           }
  2699.  
  2700.           TOOL:NODE
  2701.           { 
  2702.               angela:tool:node
  2703.           }
  2704.  
  2705.           TOOL:EDGE
  2706.           { 
  2707.               angela:tool:edge
  2708.           }
  2709.  
  2710.           TOOL:EDIT
  2711.           { 
  2712.               angela:tool:edit
  2713.           }
  2714.  
  2715.           TOOL:ADD:CASCADE
  2716.           {
  2717.               return [angela:tool:add:cascade .menubar.tools.m $arg1 $arg2]
  2718.           }
  2719.  
  2720.           NODE:INFO
  2721.           {
  2722.               return [$arg1 export $arg2]
  2723.           }
  2724.  
  2725.           NODE:MOTION
  2726.           {
  2727.               switch $angela_state {
  2728.               EDIT
  2729.               {
  2730.                   angela:node:drag $angela_canvas $arg1 \
  2731.                   [$angela_canvas canvasx $arg2 $angela_option(gui:grid:x)] \
  2732.                   [$angela_canvas canvasy $arg3 $angela_option(gui:grid:y)]
  2733.               }
  2734.               }
  2735.           }
  2736.  
  2737.           NODE:MOTION:END
  2738.           {
  2739.               switch $angela_state {              
  2740.               EDIT
  2741.               {
  2742.                   angela:node:drag:end $angela_canvas
  2743.               }
  2744.  
  2745.               
  2746.               EDGE2
  2747.               {
  2748.                   set angela_state EDGE
  2749.                   angela:msg EDGE:CREATE $angela_edgemem $arg1
  2750.               }
  2751.  
  2752.               EDGE
  2753.               {
  2754.                   set angela_edgemem $arg1
  2755.                   set angela_state EDGE2
  2756.               }
  2757.               }
  2758.           }
  2759.           
  2760.           NODE:CREATE
  2761.           {
  2762.               return [angela:node:create $angela_canvas $arg1 $arg2]
  2763.           }
  2764.  
  2765.           NODE:CREATE:DIRECT
  2766.           {
  2767.               return [angela:node:create:direct $angela_canvas $arg1 $arg2 \
  2768.                   $arg3 $arg4]
  2769.           }
  2770.  
  2771.           NODE:SWITCH
  2772.           {
  2773.               #if { $angela_state == "EDIT" } {
  2774.               angela:node:switch $angela_canvas $arg1
  2775.               #}
  2776.           }
  2777.  
  2778.           NODE:CREATE:DRAW
  2779.           {
  2780.               return [angela:node:create:draw \
  2781.                   $angela_canvas \
  2782.                   $arg1 $arg2 $arg3 $arg4 $arg5]
  2783.           }
  2784.  
  2785.           NODE:DELETE
  2786.           {
  2787.               angela:node:delete $angela_canvas $arg1
  2788.           }
  2789.  
  2790.           NODE:EDIT
  2791.           {
  2792.               switch $angela_state {
  2793.               EDIT
  2794.               {
  2795.                   angela:node:edit $angela_canvas $arg1
  2796.               }
  2797.               }
  2798.           }
  2799.  
  2800.           NODE:EDIT:GET
  2801.           {
  2802.               angela:capabilities:get:all $arg1 \
  2803.               " node $arg1 shape [$arg1 shape] text [$arg1 text] " \
  2804.               temp_cap temp_capvalue
  2805.  
  2806.               return "\{ [array get temp_cap] \} \{ [array get temp_capvalue] \}"
  2807.           }
  2808.  
  2809.           NODE:CONTEXT
  2810.           {
  2811.               angela:node:context $angela_canvas $arg1 \
  2812.               [$angela_canvas canvasx $arg2] \
  2813.               [$angela_canvas canvasy $arg3]
  2814.           }
  2815.  
  2816.           EDGE:INFO 
  2817.           {
  2818.               return [$arg1 export $arg2]
  2819.           }
  2820.  
  2821.           EDGE:EDIT
  2822.           {
  2823.               switch $angela_state {
  2824.               EDIT
  2825.               {
  2826.                   angela:edge:edit $angela_canvas $arg1
  2827.               }
  2828.               }
  2829.           }
  2830.  
  2831.           EDGE:EDIT:GET
  2832.           {
  2833.               angela:capabilities:get:all $arg1 \
  2834.               " edge $arg1 line [$arg1 line] " \
  2835.               temp_cap temp_capvalue
  2836.               
  2837.               return "\{ [array get temp_cap] \} \{ [array get temp_capvalue] \}"
  2838.           }
  2839.  
  2840.           EDGE:CREATE
  2841.           {
  2842.               angela:edge:create $angela_canvas $arg1 $arg2
  2843.           }
  2844.  
  2845.           EDGE:CREATE:DIRECT
  2846.           {
  2847.               angela:edge:create:direct $angela_canvas $arg1 $arg2 $arg3 $arg4
  2848.           }
  2849.  
  2850.           EDGE:CREATE:DRAW
  2851.           {
  2852.               angela:edge:create:draw \
  2853.               $angela_canvas \
  2854.               $arg1 $arg2 $arg3 $arg4 $arg5
  2855.           }
  2856.  
  2857.           EDGE:DELETE
  2858.           {
  2859.               angela:edge:delete $angela_canvas $arg1
  2860.           }
  2861.  
  2862.           EDGE:ENTER
  2863.           {
  2864.               angela:edge:highlight $angela_canvas $arg1
  2865.           }
  2866.  
  2867.           EDGE:SPLIT:NONE
  2868.           {
  2869.               angela:edge:lowlight $angela_canvas
  2870.           }
  2871.  
  2872.           EDGE:SPLIT
  2873.           {
  2874.               switch $angela_state {
  2875.               EDGE
  2876.               {
  2877.                   angela:edge:split:add $angela_canvas \
  2878.                   $arg1 \
  2879.                   [$angela_canvas canvasx $arg2] \
  2880.                   [$angela_canvas canvasy $arg3]
  2881.               }
  2882.               }              
  2883.           }
  2884.  
  2885.           EDGE:SPLIT:MOVE
  2886.           {
  2887.               switch $angela_state {
  2888.               EDIT
  2889.               {
  2890.                   angela:edge:split:move $angela_canvas $arg1 $arg2 $arg3 \
  2891.                   [$angela_canvas canvasx $arg4 $angela_option(gui:grid:x)] \
  2892.                   [$angela_canvas canvasy $arg5 $angela_option(gui:grid:y)]
  2893.               }
  2894.               }
  2895.           }
  2896.  
  2897.           EDGE:SPLIT:MOVE:END
  2898.           {
  2899.               switch $angela_state {
  2900.               EDIT
  2901.               {
  2902.                   angela:edge:split:move:end $angela_canvas $arg1
  2903.               }
  2904.               }
  2905.           }
  2906.  
  2907.           EDGE:CONTEXT
  2908.           {
  2909.               angela:edge:context $angela_canvas $arg1 \
  2910.               [$angela_canvas canvasx $arg2] \
  2911.               [$angela_canvas canvasy $arg3]
  2912.           }
  2913.  
  2914.           # Remove not needed hints such as edge bends to
  2915.           # prepare for print.
  2916.  
  2917.           GRAPH:CLEANUP
  2918.           {
  2919.               angela:edge:lowlight $angela_canvas
  2920.           }
  2921.  
  2922.           GRAPH:NEW
  2923.           {
  2924.               angela:new
  2925.           }
  2926.  
  2927.           GRAPH:PRINT
  2928.           {
  2929.               angela:print $angela_canvas
  2930.           }
  2931.  
  2932.           GRAPH:PROPERTIES
  2933.           {
  2934.               angela:properties
  2935.           }
  2936.  
  2937.           GRAPH:OPEN
  2938.           {
  2939.               angela:load $arg1
  2940.           }
  2941.  
  2942.           GRAPH:SAVE
  2943.           {
  2944.               set filename $angela_filename
  2945.               if { $arg1 != "" } {
  2946.               set filename $arg1
  2947.               }
  2948.               if { [file exists $filename] } {
  2949.               angela:save $filename
  2950.               } else {
  2951.               angela:msg GRAPH:SAVEAS $arg1
  2952.               }
  2953.           }
  2954.  
  2955.           GRAPH:SAVEAS
  2956.           {
  2957.               angela:save:as $arg1
  2958.           }
  2959.  
  2960.           default
  2961.           {
  2962.               tk_dialog .error \
  2963.               "Unknown message" \
  2964.               "The message server received an unknown\
  2965.                            message to process. Request will be\
  2966.                            ignored.\n\
  2967.                            $message $arg1 $arg2 $arg3\
  2968.                            $arg4 $arg5" \
  2969.               "" \
  2970.               0 \
  2971.               "Ok"
  2972.           }
  2973.           
  2974.           }
  2975.  
  2976. switch $angela_state {
  2977.     
  2978.     NORMAL
  2979.     {
  2980.     status "Press action button."
  2981.     }
  2982.  
  2983.     NODE
  2984.     {
  2985.     status "Left click to create node."
  2986.     }
  2987.  
  2988.     EDGE
  2989.     {
  2990.     status "Left click on first node for edge,\
  2991.                 Left click on existing edge to create bend."
  2992.     }
  2993.  
  2994.     EDGE2
  2995.     {
  2996.     status "Left click on second node to create edge."
  2997.     }
  2998.  
  2999.     EDIT
  3000.     {
  3001.     status "Left drag to move node(s) and edge bends.\
  3002.                 Ctrl Left click or middle click \
  3003.                 to switch node. Double Left to edit."
  3004.     }
  3005. }
  3006.  
  3007. }
  3008.           
  3009. ################################################################
  3010. #
  3011. # Fatal exit
  3012. #
  3013. ################################################################
  3014.  
  3015. proc fatal { text } {
  3016.  
  3017.     puts stderr ""
  3018.     puts stderr "I am sorry. Something was wrong and I cannot\
  3019.                  continue executing angela!."
  3020.     puts stderr "Reason: $text"
  3021.     puts stderr "For bug reports: angela@itm.uni-sb.de"
  3022.     puts stderr ""
  3023.  
  3024.     exit
  3025.  
  3026. }
  3027.  
  3028. ################################################################
  3029. #
  3030. # Quit
  3031. #
  3032. ################################################################
  3033.  
  3034. proc angela:dlg { text } {
  3035.     tk_dialog .error \
  3036.     "Warning" \
  3037.     "$text" \
  3038.     "" \
  3039.     0 \
  3040.     "Ok"
  3041. }
  3042.  
  3043. ################################################################
  3044. #
  3045. # Quit
  3046. #
  3047. ################################################################
  3048.  
  3049. proc angela:quit { } {
  3050.  
  3051.     angela:prefs:window:save . MainWindow
  3052.     exit
  3053.  
  3054. }
  3055.  
  3056. ################################################################
  3057. #
  3058. # Startup logo
  3059. #
  3060. ################################################################
  3061.  
  3062. proc angela:logo { } {
  3063.  
  3064.     catch { destroy .logo }
  3065.     toplevel .logo
  3066.     wm title .logo "Welcome to angela!"
  3067.     angela:prefs:window .logo Logo
  3068.  
  3069.     image create photo angela_logo -data R0lGODlhyACWAMYAAP////T09Ly8vOTk5I2Xa1GPSMzMzHCLIHCOWsnYv9zc3Et2Imx0FGyUFGqGD+zs7NTU1I+mOk2YGmyjD8TExKvLkjmLFYiXLJOofqS5jXKhTZSUlJycnPz09KSkpLS0tDltIDR8HCxpHEeHGqysrHx8fIyMjFG5H4W5VI2WiEapGmxsbHR0dFRUVCwsLBQUFCQkJDw8PBiIPeTs7AdMITehGPzs9ERERAAAAFxcXOJUYesFFO2apPwEHK0SHS6MFaKiov8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A/yH+FG1hZGUgYnkgT2xpdmVyIFBhYnN0ACwAAAAAyACWAAAH/oAAgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0KwBDwHV0dePAYPWiQMFMuAZBjPY5YcQGgUYAxkFGhTahAMkBhng9zIV8fIZGR4J1Mwpq7AghIgQBERYGDEiAzlBCmTQoPFtIkUBCh5sq1YDn7qHAnfF4zZIQIiTIEQsECFixEIMCgQVoIGP5goPHyAM0GbgGwdwFmVQmLEvpK0BBAoIMHAAQYJ4CgqeDLFgJUsRBRB4eDAAn0SaLDws3TnDo8UCHwwoKCpoGjW2/kZPDai6gEEDBw4aCND4AEIGAggQiAABggUBExvozaAgEVwIoC08UBhAzgNNmo1ZpCBBIWPRAR1lFBAHMm6pABHwVpUwoXUDChoDzDDwYWWIEQUSfxhbQXSKDd8ak4AQL/g9iynSZhQ0r57XfHBNg6owAa+FAw0atL4AU9sDBQYEM9QqAAIEBTMezIDwwYOHiiKGx7sXosTxEhihfq04Uely6ZmQxNYDCfylAV4FELABB+VpBIB6CiAAwgIm5DQANR0AEAB4FEBggAApFCCfIGK19xNQJQw1yEz02YSTTtEBmE07CHSogQbrxNPBhhRk5wADG+DUYIZtKaBBCgwq/kDkIFwN4KQCFOxGXFsD0CaAAO/JkMJkzHk1kQxhjRWjjIw8UAAIJxVQQEsWFDAlAB30FUF2B4hlgE4PLAmADRAIkNYAh+wTwADmrTXIDIQqoECfHIgFKAAGNCbDYxJF1hlI3JBEZqAFoDSYVQwV8FRbfV0wAQH0XBiAnoL0dZ4NjcyQXiHqVTMDhwY82lsBvwVH04gP0mgjjjttaggGI0xFFWEsLZDVAER20EECGHCQk4OIuLWJbApQdih77sE3XKtnptmpS26OmYkCOrSrww4Q7KLABxggQEBBKpVQQpCdFdWXAJ2xepqA4BlgMIgiEhdApyd9Olioo4LCQw8U/u/QwiwExvOdNjtCWUIIIDBkggckfNBZQILEaR62rzRJGZRSBoDBVIQx2+yz6lbCJ8U9+GBALAFUcMIEKCRQgXYHPDUoeymNsEByd+JZiLR5ziLooudtWEG99xK2gL78GtrJABNXfDEsD6DQWmsoDC2BdhlQ890HIZPn2arCqOcgjwScJDLJu/23CQ86UOzD4fG2jEJ2a6vd2tsT6NNqBggkZgDLxyz9wWBUQX1eRgJbYkMPO/hAQQclwDKAqa2dMHQEEQztmgQRVxk45plzRULdYnkWOiYCsPD7KtMYjQLsB6gwgQasL4/B3oRCULUzD1DOAT24YzMNzASwNsEJ/gSk8Fuq+zyA8jMDRNlhzs5s/6EGErB2QQQc1C+Z4HBiEz20cOKtIfvG2B4FMKCdCVyAANf7gMmkB0BluEUbEEgKBmbQjndkzxGdycWOBqAAAcBvAhFIzFLuBDrTdKACaDJIQhbSkNJAgnAi+U4FVHAkO3XrQhfEhkmmohKW3MYCOYqEDd7FA14MCgMkuN7JqjG8a0QFJSBbSUompJUGDqJsPujFv0qmFis+oy9/CQzIQLACBVkrV5AYYsWK+IoAUIAAEchANQxAAALIcWkUuFMOQyIb9oygJbjRjZgcwS6e+eAGsGrFAOZ0FwZEoAIMYMCPGAAbDnbLi9H4Tnge/kYeEhbrEYXbAQteoYALZOeUB7hAJCP5owzgEJPX4AoEJESh4ZgPlqFMnTQycEo6OeAABJikJC9wgQqcz1jbMFIKegdLQYRylKwYQAWOd4AD5IUB1VTlKodpgGaWIwB9+lMldHA4aK5CWhykAAkwQABJ5iUCCFgBAwyDPT5C4jvn2WMv3NceBODFAcQ8DGI28CdvAqMaD+DADXTJCBvM6hgbhECUVJkXUyGQZFz8JDSqMQATwAAHOMiBQRGhT1hMg1AG8IADRpDKCzRqNwBTy/SaUQ0FsOAFIAWpSLfFAhywQFO1OGmVMFDRkaXlc91qYjGqQYKcOnWnARJATm8A/lRBJC4WHagSAS6AGM7gKU/+o2kAPuCCGzgVBy0oaSOqUQKnCiA6MJxF+jyQwFwpNRkcBU8LnJrWAD2gpznlAO5swIMdsBFoMDMZ/qKRVwoAFqQtGOk2HtDWnG6FLQYI5WHb2BeD6eSueOUWBSoLWbUyYhomcCoJjgmAsvXsqqd5owbuSEc7dsszRsFnCvhaVUkMygNu1SgABlA40vlgs6NYpI8cEAEKCJMBAhCuOZa2Ad769QNOZSAheFC2HXDgFKXsJV606c4DYECywthedXPaV0xMQ6o51W4hQqmD0/Cyl9YE5nOJKTk+Emq9kO1tJKYBgZy+ALeFwGIppElN/ms2AJup3GYkL2CAaGkoQ6BNBMd8qyFKaENd6rWuhju8iO3l1AUI3m7pskgKdEJpnQQ4gCQbcIF4MsBenNmJWzjQAhe8AAYviEEJYNuWamyoBDAwgZE7GoMft0AAijCyAkpwAyC/wAUrgHKUp+GBHPj4xzcwwaO28V++4q4aH/DyC9bsghxo+RBcwSkOXKAqQxBWSabgpwcQYBeAHnCgSryhB+T8gio71ZwIfYABcpDTEpjvAx89K0MLwdHHllXOc17QguoXEyNzAKdlvQGmcTDpELOXLQEwgAumGgOn3uDMXFk1WhfLiohOdMYWbZR7SLAUBaQWpC/ojAIYndMN/iRaAGY99AAAfFYcfIDS20s2DkjwpBU0O6cincZec6ATJw3AA5FG60jKzF5sVYMCqnUSsyNrCK60OqQXksVJPaTSEdDYpUJSYIcMgGlu3wndBj4paQ/NgTmzwAQrGHUMaPUdaYtZUeaRNqkVmBNt42ArLlOUqrFNKgUwOwfmfoC0UQxxWYO0m7QaQLJXEG95N8kARKWxUfPoWQMUnL0GoIDOTY6DjChAoRLHgVmH7CcSMBsHe9vezUF620VRALg5jYHczNfWFZjPfE/y0NJx8LNBeVzEHHWqC8zjIWKDlAMDGgCxS9ByRSTyFFmlIwK62iFFFUwAmC7Bh3Yj8clI/rQ9Qf8Ah9pDgnDjgAIdh4DJb3AhDub8A6OWHqIKzPWrY93pAAfpCjTUl3XvjSvSzoHdDfBYHJgAc+azNg42IN1DcFcV6UsiTnJlvkUZbLQl+ACh1EkCieu+Tx4wwV5zugJEgUcAJPCAxElApT49FaG7/4DEBeskwLLg+iwowfVXkIPuiz2v67bGvEuwAhPckIMDZ8ExB/VrD7R+aoWrLyp4pMA7QYsrdleV13nv+3Qm0eykdnkf4gHDd3acVyVblwNMAh5p5lSsx0E8d23N9gIIBQHhV2RPoijpsT0DZ3VFMSg3Nxk5AwE8owNv12KdZX/SEidNckuyRAE8dlZ7/sGAXeZUurQ0yFeAOPBdArRbHNcqVSIAqgdSD2cAwEZzBnN7FFB0u3En4Gdmk4UorzQoSHZo6/dtJ8dahuBapTNmKMhBMxUANnB1bjEPyTZqe0EoyDeEpNZx6qSDPPgdTyd2TKKGbMgBHNRUOPACTqI3jcdBhYIeb9F5vCUobkENEKB6o+aBhDANAOckOeNaPiMKAWA0KZABb7UjQGVkV9d7IBUDJiBxb6WGJMCGNyiHJACHGhJ9mEaBzScAAPg5AAYB6WF5GfdKq/h1pzY1c0RsN8ABHbh+iraHdaYI7VIxiOcJRqMBKhACP/ADJ5ECF2YIiUYByRYDjaJQboVH/qVog6Tyd6ooQA2YU8+2in3ybkIHiKSFcbZoi5lCiOVGaWoHUjAgeBAQjB/IFTgAA8WYCBlSMfLXCRBwAiqgAjXwjB3xAwMgABWQAESSaB1FfFFCV6JIYOpkim74AeGoSX4Sbgv3IISCXTmVK4vyayGFNwIjflSiiwG2EZAHWbdFelaYjw9QVrfUCFiUYZAQJxlAkAVZAyHgDj9gARagAZzoJKTVAh6CJcq3jbvXjY2WMnKokU71XSApUcgXbj8lh+jofoC4dV4YKDBwMQTmedsgkvt4Q+CBj5RGhg2kAKUDcp/AFR+gATVgASFQlERJlCHwPPinhyAleDlHAp6Y/lNv1RcX6Y2cBzOquJg5dyUF6AIskAOExo7H52rZgmY4EANPiG2xsSF5522LwpYbYWQC5nph1Qk4mAISQJQSUJB7OQJq4SE6iH+00ZSGyY0Y2SqMWZUYKFFR4mOUKXZDpiovaHibR43TsGo/VZZQiFpO5X5XNwCk2YimiTEKgAF3WQM1MAIFqQJ7iQEeQgE8V3tRQgLoiAOHKVEkAICn2JuBNVngMWgwMBm7NxmKomMclXNsmI7W+QCqBw/OeWoIBYB4CH3V2Yi2MCitWQMGqQIr8J1EKQ4dGZ1TuQFoOCgfApUg9Z5R0piLKZKCd37edpNXqU6jBlkb4CcbMJyb/smJFmhmJwWAIOcdCiBxjGgIeWQLD/CgBikDJpACCAA/FlABtIGeTvUC/9ZTo6ZkG7ACb3hobpiKivkgsRaY3lai5tOImvQBpSeB5DiI9+hq0PelH1ANAuBjrvYAwUMID/BuZ2M132mQK7AgHrABJsACAJN8/VloOJUDOuinS0gCPOcChwIz6XkDpDIAaCl0LfCogNoC3dd9HuAdpAiAYOpoSwYBEseH2wOYrCZ0JglSopaMGsJsbwUJEKADMfEJAYACKoACGBCkOPEBSbQBeSR7KQpSLMABfboUBNhsJZARu3d0pEYc6QSm1wYD3dSlNaisLKB/qTZwpIqfBhB0/poHAaAKUpVaZANHAgBEWITjAzopCUZqIjhBc8i3FEy5AYb3AtfDARh6YneCqWcVA4QCddcWrYviARGorC+ArMfnASXwr3PmAd3yFl96r4tCVmdlfhKFji+wWuKXanIGA2uRMxRQXD0jCrfCewsUkx1ynruBcCywAQdDcSxwE4DYopCaAyuQfWCjhoDafTErs7/3IbAYUjDbs9x3AzdgciJlm0X3pJAaFmohraU4qZIKs9fHektpAt2nd4BIG9ynd3fzPwsZs7SXMx1QXBZDifdpMJ4hS+aRc3l0HpbkITmnFufHIX6SR5fEicdnMvY3iI43WqZXc0kYNYqSWi9w/oBOdyUUBzBq+xYHiJVNmLBNMp5p23RnK7f6p7WAeEk4WTHmBApL4xcogAJrkQCymgDnQXYJ+4d2V7pZl4QJy4n4x7bdZpqOV3As4FkeUru02y1mRWaA6Lqfo2NF1rpJeLhliDWHm6Wnu6WTlaVaqKOG4wNW6bEQoDZDcwIJsDYTkAHnd0tHiUNvcVKnO4VHmZ+re5RSNXane76kO4+l6TLKKyBlaEl92L3vC75lqL3/6ZZuh0UGYAOtKgoD4DitEwETcEoT4JeaYpof9j+W90Due4jdq8ADsGqOxr22aEnd4gKGap2JhrjK6cD42xb/Y2QaLGDXyQiF5bzlWgkK/sBI1gvApwQQlxAdoYNQM1BZJVBVS9YtwKVkzWAAJnAKoNs2rnMC1RQ7a6MdEJDClcBREQxsP5MtdDlnpoVMgXJS9YABGjABrIECBHAjqHI5eYZ/6cl2gUKdICWgVFwJL+gB8fM9FyA+CyJOpJBXELB1INVmJWACwLgC7/YCb4VetWY1U/k28rNMgJMrgFxiXpdzJrCr1+YCsHGau0BcyNUKeJTF3xMBJAMwefR+nrDIS0iVYAoDjmaiwVAlo0MxOkBkqoBQHTQBNLQZS/E5y/vJ+KRznCy1MYDBZcUC1IaLp8yxPPNaiFWXSKJYHzwKdIy2SBiI+Tm5weBaPLMD/jHAypbMHslXHjo2xQGyPbbXtrfLuImsCiS4Yj3TAkosCnHnJ/SiAckSlNasuUIFcc4cv+OsCh2QE840aVYzABhgkAf5jM9YAERxzyVmeVrKwcrQvwuqAELzndw5lBWgAQvwDuk8CQgswmlsCrIEqwaJlwXAlwuBcsYCTnvhRrDRPlxhAMDhEiPAjCowlEXJzRuFAQsAAhpwLw5AAGKzDH0kAAjAnd0Jm3hpAXuxKZBEFwTsuQZtUkZClEJdABIKRJ5sDgNwF/9UQK0RAWGZDAMgAQ76kyyAAD9ZlNIjIxUQAdhxACPwSwcQAQQgeE3dRgBtkCGgxxwAGGqCARiA/olzvQs7wh7Y4QALECQlIz0XjQuvWpAnUAB67AFCGtLOCI0hkAJ/rQsaegDVcQDWkrY0bUSy6h4Lwms9+ZMCDQ4L2ZCXXQtxwg6toRUdgkPOoIa7NkIG4NFlLQEaINNGyUfV88a2lNgicXxXkrRVQgJ2iZcvvZd5KUfKwKbIKtdTs5CHfYI0dSuetbrHXQJgXQOvCZ7K/SbGEBU3nQFO4wBHTQgdUDBVjVdSuIGLiQENOtREbQEZ0Cd8TQIM7QsPIGNVYU2uYUzT3d4OpNAQMd/cuQLf/YwuIdAnQeCtrAi89E/YsTbFxBbSQiY9GtYqAKRCCtMAjZAyIJ4VIOCu/hA0cERbdRQ3D4ICpiQB1vRLcC0On609c1oDddooG1ACZA3RQOnORDkCo1KJW0NQqw0Rah3jBABJ23Q6gzJAqlEC9ZNjRx4Miy2rtEpxd7oBCNCaeEnWzN0QzHgSz1jZ6BUjG2JK4kVe7hQ3fYEBA+wA5CG31m0s50pX6XowyQfZBcCd3vnRFvADPxnTPxAaqR0xw4UBB5QAD8JOPD0SFZDic7Ti7NBLDZBfwbRKfmZMiibAb6wc/UjFH0uYIet4yFcALsGdCzDVC/DPEB0Cus3b1VAB2IHVBsDmBMBBSY4XzfVcEYABu/5g2SRhDEBh1JAAB8Qg/LPRZAacJBQb/t+BAUT5oGpC1CPQHsl9GxrA3EBEQKgEUNs0XmruIxHGSpGEAYPJTjL2TjaGY5cjLQlgq2jE7I1Yuf0oMw6a744NGPETAtbyASkwAtz53UFu6XcBTDKm6ZaO6cIEUOa1hHvWZwEFaH+SIZ111vROCLJS0IZQARxeAFLuHilgAghEL9tJ3+DZ1qmUX8J+AQmv6djRZ8NO7Lz2ARRFY6eia7NXLK09UxkPwohgADVwIyOfQLa6ax/QoACt4AUJjQigQHntTxUFGPNkL0HKTuVVY/JkGOn6dCt1by+1hHKLkhn+844AAQmAfI3Ca+p6JRQA1t/p4UPamiIC9e50byaQ/vd5Xz8c4E/D9Gd5nxh1B3NFNXtIBeFmHygMSJi9lnXm8aAJbqd4WgIEUKsZ8CN+dgF2aj/uoUrZkWsYhcxaNXeC/1U2kJqJ/wiapHNJS8NOAqtYvkxavvac7E+fX/k1b6sKpFILAPZCwvprkVXq9FJ2lfoxjE/dQhTWeedhf3t+0mt9gh3Jzmt30reEL3N2Eog70TFRgszCbfyct4HR8bG6X3e7m08b8gEHkMcMQnsITUdcVfpXtyMYpkkqCP7uVWJji/4nlR4ZAk6A8OHBQUKh8ACQqDhAMejxYTDQoUjZ8TBwOEm5ydnp+QkaKjpKWmpqGjAAAaEwgEgZQDlg/iDwIRAZuxmgQGFrAPGgydkREHx6jJysvMz8OfMckPuZCvGbOfxQ/SsZKtz8DR4ufiwtmtpq7Hl5WD7u/g4fvxwd4D1c3C6vv8+/32HfL6DAgYqAGASyyWBBhYkONjyI0JPDhxEXJkQIMaJChp0mAthY8VRGiSE5cSQoKqTGiSA/YlRZ0mLLkx4dMpwZ86FLnctu5jxpMidKkzwr+tzZ0mLHl0hhGk2Kc6lMplBv7iy6MuvTrENDYWz4UWlUjkApVS0J0WXVplJ1jqX6EqZbt3DZdgX1taBStVr3juRrdy5clkyDTmUL0ibatBQLc716VyLFsDz3Qi5rOCndumYLXF88bHVl58+joZYWGhmsXrF1j356O5qyZrqqD9slHLgybdiYUy8ESjb4U6/CSYsG7jjocLKdRcc+zVitZd/U36Gujj17vOvau3v/Dj68+PHky5s/jz69+vXsOQUCADs=
  3070.  
  3071.     button .logo.logo \
  3072.     -command "angela:prefs:window:save .logo Logo" \
  3073.     -image angela_logo 
  3074.  
  3075.     pack .logo.logo
  3076.     update
  3077.  
  3078.     after 8000 { catch { angela:prefs:window:save .logo Logo } }
  3079. }
  3080.  
  3081. ################################################################
  3082. #
  3083. # Execute a Tcl command
  3084. #
  3085. ################################################################
  3086.  
  3087. proc angela:tcl:exec { path } {
  3088.  
  3089.     set command [$path get]
  3090.     debug "Executing $command"
  3091.     puts stderr [eval $command]
  3092.  
  3093. }
  3094.  
  3095. proc angela:tcl { } {
  3096.  
  3097.     catch { destroy .tcl }
  3098.     toplevel .tcl
  3099.     wm title .tcl "angela!:Tcl Command"
  3100.  
  3101.     frame .tcl.up -borderwidth 2 -relief ridge
  3102.     frame .tcl.down -borderwidth 2 -relief ridge
  3103.     pack .tcl.up .tcl.down -side top -fill both -expand yes
  3104.  
  3105.     button .tcl.down.exec -text "Execute..." \
  3106.     -command "angela:tcl:exec .tcl.up.entry"
  3107.  
  3108.     button .tcl.down.cancel -text "Cancel" \
  3109.     -command "destroy .tcl"
  3110.  
  3111.     label .tcl.up.label -text "Command:" -width 10
  3112.     entry .tcl.up.entry -background white -width 30
  3113.  
  3114.     bind .tcl.up.entry <Return> "angela:tcl:exec .tcl.up.entry"
  3115.     focus .tcl.up.entry
  3116.  
  3117.     pack .tcl.up.label .tcl.up.entry -side left -fill x \
  3118.     -expand yes
  3119.  
  3120.     pack .tcl.down.exec .tcl.down.cancel -side left -fill both \
  3121.     -expand yes
  3122. }
  3123.  
  3124. ################################################################
  3125. ################################################################
  3126. ################################################################
  3127. ##
  3128. ## Main part
  3129. ##
  3130. ################################################################
  3131. ################################################################
  3132. ################################################################
  3133.  
  3134. puts stderr "\n"
  3135. puts stderr "--"
  3136. puts -nonewline stderr "   angela! [angela:msg VERSION]"
  3137. foreach i [array names tcl_platform] {
  3138.     puts -nonewline stderr " $tcl_platform($i)"
  3139. }
  3140. puts stderr ""
  3141. puts stderr "   Copyright ⌐ 1997-98 by Oliver Pabst &"
  3142. puts stderr "                          Max Planck Institute for Computer Science."
  3143. puts stderr "   angela! comes with ABSOLUTELY NO WARRANTY; for details see the"
  3144. puts stderr "   provided LICENSE file."
  3145. puts stderr "--"
  3146. puts stderr "\n"
  3147.  
  3148. # The directory from which angela is called.
  3149. set angela_root [file dirname $argv0]
  3150.  
  3151. # Process command line
  3152.  
  3153. set lastused 0
  3154.  
  3155. for { set i 0 } { $i < $argc } { incr i } {
  3156.  
  3157.     switch -exact -- [lindex $argv $i] {
  3158.  
  3159.     --debug
  3160.     {
  3161.         set lastused [expr $i+1]
  3162.         set angela_debug 1
  3163.     }
  3164.  
  3165.     --help
  3166.     {
  3167.         puts stderr "Help:"
  3168.         puts stderr ""
  3169.         puts stderr "$argv0 \[options\] \[file\]"
  3170.         puts stderr ""
  3171.         puts stderr " where"
  3172.         puts stderr ""
  3173.         puts stderr "\[options\] is optional and in the following list:"
  3174.         puts stderr "  --debug            Activate debug mode."
  3175.         puts stderr "  --help             Shows this help message."
  3176.         puts stderr ""
  3177.         puts stderr "   -display display  Display (and screen) on which to display window."
  3178.         puts stderr ""
  3179.         puts stderr " and"
  3180.         puts stderr ""
  3181.         puts stderr "\[file\] is a optional file to load after startup."
  3182.         puts stderr ""
  3183.         puts stderr "Enjoy angela!"
  3184.         puts stderr ""
  3185.         exit
  3186.     }
  3187.     }
  3188. }
  3189.  
  3190. # Default filename
  3191. set angela_filename "Untitled"
  3192.  
  3193. angela:conf:setup
  3194. angela:ws:init
  3195. angela:mod:init
  3196. angela:logo
  3197. angela:capabilities:scan node object node
  3198. angela:capabilities:scan edge object edge
  3199. angela:capabilities:scan shape object shape
  3200. angela:capabilities:scan text object text
  3201. angela:capabilities:scan line object line
  3202. #angela:realtime:start
  3203.  
  3204. debug "Initialization done."
  3205.  
  3206. # Check if there are some unused arguments, and try to load them
  3207.  
  3208. if { $lastused < $argc && $argc > 0 } {
  3209.     angela:load [lindex $argv [expr $argc-1]]
  3210. }
  3211.