;;;-*-Mode:Lisp;Base:8;package:window-maker-*-
;;; Copyright C LISP MACHINE INC., 1985.
;;

(defflavor my-choose-variable-window
  (init-option-list done)
  (tv:function-text-scroll-window
   tv:mouse-sensitive-text-scroll-window
   tv:text-scroll-window
   tv:borders-mixin
   tv:top-label-mixin
   tv:basic-scroll-bar
   tv:flashy-scrolling-mixin
   tv:margin-scroll-mixin
   tv:margin-region-mixin
   tv:margin-choice-mixin
   tv:scroll-stuff-on-off-mixin
   tv:dont-select-with-mouse-mixin
   tv:window)
  (:default-init-plist
    :label '(:string "Specify window attributes" :centered :font fonts:metsi)
    :blinker-p t
    :blinker-deselected-visibility ':off
    :blinker-flavor 'tv:rectangular-blinker
    :deexposed-typeout-action ':permit
    :save-bits t
    :margin-choices '(("Do It" nil CHOICE-DONE nil nil)
		      ("Abort" NIL CHOICE-ABORT NIL NIL))
    :flashy-scrolling-region '((20 0.30 0.70) (20 0.30 0.70))
    :margin-scroll-regions '((:top) (:bottom))
    :scroll-bar-always-displayed t
    :font-map (list fonts:cptfont fonts:cptfontb fonts:tr12 fonts:tr10 fonts:tr10b fonts:tr12b)
    :print-function 'output-line)
  :settable-instance-variables
  :inittable-instance-variables
  :gettable-instance-variables)

