runandoutput.tcl 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. ############################################################################
  2. #
  3. # LIBRARY: runandoutput.tcl
  4. # AUTHOR(S): Cedric Shock (cedricgrass AT shockfamily.net)
  5. # PURPOSE: Interactive console for gis.m and other run commands
  6. # COPYRIGHT: (C) 2006 GRASS Development Team
  7. #
  8. # This program is free software under the GNU General Public
  9. # License (>=v2). Read the file COPYING that comes with GRASS
  10. # for details.
  11. #
  12. ############################################################################
  13. #############################################
  14. #Overloaded gui.tcl behaviour:
  15. # Overload run_cmd (proc called when run button is pushed)
  16. proc run_cmd {dlg} {
  17. global gronsole
  18. global opt
  19. set cmd [dialog_get_command $dlg]
  20. catch {$opt($dlg,run_button) configure -state disabled}
  21. $gronsole run $cmd {} "catch {$opt($dlg,run_button) configure -state active}"
  22. # Bring that output window up:
  23. raise [winfo toplevel $gronsole]
  24. }
  25. # no output or progress or buttons:
  26. proc make_output {dlg path root} {}
  27. proc make_progress {dlg path root} {}
  28. proc make_buttons {dlg path root} {}
  29. ###########################################
  30. proc make_fun_buttons {dlg path} {
  31. global opt env
  32. set pgm_name $opt($dlg,pgm_name)
  33. set buttonframe [frame $path.buttonframe]
  34. button $buttonframe.run -text [G_msg "Run"] -command "run_cmd $dlg"
  35. # In the future we'll have a button to make a layer from here:
  36. # button $buttonframe.layer -text [G_msg "Layer"] -command "layer_cmd $dlg"
  37. button $buttonframe.help -text [G_msg "Help"] -command "help_cmd $dlg"
  38. button $buttonframe.close -text [G_msg "Close"] -command "close_cmd $dlg"
  39. set opt($dlg,run_button) $buttonframe.run
  40. # Turn off help button if the help file doesn't exist
  41. if {! [file exists $env(GISBASE)/docs/html/$pgm_name.html]} {
  42. $buttonframe.help configure -state disabled
  43. }
  44. pack $buttonframe.run $buttonframe.help $buttonframe.close \
  45. -side left -expand yes -padx 5 -pady 5
  46. pack $buttonframe -expand no -fill x -side bottom -before [lindex [pack slaves $path] 0]
  47. # Set the starting window size if this is a toplevel window
  48. if {[winfo toplevel $path] == $path} {
  49. wm geometry $path "560x400"
  50. }
  51. }
  52. proc run_ui {cmd} {
  53. global dlg
  54. global path
  55. global devnull
  56. set program [lindex $cmd 0]
  57. set code ""
  58. if {[catch {set code [exec -- $program --tcltk 2> $devnull]} error]} {
  59. GmLib::errmsg $error
  60. }
  61. set path .dialog$dlg
  62. toplevel $path
  63. if {$code == ""} { return }
  64. eval $code
  65. # Push the command to the dialog
  66. set thisdialog $dlg
  67. dialog_set_command $dlg $cmd
  68. # Add our ui
  69. make_fun_buttons $dlg $path
  70. }
  71. #################################################
  72. proc run_disabled {gronsole button cmd} {
  73. if {[catch {$button configure -state disabled} error]} {
  74. GmLib::errmsg $error
  75. }
  76. $gronsole run $cmd {running} "catch {$button configure -state active}"
  77. }
  78. proc gronsole_history {cmdtext ci cmd} {
  79. $cmdtext delete 1.0 end
  80. $cmdtext insert end $cmd
  81. }
  82. proc command_window {where} {
  83. global keycontrol
  84. global bgcolor
  85. set cmdpane [frame $where.command -bg $bgcolor]
  86. set cmdwin [ScrolledWindow $where.win -relief flat -borderwidth 1]
  87. set gronsole [Gronsole $where.gronsole -clickcmd "gronsole_history $cmdwin.text"]
  88. set cmdtext [text $cmdwin.text -height 2 -width 80]
  89. $cmdwin setwidget $cmdtext
  90. set runbutton [button $cmdpane.run -text [G_msg "Run"] -width 14 -wraplength 90 -default active -bd 1 \
  91. -command "run_disabled $gronsole $cmdpane.run \[string trim \[$cmdtext get 1.0 end\]\]"]
  92. set run2button [button $cmdpane.run2 -text [G_msg "Run (background)"] -width 14 -wraplength 90 -bd 1 \
  93. -command "$gronsole run \[string trim \[$cmdtext get 1.0 end\]\] {} {}"]
  94. set runuibutton [button $cmdpane.runui -text [G_msg "Run (GUI)"] -width 14 -wraplength 90 -bd 1 \
  95. -command "run_ui \[string trim \[$cmdtext get 1.0 end\]\]"]
  96. set runxterm [button $cmdpane.xterm -text [G_msg "Run (in Xterm)"] -width 14 -wraplength 90 -bd 1 \
  97. -command "$gronsole run_xterm \[string trim \[$cmdtext get 1.0 end\]\] {}"]
  98. set outpane [frame $where.output -bg $bgcolor]
  99. set savebutton [button $outpane.save -text [G_msg "Save"] -command "$gronsole save" \
  100. -bd 1 -padx 10]
  101. set clearbutton [button $outpane.clear -text [G_msg "Clear"] -command "$gronsole clear" \
  102. -bd 1 -padx 10]
  103. pack $runbutton $run2button $runuibutton $runxterm \
  104. -side left -expand yes -padx 5 -pady 5
  105. pack $savebutton $clearbutton \
  106. -side left -expand yes -padx 5 -pady 5
  107. pack $cmdpane -fill x -side bottom
  108. pack $cmdwin -fill x -side bottom
  109. pack $outpane -fill x -side bottom
  110. pack $gronsole -side top -fill both -expand yes
  111. bind $cmdtext <$keycontrol-c> "tk_textCopy %W"
  112. bind $cmdtext <$keycontrol-v> "tk_textPaste %W"
  113. bind $cmdtext <$keycontrol-x> "tk_textCut %W"
  114. return $gronsole
  115. }
  116. toplevel .gronsole
  117. wm title .gronsole [G_msg "Output - GIS.m"]
  118. # If we had our own window manager we could withdraw windows instead of iconifying them:
  119. wm protocol .gronsole WM_DELETE_WINDOW "wm iconify .gronsole"
  120. set gronsole [command_window {.gronsole}]
  121. ###############################################################################
  122. # Run procs for gis.m:
  123. ################################################################################
  124. proc execute {cmd} {
  125. # Use run and output
  126. run_ui $cmd
  127. }
  128. ###############################################################################
  129. proc spawn {cmd args} {
  130. if {[catch {eval [list exec -- $cmd] $args &} error]} {
  131. GmLib::errmsg $error
  132. }
  133. }
  134. ###############################################################################
  135. proc spawn_panel {cmd args} {
  136. global gronsole
  137. $gronsole run $cmd gism {}
  138. }
  139. ###############################################################################
  140. proc run_panel {cmd} {
  141. global gronsole
  142. $gronsole run_wait $cmd gism
  143. }
  144. ###############################################################################
  145. proc run {cmd args} {
  146. global devnull
  147. # This and runcmd are being used to run command in the background
  148. # These used to go to stdout and stderr
  149. # but we don't want to pollute that console.
  150. # eval exec -- $cmd $args >@ stdout 2>@ stderr
  151. if {[catch {eval [list exec -- $cmd] $args >& $devnull} error]} {
  152. GmLib::errmsg $error
  153. }
  154. }
  155. ###############################################################################
  156. proc runcmd {cmd args} {
  157. global gronsole
  158. set ci [$gronsole annotate $cmd [list gism running]]
  159. eval run $cmd $args
  160. $gronsole remove_tag $ci running
  161. }
  162. ###############################################################################
  163. proc term_panel {cmd} {
  164. global gronsole
  165. $gronsole run_xterm $cmd gism
  166. }
  167. ###############################################################################
  168. proc term {cmd args} {
  169. global env
  170. global mingw
  171. if { $mingw == "1" } {
  172. if {[catch {eval [list exec -- cmd.exe /c start $env(GISBASE)/etc/grass-run.bat $cmd] $args &} error]} {
  173. GmLib::errmsg $error
  174. }
  175. } else {
  176. if {[catch {eval [list exec -- $env(GISBASE)/etc/grass-xterm-wrapper -name xterm-grass -e $env(GISBASE)/etc/grass-run.sh $cmd] $args &} error]} {
  177. GmLib::errmsg $error
  178. }
  179. }
  180. }
  181. ###############################################################################
  182. # Make sure there's an xmon before running some commands.
  183. # Used in menus.
  184. proc guarantee_xmon {} {
  185. if {![catch {open "|d.mon -L" r} input]} {
  186. while {[gets $input line] >= 0 } {
  187. if {[regexp -nocase {(x[0-9]+).*not running} $line dummy monitor]} {
  188. # $monnum is the monitor number
  189. #create list of non-running monitors
  190. lappend xmonlist $monitor
  191. }
  192. }
  193. }
  194. if {[catch {close $input} error]} {
  195. tk_messageBox -type ok -icon error -title [G_msg "Error"] \
  196. -message [G_msg "d.mon error: problem launching xmon, $error"]
  197. return
  198. }
  199. if { ![info exists xmonlist] } {
  200. tk_messageBox -type ok -icon error -title [G_msg "Error"] \
  201. -message [G_msg "This module requires X11 support, but no xmons were found"]
  202. return
  203. }
  204. set xmon [lindex $xmonlist 0]
  205. spawn d.mon start=$xmon
  206. }
  207. ###############################################################################
  208. # Annotation procs for gis.m:
  209. proc monitor_annotation_start {mon title tags} {
  210. global gronsole
  211. set handle [$gronsole annotate $title $tags]
  212. $gronsole set_click_command $handle {}
  213. return $handle
  214. }
  215. proc monitor_annotate {handle text} {
  216. global gronsole
  217. $gronsole annotate_text $handle $text
  218. }