This file is indexed.

/usr/share/common-lisp/source/mcclim/Apps/Scigraph/scigraph/menu-tools.lisp is in cl-mcclim 0.9.6.dfsg.cvs20100315-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
;;; -*- Syntax: Common-lisp; Package: TOOL -*-
#|
Copyright (c) 1987-1993 by BBN Systems and Technologies,
A Division of Bolt, Beranek and Newman Inc.
All rights reserved.

Permission to use, copy, modify and distribute this software and its
documentation is hereby granted without fee, provided that the above
copyright notice of BBN Systems and Technologies, this paragraph and the
one following appear in all copies and in supporting documentation, and
that the name Bolt Beranek and Newman Inc. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. Any distribution of this software or derivative
works must comply with all applicable United States export control laws.

BBN makes no representation about the suitability of this software for any
purposes.  It is provided "AS IS", without express or implied warranties
including (but not limited to) all implied warranties of merchantability
and fitness for a particular purpose, and notwithstanding any other
provision contained herein.  In no event shall BBN be liable for any
special, indirect or consequential damages whatsoever resulting from loss
of use, data or profits, whether in an action of contract, negligence or
other tortuous action, arising out of or in connection with the use or
performance of this software, even if BBN Systems and Technologies is
advised of the possiblity of such damages.
|#

(in-package :tool)

