2 ; module providing gwave commands and dialogs for exporting data
5 (define-module (app gwave export)
6 :use-module (oop goops)
8 :use-module (gnome gtk)
9 :use-module (ice-9 optargs)
10 :use-module (app gwave cmds)
11 :use-module (app gwave gtk-helpers)
13 (read-set! keywords 'prefix)
14 (debug-enable 'backtrace)
17 ; list of registered plot filters. each entry is a 3-element list:
18 ; (name dialog-builder-procedure do-plot-procedure)
19 (define plot-list '())
21 ;; Register a new plot-filter module to appear in the plot dialog box.
22 ;; plot filter modules will call this to register themselves.
23 (define-public (register-plotfilter name dproc eproc)
25 (list name dproc eproc #f)
28 ; debug: dump export filter list
29 (define (dump-plotf-list)
30 (format #t "plot-list:\n")
31 (for-each (lambda (exptype)
32 (format #t " name=~s " (car exptype))
33 (format #t "dproc=~s\n" (cadr exptype))
34 (format #t " eproc=~s\n" (caddr exptype)))
37 ;; Export the data from a list of visiblewaves to a named file.
38 (define (export-variables-to-file f vwlist . ext)
39 (let ((p (open f (logior O_WRONLY O_CREAT O_TRUNC) #o0777)))
40 ; (print "ext is " ext "\n");
42 (export-variables vwlist p)
43 (export-variables vwlist p (car ext) (cadr ext)))
47 ;; Pop up the plotting dialog box
48 (define-public (popup-export-dialog wvlist)
49 (let* ((window (gtk-window-new 'toplevel))
50 (vbox (gtk-vbox-new #f 0))
51 (hbox1 (gtk-hbox-new #f 10))
52 (outf-label (gtk-label-new "Output File:"))
53 (filename-entry (make <gtk-entry>))
54 (browse-btn (gtk-button-new-with-label "Browse"))
56 (hbox2 (gtk-hbox-new #f 10))
62 (action-hbox (gtk-hbox-new #f 10))
63 (separator (gtk-hseparator-new))
64 (cancel-btn (gtk-button-new-with-label "Cancel"))
65 (export-btn (gtk-button-new-with-label "Export"))
68 (gtk-window-set-title window "Export Data")
69 (gtk-container-set-border-width window 0)
70 (gtk-container-add window vbox)
71 (gtk-widget-show vbox)
73 (gtk-container-set-border-width hbox1 10)
74 (gtk-box-pack-start vbox hbox1 #f #t 0)
75 (gtk-widget-show hbox1)
77 (gtk-box-pack-start hbox1 outf-label #f #t 0)
78 (gtk-widget-show outf-label)
80 (gtk-box-pack-start hbox1 filename-entry #f #t 0)
81 (gtk-widget-show filename-entry)
82 (gtk-entry-set-text filename-entry "gwexport.dat")
84 (gtk-box-pack-start hbox1 browse-btn #f #t 0)
85 (gtk-signal-connect browse-btn "clicked"
86 (lambda (b) ; TODO: use filechooserbutton
87 (with-selected-filename
90 (gtk-entry-set-text filename-entry f))
91 #:default (gtk-entry-get-text filename-entry))))
92 (gtk-widget-show browse-btn)
94 ; row of buttons for x-extents to export
95 (gtk-container-set-border-width hbox2 10)
96 (gtk-box-pack-start vbox hbox2 #f #t 0)
97 (gtk-widget-show hbox2)
99 (set! extents-group (add-radio-button
100 hbox2 extents-group "All" #t
102 (display "setting all\n")
103 (set! use-extents #f))))
104 (set! extents-group (add-radio-button
105 hbox2 extents-group "Visible" #f
107 (display "setting visible\n")
108 (set! use-extents #t)
109 (set! minx (wtable-start-xval))
110 (set! maxx (wtable-end-xval)))))
111 (set! extents-group (add-radio-button
112 hbox2 extents-group "Between Cursors" #f
114 (display "setting tween-cursor\n")
115 (set! use-extents #t)
116 (set! minx (wtable-vcursor 0))
117 (set! maxx (wtable-vcursor 1)))))
119 ; row of action buttons
120 (gtk-container-set-border-width action-hbox 10)
121 (gtk-box-pack-start vbox action-hbox #f #t 0)
122 (gtk-widget-show action-hbox)
124 (gtk-signal-connect cancel-btn "clicked"
126 (gtk-widget-destroy window)))
127 (gtk-box-pack-start action-hbox cancel-btn #t #t 0)
128 (gtk-widget-show cancel-btn)
129 (gtk-tooltips-set-tip gwave-tooltips cancel-btn
130 "Cancel export and close window" "")
132 (gtk-box-pack-start action-hbox export-btn #t #t 0)
133 (gtk-signal-connect export-btn "clicked"
135 (if (and use-extents (number? minx) (number? maxx))
136 (export-variables-to-file
137 (gtk-entry-get-text filename-entry)
139 (export-variables-to-file
140 (gtk-entry-get-text filename-entry) wvlist))
141 (gtk-widget-destroy window)))
142 (gtk-widget-show export-btn)
143 (gtk-tooltips-set-tip gwave-tooltips export-btn
146 ; (gtk-widget-set-flags export-btn '(can-default))
147 (gtk-widget-grab-default export-btn)
148 (gtk-widget-show window)
152 (define-public (popup-plot-dialog plist)
153 (let* ((window (gtk-window-new 'toplevel))
154 (vbox (gtk-vbox-new #f 0))
155 (hbox1 (gtk-hbox-new #f 10))
156 (outf-label (gtk-label-new "Output File:"))
157 (filename-entry (make <gtk-entry>))
158 (browse-btn (gtk-button-new-with-label "Browse"))
160 (hbox2 (gtk-hbox-new #f 10))
161 (tmpfcheck (gtk-check-button-new-with-label "Keep Tempfiles"))
163 (notebook (gtk-notebook-new))
166 (action-hbox (gtk-hbox-new #f 10))
167 (separator (gtk-hseparator-new))
168 (cancel-btn (gtk-button-new-with-label "Cancel"))
169 (export-btn (gtk-button-new-with-label "Plot"
170 :flags 'can-default ))
174 (gtk-window-set-title window "Plot Data")
175 (gtk-container-set-border-width window 0)
176 (gtk-container-add window vbox)
177 (gtk-widget-show vbox)
179 (gtk-container-set-border-width hbox1 10)
180 (gtk-box-pack-start vbox hbox1 #f #t 0)
181 (gtk-widget-show hbox1)
183 (gtk-box-pack-start hbox1 outf-label #f #t 0)
184 (gtk-widget-show outf-label)
186 (gtk-box-pack-start hbox1 filename-entry #f #t 0)
187 (gtk-widget-show filename-entry)
188 (gtk-entry-set-text filename-entry "gwplot.dat")
190 (gtk-box-pack-start hbox1 browse-btn #f #t 0)
191 (gtk-signal-connect browse-btn "clicked"
193 (with-selected-filename
196 (gtk-entry-set-text filename-entry f))
197 #:default (gtk-entry-get-text filename-entry))))
198 (gtk-widget-show browse-btn)
200 ; notebook with entry for each supported plot filter
201 ; containing that filter's various options
202 (gtk-notebook-set-tab-pos notebook 'top)
203 (gtk-box-pack-start vbox notebook #t #t 0)
206 (for-each (lambda (exptype)
207 (let* ((panelproc ( (cadr exptype) ))
208 (panel (car panelproc))
209 (optproc (cadr panelproc))
210 (plotproc (caddr exptype))
211 (label (gtk-label-new (car exptype))))
212 (gtk-notebook-append-page notebook panel label)
214 ; associate options-procedure with plot-procedure so we can
215 ; look up the right one based on the active
216 ; notebook tab when the go button is clicked
217 (set! oproc-assoc (assoc-set! oproc-assoc plotproc optproc))
220 ; (format #t "oproc-assoc:~s\n" oproc-assoc)
222 ; put up somthing helpful if there are no plot modules registered
223 (if (= 0 (length plot-list))
224 (let ((vbox (gtk-vbox-new #f 0))
225 (label1 (gtk-label-new "No plot backend"))
226 (label2 (gtk-label-new "No plot filter modules have been loaded")) (label3 (gtk-label-new "by .gwaverc or system.gwaverc"))
228 (gtk-widget-show vbox)
229 (gtk-widget-show label1)
230 (gtk-widget-show label2)
231 (gtk-widget-show label3)
232 (gtk-box-pack-start vbox label2 #t #t 0)
233 (gtk-box-pack-start vbox label3 #t #t 0)
234 (gtk-notebook-append-page notebook vbox label1)))
236 (gtk-widget-show notebook)
239 (gtk-box-pack-start hbox2 tmpfcheck #f #t 0)
240 (gtk-widget-show tmpfcheck)
241 (gtk-widget-show hbox2)
242 (gtk-box-pack-start vbox hbox2 #t #t 0)
244 ; row of action buttons
245 (gtk-container-set-border-width action-hbox 10)
246 (gtk-box-pack-start vbox action-hbox #f #t 0)
247 (gtk-widget-show action-hbox)
249 (gtk-signal-connect cancel-btn "clicked"
251 (gtk-widget-destroy window)))
252 (gtk-box-pack-start action-hbox cancel-btn #t #t 0)
253 (gtk-tooltips-set-tip gwave-tooltips cancel-btn
254 "Cancel export and close window" "")
255 (gtk-widget-show cancel-btn)
257 (gtk-box-pack-start action-hbox export-btn #t #t 0)
258 (gtk-tooltips-set-tip gwave-tooltips export-btn "Plot data" "")
259 (gtk-signal-connect export-btn "clicked"
261 (let* ((n (gtk-notebook-get-current-page notebook))
263 (caddr (list-ref plot-list n))
265 (op (assoc-ref oproc-assoc pp))
266 (optlist (if (procedure? op) (op) (list))))
267 ; (format #t "plot filter ~d ~s ~s\n" n op pp)
268 ; (format #t "opts: ~s\n" optlist)
271 (gtk-entry-get-text filename-entry)
273 (gtk-toggle-button-get-active tmpfcheck))))
274 (gtk-widget-destroy window)))
275 (if (= 0 (length plot-list))
276 (gtk-widget-set-sensitive export-btn #f))
277 (gtk-widget-show export-btn)
279 ; (gtk-widget-set-flags export-btn '(can-default))
280 ; (set-flags export-btn '(can-default))
281 (gtk-widget-grab-default export-btn)
282 (gtk-widget-show window)
285 ;; run a command in a subprocess, redirecting its output to a named file.
286 (define-public (subprocess-to-file f cmd arglist)
288 (open f (logior O_WRONLY O_CREAT O_TRUNC) #o0777)
290 (null (open "/dev/null" O_RDONLY 0)))
292 (format #t "subprocess-to-file ~a ~s\n" cmd arglist))
294 ; TODO: search for and stat cmd to make sure it exists and is executable.
295 (let ((p (primitive-fork)))
302 (redirect-port port (current-output-port)))
303 (redirect-port null (current-input-port))
304 (close-all-ports-except (current-input-port)
305 (current-output-port)
306 (current-error-port))
309 (apply execlp cmd arglist)
310 (primitive-exit 127)))
318 (format #t "child process ~d started for ~a ~s\n" p cmd arglist))
323 (let* ((w (catch 'system-error
324 (lambda () (waitpid 0 WNOHANG))
325 (lambda (func . stuff) (cons 0 #f))))
328 (if (not (eq? 0 pid))
330 (format #t "process ~d" pid)
331 (if (status:exit-val st)
332 (format #t " exited (~d)" (status:exit-val st)))
333 (if (status:term-sig st)
334 (format #t " terminated on signal ~d" (status:term-sig st)))
335 (if (status:stop-sig st)
336 (format #t " stopped on signal~d" (status:exit-sig st)))
338 ;(display "no child\n")
341 (dbprint "setting SIGCHLD handler\n")
342 ;(display (sigaction SIGCHLD (lambda (s) (reap-child)))) (newline)
343 ;(display (sigaction SIGCHLD)) (newline)
344 (dbprint "export.scm done")