doted.tcl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. #!/bin/sh
  2. # next line is a comment in tcl \
  3. exec wish "$0" ${1+"$@"}
  4. package require Tcldot
  5. # doted - dot/gv graph editor - John Ellson ([email protected])
  6. #
  7. # Usage: doted <file.gv>
  8. #
  9. # doted displays the graph described in the input file and allows
  10. # the user to add/delete nodes/edges, to modify their attributes,
  11. # and to save the result.
  12. global saveFill tk_library modified fileName printCommand g
  13. # as the mouse moves over an object change its shading
  14. proc mouse_anyenter {c} {
  15. global tk_library saveFill
  16. set item [string range [lindex [$c gettags current] 0] 1 end]
  17. set saveFill [list $item [lindex [$c itemconfigure 1$item -fill] 4]]
  18. $c itemconfigure 1$item -fill black \
  19. -stipple @$tk_library/demos/images/gray25.xbm
  20. }
  21. # as the mouse moves out of an object restore its shading
  22. proc mouse_anyleave {c} {
  23. global saveFill
  24. $c itemconfigure 1[lindex $saveFill 0] \
  25. -fill [lindex $saveFill 1] -stipple {}
  26. }
  27. # if b1 is pressed over the background then start a node,
  28. # if b1 is pressed over a node then start an edge
  29. proc mouse_b1_press {c x y} {
  30. global startObj graphtype
  31. set x [$c canvasx $x]
  32. set y [$c canvasy $y]
  33. foreach item [$c find overlapping $x $y $x $y] {
  34. foreach tag [$c gettags $item] {
  35. if {[string first "node" $tag] == 1} {
  36. set item [string range $tag 1 end]
  37. if {[string equal $graphtype digraph]} {
  38. set startObj [$c create line $x $y $x $y \
  39. -tag $item -fill red -arrow last]
  40. } {
  41. set startObj [$c create line $x $y $x $y \
  42. -tag $item -fill red]
  43. }
  44. return
  45. }
  46. }
  47. }
  48. set startObj [$c create oval [expr $x - 10] [expr $y - 10] \
  49. [expr $x + 10] [expr $y + 10] -fill red -outline black]
  50. }
  51. # if node started by b1_press then move it,
  52. # else extend edge
  53. proc mouse_b1_motion {c x y} {
  54. global startObj
  55. set pos [$c coords $startObj]
  56. if {[$c type $startObj] == "line"} {
  57. $c coords $startObj [lindex $pos 0] [lindex $pos 1] \
  58. [$c canvasx $x] [$c canvasy $y]
  59. } {
  60. $c move $startObj [expr [$c canvasx $x] - [lindex $pos 0] - 10] \
  61. [expr [$c canvasy $y] - [lindex $pos 1] - 10]
  62. }
  63. }
  64. # complete node or edge construction.
  65. proc mouse_b1_release {c x y} {
  66. global startObj modified g
  67. set x [$c canvasx $x]
  68. set y [$c canvasy $y]
  69. set t [$c type $startObj]
  70. if {$t == "line"} {
  71. set tail [lindex [$c gettags $startObj] 0]
  72. foreach item [$c find overlapping $x $y $x $y] {
  73. foreach tag [$c gettags $item] {
  74. set head [string range $tag 1 end]
  75. if {[string first "node" $head] == 0} {
  76. set e [$tail addedge $head]
  77. $c dtag $startObj $tail
  78. $c addtag 1$e withtag $startObj
  79. $c itemconfigure $startObj -fill black
  80. set modified 1
  81. set startObj {}
  82. return
  83. }
  84. }
  85. }
  86. # if we get here then edge isn't terminating on a node
  87. $c delete $startObj
  88. } {
  89. set n [$g addnode]
  90. $c addtag 1$n withtag $startObj
  91. $c itemconfigure $startObj -fill white
  92. set modified 1
  93. }
  94. set startObj {}
  95. }
  96. proc loadFileByName {c name} {
  97. global modified
  98. if {$modified} {
  99. confirm "Current graph has been modified. Shall I overwrite it?" \
  100. "loadFileByNameDontAsk $c $name"
  101. } {
  102. loadFileByNameDontAsk $c $name
  103. }
  104. }
  105. proc loadFileByNameDontAsk {c name} {
  106. global fileName g
  107. $g delete
  108. $c delete all
  109. set modified 0
  110. if {[string first / $name] == 0} {
  111. set fileName $name
  112. } {
  113. if {[pwd] == "/"} {
  114. set fileName /$name
  115. } {
  116. set fileName [pwd]/$name
  117. }
  118. }
  119. if {[catch {open $fileName r} f]} {
  120. warning "Unable to open file: $fileName"
  121. }
  122. if {[catch {dotread $f} g]} {
  123. warning "Invalid .gv file: $fileName"
  124. close $f
  125. }
  126. close $f
  127. $g layout
  128. eval [$g render]
  129. $c configure -scrollregion [$c bbox all]
  130. }
  131. proc resize_canvas {c w h} {
  132. $c configure -scrollregion [$c bbox all]
  133. }
  134. proc update_entry {w x y} {
  135. $w.entry delete 0 end
  136. $w.entry insert end [$w.l.list get @$x,$y]
  137. }
  138. # doesn't work well with window managers that position initial window
  139. # on the left because then all popups get obscured
  140. #
  141. #proc positionWindow {w} {
  142. # set pos [split [wm geometry .] +]
  143. # set x [expr [lindex $pos 1] - 350]
  144. # set y [expr [lindex $pos 2] + 20]
  145. # wm geometry $w +$x+$y
  146. #}
  147. proc loadFile {c} {
  148. global fileName
  149. set types {
  150. {{GV Graph Files} {.gv}}
  151. {{DOT Graph Files} {.dot}}
  152. {{All Files} *}
  153. }
  154. set fn [tk_getOpenFile \
  155. -defaultextension .gv \
  156. -filetypes $types \
  157. -initialfile $fileName]
  158. if {[string length $fn]} {
  159. loadFileByName $c $fn
  160. }
  161. }
  162. proc saveFile {type} {
  163. global fileName
  164. if {$fileName == {}} {
  165. saveFileAs $type
  166. } {
  167. saveFileByName $fileName $type
  168. }
  169. }
  170. proc saveFileByName {name type} {
  171. global fileName
  172. if {$name != $fileName && [file exists $name]} {
  173. confirm "File exists. Shall I overwrite it?" \
  174. "saveFileByNameDontAsk $name $type"
  175. } {
  176. saveFileByNameDontAsk $name $type
  177. }
  178. }
  179. proc saveFileByNameDontAsk {name type} {
  180. global modified fileName g
  181. if {[catch {open $name w} f]} {
  182. warning "Unable to open file for write:\n$name; return"
  183. }
  184. if {$type == "gv"} {
  185. set type canon
  186. set fileName $name
  187. set modified 0
  188. }
  189. $g write $f $type
  190. close $f
  191. message "Graph written to:\n$name"
  192. }
  193. proc saveFileAs {type} {
  194. global fileName
  195. set cmap {{{CMAP Image Map Files} {.cmap}} {{All Files} *}}
  196. set dot {{{DOT Graph Files} {.dot}} {{All Files} *}}
  197. set fig {{{FIG Image Files} {.fig}} {{All Files} *}}
  198. set gif {{{GIF Image Files} {.gif}} {{All Files} *}}
  199. set gv {{{GV Graph Files} {.gv}} {{All Files} *}}
  200. set jpg {{{JPG Image Files} {.jpg}} {{All Files} *}}
  201. set mif {{{MIF Image Files} {.mif}} {{All Files} *}}
  202. set pcl {{{PCL Image Files} {.pcl}} {{All Files} *}}
  203. set pdf {{{PDF Image Files} {.pdf}} {{All Files} *}}
  204. set png {{{PNG Image Files} {.png}} {{All Files} *}}
  205. set ps {{{PostScript Files} {.ps}} {{All Files} *}}
  206. set svg {{{SVG Image Files} {.svg}} {{All Files} *}}
  207. set tiff {{{TIFF Image Files} {.tiff}} {{All Files} *}}
  208. set vml {{{VML Image Files} {.vml}} {{All Files} *}}
  209. set vtx {{{VTX Image Files} {.vtx}} {{All Files} *}}
  210. set fn [tk_getSaveFile \
  211. -defaultextension .$type \
  212. -filetypes [set $type] \
  213. -initialdir [file dirname $fileName] \
  214. -initialfile [file tail [file rootname $fileName]].$type]
  215. if {[string length $fn]} {
  216. saveFileByNameDontAsk $fn $type
  217. }
  218. }
  219. proc print {} {
  220. global g printCommand
  221. if {[catch {open "| $printCommand &" w} f]} {
  222. warning "Unable to open pipe to printer command:\n$printCommand; return"
  223. }
  224. $g write $f ps
  225. close $f
  226. message "Graph printed to:\n$printCommand"
  227. }
  228. proc setPrinterCommand {w} {
  229. global printCommand
  230. set printCommand [$w.printCommand get]
  231. message "Printer command changed to:\n$printCommand"
  232. destroy $w
  233. }
  234. proc printSetup {} {
  235. global printCommand
  236. set w .printer
  237. catch {destroy $w}
  238. toplevel $w
  239. # positionWindow $w
  240. wm title $w "Printer"
  241. wm iconname $w "Printer"
  242. label $w.message -text "Printer command:"
  243. frame $w.spacer -height 3m -width 20
  244. entry $w.printCommand
  245. $w.printCommand insert end $printCommand
  246. bind $w.printCommand <Return> "setPrinterCommand $w"
  247. frame $w.buttons
  248. button $w.buttons.confirm -text OK -command "setPrinterCommand $w"
  249. button $w.buttons.cancel -text Cancel -command "destroy $w"
  250. pack $w.buttons.confirm $w.buttons.cancel -side left -expand 1
  251. pack $w.message $w.spacer $w.printCommand -side top -anchor w
  252. pack $w.buttons -side bottom -expand y -fill x -pady 2m
  253. }
  254. proc confirm {msg cmd} {
  255. set w .confirm
  256. catch {destroy $w}
  257. toplevel $w
  258. # positionWindow $w
  259. wm title $w "Confirm"
  260. wm iconname $w "Confirm"
  261. label $w.message -text "\n$msg\n"
  262. frame $w.spacer -height 3m -width 20
  263. frame $w.buttons
  264. button $w.buttons.confirm -text OK -command "$cmd; destroy $w"
  265. button $w.buttons.cancel -text Cancel -command "destroy $w"
  266. pack $w.buttons.confirm $w.buttons.cancel -side left -expand 1
  267. pack $w.message $w.spacer -side top -anchor w
  268. pack $w.buttons -side bottom -expand y -fill x -pady 2m
  269. }
  270. proc message {m} {
  271. set w .message
  272. catch {destroy $w}
  273. toplevel $w
  274. # positionWindow $w
  275. wm title $w "Message"
  276. wm iconname $w "Message"
  277. label $w.message -text "\n$m\n"
  278. pack $w.message -side top -anchor w
  279. update
  280. after 2000 "destroy $w"
  281. }
  282. proc warning {m} {
  283. set w .warning
  284. catch {destroy $w}
  285. toplevel $w
  286. # positionWindow $w
  287. wm title $w "Warning"
  288. wm iconname $w "Warning"
  289. label $w.message -text "\nWarning:\n\n$m"
  290. pack $w.message -side top -anchor w
  291. update
  292. after 2000 "destroy $w"
  293. }
  294. proc setoneattribute {w d a s} {
  295. set aa [$w.e$a.a get]
  296. if {$aa == {}} {
  297. error "no attribute name set"
  298. } {
  299. set v [$w.e$a.v get]
  300. eval $s $aa $v
  301. }
  302. if {$a == {}} {
  303. destroy $w.e
  304. addEntryPair $w $d $aa $v $s
  305. addEntryPair $w d {} {} $s
  306. }
  307. }
  308. proc addEntryPair {w d a v s} {
  309. pack [frame $w.e$a] -side top
  310. pack [entry $w.e$a.a] [entry $w.e$a.v] -side left
  311. if {$a != {}} {
  312. $w.e$a.a insert end $a
  313. $w.e$a.a configure -state disabled -relief flat
  314. $w.e$a.v insert end $v
  315. if {$d != "d"} {
  316. $w.e$a.v configure -state disabled -relief flat
  317. }
  318. }
  319. bind $w.e$a.a <Return> "focus $w.e$a.v"
  320. bind $w.e$a.v <Return> [list setoneattribute $w $d $a $s]
  321. pack $w.e$a -side top
  322. focus $w.e$a.a
  323. }
  324. proc deleteobj {c o} {
  325. if {[string first "node" $o] == 0} {
  326. foreach e [$o listedges] {
  327. $c delete 1$e
  328. $c delete 0$e
  329. $e delete
  330. }
  331. }
  332. $c delete 1$o
  333. $c delete 0$o
  334. $o delete
  335. }
  336. # open a requestor for object $o,
  337. # deletable if $d is not null,
  338. # command to list attribute in $l
  339. # command to query attributes in $q
  340. # command to set attributes in $s
  341. proc setAttributesWidget {c o d l q s} {
  342. set w .attributes
  343. catch {destroy $w}
  344. toplevel $w
  345. # positionWindow $w
  346. wm title $w "[$o showname] Attributes"
  347. wm iconname $w "Attributes"
  348. foreach a [eval $l] {
  349. if {[catch {eval $q $a} v]} {set v {}}
  350. addEntryPair $w $d $a $v $s
  351. }
  352. addEntryPair $w d {} {} $s
  353. frame $w.spacer -height 3m -width 20
  354. frame $w.buttons
  355. if {$d == "d"} {
  356. button $w.buttons.delete -text Delete -command "deleteobj $c $o; destroy $w"
  357. pack $w.buttons.delete -side left -expand 1
  358. }
  359. button $w.buttons.dismiss -text OK -command "destroy $w"
  360. pack $w.buttons.dismiss -side left -expand 1
  361. pack $w.buttons -side bottom -expand y -fill x -pady 2m
  362. }
  363. # open a requestor according to the type of graph object $obj, to allow the user to read and set attributions
  364. proc setAttributes {c obj} {
  365. global g
  366. if {$obj == {}} {
  367. set obj [string range [lindex [$c gettags current] 0] 1 end]
  368. }
  369. set type [string range $obj 0 3]
  370. if {$type == "node" || $type == "edge"} {
  371. if {[string length $obj] > 4} {
  372. setAttributesWidget $c $obj d \
  373. "$obj listattributes" \
  374. "$obj queryattributes" \
  375. "$obj setattributes"
  376. } {
  377. setAttributesWidget $c $obj {} \
  378. "$g list[set type]attributes" \
  379. "$g query[set type]attributes" \
  380. "$g set[set type]attributes"
  381. }
  382. } {
  383. setAttributesWidget $c $g {} \
  384. "$g listattributes" \
  385. "$g queryattributes" \
  386. "$g setattributes"
  387. }
  388. }
  389. # unconditionally remove any old graph and canvas contents, the create a new graph of $type
  390. proc newGraphDontAsk {c type} {
  391. global modified g graphtype
  392. set graphtype $type
  393. $c delete all
  394. set modified 0
  395. if {[info exists g]} {$g delete}
  396. set g [dotnew $type]
  397. }
  398. # upon confirmation, remove any old graph and canvas contents, the create a new graph of $type
  399. proc newGraph {c type} {
  400. global modified
  401. if {$modified} {
  402. confirm "Current graph has been modified. Shall I continue?" \
  403. "newGraphDontAsk $c $type"
  404. } {
  405. newGraphDontAsk $c $type
  406. }
  407. }
  408. # generate a new graph layout and update rendering on the canvas
  409. # this proc is attached to the green button to the lower right of the window
  410. proc layout {c} {
  411. global g
  412. $c delete all
  413. $g layout
  414. eval [$g render]
  415. $c configure -scrollregion [$c bbox all]
  416. }
  417. # generate a help window with $msg as the contents
  418. proc help {msg} {
  419. set w .help
  420. catch {destroy $w}
  421. toplevel $w
  422. # positionWindow $w
  423. wm title $w "DotEd Help"
  424. wm iconname $w "DotEd"
  425. frame $w.menu -relief raised -bd 2
  426. pack $w.menu -side top -fill x
  427. label $w.msg \
  428. -font -Adobe-helvetica-medium-r-normal--*-140-*-*-*-*-*-* \
  429. -wraplength 4i -justify left -text $msg
  430. pack $w.msg -side top
  431. frame $w.buttons
  432. pack $w.buttons -side bottom -expand y -fill x -pady 2m
  433. button $w.buttons.dismiss -text Dismiss -command "destroy $w"
  434. pack $w.buttons.dismiss -side left -expand 1
  435. }
  436. # proc that supports zoom in/out events
  437. proc zoom {c fact} {
  438. upvar #0 $c data
  439. set x [$c canvasx [expr {[winfo pointerx $c] - [winfo rootx $c]}]]
  440. set y [$c canvasy [expr {[winfo pointery $c] - [winfo rooty $c]}]]
  441. $c scale all $x $y $fact $fact
  442. set data(zdepth) [expr {$data(zdepth) * $fact}]
  443. after cancel $data(idle)
  444. set data(idle) [after idle "zoomupdate $c"]
  445. }
  446. # update all text strings after zoom operation is complete
  447. proc zoomupdate {c} {
  448. upvar #0 $c data
  449. # adjust fonts
  450. foreach {i} [$c find all] {
  451. if { ! [string equal [$c type $i] text]} {continue}
  452. set fontsize 0
  453. # get original fontsize and text from tags
  454. # if they were previously recorded
  455. foreach {tag} [$c gettags $i] {
  456. scan $tag {_f%d} fontsize
  457. scan $tag "_t%\[^\0\]" text
  458. }
  459. # if not, then record current fontsize and text
  460. # and use them
  461. set font [$c itemcget $i -font]
  462. if {!$fontsize} {
  463. set text [$c itemcget $i -text]
  464. if {[llength $font] < 2} {
  465. #new font API
  466. set fontsize [font actual $font -size]
  467. } {
  468. #old font API
  469. set fontsize [lindex $font 1]
  470. }
  471. $c addtag _f$fontsize withtag $i
  472. $c addtag _t$text withtag $i
  473. }
  474. # scale font
  475. set newsize [expr {int($fontsize * $data(zdepth))}]
  476. if {abs($newsize) >= 4} {
  477. if {[llength $font] < 2} {
  478. #new font api
  479. font configure $font -size $newsize
  480. } {
  481. #old font api
  482. lreplace $font 1 1 $newsize
  483. }
  484. $c itemconfigure $i -font $font -text $text
  485. } {
  486. # suppress text if too small
  487. $c itemconfigure $i -text {}
  488. }
  489. }
  490. set bbox [$c bbox all]
  491. if {[llength $bbox]} {
  492. $c configure -scrollregion $bbox
  493. } {
  494. $c configure -scrollregion [list -4 -4 \
  495. [expr {[winfo width $c]-4}] \
  496. [expr {[winfo height $c]-4}]]
  497. }
  498. }
  499. #--------------------------------------------------------------------------
  500. set help_about "DotEd - Dot Graph Editor
  501. Copyright (C) 1995 AT&T Bell Labs
  502. (C) 1996 Lucent Technologies
  503. Written by: John Ellson ([email protected])
  504. and: Stephen North ([email protected])
  505. DotEd provides for the graphical editing of
  506. directed graphs. Once a graph has been manually
  507. entered then the dot layout algorithm can be applied
  508. by clicking on the button in the lower right corner
  509. of the window."
  510. set help_mouse "Button-1: When the cursor is over the
  511. background Button-1-Press will start a node,
  512. Button-1-Motion (dragging the mouse with
  513. Button-1 still down) will move it and
  514. Button-1-Release will complete the node
  515. insertion into the graph.
  516. When the cursor is over an existing node
  517. then Button-1-Press will start an edge from
  518. that node. Button-1-Motion will extend the
  519. edge and Button-1-Release over a different
  520. node will complete the edge.
  521. Button-2: Button-2-Motion (click and drag) will
  522. reposition the canvas under the window.
  523. Button-3: When Button-3 is clicked over a
  524. node or edge the attribute editor will
  525. be opened on that object.
  526. Scrollwheel: Zooms canvas in/out.
  527. Once a graph has been manually entered then
  528. the dot layout algorithm can be applied by
  529. clicking on the button in the lower right
  530. corner of the window."
  531. #--------------------------------------------------------------------------
  532. #initialize some globals
  533. set startObj {}
  534. set saveFill {}
  535. set modified 0
  536. set fileName {no_name}
  537. set printCommand {lpr}
  538. set zfact 1.1
  539. # create main window
  540. wm title . "DotEd"
  541. wm iconname . "DotEd"
  542. wm minsize . 120 100
  543. wm geometry . 400x300
  544. frame .m -relief raised -borderwidth 1
  545. frame .a
  546. frame .b
  547. set c [canvas .a.c \
  548. -cursor crosshair \
  549. -xscrollcommand ".b.h set" \
  550. -yscrollcommand ".a.v set" \
  551. -width 0 \
  552. -height 0 \
  553. -borderwidth 0]
  554. scrollbar .b.h \
  555. -orient horiz \
  556. -relief sunken \
  557. -command "$c xview"
  558. scrollbar .a.v \
  559. -relief sunken \
  560. -command "$c yview"
  561. button .b.layout \
  562. -width [.a.v cget -width] \
  563. -height [.b.h cget -width] \
  564. -foreground green \
  565. -activeforeground green\
  566. -bitmap @$tk_library/demos/images/gray25.xbm \
  567. -command "layout $c"
  568. # initialize zoom state
  569. set [set c](zdepth) 1.0
  570. set [set c](idle) {}
  571. # create graph structure and set global "g"
  572. newGraphDontAsk $c digraph
  573. # canvas bindings
  574. bind $c <Configure> "resize_canvas $c %w %h"
  575. bind $c <ButtonPress-1> "mouse_b1_press $c %x %y"
  576. bind $c <B1-Motion> "mouse_b1_motion $c %x %y"
  577. bind $c <ButtonRelease-1> "mouse_b1_release $c %x %y"
  578. bind $c <Button-2> "$c scan mark %x %y"
  579. bind $c <B2-Motion> "$c scan dragto %x %y 1"
  580. bind $c <Button-3> "setAttributes $c {}"
  581. bind $c <Button-4> "zoom $c $zfact"
  582. bind $c <Button-5> "zoom $c [expr {1.0/$zfact}]"
  583. # canvas item bindings
  584. $c bind all <Any-Enter> "mouse_anyenter $c"
  585. $c bind all <Any-Leave> "mouse_anyleave $c"
  586. menubutton .m.file -text "File" -underline 0 -menu .m.file.m
  587. menu .m.file.m
  588. .m.file.m add command -label "Load ..." -underline 0 \
  589. -command "loadFile $c"
  590. .m.file.m add command -label "New - directed" -underline 0 \
  591. -command "newGraph $c digraph"
  592. .m.file.m add command -label "New - undirected" -underline 6 \
  593. -command "newGraph $c graph"
  594. .m.file.m add command -label "Save" -underline 0 \
  595. -command "saveFile gv"
  596. .m.file.m add command -label "Save As ..." -underline 5 \
  597. -command "saveFileAs gv"
  598. .m.file.m add separator
  599. .m.file.m add cascade -label "Export" -underline 1 \
  600. -menu .m.file.m.export
  601. menu .m.file.m.export
  602. .m.file.m.export add command -label "CMAP ..." -underline 0 \
  603. -command "saveFileAs cmap"
  604. .m.file.m.export add command -label "FIG ..." -underline 0 \
  605. -command "saveFileAs fig"
  606. .m.file.m.export add command -label "GIF ..." -underline 0 \
  607. -command "saveFileAs gif"
  608. .m.file.m.export add command -label "MIF ..." -underline 0 \
  609. -command "saveFileAs mif"
  610. .m.file.m.export add command -label "PDF ..." -underline 0 \
  611. -command "saveFileAs pdf"
  612. .m.file.m.export add command -label "PNG ..." -underline 0 \
  613. -command "saveFileAs png"
  614. .m.file.m.export add command -label "PS ..." -underline 0 \
  615. -command "saveFileAs ps"
  616. .m.file.m.export add command -label "SVG ..." -underline 0 \
  617. -command "saveFileAs svg"
  618. .m.file.m.export add command -label "TIFF ..." -underline 0 \
  619. -command "saveFileAs tiff"
  620. .m.file.m.export add command -label "VML ..." -underline 0 \
  621. -command "saveFileAs vml"
  622. .m.file.m.export add command -label "VTX ..." -underline 0 \
  623. -command "saveFileAs vtx"
  624. .m.file.m add separator
  625. .m.file.m add command -label "Print Setup ..." -underline 0 \
  626. -command "printSetup"
  627. .m.file.m add command -label "Print" -underline 0 \
  628. -command "print"
  629. .m.file.m add separator
  630. .m.file.m add command -label "Exit" -underline 0 -command "exit"
  631. menubutton .m.graph -text "Graph" -underline 0 -menu .m.graph.m
  632. menu .m.graph.m
  633. .m.graph.m add command -label "Graph Attributes" -underline 0 \
  634. -command "setAttributes $c graph"
  635. .m.graph.m add command -label "Node Attributes" -underline 0 \
  636. -command "setAttributes $c node"
  637. .m.graph.m add command -label "Edge Attributes" -underline 0 \
  638. -command "setAttributes $c edge"
  639. menubutton .m.help -text "Help" -underline 0 -menu .m.help.m
  640. menu .m.help.m
  641. .m.help.m add command -label "About DotEd" -underline 0 \
  642. -command {help $help_about}
  643. .m.help.m add command -label "Mouse Operations" -underline 0 \
  644. -command {help $help_mouse}
  645. pack append .m .m.file {left} .m.graph {left} .m.help {right}
  646. pack append .a $c {left expand fill} .a.v {right filly}
  647. pack append .b .b.h {left expand fillx} .b.layout {right}
  648. pack append . .m {top fillx} .a {expand fill} .b {bottom fillx}
  649. tk_menuBar .m.file .m.graph .m.help
  650. if {$argc} {loadFileByNameDontAsk $c [lindex $argv 0]}