(defun choice-done (&rest ignore)
  (DECLARE (:SELF-FLAVOR my-choose-variable-window))
  (SETQ	init-option-list
	(loop for i from 0 to (ARRAY-ACTIVE-LENGTH tv:ITEMS)
	      with return-list = NIL
	      as item = (aref tv:items i)
	      do
	      (selectq item
		(*name* (update-list return-list (if (and (boundp '*name*) *name*)
						     *name* (gentemp 'unspecified-pane-name))))
		(*label* (if (boundp '*label*) (nconc return-list (list ':label *label*))))
		(*type* (update-list return-list (or *type* 'tv:window)))
		(*blinker-p* (nconc return-list (list ':blinker-p *blinker-p*)))
		(*save-bits* (nconc return-list (list ':save-bits *save-bits*)))
		(*blinker-flavor* (nconc return-list (list ':blinker-flavor *blinker-flavor*)))
		(*blinker-deselected-visibility*
		  (nconc return-list (list ':blinker-deselected-visibility *blinker-deselected-visibility*)))
		(*deexposed-typeout-action* (nconc return-list (list ':deexposed-typeout-action *deexposed-typeout-action*)))
		(*deexposed-typein-action* (nconc return-list (list ':deexposed-typein-action *deexposed-typein-action*))))
	      finally (return (if (eq *type* 'tv:command-menu)
				  (nconc return-list (list ':item-list '("you" "have" "to" "change" "me")))
				(if (eq *type* 'b+w-display-window)
				    (nconc return-list (list ':name-of-pane *name*))
				return-list)))))
  (funcall self :force-kbd-input (list ':choice-box 'do-it)))



(DEFUN CHOICE-ABORT (&REST IGNORE)
  (DECLARE (:SELF-FLAVOR my-choose-variable-window))
  (setq init-option-list (list (gentemp 'unspecified-pane-name) 'tv:window))
  (funcall-self :force-kbd-input (list ':choice-box 'abort)))

(defmethod (tv:scroll-stuff-on-off-mixin :adjustable-size-p) ()
  nil)

(defmethod (my-choose-variable-window :enable-scrolling-p) ()
  tv:scroll-bar-always-displayed)



(defun find-line (variable-to-bind &optional (reset-value? nil))
  (loop for line in *lines-on-the-window*
	when (equal (variable-to-bind line) variable-to-bind)
	do
	(and reset-value? (set (variable-to-bind line) nil))
	(return line)
	finally (return nil)))

(defun update-line-for-name ()
  (let ((line (find-line '*name*))
	items)
    (setq items (sensitive-items line))
    (if *list-of-existing-and-not-yet-used-names*
	(and (= (length items) 1)
	     (rplacd items '((:name "Name from menu"))))
      (and (= (length items) 2)
	   (rplacd items nil)))))

(defun create-line (text variable-to-bind default-value sensitive-items selected-element font &optional (reset-value? nil))
  (let ((line (find-line text reset-value?)))
    (when (null line)
      (setq line (make-line-to-output
		   :text-to-display text
		   :variable-to-bind variable-to-bind
		   :sensitive-items sensitive-items
		   :selected-element selected-element
		   :font font))
      (set variable-to-bind default-value)
      (update-list *lines-on-the-window* line))
    line))

(defmethod (my-choose-variable-window :add-line-to-be-displayed) (line)
  (funcall-self ':append-item (variable-to-bind line)))

(defmethod (my-choose-variable-window :delete-all-elements) (&optional (index 0))
  (loop with index-of-item-to-flush = index
	when (= (array-leader tv:items 0) index)
	do (return nil)
	else
	do
	(funcall-self ':delete-item index-of-item-to-flush)))

(defmethod (my-choose-variable-window :output-string-to-window) (text &optional (line-no nil))
  "method to output the string which is the choice for the line. if line-no is unspecified then we supposed that
the cursor is already on the line"
  (if (not line-no) nil
    (if (zerop tv:top-item) nil (setq line-no (- line-no tv:top-item)))
    (SEND self ':SET-CURSORPOS 0 (* LINE-NO tv:line-height)));(tv:SHEET-LINE-HEIGHT self))))
  (setq tv:cursor-x 0)
  (format self "~60T")
  (multiple-value-bind (x y) (funcall-self ':read-cursorpos)
    (funcall self ':bitblt-within-sheet tv:alu-xor
	     (- tv:width x)
	     tv:line-height
	     x y x y)
    (let ((allowed-width (// (- (tv:sheet-inside-width self) x) tv:char-width))
	  (length-of-text (string-length text)))
      (format self "~A" (if (<= length-of-text allowed-width) text (substring text 0 allowed-width))))))

(defmethod (my-choose-variable-window :end-of-line-exception) ()
  (multiple-value-bind (NIL cursor-y) (funcall-self ':read-cursorpos)
    (funcall-self ':set-cursorpos 0 cursor-y)
    (format self "~60T")
    (multiple-value-bind (x y) (funcall-self ':read-cursorpos)
	(funcall self ':bitblt-within-sheet tv:alu-xor
		 (- (funcall self ':width) x)
		 (funcall-self ':line-height)
		 x y x y))))

(defun output-line (item arg window &rest ignore)
  arg
  (let ((line (find-line item)))
    (when line
      (funcall window ':Set-current-font fonts:tr12)
      (format window "~A   : " (text-to-display line))
      (format window "~40T")
      ;; output now mouse sensitive items
      (funcall window ':set-current-font fonts:tr10)
      (loop for (type text) in (sensitive-items line)
	    with selected-element = (selected-element line)
	    when (and selected-element (string-equal text selected-element))
	    do
	    (funcall window ':set-current-font (font line))
	    (funcall window ':item1 text type #'princ)
	    (funcall window ':set-current-font fonts:tr10)
	    (format window "   ")
	    else
	    do
	    (funcall window ':item1 text type #'princ)
	    (format window "   ")
	    finally
	    (progn
	      (funcall window ':set-current-font fonts:cptfont)
	      (format window "~60T")
	      ;; first erase all of that left over region.
	      (multiple-value-bind (x y) (funcall window ':read-cursorpos)
		(funcall self ':bitblt-within-sheet tv:alu-xor
			 (- (funcall window ':width) x)
			 (funcall window ':line-height)
			 x y x y))
	      (and (not selected-element)
		   (boundp (variable-to-bind line))
		   (eval (variable-to-bind line))
		   (funcall window ':output-string-to-window
			    (format nil "~S" (eval (variable-to-bind line))))))))))
      
(defmethod (my-choose-variable-window :after :read-from-the-window) (item line-no &rest ignore)
  "just checking to see if we have any thing to redisplay. Making sure that all lines are still
displayed"
  item
  (let (line-clobbered item1)
    (setq line-clobbered (+ tv:top-item(TRUNCATE (- (tv:SHEET-CURSOR-Y self) (tv:SHEET-INSIDE-TOP self))
						  (tv:SHEET-LINE-HEIGHT self))) 
	  item1 (funcall-self :item-of-number line-clobbered))
    (if (not item1) NIL
      (funcall-self :delete-item line-clobbered)
      (funcall-self :insert-item line-clobbered item1)
      (setq tv:cursor-y (* (if (zerop tv:top-item) LINE-NO (- line-no tv:top-item)) (tv:SHEET-LINE-HEIGHT self))))))


(defmethod (my-choose-variable-window :read-from-the-window) (item line-no &optional (rf 'read)
							      &aux var str newval no-change redis oldval)
  (setq  line-no (if (zerop tv:top-item) line-no (- line-no tv:top-item)))
  (COND ((STRINGP item)
	 (SETQ STR ITEM))	;Can't happen
	((SYMBOLP ITEM)
	 (SETQ VAR ITEM STR (GET-PNAME VAR))))
  (tv:SHEET-SET-FONT self (AREF (tv:SHEET-FONT-MAP self) 0))
  (LET ((BL (tv:SHEET-FOLLOWING-BLINKER self))
	(WS (SEND self ':STATUS)))
    (UNWIND-PROTECT
	(PROGN (SEND self ':SELECT)
	       ;; Next line makes the mouse highlight go away
	       (SEND BL :SET-VISIBILITY ':BLINK)
	       (SEND self ':SET-CURSORPOS
		     (IF (NULL STR) 0
		       (+ (tv:SHEET-STRING-LENGTH self (STRING STR))
			  (tv:SHEET-CHAR-WIDTH self)))
		     (* line-no (tv:SHEET-LINE-HEIGHT self)))
	       (format self "~60T")
	       ;; clears the area of the window where the typeout is going to be done
	       (multiple-value-bind (x y) (funcall-self ':read-cursorpos)
		 (funcall self ':bitblt-within-sheet tv:alu-xor
			  (- (funcall self ':width) x)
			  (funcall-self ':line-height)
			  x y x y))
	       (SEND self ':CLEAR-EOL)
	       ;; clear io buffer from any pending characters
	       (tv:io-buffer-clear tv:io-buffer)
	       ;; Hair for over-rubout => save old value
	       (DO ((CH) (FULL-RUBOUT T) (REDISPLAY-FLAG NIL)
		    (FIRST-TIME T NIL)
		    (*TERMINAL-IO* self))	;Should be ERROR-OUTPUT
		   ((NOT FULL-RUBOUT))
		 (DECLARE (SPECIAL REDISPLAY-FLAG))
		 (UNLESS FIRST-TIME
		   (AND (CHAR= (SETQ CH (SEND self ':TYI)) #/RUBOUT)
			(RETURN (SETQ NO-CHANGE T)))
		   (SEND self ':UNTYI CH))
		 (MULTIPLE-VALUE (NEWVAL FULL-RUBOUT)
		   (SEND self ':RUBOUT-HANDLER '((:full-rubout t))
			 #'(LAMBDA (rf STREAM &AUX WIN)
			     (UNWIND-PROTECT
				 (PROG1
				   (FUNCALL RF STREAM)
				   (SETQ WIN T))
			       (UNLESS WIN 
				 (SETQ REDISPLAY-FLAG T))))
			 RF self))
		 ;; If we got a read error, try to avoid garbage in the display
		 ;; This is really a kludge, is there a better way?
		 (SETQ REDIS REDISPLAY-FLAG)))
      (SEND BL :SET-VISIBILITY NIL)
      (OR (EQ WS ':SELECTED) (SEND self ':SET-STATUS WS)))	;)
    (SETQ OLDVAL (IF (SYMBOLP VAR)
		     (SYMEVAL VAR)
		   (CAR VAR)))
    (AND NO-CHANGE (SETQ NEWVAL OLDVAL))
    (IF (SYMBOLP VAR)
	(SET VAR NEWVAL)
      (RPLACA VAR NEWVAL))))

(defun add-keyword (keyword text variable-to-bind default-value sensitive-items selected-element font)
  (if (memq keyword *list-of-known-keywords*) nil
    (putprop keyword text 'text)
    (putprop keyword variable-to-bind 'variable-to-bind)
    (putprop keyword default-value 'default-value)
    (putprop keyword sensitive-items 'sensitive-items)
    (putprop keyword selected-element 'selected-element)
    (putprop keyword font 'font)
    (update-list *list-of-known-keywords* keyword)))

(add-keyword ':label "Specify a label" '*label* nil '((:label "NIL") (:label "Default") (:label "From keyboard"))
	     "nil" fonts:tr10b)

(add-keyword ':deexposed-typeout-action "Deexposed typeout action" '*deexposed-typeout-action* ':NORMAL
	     '((:deexposed-typeout-action "PERMIT") (:deexposed-typeout-action "NORMAL")
	       (:deexposed-typeout-action  "EXPOSE") (:deexposed-typeout-action "NOTIFY")
	       (:deexposed-typeout-action "ERROR")) "NORMAL" fonts:tr10b)

;(add-keyword ':item-list "Specify item list" '*item-list* '("item" "list")
;	     '((:item-list "Default") (:item-list "From keyboard")) nil nil)

(add-keyword ':save-bits "Save bit array" '*save-bits* T '((:save-bits "Yes") (:save-bits "No")) "Yes" fonts:tr10b)

(add-keyword ':blinker-p "Blinker for window" '*blinker-p* T '((:blinker-p "Yes") (:blinker-p "No")) "Yes" fonts:tr10b)

(add-keyword ':blinker-flavor "Specify blinker flavor" '*blinker-flavor* 'tv:rectangular-blinker
	     '((:blinker-flavor "From keyboard") (:blinker-flavor "From menu")) nil nil)

(add-keyword ':blinker-deselected-visibility "Visibility of blinker" '*blinker-deselected-visibility* ':ON
	     '((:blinker-deselected-visibility "On") (:blinker-deselected-visibility "Off")
	       (:blinker-deselected-visibility  "Blink") (:blinker-deselected-visibility "T")
	       (:blinker-deselected-visibility "NIL")) "On" fonts:tr10b)

(add-keyword ':deexposed-typein-action "Deexposed typein action" '*deexposed-typein-action* ':NORMAL
	     '((:deexposed-typein-action "NORMAL") (:deexposed-typein-action "NOTIFY")) "NORMAL" fonts:tr10b)

(defun get-all-the-other-init-keywords-for-option-list (window type)
  (let ((init-keyword-list
	  (condition-case (error)
	      (si:flavor-all-allowed-init-keywords type)
	    (error NIL))))
    (funcall window ':delete-all-elements 2)
    (loop for keyword in init-keyword-list
	  when (memq keyword *list-of-known-keywords*)
	  do
	  (funcall window ':add-line-to-be-displayed
		   (create-line (get keyword 'text)
				(get keyword 'variable-to-bind)
				(get keyword 'default-value)
				(get keyword 'sensitive-items)
				(get keyword 'selected-element)
				(get keyword 'font) T)))))

(defun create-all-line-except-for-name (option-list &aux line)
  (setq line (create-line "Window flavor" '*type* *type* '((:type "From keyboard")(:type "From menu")) nil nil))
  (loop for index from 0 to (- (length option-list) 2) by 2
	as keyword = (nth index option-list)
	when (memq keyword *list-of-known-keywords*) 
	do
	(create-line (get keyword 'text)
		     (get keyword 'variable-to-bind)
		     (get keyword 'default-value)
		     (get keyword 'sensitive-items)
		     (get keyword 'selected-element)
		     (get keyword 'font)))
  line)
;;
;;
;;   The name of the panes should be unique to avoid any loss when trying to
;; instantiate the frame.
;;
;;

(defun regenerate-lines-for-window (window &aux option-list line)
  ;; first flush all elements already in the window except for
  ;; name
  (funcall window :delete-all-elements 1)
  (setq *type* (get *name* 'flavor))
  (setq option-list (copylist (get *name* 'option-list)))
  (setq line (create-all-line-except-for-name option-list))
  (funcall window :add-line-to-be-displayed line) ;(find-line *type*))
  (and (member ':item-list option-list)
       (progn
	 (delete-element-from-list option-list ':item-list)
	 (delete-element-from-list option-list "you have to change me")))
  (loop for index from 0 to (- (length option-list) 2) by 2
	as keyword = (nth index option-list)
	as value = (nth (1+ index) option-list)
	when (memq keyword *list-of-known-keywords*)
	do
	(funcall window :add-line-to-be-displayed
		 (selectq keyword
		   (:label (setq *label* value) (find-line '*label*))
		   (:save-bits (setq *save-bits* value) (find-line '*save-bits*))
		   (:deexposed-typeout-action (setq *deexposed-typeout-action* value)
					      (find-line '*deexposed-typeout-action*))
		   (:blinker-p (setq *blinker-p* value) (find-line '*blinker-p*))
		   (:deexposed-typein-action (setq *deexposed-typein-action* value)
					     (find-line '*deexposed-typein-action*))
		   (:blinker-flavor (setq *blinker-flavor* value) (find-line '*blinker-flavor*))
		   (:blinker-deselected-visibility (setq *blinker-deselected-visibility* value)
						   (find-line '*blinker-deselected-visibility*)))))
  ;; Now the trick is to turn off the mouse sensitivity of every thing except for name.
  ;; This ought to do it.
  (funcall window :set-sensitive-item-types '(:name)))

;;; This function get-the-name-of-pane when called will always check to see if the name
;;; entered from the keyboard has been already entered previously. If it has then it gets
;;; all the data associated with that name. A check is done to see if the name just
;;; entered from the keyboard has not been already in use. If yes then window maker refuses
;;; to take it.

(defun get-the-name-of-pane (window element)
  (funcall window ':set-current-font fonts:cptfont)
  (let ((line-no (funcall window ':number-of-item '*name*)))
    (loop do
	  (if (string-equal element "From keyboard")
	      (funcall window ':read-from-the-window '*name* line-no)
	    (setq *name* (tv:menu-choose *list-of-existing-and-not-yet-used-names*
					 '(:string "Known names" :font fonts:cptfontb)))
	    (SEND window ':SET-CURSORPOS 0 (* LINE-NO (tv:SHEET-LINE-HEIGHT window)))
	    (format window "~60T")
	    (multiple-value-bind (x y) (funcall window ':read-cursorpos)
	      (funcall window ':bitblt-within-sheet tv:alu-xor
		       (- (funcall window ':width) x)
		       (funcall window ':line-height)
		       x y x y)))
	  (if (not (member *name* *list-of-existing-and-used-names*)) (return nil)))
    (funcall window ':output-string-to-window (format nil "~S" *name*) line-no))
  (if (member *name* *list-of-existing-and-not-yet-used-names*)
      (regenerate-lines-for-window window)
    (funcall window :set-sensitive-item-types T)))


(defun get-the-type-of-flavor-window (window element)
  (funcall window ':set-current-font fonts:cptfont)
  (let ((line-no (funcall window ':number-of-item '*type*)))
    (if (string-equal element "From keyboard")
	(funcall window ':read-from-the-window '*type* line-no)
      (setq *type* (or (tv:menu-choose *list-of-known-flavor-types*
				       '(:string "flavor types" :font fonts:cptfontb)
				       '(:MOUSE) "tv:window")
		       'tv:window)))
    (funcall window ':output-string-to-window (format nil "~S" *type*) line-no)
    ;;add a function which get the new items to display on the window for init option list.
    (get-all-the-other-init-keywords-for-option-list window *type*)))

(defun get-the-save-bits (window element)
  (let ((line (find-line '*save-bits*))
	(line-no (funcall window ':number-of-item '*save-bits*)))
  (setf (selected-element line) element)
  (funcall window ':delete-item line-no)
  (funcall window ':insert-item line-no '*save-bits*))
  (setq *save-bits* (cond ((string-equal element "Yes") t)
			  ((string-equal element "No") nil))))


(defun get-the-item-list (window element)
  window element)

(defun get-the-blinker-flavor (window element)
  (funcall window ':set-current-font fonts:cptfont)
  (let ((line-no (funcall window ':number-of-item '*blinker-flavor*)))
    (if (string-equal element "From keyboard")
	(funcall window ':read-from-the-window '*blinker-flavor* line-no)
      (setq *blinker-flavor* (or (tv:menu-choose  *list-of-blinker-flavor*
						  '(:string "blinker types" :font fonts:cptfontb)
						  '(:MOUSE) 'TV:RECTANGULAR-BLINKER)
				 'TV:RECTANGULAR-BLINKER)))
    (funcall window ':output-string-to-window (format nil "~S" *blinker-flavor*) line-no)))


(defun get-the-blinker-deselected-visibility (window element)
  (let ((line (find-line '*blinker-deselected-visibility*))
	(line-no (funcall window ':number-of-item '*blinker-deselected-visibility*)))
    (setf (selected-element line) element)
    (funcall window ':delete-item line-no)
    (funcall window ':insert-item line-no '*blinker-deselected-visibility*)
    ;; now update the variable.
    (setq *blinker-deselected-visibility*
	  (cond ((string-equal element "on") ':on)
		((string-equal element "blink") ':blink)
		((string-equal element "off") ':off)
		((string-equal element "T") T)
		((string-equal element "NIL") nil)))))

(defun get-the-blinker (window element)
  (let ((line (find-line '*blinker-p*))
	(line-no (funcall window ':number-of-item '*blinker-p*)))
    (setf (selected-element line) element)
  (funcall window ':delete-item line-no)
  (funcall window ':insert-item line-no '*blinker-p*))
  (setq *blinker-p* (cond ((string-equal element "Yes") t)
			  ((string-equal element "No") nil))))

(defun get-the-label-for-window (window element)
  "this will ask the user to specify a label for the window. If no label is needed then select nil
if want to use default then window will have same label as *name*. if keyboard is entered then a string is read
from the keyboard."
  (funcall window ':set-current-font fonts:cptfont)
  (let ((line (find-line '*label*))
	(line-no (funcall window ':number-of-item '*label*)))
    (setf (selected-element line) (if (string-equal element "NIL") "NIL" nil))
    ;; another way of cleaning the line from previous text.
    (setq *label* nil)
    (funcall window ':delete-item line-no)
    (funcall window ':insert-item line-no '*label*)
    (if (string-equal element "NIL")
	(setq *label* nil)
      (setq *label* *name*)
      (if (string-equal element "Default")
	  (funcall window ':output-string-to-window (format nil "~A" *label*) line-no)
	(funcall window ':read-from-the-window '*label* line-no 'readline)
	(funcall window ':output-string-to-window *label* line-no)
	))))


(defun get-deexposed-typeout-action (window element)
  (let ((line-no (funcall window ':number-of-item '*deexposed-typeout-action*))
	(line (find-line '*deexposed-typeout-action*)))
    (setf (selected-element line) element)

    (funcall window ':delete-item line-no)
    (funcall window ':insert-item line-no '*deexposed-typeout-action*)
    (setq *deexposed-typeout-action*
	  (cond ((string-equal element "PERMIT") ':PERMIT)
		((string-equal element "NORMAL") ':NORMAL)
		((string-equal element "ERROR") ':ERROR)
		((string-equal element "NOTIFY") ':NOTIFY)
		((string-equal element "EXPOSE") ':EXPOSE)))))

(defun get-the-deexposed-typein-action (window element)
  (let ((line-no (funcall window ':number-of-item '*deexposed-typein-action*))
	(line (find-line '*deexposed-typein-action*)))
    (setf (selected-element line) element)
    (funcall window ':delete-item line-no)
    (funcall window ':insert-item line-no '*deexposed-typein-action*)
    (setq *deexposed-typein-action*
	  (cond ((string-equal element "PERMIT") ':PERMIT)
		((string-equal element "NORMAL") ':NORMAL)))))
;;
;;
;;     There is a problem when the layout of the screen has changed. this should be taken care of
;;  each time that i want to print something on the side.
;;
;;

(defflavor temporary-my-choose-variable-window () (my-choose-variable-window))

(defwindow-resource temporary-my-choose-variable-window ()
  :make-window (temporary-my-choose-variable-window :height 300 :width 1200)
  :reusable-when :deactivated
  :initial-copies 1)

(defun get-name-and-type (left top right bottom superior &aux line (name-and-option nil) list-to-return)
  (using-resource (*choose-window* temporary-my-choose-variable-window superior)
    ;; Make-sure that the window does not have any thing from before.
    (makunbound '*name*)
    (funcall *choose-window* :set-done nil)
    (funcall *choose-window* :delete-all-elements)
    (funcall *choose-window* :clear-screen)
    (setq line (create-line "Name must be unique" '*name* nil (list '(:name "From keyboard")) nil nil T))
    (update-line-for-name)
    (funcall *choose-window* :add-line-to-be-displayed line)
    (setq line (create-line "Window flavor" '*type* nil '((:type "From keyboard")(:type "From menu")) nil nil))
    (funcall *choose-window* :add-line-to-be-displayed line)
    (funcall *choose-window* :set-sensitive-item-types T)
    (funcall *choose-window* :set-scroll-bar-always-displayed t)
    (funcall *choose-window* :expose-near (list ':rectangle left top right bottom))
    (unwind-protect
	(setq list-to-return
	      (loop with tv:mouse-sheet = *choose-window*
		    as blip = (funcall *choose-window* ':list-tyi)
		    as type = (first blip)
		    as element = (second blip)
		    do
		    (funcall *choose-window* :set-scroll-bar-always-displayed nil)
		    (selectq type 
		      (:type
		       (get-the-type-of-flavor-window *choose-window* element))
		      (:name
		       (get-the-name-of-pane *choose-window* element))
		      (:label
		       (get-the-label-for-window *choose-window* element))
		      (:save-bits
		       (get-the-save-bits *choose-window* element))
		      (:deexposed-typeout-action
		       (get-deexposed-typeout-action *choose-window* element))
		      (:item-list
		       (get-the-item-list *choose-window* element))
		      (:blinker-p
		       (get-the-blinker *choose-window* element))
		      (:blinker-flavor
		       (get-the-blinker-flavor *choose-window* element))
		      (:blinker-deselected-visibility
		       (get-the-blinker-deselected-visibility *choose-window* element))
		      (:deexposed-typein-action
		       (get-the-deexposed-typein-action *choose-window* element))
		      (:choice-box
		       (selectq element
			 (do-it (setq name-and-option (funcall *choose-window* :init-option-list))
				(rplacd (cdr name-and-option) (ncons (cddr name-and-option)))
				(delete-element-from-list *list-of-existing-and-not-yet-used-names* *name*)
				(and *name* (not (string-search "unspecified-pane-name" (string *name*)))
				     (progn (update-list *list-of-existing-and-used-names* *name*)
					    (putprop *name* *type* 'flavor)
					    (putprop *name* (third name-and-option) 'option-list)))
				(return (list name-and-option element)))
			 (Abort (return (list nil element))))))
		    (funcall *choose-window* :set-scroll-bar-always-displayed t)))
      ;; we want something which recognize the control-abort.
      (or name-and-option (setq list-to-return (list NIL 'ABORT)))
      (funcall *choose-window* :set-scroll-bar-always-displayed t)
      (funcall *choose-window* :deactivate))
    (apply #'values list-to-return)))


(compile-flavor-methods my-choose-variable-window)

(compile-flavor-methods temporary-my-choose-variable-window)