Changed russian description a little bit
[gnuplot] / lisp / gnuplot-gui.el
1 ;;;; gnuplot-gui.el -- GUI interface to setting options in gnuplot-mode
2
3 ;; Copyright (C) 1998-2000 Bruce Ravel
4
5 ;; Author:     Bruce Ravel <ravel@phys.washington.edu>
6 ;; Maintainer: Bruce Ravel <ravel@phys.washington.edu>
7 ;; Created:    19 December 1998
8 ;; Updated:    16 November 2000
9 ;; Version:    (same as gnuplot.el)
10 ;; Keywords:   gnuplot, plotting, interactive, GUI
11
12 ;; This file is not part of GNU Emacs.
13
14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ;; This program is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; any later version.
19 ;;
20 ;; This lisp script is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 ;;
24 ;; Permission is granted to distribute copies of this lisp script
25 ;; provided the copyright notice and this permission are preserved in
26 ;; all copies.
27 ;;
28 ;; You should have received a copy of the GNU General Public License
29 ;; along with this program; if not, you can either send email to this
30 ;; program's maintainer or write to: The Free Software Foundation,
31 ;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA.
32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33 ;; send bug reports to the authors (ravel@phys.washington.edu)
34 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35 ;;
36 ;;; Commentary:
37 ;;
38 ;; This file provides a graphical user interface to setting arguments
39 ;; to gnuplot commands.  Positioning point near a command and invoking
40 ;; `gnuplot-gui-set-options-and-insert' (C-c C-c or shift-mouse-2)
41 ;; will pop open a frame with widgets for setting the various
42 ;; arguments appropriate the the item that was near point.  The goal
43 ;; is to provide point-and-click functionality to gnuplot-mode.
44 ;;
45 ;; gnuplot-gui is designed for gnuplot 3.7, but since much of 3.7 is
46 ;; backward compatible to 3.5, it will work well for that version
47 ;; also.
48 ;;
49 ;; gnuplot-gui.el was developed using Emacs 19.34 and is known to work
50 ;; on Emacs 20.x and XEmacs 20.x.  I do not know what is the earliest
51 ;; version for which it will work, but I make no guarantees for
52 ;; versions before 19.34.  Note that this makes heavy use of the
53 ;; widget package, so this will not work on Emacs 19.34 unless you
54 ;; install the widget package separately.
55 ;;
56 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57 ;;
58 ;;; To do:
59 ;;
60 ;; Widgets I need:
61 ;; -- 'position: two or three comma separated numbers used to denote a
62 ;;               position or a tic start/end/increment (see arrow,
63 ;;               need a prefix)
64 ;; -- 'modifier: colon separated fields used for datafile modifiers
65 ;;
66 ;; command types which are currently unsupported or contain mistakes
67 ;; -- unsupported: cntrparam
68 ;; -- plot, splot, fit: rather lame
69 ;; -- label: position information missing
70 ;; -- label: font string handled in overly simple manner
71 ;; -- hidden3d: not really suited to 'list, but all options are exclusive...
72 ;; -- pointstyle argument to "set label"
73 ;;
74 ;; overall:
75 ;; -- continuation lines (ugh!)
76 ;; -- multiple frames end up displaying same window after setting options
77 ;;
78 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79 ;;; Code:
80
81 (require 'gnuplot)
82 (eval-and-compile
83   (condition-case ()
84       (progn
85         (require 'widget)
86         (require 'wid-edit))
87     (error nil)))
88 (require 'cl)
89 (eval-when-compile                      ; suppress some compiler warnings
90   (defvar gnuplot-xemacs-p nil)
91   (defvar gnuplot-quote-character nil)
92   (defvar gnuplot-info-display nil)
93   (defvar gnuplot-mode-map nil))
94
95 ;; (eval-when-compile
96 ;;   (require 'wid-edit))
97
98 (eval-and-compile                       ; I need this!
99   (if (fboundp 'split-string)
100       ()
101     (defun split-string (string &optional pattern)
102       "Return a list of substrings of STRING which are separated by PATTERN.
103 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
104       (or pattern
105           (setq pattern "[ \f\t\n\r\v]+"))
106       ;; The FSF version of this function takes care not to cons in case
107       ;; of infloop.  Maybe we should synch?
108       (let (parts (start 0))
109         (while (string-match pattern string start)
110           (setq parts (cons (substring string start (match-beginning 0)) parts)
111                 start (match-end 0)))
112         (nreverse (cons (substring string start) parts)))) ))
113
114
115 \f
116 ;;; customizable variables
117
118 (defgroup gnuplot-gui nil
119   "Graphical interface to setting arguments in gnuplot scrips."
120   :prefix "gnuplot-gui-"
121   :group 'gnuplot)
122
123 (defcustom gnuplot-gui-popup-flag nil
124   "*Non-nil means to open arguments pop-ups automatically.
125 This would be done after menu insertion of Gnuplot commands."
126   :group 'gnuplot-gui
127   :type 'boolean)
128
129 (defvar gnuplot-gui-frame nil
130   "Frame used to hold the buffer for setting options.")
131 (defcustom gnuplot-gui-frame-plist
132   '(height 18 width 65 border-width 0
133            user-position t top 150 left 150
134            internal-border-width 0 unsplittable t
135            default-toolbar-visible-p nil has-modeline-p nil
136            menubar-visible-p nil)
137   "Frame plist for the input run-time display frame in XEmacs."
138   :type '(repeat (group :inline t
139                         (symbol :tag "Property")
140                         (sexp :tag "Value")))
141   :group 'gnuplot-gui)
142 (defcustom gnuplot-gui-frame-parameters
143   '((height . 18)
144     (width . 65)
145     (user-position . t)
146     (top . 150)
147     (left . 150)
148     (border-width . 0)
149     (menu-bar-lines . 0)
150     (unsplittable . t))
151   "Frame parameters for the input run-time display frame in Emacs."
152   :group 'gnuplot-gui
153   :type '(repeat (sexp :tag "Parameter:")))
154
155 (defcustom gnuplot-gui-fontname-list
156   '(" " "\"Helvetica\"" "\"Times-Roman\"")
157   "List of known font names.
158 These *must* be quoted, like so \"\\\"Helvetica\\\"\".  This allows
159 for fonts with names like \"\\\"Arial Bold Italic\\\"\" to be treated
160 as single entries in the menu-buttons.  And it is really important that
161 the first entry in the list be a blank string."
162   :group 'gnuplot-gui
163   :type '(repeat (string :tag "Font name:")))
164
165 ;; some global variables
166 (defvar gnuplot-current-frame nil)
167 (defvar gnuplot-current-buffer nil)
168 (defvar gnuplot-current-buffer-point nil)
169 (defvar gnuplot-gui-alist nil)
170 (defvar gnuplot-gui-current-string nil)
171
172 \f
173 ;;; various tools for handling data structures and text in the buffer
174
175 ;; tools for accessing the elements of the lists in `gnuplot-gui-all-types'
176 (defsubst gnuplot-gui-type-tag     (obj) (elt obj 0))
177 (defsubst gnuplot-gui-type-symbol  (obj) (elt obj 1))
178 (defsubst gnuplot-gui-type-default (obj) (elt obj 2))
179 (defsubst gnuplot-gui-type-prefix  (obj) (elt obj 3)) ; also 'range seperator
180 (defsubst gnuplot-gui-type-fourth  (obj) (elt obj 4))
181 (defsubst gnuplot-gui-type-list    (obj) (cddr obj))
182
183 (defun gnuplot-this-word ()
184   "Return the word under point."
185   (let ((begin (save-excursion (beginning-of-line) (point-marker)))
186         (end   (save-excursion (end-of-line)       (point-marker))))
187     (save-excursion
188       (or (looking-at "\\<") (= (current-column) 0) (forward-word -1))
189       (if (> (point) begin) (setq begin (point-marker)))
190       (forward-word 1)
191       (if (> (point) end) (goto-char end))
192       (buffer-substring-no-properties begin (point)))))
193
194
195 \f
196 ;;; data structures containing regarding options in Gnuplot 3.7
197
198 ;; various constants used for options that take the same sorts of arguments
199 (defconst gnuplot-gui-mtics-list
200   '(("FREQUENCY"   'number " ")
201     ("DEFAULT"     'list " " "default")))
202 (defconst gnuplot-gui-data-list
203   '(("DATA TYPE"   'list " " "time")))
204 (defconst gnuplot-gui-label-list
205   '(("LABEL"       'string " ")
206     ("POSITION"    'position " " "" 2)
207     ("FONTNAME"    'list " " gnuplot-gui-fontname-list)
208     ("FONTSIZE"    'fontsize " ")))
209 (defconst gnuplot-gui-range-list
210   '(("RANGE"       'range (" " . " ") ":")
211     ("REVERSE"     'list " " "reverse" "noreverse")
212     ("WRITEBACK"   'list " " "writeback" "nowriteback")))
213 (defconst gnuplot-gui-tics-list
214   '(("WHERE"       'list " " "axis" "border")
215     ("MIRROR"      'list " " "mirror" "nomirror")
216     ("ROTATE"      'list " " "rotate" "norotate")
217     ("SERIES"      'position " " "" 3)
218     ("LABEL ARRAY" 'labels () )))
219 (defconst gnuplot-gui-zeroaxis-list
220   '(("LINETYPE"    'number " ")))
221
222 (defvar gnuplot-gui-terminal-types nil
223   "Associated list of terminal descriptions.
224 See the doc-string for `gnuplot-gui-all-types'.")
225 (setq gnuplot-gui-terminal-types
226       (list (cons "aifm"
227                   '(("COLOR"     'list " " "monochrome" "gray" "color")
228                     ("FONTNAME"  'list " " gnuplot-gui-fontname-list)
229                     ("FONTSIZE"  'fontsize " ")))
230             (cons "cgm"
231                   '(("MODE"      'list   " " "landscape" "portrait" "default")
232                     ("COLOR"     'list   " " "color" "monochrome")
233                     ("ROTATION"  'list   " " "rotate" "norotate")
234                     ("WIDTH"     'number " " "width")
235                     ("LINEWIDTH" 'number " " "linewidth")
236                     ("FONTNAME"  'list   " " "\"Arial\"" "\"Arial Italic\""
237                      "\"Arial Bold\"" "\"Arial Bold Italic\""
238                      "\"Times Roman\"" "\"Times Roman Italic\""
239                      "\"Times Roman Bold\"" "\"Times Roman Bold Italic\""
240                      "\"Helvetica\"" "\"Roman\"")
241                     ("FONTSIZE"  'fontsize " ")))
242             (cons "corel"
243                   '(("COLOR"            'list " " "default" "color" "monochrome")
244                     ("FONTNAME"         'list " " "\"SwitzerlandLight\""
245                      "\"Helvetica\"" "\"Times-Roman\"")
246                     ("FONTSIZE "        'number " ")
247                     ("X-SIZE   "        'number " ")
248                     ("Y-SIZE   "        'number " ")
249                     ("LINEWIDTH"        'number " ")))
250             (cons "dumb"
251                   '(("LINEFEED"         'list   " " "feed" "nofeed")
252                     ("X-SIZE"           'number " ")
253                     ("Y-SIZE"           'number " ")))
254             (cons "emf"
255                   '(("COLOR"            'list " " "color" "monochrome")
256                     ("LINE"             'list " " "solid" "dashed")
257                     ("FONTNAME"         'string " ")
258                     ("FONTSIZE"         'number " ")))
259             (cons "emtex"
260                   '(("FONTNAME"         'list     " " "courier" "roman")
261                     ("FONTSIZE"         'fontsize " ")))
262             (cons "fig"
263                   '(("COLOR"            'list   " " "color" "monochrome")
264                     ("FRAMESIZE"        'list   " " "small" "big")
265                     ("POINTSMAX"        'number " " "pointsmax")
266                     ("ORIENTATION"      'list   " " "landscape" "portrait")
267                     ("UNITS"            'list   " " "metric" "inches")
268                     ("FONT SIZE"        'number " " "fontsize")
269                     ("SIZE"             'pair   (" " . " ") "size")
270                     ("LINE THICKNESS"   'number " " "thickness")
271                     ("LAYER DEPTH"      'number " " "depth")))
272             (cons "hp500c"
273                   '(("RESOLUTION"       'list " " "75" "100" "150" "300")
274                     ("COMPRESSION"      'list " " "rle" "tiff")))
275             (cons "hpgl"
276                   '(("PENS"             'number " ")
277                     ("EJECT"            'list   " " "eject")))
278             (cons "hpdj"
279                   '(("RESOLUTION"       'list " " "75" "100" "150" "300")))
280             (cons "hpljii"
281                   '(("RESOLUTION"       'list " " "75" "100" "150" "300")))
282             (cons "hppj"
283                   '(("FONT"             'list " " "FNT9X17" "FNT5X9" "FNT13X25")))
284             (cons "imagen"
285                   '(("FONT SIZE"        'number " ")
286                     ("LAYOUT"           'list   " " "portrait" "landscape")
287                     ("NUMBER OF GRAPHS" 'range (" " . " ") ",")))
288             (cons "gpic"
289                   '(("X ORIGIN"         'number " ")
290                     ("Y ORIGIN"         'number " " ",")))
291             (cons "latex"
292                   '(("FONTNAME"         'list " " "courier" "roman")
293                     ("FONTSIZE"         'fontsize " ")))
294             (cons "mif"
295                   '(("COLOUR"           'list " " "colour" "monochrome")
296                     ("LINETYPE"         'list " " "polyline" "vectors")))
297             (cons "nec-cp6"
298                   '(("MODE"             'list " " "monochrome" "colour" "draft")))
299             (cons "pbm"
300                   '(("SIZE"      'list " " "small" "medium" "large")
301                     ("COLOR"     'list " " "monochrome" "gray" "color")))
302             (cons "pcl5L"
303                   '(("MODE"      'list " " "landscape" "portrait")
304                     ("FONTNAME"  'list " " "stick" "univers" "cg_times")
305                     ("FONTSIZE"  'fontsize " ")))
306             (cons "png"
307                   '(("SIZE"      'list " " "small" "medium" "large")
308                     ("COLOR"     'list " " "monochrome" "gray" "color")))
309             (cons "postscript"
310                   '(("MODE"      'list " " "landscape" "portrait" "eps" "default")
311                     ("ENHANCED"  'list " " "enhanced" "noenhanced")
312                     ("COLOR"     'list " " "color" "monochrome")
313                     ("SOLID"     'list " " "solid" "dashed")
314                     ("DUPLEXING" 'list " " "defaultplex" "simplex" "duplex")
315                     ("FONTNAME"  'list " " gnuplot-gui-fontname-list)
316                     ("FONTSIZE"  'fontsize " ")))
317             (cons "pslatex"
318                   '(("COLOR"     'list " " "monochrome" "color")
319                     ("DASHED"    'list " " "dashed")
320                     ("ROTATION"  'list " " "rotate" "norotate")
321                     ("AUXFILE"   'list " " "auxfile")))
322             (cons "pstex"
323                   '(("COLOR"     'list " " "monochrome" "color")
324                     ("DASHED"    'list " " "dashed")
325                     ("ROTATION"  'list " " "rotate" "norotate")
326                     ("AUXFILE"   'list " " "auxfile")))
327             (cons "pstricks"
328                   '(("HACK TEXT"        'list " " "hacktext" "nohacktext")
329                     ("PLOT SCALING"     'list " " "nounit" "unit")))
330             (cons "regis"
331                   '(("COLOR DEPTH"      'list "4" "16")))
332             (cons "tgif"
333                   '(("LAYOUT"           'list   " " "portrait" "landscape")
334                     ("NUMBER OF GRAPHS" 'range (" " . " ") ",")
335                     ("LINE TYPE"        'list " " "solid" "dashed")
336                     ("FONTNAME"         'list " " gnuplot-gui-fontname-list)
337                     ("FONTSIZE"         'fontsize " ")))
338             (cons "tpic"
339                   '(("POINTSIZE"        'number " ")
340                     ("LINEWIDTH"        'number " ")
341                     ("INTERVAL "        'number " ")))
342             (cons "vgagl"               ; for pm3d patch (also persist, raise in x11) <MT>
343                   '(("BACKGROUND"       'position  " " "background" 3)
344                     ("INTERPOLATION"    'list " " "uniform" "interpolate")
345                     ("DUMP"             'file " ")
346                     ("MODE"             'string  " " "")))
347             (cons "x11"
348                   '(("RESET"            'list " " "reset")
349                     ("TERMINAL NUMBER"  'number " ")
350                     ("PERSIST"          'list " " "persist" "nopersist")
351                     ("RAISE"            'list " " "raise" "noraise"))) ))
352
353 (defvar gnuplot-gui-terminal-list nil)
354 (setq gnuplot-gui-terminal-list
355       (append (list " ") (mapcar 'car gnuplot-gui-terminal-types)))
356
357 (defvar gnuplot-gui-set-types nil
358   "Associated list of set option descriptions.
359 See the doc-string for `gnuplot-gui-all-types'.")
360 (setq gnuplot-gui-set-types
361       (list (cons "angles"
362                   '(("UNITS" 'list " " "degrees" "radians")))
363             (cons "arrow"
364                   '(("TAG"       'tag " ")
365                     ("FROM"      'position " " "from" 3)
366                     ("TO"        'position " " "to" 3)
367                     ("HEAD"      'list " " "head" "nohead")
368                     ("LINESTYLE" 'number " " "ls")
369                     ("LINETYPE " 'number " " "lt")
370                     ("LINEWIDTH" 'number " " "lw")))
371             (cons "noarrow"
372                   '(("TAG" 'tag " ")))
373             (cons "autoscale"
374                   '(("AXIS" 'list " " "x" "y" "z" "x2" "y2" "xy"
375                      "xmin" "ymin" "zmin" "x2min" "y2min" "xymin"
376                      "xmax" "ymax" "zmax" "x2max" "y2max" "xymax")))
377             (cons "noautoscale"
378                   '(("AXIS" 'list " " "x" "y" "z" "x2" "y2" "xy"
379                      "xmin" "ymin" "zmin" "x2min" "y2min" "xymin"
380                      "xmax" "ymax" "zmax" "x2max" "y2max" "xymax")))
381             (cons "bar"
382                   '(("SIZE" 'list " " "small" "large")))
383             (cons "border"
384                   '(("BORDER CODE" 'number " ")
385                     ("LINE STYLE"  'list   " " "lines"
386                      "dots" "points" "linespoints")
387                     ("LINESTYLE"   'number " " "ls")
388                     ("LINETYPE"    'number " " "lt")
389                     ("LINEWIDTH"   'number " " "lw")
390                     ))
391             (cons "boxwidth"
392                   '(("WIDTH" 'number " ")))
393             (cons "clabel"
394                   '(("FORMAT" 'format " ")))
395             (cons "clip"
396                   '(("CLIP TYPE" 'list " " "points" "one" "two")))
397             (cons "noclip"
398                   '(("CLIP TYPE" 'list " " "points" "one" "two")))
399             ;;(cons "cntrparam"
400                 ;;  '(("INTERPOLATION" 'list " " "linear" "cubicspline" "bspline")
401                 ;;    ("POINTS" 'number " " "points")
402                 ;;    ("ORDER"  'number " " "order")))
403             (cons "contour"
404                   '(("WHERE"     'list " " "base" "surface" "both")))
405             (cons "dgrid3d"
406                    '(("ROW,COLUMN,NORM" 'position " " "" 3)))
407             (cons "encoding"
408                   '(("ENCODING" 'list " " "default" "iso_8859_1"
409                      "cp850" "cp437")))
410             (cons "format"
411                   '(("AXIS"   'list " " "x" "y" "z" "xy" "x2" "y2")
412                     ("FORMAT" 'format  " ")))
413             (cons "dummy"
414                   '(("VAR 1" 'string " " "")
415                     ("VAR 2" 'string " " ",")))
416             (cons "grid"
417                   '(("XTICS"  'list " " "xtics" "mxtics" "noxtics" "nomxtics")
418                     ("YTICS"  'list " " "ytics" "mytics" "noytics" "nomytics")
419                     ("ZTICS"  'list " " "ztics" "mztics" "noztics" "nomztics")
420                     ("X2TICS" 'list " " "x2tics" "mx2tics" "nox2tics" "nomx2tics")
421                     ("Y2TICS" 'list " " "y2tics" "my2tics" "noy2tics" "nomy2tics")
422                     ("POLAR"  'number " " "polar")
423                     ("MAJOR LINETYPE" 'number " ")
424                     ("MINOR LINETYPE" 'number " ")))
425             (cons "hidden3d"
426                   '(("ALGORITHM" 'list " " "defaults"
427                     "offset"
428                     "nooffset"
429                     ;;"trianglepattern  # bitpattern between 0 and 7"
430                     "trianglepattern 0" "trianglepattern 1"
431                     "trianglepattern 2" "trianglepattern 3"
432                     "trianglepattern 4" "trianglepattern 5"
433                     "trianglepattern 6" "trianglepattern 7"
434                     ;;"undefined        # level between 0 and 3"
435                     "undefined 0" "undefined 1" "undefined 2" "undefined 3"
436                     "noundefined" "altdiagonal" "noaltdiagonal"
437                     "bentover" "nobentover")))
438             (cons "historysize"
439                   '(("SIZE" 'number " ")))
440             (cons "isosamples"
441                   '(("ISO_U LINES" 'number " ")
442                     ("ISO_V LINES" 'number " " ",")))
443             (cons "key"
444                   '(("LOCATION"      'list " " "left" "right" "top" "bottom"
445                                            "outside" "below")
446                     ("POSITION"      'position  " " "" 3)
447                     ("JUSTIFICATION" 'list " " "Left" "Right")
448                     ("REVERSE"       'list " " "reverse" "noreverse")
449                     ("SAMPLE LENGTH" 'number " " "samplen")
450                     ("SPACING"       'number " " "spacing")
451                     ("WIDTH"         'number " " "width")
452                     ("TITLE"         'string " " "title ")
453                     ("BOX LINETYPE"  'number " " "box") ;; linetype data
454                     ("NOBOX"         'list   " " "nobox")))
455             (cons "label"
456                   '(("TAG" 'tag " ")
457                     ("LABEL TEXT" 'string " ")
458                     ("POSITION"   'position " " "at" 3)
459                     ;; first, second, graph, screen
460                     ("JUSTIFICATION" 'list " " "left" "right" "center")
461                     ("ROTATE"        'list " " "rotate" "norotate")
462                     ("FONT"          'string " " "font"))) ;; font "name,size"
463             (cons "nolabel"
464                   '(("TAG"        'tag " ")))
465             (cons "linestyle"
466                   '(("TAG      "  'tag " ")
467                     ("LINE STYLE" 'list " " "boxerrorbars" "boxes"
468                      "boxxyerrorbars" "candlesticks" "dots"
469                      "financebars" "fsteps" "histeps" "impulses"
470                      "lines" "linespoints" "points" "steps" "vector"
471                      "xerrorbars" "xyerrorbars" "yerrorbars")
472                     ("LINETYPE " 'number " " "lt")
473                     ("LINEWIDTH" 'number " " "lw")
474                     ("POINTTYPE" 'number " " "pt")
475                     ("POINTSIZE" 'number " " "ps")))
476             (cons "locale"
477                   '(("LOCALE" 'string " ")))
478             (cons "logscale"
479                   '(("AXIS" 'list " " "x" "y" "z" "xy" "xz" "yz" "xyz"
480                      "x2" "y2")
481                     ("BASE" 'number " ")))
482             (cons "nologscale"
483                   '(("AXIS" 'list " " "x" "y" "z" "xy" "xz" "yz" "xyz"
484                      "x2" "y2")))
485             (cons "mapping"
486                   '(("COORDINATE SYSTEM" 'list " " "cartesian" "spherical"
487                      "cylindrical")))
488                                         ; _margin
489             (cons "bmargin"
490                   '(("BOTTOM MARGIN" 'number " ")))
491             (cons "lmargin"
492                   '(("LEFT MARGIN"   'number " ")))
493             (cons "rmargin"
494                   '(("RIGHT MARGIN"  'number " ")))
495             (cons "tmargin"
496                   '(("TOP MARGIN"    'number " ")))
497
498             (cons "missing"
499                   '(("CHARACTER" 'string " " 1)))
500                                         ; m_tics
501             (cons "mxtics"  gnuplot-gui-mtics-list)
502             (cons "mytics"  gnuplot-gui-mtics-list)
503             (cons "mztics"  gnuplot-gui-mtics-list)
504             (cons "mx2tics" gnuplot-gui-mtics-list)
505             (cons "my2tics" gnuplot-gui-mtics-list)
506
507                                         ; pm3d additions <MT>
508             (cons "mouse"
509                   '(("DOUBLECLICK"     'number " " "doubleclick")
510                     ("ZOOM"            'list   " " "zoomcoordinates" "nozoomcoordinates")
511                     ("POLAR"           'list   " " "polarcoordinates" "nopolarcoordinates")
512                     ("FORMAT"          'string " " "format")
513                     ("CLIPBOARDFORMAT" 'string " " "clipboardformat")
514                     ("MOUSEFORMAT"     'string " " "mouseformat")
515                     ("LABELS"          'list   " " "labels" "nolabels")
516                     ("LABELOPTIONS"    'string " " "labeloptions")
517                     ("ZOOMJUMP"        'list   " " "zoomjump" "nozoomjump")
518                     ("VERBOSE"         'list   " " "verbose" "noverbose")))
519             (cons "palette"
520                   '(("COLOR"       'list     " " "gray" "color")
521                     ("RGBFORMULAE" 'position " " "rgbformulae" 3)
522                     ("PARITY"      'list     " " "positive" "negative")
523                     ("FORMULAE"    'list     " " "nops_allcF" "ps_allcF")
524                     ("MAXCOLORS"   'number   " ")
525                     ("COLOR_BOX"   'list     " " "nocb" "cbdefault" "cbuser")
526                     ("ORIENTATION" 'list     " " "cbvertical" "cbhorizontal")
527                     ("ORIGIN"      'position " " "origin" 2)
528                     ("SIZE"        'position " " "size" 2)
529                     ("BORDER"      'number   " ")
530                     ("NOBORDER"    'list     " " "bdefault" "noborder")))
531             (cons "pm3d"
532                   '(("AT"         'list*  " " "b" "s" "t" "bs" "bt" "st" "bst")
533                     ("SCANS"      'list   " " "scansautomatic" "scansforward" "scansbackward")
534                     ("FLUSH"      'list*  " " "begin" "center" "end")
535                     ("CLIP"       'list   " " "clip1in" "clip4in")
536                     ("ZRANGE"     'range (" " . " ") ":")
537                     ("HIDDEN3D"   'number " ")
538                     ("NOHIDDEN3D" 'list   " " "nohidden3d")
539                     ("FILLING"    'list   " " "transparent" "solid")
540                     ("MAP"        'list   " " "map")))
541
542             (cons "offsets"
543                   '(("LEFT  " 'number " ")
544                     ("RIGHT " 'number " " ",")
545                     ("TOP   " 'number " " ",")
546                     ("BOTTOM" 'number " " ",")))
547             (cons "origin"
548                   '(("X ORIGIN"   'number " ")
549                     ("Y ORIGIN"   'number " " ",")))
550             (cons "output"
551                   '(("FILENAME"   'file " ")))
552             (cons "pointsize"
553                   '(("MULTIPLIER" 'number " ")))
554             (cons "samples"
555                   '(("2D PLOT"    'number " ")
556                     ("3D PLOT"    'number " " ",")))
557             (cons "size"
558                   '(("ASPECT"           'list " " "square" "nosquare"
559                                                   "ratio" "noratio")
560                     ("X-SCALE OR RATIO" 'number " ")
561                     ("Y-SCALE"          'number " " ",")))
562             (cons "style"
563                   '(("DATA TYPE"  'list " " "data" "function")
564                     ("PLOT STYLE" 'list " " "boxerrorbars" "boxes"
565                      "boxxyerrorbars" "candlesticks" "dots"
566                      "financebars" "fsteps" "histeps" "impulses"
567                      "lines" "linespoints" "points" "steps" "vector"
568                      "xerrorbars" "xyerrorbars" "yerrorbars")))
569             (cons "terminal"
570                   '(("TERMINAL TYPE" 'list " " gnuplot-gui-terminal-list)))
571             (cons "tics"
572                   '(("DIRECTION"  'list " " "in" "out")))
573             (cons "ticslevel"
574                   '(("RELATIVE HEIGHT" 'number " ")))
575             (cons "ticscale"
576                   '(("MAJOR" 'number " ")
577                     ("MINOR" 'number " ")))
578             (cons "timestamp"
579                   '(("FORMAT STRING" 'format " ")
580                     ("WHERE"         'list " " "top" "bottom")
581                     ("ROTATE"        'list " " "rotate" "norotate")
582                     ("X-OFFSET"      'number " ")
583                     ("Y-OFFSET"      'number " " ",")
584                     ("FONTNAME"      'list " " gnuplot-gui-fontname-list)))
585             (cons "timefmt"
586                   '(("FORMAT STRING" 'string " ")))
587             (cons "title"
588                   '(("TITLE" 'string " ")))
589             (cons "view"
590                   '(("X-ROTATION" 'number " ")
591                     ("Z-ROTATION" 'number " " ",")
592                     ("SCALE"      'number " " ",")
593                     ("Z-SCALE"    'number " " ",")))
594             ;; ("SCALE" 'position " " "," 4)
595                                         ; _data
596             (cons "xdata"      gnuplot-gui-data-list)
597             (cons "ydata"      gnuplot-gui-data-list)
598             (cons "zdata"      gnuplot-gui-data-list)
599             (cons "x2data"     gnuplot-gui-data-list)
600             (cons "y2data"     gnuplot-gui-data-list)
601                                         ; _label
602             (cons "xlabel"     gnuplot-gui-label-list)
603             (cons "ylabel"     gnuplot-gui-label-list)
604             (cons "zlabel"     gnuplot-gui-label-list)
605             (cons "x2label"    gnuplot-gui-label-list)
606             (cons "y2label"    gnuplot-gui-label-list)
607                                         ; _range, note that the [] syntax for
608                                         ;         the writeback argument is
609                                         ;         not properly supported
610             (cons "xrange"     gnuplot-gui-range-list)
611             (cons "yrange"     gnuplot-gui-range-list)
612             (cons "zrange"     gnuplot-gui-range-list)
613             (cons "x2range"    gnuplot-gui-range-list)
614             (cons "y2range"    gnuplot-gui-range-list)
615             (cons "trange"     gnuplot-gui-range-list)
616             (cons "rrange"     gnuplot-gui-range-list)
617             (cons "urange"     gnuplot-gui-range-list)
618             (cons "vrange"     gnuplot-gui-range-list)
619                                         ; _tics
620             (cons "xtics"      gnuplot-gui-tics-list)
621             (cons "ytics"      gnuplot-gui-tics-list)
622             (cons "ztics"      gnuplot-gui-tics-list)
623             (cons "x2tics"     gnuplot-gui-tics-list)
624             (cons "y2tics"     gnuplot-gui-tics-list)
625                                         ; zeroaxis
626             (cons "zeroaxis"   gnuplot-gui-zeroaxis-list)
627             (cons "xzeroaxis"  gnuplot-gui-zeroaxis-list)
628             (cons "yzeroaxis"  gnuplot-gui-zeroaxis-list)
629             (cons "y2zeroaxis" gnuplot-gui-zeroaxis-list)
630             (cons "x2zeroaxis" gnuplot-gui-zeroaxis-list)
631
632             (cons "zero"
633                   '(("THRESHOLD" 'number " ")))
634             ))
635
636 (defvar gnuplot-gui-command-types nil
637   "Associated list of command descriptions.
638 See the doc-string for `gnuplot-gui-all-types'.")
639 (setq gnuplot-gui-command-types
640       (list (cons "cd"
641                   '(("FILENAME"       'file   " ")))
642             (cons "call"
643                   '(("INPUT FILE"     'file   " ")
644                     ("PARAMETER LIST" 'string " ")))
645             (cons "load"
646                   '(("INPUT FILE"     'file   " ")))
647             (cons "pause"
648                   '(("TIME"           'number " ")
649                     ("MESSAGE"        'string " ")))
650             (cons "print"
651                   '(("EXPRESSION"     'string " ")))
652             (cons "save"
653                   '(("SAVE"           'list   " " "functions" "variables" "set")
654                     ("FILE"           'file   " ")))
655             (cons "update"
656                   '(("INITIAL FILE"   'file   " " t)
657                     ("UPDATED FILE"   'file   " " t))) ))
658
659
660 (defcustom gnuplot-gui-plot-splot-fit-style 'simple
661   "Control the complexity of the GUI display for plot, splot, and fit.
662 The values are 'simple, which causes a limited set of plot, splot, or
663 fit options to be displayed, and 'complete, which attempts to display
664 all options.  The 'complete setting is prone to making errors when
665 parsing values already in the script buffer."
666   :group 'gnuplot-gui
667   :type '(radio (const :tag "Simple listing"   simple)
668                 (const :tag "Complete listing" complete)))
669
670
671 (defconst gnuplot-gui-plot-simple-list
672   '(("X RANGE"     'range (" " . " ") ":")
673     ("Y RANGE"     'range (" " . " ") ":")
674     ("DATA FILE"   'file   " ")
675     ("THRU"        'string* " " "thru")
676     ("USING"       'modifier " ")
677     ("TITLE"       'string " ")
678     ("WITH"        'list* " " "boxerrorbars" "boxes"
679      "boxxyerrorbars" "candlesticks" "dots" "financebars"
680      "fsteps" "histeps" "impulses" "lines" "linespoints"
681      "points" "steps" "vector" "xerrorbars" "xyerrorbars"
682      "yerrorbars")))
683 (defconst gnuplot-gui-plot-full-list
684   '(;;("T RANGE"     'range (" " . " ") ":")
685     ("X RANGE"     'range (" " . " ") ":")
686     ("Y RANGE"     'range (" " . " ") ":")
687     ("xa"          'text   "\t---------------------")
688     ("FUNCTION"    'string " ")
689     ("xc"          'text   "   or")
690     ("DATA FILE"   'file   " ")
691     ("INDEX"       'modifier " ")
692     ("EVERY"       'modifier " ")
693     ("THRU"        'string* " " "thru")
694     ("USING"       'modifier " ")
695     ("SMOOTH"      'list* " " "unique" "csplines" "acsplines"
696      "bezier" "sbezier")
697     ;; datafile modifiers
698     ("AXES"        'list* " " "x1y1" "x2y2" "x1y2" "x2y1")
699     ("TITLE"       'string " ")
700     ("NOTITLE"     'list   " " "notitle")
701     ("xf"          'text   "\t---------------------")
702     ("xi"          'text   "Select a standard plotting style")
703     ("WITH"        'list* " " "boxerrorbars" "boxes"
704      "boxxyerrorbars" "candlesticks" "dots" "financebars"
705      "fsteps" "histeps" "impulses" "lines" "linespoints"
706      "points" "steps" "vector" "xerrorbars" "xyerrorbars"
707      "yerrorbars")
708     ("xo"          'text   "     or a previously defined style")
709     ("LINE STYLE " 'number " " "ls")
710     ("xr"          'text   "     or specify a style in-line")
711     ("LINE TYPE  " 'number " " "lt")
712     ("LINE WIDTH " 'number " " "lw")
713     ("POINT TYPE " 'number " " "pt")
714     ("POINT STYLE" 'number " " "ps")
715     ))
716 (defconst gnuplot-gui-splot-simple-list
717   '(("DATA FILE"   'file   " ")
718     ("TITLE"       'string " ")
719     ("WITH"        'list* " " "lines" "linespoints" "points" "dots" "impulses")))
720 (defconst gnuplot-gui-splot-full-list
721   '(;;("U RANGE"     'range (" " . " ") ":")
722     ;;("V RANGE"     'range (" " . " ") ":")
723     ("X RANGE"     'range (" " . " ") ":")
724     ("Y RANGE"     'range (" " . " ") ":")
725     ("Z RANGE"     'range (" " . " ") ":")
726     ("xa"          'text   "\t---------------------")
727     ("FUNCTION"    'string " ")
728     ("xc"          'text   "   or")
729     ("DATA FILE"   'file   " ")
730     ("INDEX"       'modifier " ")
731     ("EVERY"       'modifier " ")
732     ("THRU"        'string* " " "thru")
733     ("USING"       'modifier " ")
734     ("SMOOTH"      'list* " " "unique" "csplines" "acsplines"
735      "bezier" "sbezier")
736     ("TITLE"       'string " ")
737     ("NOTITLE"     'list   " " "notitle")
738     ("WITH"        'list* " " "lines" "linespoints" "points" "dots" "impulses")))
739 (defconst gnuplot-gui-fit-simple-list
740   '(("FUNCTION"     'string* " " "")
741     ("DATA FILE"    'file    " ")
742     ("VIA (params)" 'string* " " "via") ))
743 (defconst gnuplot-gui-fit-full-list
744   '(("X RANGE"      'range  (" " . " ") ":")
745     ("Y RANGE"      'range  (" " . " ") ":")
746     ("xa"           'text    "----- fitting functionn and file --------")
747     ("FUNCTION"     'string* " " "")
748     ("DATA FILE"    'file    " ")
749     ("xb"           'text    "----- datafile modifiers ----------------")
750     ("INDEX"        'modifier " ")
751     ("EVERY"        'modifier " ")
752     ("THRU"         'string* " " "thru")
753     ("USING"        'modifier " ")
754     ("SMOOTH"       'list* " " "unique" "csplines" "acsplines"
755      "bezier" "sbezier")
756     ("xc"           'text    "----- parameters (file or parameters) ---")
757     ("VIA (file)"   'string  " " "via")
758     ("VIA (params)" 'string* " " "via") ))
759
760 (defvar gnuplot-gui-plot-splot-fit nil
761   "Associated list of plot, splot, and fit descriptions.
762 See the doc-string for `gnuplot-gui-all-types'.")
763 (setq gnuplot-gui-plot-splot-fit
764       (list (cons "plot"  (if (equal gnuplot-gui-plot-splot-fit-style 'complete)
765                               gnuplot-gui-plot-full-list
766                             gnuplot-gui-plot-simple-list))
767             (cons "splot" (if (equal gnuplot-gui-plot-splot-fit-style 'complete)
768                               gnuplot-gui-splot-full-list
769                             gnuplot-gui-splot-simple-list))
770             (cons "fit"   (if (equal gnuplot-gui-plot-splot-fit-style 'complete)
771                               gnuplot-gui-fit-full-list
772                             gnuplot-gui-fit-simple-list))) )
773
774
775 (defvar gnuplot-gui-test-type nil)
776 (setq gnuplot-gui-test-type
777       (list (cons "test"
778                   '(("TAG"      'tag      " ")
779                     ("LIST"     'list     " " "1" "2" "3")
780                     ("LIST*"    'list*    " " "1" "2" "3")
781                     ("NUMBER"   'number   " " "number")
782                     ("RANGE"    'range   (" " . " ") ":")
783                     ("PAIR"     'pair    (" " . " ") "pair")
784                     ("LABELS"   'labels   ())
785                     ("FILE"     'file     " ")
786                     ("TEXT"     'text     "this is text")
787                     ("STRING"   'string   " ")
788                     ("STRING*"  'string*  " " "string*")
789                     ("FORMAT"   'format   " ")
790                     ("POSITION" 'position " " "at" 3)
791                     ("FONTSIZE" 'fontsize " ") ))))
792
793 (defvar gnuplot-gui-all-types nil
794     "Associated list of terminal, set option, and command arguments.
795
796 Each entry in the list is a cons cell of the form
797       (OPTION . ALIST)
798 where OPTION is one of the recognized options in Gnuplot, either a
799 command, something that is set, or a terminal type.  Only those
800 commands, set options, and terminal types that actually take arguments
801 are in this associated list.
802
803 ALIST is itself an associated list where each entry is of the form:
804
805       (TAG TYPE DEFAULT REST)
806
807 TAG is the name used on the widget and indicates one of the options
808 for this command, set option, or terminal type.
809
810 TYPE is one of
811      'list       a menu-list of strings
812      'list*      a menu-list of strings with a prefix
813      'number     a number with an optional prefix
814      'tag        like number but must be the first argument
815      'fontsize   like number but must be the last argument
816      'range      a pair of numbers like [#,#] or [#:#]
817      'pair       a pair of numbers with no punctuation and a prefix
818      'file       a quoted string and a file browser
819      'string     a quoted string with an optional prefix
820      'string*    an unquoted string with a prefix
821      'format     a quoted string and an info-link to (gnuplot)format
822      'labels     an array as needed for xtics, ytics, etc
823      'position   2 or 3 comma separated numbers with an optional prefix
824
825 DEFAULT is the default value for this option.  Note that the default
826 for 'range and 'pair is a cons cell and the default for 'labels is a
827 list.  For most things, the best choice of DEFAULT is a string of
828 white space or a cons cell of two strings of white space.  Strings of
829 white space are better defaults than empty strings or nil.
830
831 The value of REST depends upon TYPE:
832
833   For 'list &    REST is the list of options that will go into the
834       'list*       menu-button.  This can also be a symbol which
835                    evaluates to a list containing the options to go into
836                    the menu-button.  This list variable must contain the
837                    DEFAULT.
838   For 'number    REST is the prefix string (if it exists) for that number.
839   For 'range     REST is the separator, \":\" for plot ranges and
840                    \",\" for plot dimensions (see for example the tgif
841                    terminal type)
842   For 'string &  REST may a number denoting the width of the editable-text
843       'string*     field or it may be a string denoting a prefix.  By
844                    default, the width is half the width of the frame
845                    and there is no prefix.  It may be useful to
846                    specify \"1\" when the input is a single character
847                    as in 'set missing'.
848   For 'file      REST determines the label placed before the file insertion
849                    field.  If non-nil, then TAG is used.  If nil, then
850                    the default \"File\" is used.
851   For 'position  REST is the prefix and the number of comma separated numbers
852   For others     REST is not used.
853
854 Here is an example entry for the png terminal type:
855
856   (cons \"png\"
857         '((\"SIZE\"  'list \" \" \"small\" \"medium\" \"large\")
858           (\"COLOR\" 'list \" \" \"monochrome\" \"gray\" \"color\")))
859
860 This alist is formed at load time by appending together
861 `gnuplot-gui-terminal-types', `gnuplot-gui-set-types' and
862 `gnuplot-gui-command-types'.")
863
864 (setq gnuplot-gui-all-types (append gnuplot-gui-terminal-types
865                                     gnuplot-gui-set-types
866                                     gnuplot-gui-command-types
867                                     gnuplot-gui-plot-splot-fit
868                                     gnuplot-gui-test-type
869                                     ))
870
871
872 (defun gnuplot-gui-swap-simple-complete ()
873   (interactive)
874   (setq gnuplot-gui-plot-splot-fit-style
875         (if (equal gnuplot-gui-plot-splot-fit-style 'complete)
876             'simple 'complete))
877   (if (equal gnuplot-gui-plot-splot-fit-style 'complete)
878       (progn
879         (setcdr (assoc "plot"  gnuplot-gui-all-types) gnuplot-gui-plot-full-list)
880         (setcdr (assoc "splot" gnuplot-gui-all-types) gnuplot-gui-splot-full-list)
881         (setcdr (assoc "fit"   gnuplot-gui-all-types) gnuplot-gui-fit-full-list))
882     (setcdr (assoc "plot"  gnuplot-gui-all-types) gnuplot-gui-plot-simple-list)
883     (setcdr (assoc "splot" gnuplot-gui-all-types) gnuplot-gui-splot-simple-list)
884     (setcdr (assoc "fit"   gnuplot-gui-all-types) gnuplot-gui-fit-simple-list))
885   (message "Using %s lists for plot, splot, and fit."
886            gnuplot-gui-plot-splot-fit-style) )
887
888
889
890 \f
891 ;;; user interface to the widget-y stuff
892
893 (defun gnuplot-gui-mouse-set (event)
894   "Use the mouse to begin setting options using a GUI interface.
895 EVENT is a mouse event.  Bound to \\[gnuplot-gui-mouse-set]
896 Note that \"plot\", \"splot\", \"fit\", and \"cntrparam\" are not
897 currently supported."
898   (interactive "@e")
899   (when (fboundp 'widget-create)
900     (save-excursion
901       (mouse-set-point event)
902       (gnuplot-gui-set-options-and-insert))))
903
904 (defun gnuplot-gui-get-frame-param (param)
905   (if gnuplot-xemacs-p
906       (plist-get gnuplot-gui-frame-plist param)
907     (cdr (assoc param gnuplot-gui-frame-parameters))))
908 (defun gnuplot-gui-set-frame-param (param value)
909   (if gnuplot-xemacs-p
910       (plist-put gnuplot-gui-frame-plist param value)
911     (setcdr (assoc param gnuplot-gui-frame-parameters) value)))
912
913 (defun gnuplot-gui-set-options-and-insert ()
914   "Insert arguments using a GUI interface.
915 Determine contents of current line and set up the appropriate GUI
916 frame.  Bound to \\[gnuplot-gui-set-options-and-insert]
917 Note that \"cntrparam\" is not currently supported."
918   (interactive)
919   (when (fboundp 'widget-create)
920     (let ((begin  (save-excursion (beginning-of-line) (point-marker)))
921           (end    (save-excursion (end-of-line)       (point-marker)))
922           (termin (concat "\\(,\\s-*" (regexp-quote "\\") "\\|;\\)"))
923           (set nil) (term nil))
924       (save-excursion
925         ;; there can be more then one command per line
926         (if (search-backward ";" begin "to_limit")
927             (progn (forward-char  1) (setq begin (point-marker))))
928         (if (re-search-forward termin end "to_limit")
929             (progn (backward-char (length (match-string 1)))
930                    (setq end (point-marker))))
931         (goto-char begin)
932         (skip-syntax-forward "-" end)
933         ;; various constructions are recognized here. at the end of this
934         ;; cond, point should be just after the word whose arguments are
935         ;; to be set
936         (cond ((looking-at "set\\s-+")
937                (setq set t)
938                (goto-char (match-end 0))
939                (if (looking-at "\\sw+") (goto-char (match-end 0)))
940                (when (string-match "^ter" (gnuplot-this-word)) ; terminal?
941                  (setq term t)
942                  (forward-word 1))
943                (when (string-match "^\\(da\\|fu\\)" (gnuplot-this-word))
944                  (unless (looking-at "\\s-+st")
945                    (insert " style") (forward-word 1))
946                  (forward-word 1)))
947               ((looking-at (concat "\\(cd\\|ca\\|lo\\|pa\\|pr\\|sa\\|u\\)"
948                                    "\\w*"
949                                    "[\\s-\\']"))
950                (forward-word 1))
951               ;;(goto-char (match-end 0)))
952               (t
953                (forward-word 1)))
954         (if (> (point) end) (goto-char end))
955         (let* ((w (gnuplot-this-word))
956                (wd (try-completion w gnuplot-gui-all-types))
957                (word "") wrd list)
958           (cond ((equal wd t)                     (setq word w))
959                 ((equal wd nil)                   (setq word w))
960                 ((assoc wd gnuplot-gui-all-types) (setq word wd))
961                 (t                                (setq wd nil)))
962           (cond ((equal (string-match "^\\s-*$" w) 0)
963                  (message "Blank line"))
964                 ((and wd (stringp word))
965                  (gnuplot-gui-correct-command word set term begin)
966                  (setq gnuplot-gui-alist nil
967                        gnuplot-gui-current-string
968                        (buffer-substring-no-properties (point) end))
969                  (gnuplot-gui-set-alist word gnuplot-gui-current-string)
970                  (let* ((old-height (gnuplot-gui-get-frame-param 'height))
971                         (old-top    (gnuplot-gui-get-frame-param 'top)))
972                    (when (or
973                           (and (equal gnuplot-gui-plot-splot-fit-style 'complete)
974                                (member* word '("plot" "splot" "fit")
975                                         :test 'string=))
976                           (equal word "test"))
977                      (gnuplot-gui-set-frame-param 'height 32)
978                      (gnuplot-gui-set-frame-param 'top    50))
979                    (gnuplot-gui-prompt-for-frame word)
980                    (when (or
981                           (and (equal gnuplot-gui-plot-splot-fit-style 'complete)
982                                (member* word '("plot" "splot" "fit")
983                                         :test 'string=))
984                           (equal word "test"))
985                      (gnuplot-gui-set-frame-param 'height old-height)
986                      (gnuplot-gui-set-frame-param 'top    old-top)) ))
987                 ((setq wrd (car (all-completions w '(("cntrparam")))))
988                  (message
989                   "Setting arguments for %S is currently unsuported in gnuplot-mode"
990                   wrd))
991                 ((setq list (all-completions w gnuplot-gui-all-types))
992                  (message "%S could be one of %S" w list))
993                 (t
994                  (message
995                   "%S is not a gnuplot command which takes options" w)))) ))))
996
997 (defun gnuplot-gui-toggle-popup ()
998   (interactive)
999   (setq gnuplot-gui-popup-flag (not gnuplot-gui-popup-flag))
1000   (message (if gnuplot-gui-popup-flag
1001                "Argument popup will appear after insertions."
1002              "Argument popup will no longer appear after insertions.")))
1003
1004
1005 (defun gnuplot-gui-y-n (foo))
1006 (if gnuplot-xemacs-p
1007     (defalias 'gnuplot-gui-y-n 'y-or-n-p-maybe-dialog-box)
1008   (defalias 'gnuplot-gui-y-n 'y-or-n-p))
1009
1010 (defun gnuplot-gui-correct-command (word set term begin)
1011   "Check syntax of set command and terminal specifications.
1012 WORD is the item being set. SET and TERM are non-nil if the words
1013 \"set\" and \"terminal\" were found preceding WORD in the buffer.
1014 BEGIN is the beginning of the command."
1015   (save-excursion
1016     (cond ((assoc word gnuplot-gui-terminal-types)
1017            (when (and (not (and set term))
1018                       (gnuplot-gui-y-n
1019                        (format
1020                         "%S must be preceded by \"set terminal\".  Add it? "
1021                         word)))
1022              (backward-word 1)
1023              (let ((e (point-marker)))
1024                (goto-char begin)
1025                (skip-syntax-forward "-" e)
1026                (delete-region (point) e)
1027                (insert "set terminal "))))
1028           ((assoc word gnuplot-gui-set-types)
1029            (when (and (not set)
1030                       (gnuplot-gui-y-n
1031                        (format
1032                         "%S must be preceded by \"set\".  Add \"set\"? " word)))
1033              (backward-word 1)
1034              (let ((e (point-marker)))
1035                (goto-char begin)
1036                (skip-syntax-forward "-" e)
1037                (delete-region (point) e)
1038                (insert "set "))))))
1039   (message nil))
1040
1041
1042 \f
1043 ;;; handle the actual arguments
1044
1045 (defun gnuplot-gui-fix-arg-list (list)
1046   "Correct the result of splitting `gnuplot-gui-current-string'.
1047 LIST is the split string.  This removes empty and all-blank strings
1048 from the list and concatenates the strings that are part of a quoted
1049 argument, for example an axis label or a font name.  It also replaces
1050 bounding single quotes with double quotes, since double quotes are
1051 used in `gnuplot-gui-all-types'."
1052   (let (fixed-list quote quoted)        ; remove blanks
1053     (setq list (remove* "\\s-+" list :test 'string-match)
1054           list (remove* ""      list :test 'string=))
1055     (while list                         ; concatinate parts of quoted string
1056       (if (not (string-match "^\\([\]\[()'\"]\\)" (car list)))
1057           (setq fixed-list (append fixed-list (list (car list))))
1058         (setq quote (match-string 1 (car list))
1059               quoted (car list))
1060         (if (string= quote "[") (setq quote "]"))
1061         (if (string= quote "(") (setq quote ")"))
1062         (while (and list
1063                     (or (equal (length quoted) 1)
1064                         (not (string-match (concat (regexp-quote quote) "$")
1065                                            quoted))))
1066           (setq quoted (concat quoted " " (cadr list))
1067                 list (cdr list)))
1068         (if (string= quote "'")
1069             (setq quoted (concat "\"" (substring quoted 1))
1070                   quoted (concat (substring quoted 0 -1) "\"")))
1071         (setq fixed-list (append fixed-list (list quoted))))
1072       (setq list (cdr list)) )
1073     fixed-list))
1074
1075 (defun gnuplot-gui-set-alist (word string)
1076   "Set defaults for arguments, using text from buffer if appropriate.
1077 WORD is the Gnuplot expression whose arguments are being set.  STRING
1078 is text from the buffer containing the previous values for WORD's
1079 arguments."
1080   (let ((alist    (cdr (assoc word gnuplot-gui-all-types)))
1081         (arg-list (gnuplot-gui-fix-arg-list (split-string string)) ))
1082     ;; arg-list contains the arguments taken from the buffer
1083     (setq gnuplot-gui-alist nil)
1084     (while alist
1085       (let* ((list      (car alist))
1086              (tag       (gnuplot-gui-type-tag     list))
1087              (symbol    (eval (gnuplot-gui-type-symbol list)))
1088              (default   (gnuplot-gui-type-default list))
1089              (prefix    (gnuplot-gui-type-prefix  list))
1090              (values    (gnuplot-gui-type-list    list))
1091              (this-cons (cond ((stringp default) (cons tag default))
1092                               ((consp default) ; set cons valued default w/care
1093                                (cons tag (cons (car default) (cdr default))))
1094                               (t (cons tag default))))
1095              (temp-list arg-list) )
1096         ;;(message "%S" temp-list)      ; want to lop values off arg-list
1097                                         ; as they are found
1098         (if (symbolp (cadr values))
1099           (setq values (symbol-value (cadr values))))
1100         ;; check if an argument of this type is in arg-list
1101         ;; set the current cons cell if it is
1102         (while temp-list
1103           (cond
1104            ;; ---------------------------- list
1105            ((member* symbol '(list list*) :test 'equal)
1106             (let* ((case-fold-search nil)
1107                    (match-cons (member* (concat "^" (car temp-list))
1108                                         values :test 'string-match)))
1109               (if (and (car match-cons) ; " " may be first elem. of list
1110                        (not (string= " " (car match-cons))))
1111                   (setq this-cons (cons tag (car match-cons))
1112                         arg-list (remove* (car temp-list) arg-list
1113                                           :test 'string= :count 1)
1114                         temp-list nil)
1115                 (setq temp-list (cdr temp-list)))))
1116            ;; ---------------------------- tag (first number in list)
1117            ((equal symbol 'tag)
1118             (if (string-match "^[-0-9.]+$" (car arg-list))
1119                 (setq this-cons (cons  tag (car arg-list))
1120                       temp-list nil)
1121               (setq temp-list (cdr temp-list))) )
1122            ;; ---------------------------- fontsize (last number in list)
1123            ((equal symbol 'fontsize)
1124             (if (string-match "^[-0-9.]+$" (car (last arg-list)))
1125                 (setq this-cons (cons  tag (car (last arg-list)))
1126                       temp-list nil)
1127               (setq temp-list (cdr temp-list))) )
1128            ;; ---------------------------- number with prefix
1129            ((equal symbol 'number)
1130             (cond ((and (string= prefix (car temp-list))
1131                         (string-match "^[-0-9.]+$" (cadr temp-list)))
1132                    (setq this-cons (cons tag (cadr temp-list))
1133                          arg-list (remove* (car temp-list) arg-list
1134                                            :test 'string= :count 1)
1135                          arg-list (remove* (cadr temp-list) arg-list
1136                                            :test 'string= :count 1)
1137                          temp-list nil))
1138                   ;; --------------------- number without prefix
1139                   ((and (not prefix)
1140                         (string-match "^[-0-9.]+$" (car temp-list)))
1141                    (setq this-cons (cons tag (car temp-list))
1142                          arg-list (remove* (car temp-list) arg-list
1143                                            :test 'string= :count 1)
1144                          temp-list nil))
1145                   (t
1146                    (setq temp-list (cdr temp-list)))))
1147            ;; ---------------------------- pair with prefix
1148            ((equal symbol 'pair)
1149             (if (and (string= prefix (car temp-list))
1150                      (string-match "^[-0-9.]+$" (cadr temp-list)))
1151                 (let ((this-car (cadr temp-list))
1152                       (this-cdr (if (string-match "^[-0-9.]+$" (caddr temp-list))
1153                                     (caddr temp-list) "")))
1154                   (setq this-cons (cons tag (cons this-car this-cdr))
1155                         temp-list nil))
1156               (setq temp-list (cdr temp-list))))
1157            ;; ---------------------------- range
1158            ((equal symbol 'range)
1159             (if (string-match (concat "\\[\\s-*" ; opening bracket
1160                                       "\\([^:, \t]*\\)" ; first argument
1161                                       "\\s-*[:,]\\s-*" ; separator
1162                                       "\\([^\] \t]*\\)" ; second argument
1163                                       "\\s-*\\]") ; closing bracket
1164                               (car temp-list))
1165                 (setq this-cons
1166                       (cons tag (cons (match-string 1 (car temp-list))
1167                                       (match-string 2 (car temp-list))))
1168                       arg-list (remove* (car temp-list) arg-list
1169                                         :test 'string= :count 1)
1170                       temp-list nil)
1171               (setq temp-list (cdr temp-list)) ))
1172            ;; ---------------------------- labels
1173            ((equal symbol 'labels)
1174             (if (string-match (concat "(" ; opening paren
1175                                       "\\([^\)]*\\)" ; string
1176                                       ")") ; closing paren
1177                               (car temp-list))
1178                 (let* ((list (split-string (car temp-list) "[ \t(),]+"))
1179                        (list (remove* "" list :test 'string=))
1180                        (return ()))
1181                   (while list
1182                     (if (string-match "['\"]\\([^'\"]*\\)['\"]" (car list))
1183                         (setq return (append return
1184                                              (list (match-string 1 (car list))))
1185                               list (cdr list)
1186                               return (append return (list (car list))) )
1187                       (setq return (append return (list "" (car list)))))
1188                     (setq list (cdr list)) )
1189                   (setq this-cons (cons tag return)
1190                         arg-list (remove* (car temp-list) arg-list
1191                                           :test 'string= :count 1)
1192                         temp-list nil))
1193               (setq temp-list (cdr temp-list))) )
1194            ;; ---------------------------- string, file, format
1195            ((member* symbol '(string file format) :test 'equal)
1196             (if (string-match (concat "['\"]" ; opening quote
1197                                       "\\([^'\"]*\\)" ; string
1198                                       "['\"]") ; closing quote
1199                               (car temp-list))
1200                 (setq this-cons (cons tag (match-string 0 (car temp-list)))
1201                       arg-list (remove* (car temp-list) arg-list
1202                                         :test 'string= :count 1)
1203                       temp-list nil)
1204               (setq temp-list (cdr temp-list)) ))
1205            ;; ---------------------------- string*
1206            ((equal symbol 'string*)
1207             (if (string= prefix (car temp-list))
1208                 (setq this-cons (cons tag (cadr temp-list))
1209                       arg-list (remove* (car temp-list) arg-list
1210                                         :test 'string= :count 1)
1211                       arg-list (remove* (cadr temp-list) arg-list
1212                                         :test 'string= :count 1)
1213                       temp-list nil)
1214               (setq temp-list (cdr temp-list)) ) )
1215            ;; ---------------------------- other or unknown
1216            (t
1217             (setq temp-list nil))
1218            ))
1219         (setq gnuplot-gui-alist
1220               (append gnuplot-gui-alist (list this-cons))))
1221       (setq alist (cdr alist))) ))
1222
1223
1224 (defun gnuplot-gui-post-process-alist (type)
1225   "A few types need some additional processing.
1226 'range, 'pair, and 'labels are cons or list valued and need to b made
1227 into strings.  This is called right before inserting the arguments
1228 into the buffer.  TYPE is the object whose arguments are being set."
1229   (let ((alist gnuplot-gui-alist)
1230         (types (cdr (assoc type gnuplot-gui-all-types))) )
1231     (while alist  ;; loop thru alist looking for tyeps needing post-processing
1232       (let* ((list   (assoc (caar alist) types))
1233              (value  (cdr (assoc (caar alist) gnuplot-gui-alist)))
1234              (prefix (gnuplot-gui-type-prefix list))
1235              (symb   (gnuplot-gui-type-symbol list)) )
1236         (cond
1237          ;;-------------------------- flat text
1238          ((equal (eval symb) 'text)
1239           (setcdr (assoc (caar alist) gnuplot-gui-alist) ""))
1240          ;;-------------------------- range [#:#] or [#,#]
1241          ((equal (eval symb) 'range)
1242           (if (and (string-match "^\\s-*$" (car value))
1243                    (string-match "^\\s-*$" (cdr value)))
1244               (setcdr (assoc (caar alist) gnuplot-gui-alist) "")
1245             (setcdr (assoc (caar alist) gnuplot-gui-alist)
1246                     (concat "[" (car value) prefix (cdr value) "]")) ) )
1247          ;;-------------------------- pair
1248          ((equal (eval symb) 'pair)
1249           (if (and (string-match "^\\s-*$" (car value))
1250                    (string-match "^\\s-*$" (cdr value)))
1251               (setcdr (assoc (caar alist) gnuplot-gui-alist) "")
1252             (setcdr (assoc (caar alist) gnuplot-gui-alist)
1253                     (concat prefix " " (car value) " " (cdr value) )) ) )
1254          ;;-------------------------- labels
1255          ((equal (eval symb) 'labels)
1256           (if (consp value)
1257               (let ((word "") (list value))
1258                 (while list
1259                   (if (string-match "^\\s-*$" (car list))
1260                       (setq word (concat word (format "%s, " (cadr list))))
1261                     (setq word (concat word (format "%S %s, " (car list)
1262                                                     (cadr list)))))
1263                   (setq list (cddr list)) )
1264                 (setq value (concat "(" (substring word 0 -2) ")")))
1265             (setq value "") )
1266           (setcdr (assoc (caar alist) gnuplot-gui-alist) value) ))
1267
1268         (setq alist (cdr alist))) )))
1269
1270 \f
1271 ;;; GUI frames
1272
1273 (defun gnuplot-gui-prompt-for-frame (&optional option save-frame)
1274   (setq option (or option (completing-read "Option: " gnuplot-gui-all-types
1275                                            nil t nil t)))
1276   (gnuplot-gui-make-frame
1277    option (cdr (assoc option gnuplot-gui-all-types)) save-frame) )
1278
1279
1280 (defface gnuplot-gui-error-face '((((class color) (background light))
1281                                   (:foreground "grey30"))
1282                                  (((class color) (background dark))
1283                                   (:foreground "grey70")))
1284   "Face used to display message about unknown widget types."
1285   :group 'gnuplot-faces)
1286
1287 (defface gnuplot-gui-flat-text-face '((((class color) (background light))
1288                                        (:foreground "MediumBlue"))
1289                                       (((class color) (background dark))
1290                                        (:foreground "LightSteelBlue")))
1291   "Face used to display message about unknown widget types."
1292   :group 'gnuplot-faces)
1293
1294 (defun gnuplot-gui-make-frame (item alist &optional save-frame)
1295   "Open the frame and populate it with widgets.
1296 ITEM is the object for which arguments are being set.  ALIST is
1297 the alist of arguments for ITEM taken from `gnuplot-gui-all-types'.
1298 SAVE-FRAME is non-nil when the widgets are being reset."
1299   (unless save-frame
1300     (setq gnuplot-current-frame (selected-frame)
1301           gnuplot-current-buffer (current-buffer)
1302           gnuplot-current-buffer-point (point-marker))
1303     (unless (and gnuplot-gui-frame (frame-live-p gnuplot-gui-frame))
1304       (setq gnuplot-gui-frame (if gnuplot-xemacs-p
1305                                   (make-frame gnuplot-gui-frame-plist)
1306                                 (make-frame gnuplot-gui-frame-parameters))))
1307     (select-frame gnuplot-gui-frame)
1308     ;;(set-frame-position gnuplot-gui-frame 150 150) ;; so herky-jerky
1309     (if gnuplot-xemacs-p
1310         (set-mouse-position (selected-window) 0 0)
1311       (set-mouse-position gnuplot-gui-frame 0 0)))
1312   (kill-buffer (get-buffer-create "*Gnuplot GUI*"))
1313   (switch-to-buffer (get-buffer-create "*Gnuplot GUI*"))
1314   (kill-all-local-variables)
1315   (if gnuplot-xemacs-p
1316       (progn
1317         (set (make-local-variable 'frame-title-format)
1318              "Set Gnuplot Options")
1319         (set (make-local-variable 'frame-icon-title-format)
1320              "Set Gnuplot Options"))
1321     (modify-frame-parameters (selected-frame)
1322                              '((title . "Set Gnuplot Options"))) )
1323   (widget-insert "\nSet options for \"" item "\"  ")
1324   (let (tag help val)
1325     (cond ((string-match "^[xyz]2?tics" item)
1326            (setq tag  "info on tic labels"
1327                  help "Open a frame displaying the info entry for tic labels"
1328                  val  "xtics"))
1329           ((string-match "^no" item)
1330            (setq tag  (concat "info on " (substring item 2))
1331                  help (format "Open a frame displaying the info entry for %S"
1332                               item)
1333                  val  item))
1334           (t
1335            (setq tag  (concat "info on " item)
1336                  help (format "Open a frame displaying the info entry for %S"
1337                               item)
1338                  val  item)))
1339     (widget-create 'gnuplot-gui-info-link :tag tag :help-echo help :value val))
1340
1341   (widget-insert "\n\n")
1342   (while alist
1343     (let* ((this    (car   alist))
1344            (tag     (gnuplot-gui-type-tag    this))
1345            (wtype   (gnuplot-gui-type-symbol this))
1346            (prefix  (gnuplot-gui-type-prefix this))
1347            (default (cdr (assoc tag gnuplot-gui-alist)))
1348            (list    (gnuplot-gui-type-list   this)))
1349       (if (symbolp (cadr list))
1350           (setq list (symbol-value (cadr list))))
1351       (widget-insert "\t")              ; insert the appropriate widget
1352       (cond
1353        ;;------------------------------ list, list* ------------
1354        ((member* (eval wtype) '(list list*) :test 'equal)
1355         (let ((starred (if (equal (eval wtype) 'list*) t nil)))
1356           (gnuplot-gui-menu-choice tag default list starred)))
1357        ;;------------------------------ number, tag, fontsize --
1358        ((member* (eval wtype) '(number tag fontsize) :test 'equal)
1359         (gnuplot-gui-number tag default prefix))
1360        ;;------------------------------ position ---------------
1361        ;;------------------------------ range, pair ------------
1362        ((member* (eval wtype) '(range pair) :test 'equal)
1363         (let ((is-range (equal (eval wtype) 'range)))
1364           (gnuplot-gui-range tag default prefix is-range)))
1365        ;;------------------------------ string, string* --------
1366        ((member* (eval wtype) '(string string*) :test 'equal)
1367         (let ((starred (if (equal (eval wtype) 'string) nil t)))
1368           (gnuplot-gui-string tag default prefix starred)))
1369        ;;------------------------------ format -----------------
1370        ((equal (eval wtype) 'format)
1371         (gnuplot-gui-format tag default))
1372        ;;------------------------------ file -------------------
1373        ((equal (eval wtype) 'file)
1374         (gnuplot-gui-file tag default prefix))
1375        ;;------------------------------ labels -----------------
1376        ((equal (eval wtype) 'labels)
1377         (gnuplot-gui-labels tag default))
1378        ;;------------------------------ text -------------------
1379        ((equal (eval wtype) 'text)
1380         (let ((str (gnuplot-gui-type-default this)))
1381           (put-text-property 0 (length str) 'face 'gnuplot-gui-flat-text-face str)
1382           (widget-insert str "\n")))
1383        ;;------------------------------ unknown ----------------
1384        (t
1385         (let ((str (concat "<" (downcase tag) "> ('"
1386                            (symbol-name (eval wtype))
1387                            " arguments are not yet supported)\n")))
1388           (put-text-property 0 (length str) 'face 'gnuplot-gui-error-face str)
1389           (widget-insert str)) )))
1390     (setq alist (cdr alist)))
1391   ;; insert control buttons: [Set options]   [Reset]   [Clear]   [Cancel]
1392   (widget-insert "\n\t")
1393   (widget-create 'push-button
1394                  :value "Set options"
1395                  :doc item
1396                  :button-face 'gnuplot-gui-button-face
1397                  :help-echo "Push this button to set options"
1398                  :notify
1399                  (lambda (widget &rest ignore)
1400                    (kill-buffer (get-buffer-create "*Gnuplot GUI*"))
1401                    (delete-frame)
1402                    (select-frame gnuplot-current-frame)
1403                    (switch-to-buffer gnuplot-current-buffer)
1404                    (goto-char gnuplot-current-buffer-point)
1405                    (gnuplot-gui-post-process-alist
1406                     (widget-get widget :doc))
1407                    (let ((alist gnuplot-gui-alist) marker
1408                          (eol (save-excursion (end-of-line) (point-marker) )) )
1409                      (if (re-search-forward ";" eol "to_limit")
1410                          (backward-char 1))
1411                      (delete-region gnuplot-current-buffer-point (point-marker))
1412                      (delete-horizontal-space)
1413                      (setq marker (point-marker))
1414                      (while alist
1415                        (let ((val (cdar alist)))
1416                          (if (string-match "^\\s-+$" val) ()
1417                            (if (string-match "^['\"]\\(.*\\)['\"]$" val)
1418                                (setq val (concat gnuplot-quote-character
1419                                                  (match-string 1 val)
1420                                                  gnuplot-quote-character)))
1421                            (insert (format " %s" val))))
1422                        (setq alist (cdr alist)))
1423                      (setq eol (point-marker))
1424                      (goto-char marker)
1425                      (while (< (point) eol) ; a few odd cases
1426                        (unless (looking-at (concat "[" (regexp-quote "(")
1427                                                    (regexp-quote "*") ",]"))
1428                          (just-one-space))
1429                        (forward-sexp)))
1430                    (delete-horizontal-space)
1431                    (if (string= "terminal" (widget-get widget :doc))
1432                        (gnuplot-gui-set-options-and-insert)) ))
1433   (widget-insert "   ")
1434   (widget-create 'push-button :value "Reset"
1435                  :help-echo "Push this button to reset all values"
1436                  :button-face 'gnuplot-gui-button-face
1437                  :doc item
1438                  :notify
1439                  (lambda (widget &rest ignore)
1440                    (let ((word (widget-get widget :doc)))
1441                      (gnuplot-gui-set-alist word gnuplot-gui-current-string)
1442                      (gnuplot-gui-prompt-for-frame word t))))
1443   (widget-insert "   ")
1444   (widget-create 'push-button :value "Clear"
1445                  :help-echo "Push this button to clear all values"
1446                  :button-face 'gnuplot-gui-button-face
1447                  :doc item
1448                  :notify
1449                  (lambda (widget &rest ignore)
1450                    (let* ((word (widget-get widget :doc))
1451                           (alist (cdr (assoc word gnuplot-gui-all-types))))
1452                      (while alist
1453                        (setcdr (assoc (gnuplot-gui-type-tag (car alist))
1454                                       gnuplot-gui-alist)
1455                                (gnuplot-gui-type-default (car alist)))
1456                        (setq alist (cdr alist)))
1457                      (gnuplot-gui-prompt-for-frame word t))) )
1458   (widget-insert "   ")
1459   (widget-create 'push-button :value "Cancel"
1460                  :help-echo "Quit setting options and dismiss frame"
1461                  :button-face 'gnuplot-gui-button-face
1462                  :notify (lambda (widget &rest ignore)
1463                            (kill-buffer (get-buffer-create "*Gnuplot GUI*"))
1464                            (setq gnuplot-gui-alist nil
1465                                  gnuplot-gui-current-string nil)
1466                            (delete-frame)
1467                            (select-frame gnuplot-current-frame)))
1468   (goto-char (point-min))
1469   (use-local-map widget-keymap)
1470   (widget-setup))
1471
1472 \f
1473 ;;; widgets
1474
1475 (defface gnuplot-gui-menu-face '((((class color) (background light))
1476                                   (:bold t :foreground "darkolivegreen"))
1477                                  (((class color) (background dark))
1478                                   (:bold t :foreground "seagreen"))
1479                                  (t
1480                                   (:italic t)))
1481   "Face used for menu-buttons."
1482   :group 'gnuplot-faces)
1483 (defface gnuplot-gui-button-face '((((class color) (background light))
1484                                   (:bold t :foreground "sienna"))
1485                                  (((class color) (background dark))
1486                                   (:bold t :foreground "tan"))
1487                                  (t
1488                                   (:italic t)))
1489   "Face used for push-buttons.
1490 Only used in Emacs.  XEmacs displays push-buttons with a pixmap."
1491   :group 'gnuplot-faces)
1492 (defface gnuplot-gui-labels-face '((((class color) (background light))
1493                                     (:bold t :foreground "darkslateblue"))
1494                                    (((class color) (background dark))
1495                                     (:bold t :foreground "lightslateblue"))
1496                                    (t
1497                                     (:italic t)))
1498   "Face used for insert and delete button in the labels widget."
1499   :group 'gnuplot-faces)
1500
1501 (defun gnuplot-gui-menu-choice (item default list &optional starred)
1502   "Create a menu widget for the Gnuplot GUI.
1503 ITEM is the object whose arguments are set by this widget, DEFAULT
1504 is the default argument value, LIST contains the items for the pop-up
1505 menu.  STARRED is true if this a 'list* widget."
1506   (let ((widget
1507          (apply 'widget-create
1508                 'menu-choice :value default :tag item :doc starred
1509                 :button-face 'gnuplot-gui-menu-face
1510                 :button-prefix "[" :button-suffix "]"
1511                 :help-echo (format "Mouse-2 to view the %S menu" (downcase item))
1512                 :notify
1513                 (lambda (widget &rest ignore)
1514                   (let ((lab (if (widget-get widget :doc)
1515                                  (concat (downcase (widget-get widget :tag)) " ")
1516                                "" )))
1517                     (setcdr (assoc (widget-get widget :tag) gnuplot-gui-alist)
1518                             (if (string= (widget-value widget) " ") ""
1519                               (format "%s%s" lab (widget-value widget))) )))
1520                 (mapcar (lambda (x) (list 'item :value x))
1521                         list))))
1522     (widget-value-set widget default)
1523     (if (and starred (not (string-match "^\\s-*$" default)))
1524         (setcdr (assoc item gnuplot-gui-alist)
1525                 (format "%s %s" (downcase item) default)))
1526     widget))
1527
1528 (defun gnuplot-gui-number (item default &optional prefix)
1529   "Create a number widget for the Gnuplot GUI.
1530 ITEM is the object whose arguments are set by this widget, DEFAULT
1531 is the default value for the widget, PREFIX is a text string preceding
1532 the numerical argument."
1533   (let ((help-label (or prefix (downcase item))))
1534     (widget-insert (capitalize item) ": ")
1535     (widget-create 'editable-field
1536                    :size 2 :tag item :value default :doc prefix
1537                    :help-echo (format "Insert new value of %S here" help-label)
1538                    :notify (lambda (widget &rest ignore)
1539                              (let ((val (widget-value widget))
1540                                    (pre (concat (widget-get widget :doc) " ")))
1541                                (setcdr (assoc (widget-get widget :tag)
1542                                               gnuplot-gui-alist)
1543                                        (if (string-match
1544                                             "^\\s-*[-0-9.*]+\\s-*$" val)
1545                                            (format "%s%s" pre val) "") )))))
1546   (unless (string-match "^\\s-*$" default)
1547     (setcdr (assoc item gnuplot-gui-alist) (format "%s %s" prefix default)))
1548   (widget-insert " " (make-string (- 40 (current-column)) ?.)
1549                  " (numeric value)\n"))
1550
1551 (defun gnuplot-gui-string (item default &optional width_or_prefix starred)
1552   "Create a string widget for the Gnuplot GUI.
1553 ITEM is the object whose arguments are set by this widget, DEFAULT is
1554 the default value for the widget, and WIDTH_OR_PREFIX is the width of
1555 the text entry field (which defaults to half the frame width) or the
1556 prefix for the string.  STARRED is t if quotes are not to be used."
1557   (let ((help-label (downcase item)) width (prefix "") (pp ""))
1558     (cond ((stringp width_or_prefix)
1559            (setq prefix width_or_prefix
1560                  pp prefix)
1561            (if starred (setq prefix (concat prefix "_star"))) )
1562           ((numberp width_or_prefix)
1563            (setq width width_or_prefix)))
1564     (setq width (or width (/ (frame-width) 2)))
1565     (if (string-match "^['\"]" default)
1566         (setq default (replace-match "" nil nil default)))
1567     (if (string-match "['\"]$" default)
1568         (setq default (replace-match "" nil nil default)))
1569     (widget-insert (capitalize item) ": ")
1570     (widget-create
1571      'editable-field
1572      :size width :tag item :doc prefix :value default
1573      :help-echo (format "Insert new value of %S here" help-label)
1574      :notify (lambda (widget &rest ignore)
1575                (let ((val (widget-value widget))
1576                      (q gnuplot-quote-character)
1577                      (p (widget-get widget :doc)) )
1578                  (setcdr (assoc (widget-get widget :tag) gnuplot-gui-alist)
1579                          (if (string-match "^\\s-*$" val)
1580                              ""
1581                            (progn
1582                              (if (string-match "_star$" p)
1583                                  (setq p (concat (substring p 0 -5) " ")
1584                                        q ""))
1585                              (if (string-match "^\\s-+" val)
1586                                  (setq val (replace-match "" nil nil val)))
1587                              (if (string-match "\\s-+$" val)
1588                                  (setq val (replace-match "" nil nil val)))
1589                              (format "%s%s%s%s" p q val q)))))))
1590     (unless (string-match "^\\s-*$" default)
1591       (setcdr (assoc item gnuplot-gui-alist) (format "%s %s" pp default)))
1592     (widget-insert "\n")))
1593
1594 (defun gnuplot-gui-format (item default)
1595   "Create a string widget for the Gnuplot GUI.
1596 ITEM is the object whose arguments are set by this widget, DEFAULT is
1597 the default value for the widget, and WIDTH_OR_PREFIX is the width of
1598 the text entry field (which defaults to half the frame width) or the
1599 prefix for the string."
1600   (if (string-match "^['\"]" default)
1601       (setq default (replace-match "" nil nil default)))
1602   (if (string-match "['\"]$" default)
1603       (setq default (replace-match "" nil nil default)))
1604   (widget-insert (capitalize item) ": ")
1605   (widget-create 'editable-field
1606                  :size (/ (frame-width) 3) :tag item :value default
1607                  :help-echo (format "Insert new format string here")
1608                  :notify (lambda (widget &rest ignore)
1609                            (let ((val (widget-value widget)))
1610                              (setcdr (assoc (widget-get widget :tag)
1611                                             gnuplot-gui-alist)
1612                                      (format "%s%s%s"
1613                                              gnuplot-quote-character
1614                                              val
1615                                              gnuplot-quote-character)))))
1616   (widget-insert "   ")
1617   (widget-create 'gnuplot-gui-info-link
1618                  :tag (concat "info on format")
1619                  :help-echo "Open a frame displaying the info entry for format"
1620                  :value "format")
1621   (widget-insert "\n"))
1622
1623
1624 ;; swiped from widget-color-complete
1625 (defun gnuplot-gui-file-completion (widget)
1626   "Complete the filename in WIDGET."
1627   (let* ((str (buffer-substring-no-properties (widget-field-start widget)
1628                                               (point)))
1629          (file (or (file-name-nondirectory str) ""))
1630          (dir  (or (file-name-directory str) "./"))
1631          (val  (file-name-completion file dir)) )
1632     (cond ((eq val t)
1633            (message "Exact match"))
1634           ((null val)
1635            (error "Can't find completion for \"%s\"" str))
1636           ((not (string-equal str val))
1637            (insert (substring val (length file))))
1638           (t
1639            (message "Making completion list...")
1640            (let ((list (file-name-all-completions file dir)))
1641              (with-output-to-temp-buffer "*Completions*"
1642                (display-completion-list list)))
1643            (message "Making completion list...done")))))
1644
1645 (defun gnuplot-gui-file (item default &optional tag)
1646   "Create a file widget for the Gnuplot GUI.
1647 ITEM is the object whose arguments is set by this widget, DEFAULT is
1648 the default value for the argument.  TAG is non-nil if ITEM rather than
1649 \"File:\" is to be used as the tag."
1650   (setq tag (if tag (capitalize item) "File"))
1651   (if (string-match "^['\"]" default)
1652       (setq default (replace-match "" nil nil default)))
1653   (if (string-match "['\"]$" default)
1654       (setq default (replace-match "" nil nil default)))
1655   (let ((widg (widget-create
1656                'file
1657                :value default :tag tag
1658                :size (- (/ (frame-width) 2) 3)
1659                :doc item :help-echo "Insert a filename here"
1660                :complete 'gnuplot-gui-file-completion
1661                :notify
1662                (lambda (widget &rest ignore)
1663                  (setcdr (assoc (widget-get widget :doc) gnuplot-gui-alist)
1664                          (format "%s%s%s" gnuplot-quote-character
1665                                  (widget-value widget)
1666                                  gnuplot-quote-character)) )) ))
1667     (widget-insert " ")
1668     (widget-create
1669      'push-button :value "Browse"
1670      :doc item :help-echo "Browse directories for a filename."
1671      :parent widg
1672      :notify (lambda (widget &rest ignore)
1673                (let ((fname (file-relative-name (read-file-name "File: ")
1674                                                 default-directory))
1675                      (q gnuplot-quote-character))
1676                  (widget-value-set (widget-get widget :parent) fname)
1677                  (setcdr (assoc (widget-get widget :doc) gnuplot-gui-alist)
1678                          (format "%s%s%s" q fname q))
1679                  (widget-setup))))
1680     (widget-insert "\n")))
1681
1682 (defun gnuplot-gui-labels (item default)
1683   "Create a labels widget for the Gnuplot GUI.
1684 ITEM is the object whose arguments is set by this widget, DEFAULT is
1685 the default value for the argument."
1686   (widget-create
1687    '(editable-list
1688      (list :inline t :tag "Tic label"
1689            (string :tag "label" :size 10
1690                    :help-echo "Enter the tic label here" )
1691            (string :tag "  position" :size 10
1692                    :help-echo "Enter an expression for the tic location here" )))
1693                  :tag (capitalize item)
1694                  :value default
1695                  :format "%{%t%}:\n%v\t  %i\n"
1696                  :entry-format "\t  %i %d %v\n"
1697                  :button-face 'gnuplot-gui-labels-face
1698                  :notify (lambda (widget &rest ignore)
1699                            (setcdr (assoc (upcase (widget-get widget :tag))
1700                                           gnuplot-gui-alist)
1701                                    (widget-value widget)))))
1702
1703 (defun gnuplot-gui-range (item default separator is-range)
1704   "Create a range or pair widget for the Gnuplot GUI.
1705 ITEM is the object whose arguments are set by this widget, DEFAULT is
1706 the default value for the widget, SEPARATOR is a text string preceding
1707 the numerical argument, or the prefix for a pair operator.  IS-RANGE
1708 is non-nil if this is a 'range widget."
1709   (widget-insert (capitalize item) ": ")
1710   (if is-range (widget-insert "["))
1711   (widget-create 'editable-field
1712                  :size 4 :tag item :value (car default)
1713                  :help-echo (format "Insert the first value of the %S here"
1714                                     (downcase item))
1715                  :notify (lambda (widget &rest ignore)
1716                            (setcar (cdr (assoc (widget-get widget :tag)
1717                                                gnuplot-gui-alist))
1718                                    (format "%s" (widget-value widget)))))
1719   (if is-range (widget-insert separator) (widget-insert "  "))
1720   (widget-create 'editable-field
1721                  :size 4 :tag item :value (cdr default)
1722                  :help-echo (format "Insert the second value of the %S here"
1723                                     (downcase item))
1724                  :notify (lambda (widget &rest ignore)
1725                            (setcdr (cdr (assoc (widget-get widget :tag)
1726                                                gnuplot-gui-alist))
1727                                    (format "%s" (widget-value widget)))))
1728   (if is-range (widget-insert "]"))
1729   (widget-insert " " (make-string (- 39 (current-column)) ?.)
1730                  " (numeric values)\n"))
1731
1732
1733 ;; suppress compiler warning
1734 ;;(eval-when-compile (defun gnuplot-info-lookup-symbol (sym mode)))
1735 (define-widget 'gnuplot-gui-info-link 'info-link
1736   "A link to an info file for the Gnuplot GUI."
1737   :action '(lambda (widget &optional event)
1738              (let ((gnuplot-info-display 'frame))
1739                (if gnuplot-keywords-pending             ; <HW>
1740                    (gnuplot-setup-info-look))
1741                (gnuplot-info-lookup-symbol (widget-value widget)
1742                                            'gnuplot-mode))))
1743
1744 \f
1745 ;;; just about done
1746
1747 (provide 'gnuplot-gui)
1748 ;;;============================================================================
1749 ;;;
1750 ;;; gnuplot-gui.el ends here