(eval-when (compile load eval)
  (export '(several-choose choose-character-style window-edit-text string-size)))

(defun string-size (stream style format-string &rest format-args)
  ;; A bad implementation of this can really slow down graph generation.
  (unless (stringp format-string)
    (setq format-string (string format-string)))
  (when format-args
    ;; Typically, the formatter is not needed.
    (setq format-string (apply #'format nil format-string format-args)))
  #+clim-1.0
  (when (eq style clim:*null-text-style*)
    ;; A kludge for sure.  
    (setq style clim:*default-text-style*))
  #+clim
  (let* ((return #.(aref (format nil "~%") 0))
	 (line-cnt (1+ (count return format-string :test #'char=))))
    ;; This is 2-3 times faster than using continuation-output-size.
    (multiple-value-bind (x xmax)
	(stream-string-width stream format-string :text-style style)
      (declare (ignore x))
      (values xmax (* line-cnt (stream-line-height stream style)))))
  #-clim
  (continuation-output-size #'(lambda (s)
				(if style
				    (with-character-style (style s)
				      (format s format-string))
				  (format s format-string)))
			    stream))

;;; These things are needed mainly for annotations, but they are kept in a separate
;;; file to minimize the clutter in the annotations code.

(defun draw-radio-button (stream object text selected-p &optional size)
  (declare (ignore object))
  (or size (setq size (stream-line-height stream)))
  (let* ((rad (values (truncate (- size 2) 2)))
	 (offset rad))
    ;; Since clim insists on flipping the coordinate system...
    #+(or clim-1.0 clim-2) (setq offset (- offset))
;;    #+clim-0.9 (terpri stream)
    (multiple-value-bind (x y) (stream-cursor-position* stream)
      #+clim-0.9
      (stream-set-cursor-position* stream (setq x (+ x size)) y)
      (draw-circle (+ x offset) (+ y offset)
		   rad :stream stream :filled selected-p)
      (if selected-p
	  (with-character-face (:bold stream)
	    (draw-string text (+ x (* size 2))
			 (+ y (* offset 2))
			 :stream stream))
          (draw-string text (+ x (* size 2))
		       (+ y (* offset 2))
		       :stream stream)))))

#+clim-2
(define-presentation-type-abbreviation button-subset (&key alist (test 'equal))
  `(subset-alist ,alist :test ,test))

#+(or (not clim) clim-0.9 clim-1.0)
(define-presentation-type button-subset (&key alist)  
  :parser ((stream)
	   (accept `(sequence (alist-member :alist ,alist))
		   :stream stream :prompt nil))
  :printer ((object stream)
	    (present object `(sequence (alist-member :alist ,alist))
		     :stream stream))
  :typep ((object)
	  (block testem
	    (dolist (element object)
	      (or (find element alist :key #'dwim::menu-execute-no-side-effects)
		  (return-from testem nil)))
	    t))
  :describer ((stream)
	      (write-string "any of " stream)
	      (let (length
		    (name-key #'dwim::token-element-string)
		    (rest-of-elements alist))
		(loop
		  (or rest-of-elements (return))
		  (setq length (length rest-of-elements))
		  (format stream "~A" (funcall name-key (car rest-of-elements)))
		  (cond ((> length 2)
			 (write-string ", " stream))
			((= length 2)
			 (write-string " or " stream))))))
  :accept-values-displayer
  ((stream object query-identifier)
   ;; OBJECT is the currently chosen subset.
   (accept-values-choose-from-sequence
     stream alist object query-identifier
     :select-action
     #'(lambda (new list)
	 (cond ((not (listp list)) (list new))
	       ((member new list)  (remove new list))
	       (t (adjoin new list))))
     :selection-test #'member
     :n-columns 1
     :drawer
     #'(lambda (stream object text selected-p)
	 (draw-radio-button stream object text selected-p)))))

(defun SEVERAL-CHOOSE (ITEM-LIST
		       &key highlighted-values (label "Choose Several")
			    (stream *standard-output*) (own-window t))
  "Lets you select several choices."
  (declare (values choices abort-p))
  ;; Used by choose-descriptors to produce interval annotations.
  ;;
  ;; item-list is a list whose elements are either:
  ;;   a.  atoms
  ;;   b.  lists of length 2 whose CAR is the pretty name and whose CADR is the
  ;;        actual value.
  (labels ((stringify (thing)
	     (typecase thing
	       (string thing)
	       (symbol (symbol-name thing))
	       (otherwise (format nil "~A" thing)))))
    (let ((ptype `(button-subset
		   :alist
		   ,(mapcar #'(lambda (item)
				(if (atom item)
				    (list (stringify item)
					  :value item)
				  (list (stringify (car item))
					:value (cadr item))))
			    item-list))))
      (if (eq :abort
	      (accepting-values (stream :own-window own-window
					:label "Choose")
				(format stream label)
				(terpri stream)
				(setq highlighted-values
				  #+clim-2
				  (accept
				   ptype
				   :default highlighted-values
				   :view
				   '(check-box-view :orientation :vertical)
				   :prompt "Choose Several"
				   :stream stream)
				  #-clim-2
				  (accept ptype
					  :default highlighted-values
					  :prompt "Choose Several"
					  :stream stream))
				(terpri stream)))
	  (values nil t)
	(nreverse highlighted-values)))))

(defun test-chooser ()
  (several-choose '(apples oranges pears)))

(defun character-style-choices (family)
  (mapcar
   #'(lambda (style)
       `(,(apply #'format nil "~A ~A ~A" style)	:value ,style :style ,style))
   (mapcar #'(lambda (face-size) (cons family face-size))
	   (mapcan #'(lambda (size)
		       `((:bold-italic ,size)
			 (:bold ,size)
			 (:italic ,size)
			 (:roman ,size)))
		   '(:very-large :large :normal :small :very-small)))))

(defun CHOOSE-CHARACTER-STYLE ()
  (let* ((family (menu-choose
		  (mapcar #'(lambda (fam)
			      `(,fam :value ,fam :style (,fam :roman :normal)))
			  '(:fix #+clim :serif #-clim :dutch :sans-serif))
		  :prompt "Family"))
	 (style (when family (menu-choose (character-style-choices family)
					  :prompt "Character Styles"))))
    style))

(defvar *EDIT-DELIMITER* #-clim #\end #+clim #\return)
(defvar *min-window-height* 100)
(defvar *min-window-width* 220)

#-clim
(let ((edit-window nil))
  (defun FIND-EDIT-WINDOW (stream)
    (let ((window edit-window))
      (unless window
	(setq window
	      (tv:make-window 'tv:pop-up-text-window
			      :deexposed-typeout-action :permit
			      :more-p nil
			      :save-bits t
			      :superior stream
			      :label (format nil
					     "Edit text (~C or ~C):~%"
					     *edit-delimiter* #\abort) ))
	(setq edit-window window))
      (funcall #'(setf sheet-parent) stream window)	; +++ Unresolved genera problem.
      window)))

#-clim
(defmacro with-edit-window ((symbol superior) &body body)
  `(let ((,symbol (find-edit-window ,superior))) ,@body))

#-clim
(defun WINDOW-EDIT-TEXT (window left top right bottom &optional string)
  "Edit text in the given region of the window."
  (if (> top bottom) (psetq bottom top top bottom))
  (if (> left right) (psetq right left left right))
  (with-edit-window (ed-window window)
    (multiple-value-bind (ml mto mr mb) (scl:send ed-window :margins)
      (let* ((extra-width (+ ml mr (values (truncate (* (- right left) .5)))))
	     (extra-height (+ mto mb (* (stream-line-height ed-window) 2)))
	     width height)
	(setq width (max *min-window-width* (+ (- right left) extra-width)))
	(setq height (max *min-window-height* (+ (- bottom top) extra-height)))
	(change-size ed-window width height)
	(dw::position-window-near-carefully ed-window '(:mouse)))
      (scl:send ed-window :clear-window)
      (tv:with-window-shadowed-for-selection
	((sys:console-selected-window (tv:sheet-console window)) ed-window)
	(tv:window-call (ed-window :deactivate)
	  (scl:with-input-editing-options ((:initial-input string))
	    (scl:read-delimited-string *edit-delimiter* ed-window)))))))

#+clim
(defun WINDOW-EDIT-TEXT (window left top right bottom &optional string)
  "Edit text in the given region of the window."
  ;; This only reads a single line...	  
  ;; Note that clim 0.9 ignores the default string.
  (if (> top bottom) (psetq bottom top top bottom))
  (if (> left right) (psetq right left left right))
  (multiple-value-bind (x y) (stream-cursor-position* window)
    (let* ((prompt "Input a string")
	   (prompt-width (string-size window nil "~A: " prompt))
	   (cursor-x (max 0 (- left prompt-width)))
	   (cursor-y top)
	   string-width)
      (unwind-protect
	  (catch #+clim-0.9 'ci::abort-gesture-seen #-clim-0.9 :abort
	    (stream-set-cursor-position* window cursor-x cursor-y)
	    (with-output-recording-disabled (window)
	      (setq string (accept 'string :stream window :default string
				   :prompt prompt))
	      (setq string-width (string-size window nil string))
	      ;; erase editor typeout
	      (let* ((right (+ cursor-x prompt-width string-width))
		     (bottom (+ top (stream-line-height window)))
		     (rect (make-rectangle* cursor-x top right bottom)))
		(draw-rectangle cursor-x right top bottom
				:stream window
				:filled t
				:alu %erase)
		#-clim-2
		(output-recording-stream-replay window rect)
		#+clim-2
		(stream-replay window rect))
	      ))
	(stream-set-cursor-position* window x y))))
  string)

#+someday
(defun read-note (&optional default-note)
  (with-menu (stream)
    ;; Set up the pop-up window the way we want to see it
    (setf (clim::cursor-visibility (clim::stream-text-cursor stream)) :off)
    (clim::window-set-inside-size  stream
      (* 60 (stream-character-width stream #\Space))
      (* 10 (stream-line-height stream)))
    (write-string "Enter a note:" stream)
    (fresh-line stream)
    (setf (stream-text-margin stream) (bounding-rectangle-width (window-viewport stream)))
    (window-expose stream)
    (unwind-protect
	(with-input-editing (stream)
	  ;; Put the default note into the input buffer and ensure that
	  ;; we never do it again
	  (when default-note
	    (replace-input stream default-note :rescan t)
	    (setq default-note nil))
	  ;; Now get the input from the user
	  (with-activation-characters ('(#\Newline) :override t)
	    (unwind-protect
		(read-token stream)
	      ;; Eat the activation character
	      (read-gesture :stream stream :timeout 0))))
      (setf (clim::cursor-visibility (clim::stream-text-cursor stream)) :inactive))))