(FILECREATED "24-Jan-86 00:06:39" {ERIS}<CUTTING>LISP>KOTO>XQPINFO.;7 50293  

      changes to:  (FNS XQPINFO.CHANGE.GRAPHS XQPINFO.CLOSEFN)

      previous date: "23-Jan-86 17:11:08" {ERIS}<CUTTING>LISP>KOTO>XQPINFO.;6)


(* Copyright (c) 1985, 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT XQPINFOCOMS)

(RPAQQ XQPINFOCOMS ((* * NOTE: This is a hacked-up version of LispCore DInfo recompiled for the 
			 Koto Xerox Quintus Prolog release. This file was generated by substituting 
			 "XQPINFO"
			 for "DINFO" in the text of the DInfo source. Some functions have also been 
			 hacked out.)
		      (FILES TEDIT GRAPHER FREEMENU)
		      (RECORDS XQPINFOGRAPH XQPINFONODE)
		      (MACROS XQPINFOGRAPHPROP)
		      (FNS (* Primary functions)
			   XQPINFO XQPINFO.UPDATE XQPINFOGRAPH XQPINFO.SPECIAL.UPDATE 
			   XQPINFO.CHANGE.GRAPHS XQPINFO.READ.GRAPH XQPINFO.WRITE.GRAPH 
			   XQPINFO.DEFAULT.MENU XQPINFO.FIND XQPINFO.LOOKUP)
		      (FNS (* Window functions)
			   XQPINFO.SETUP.WINDOW XQPINFO.CLOSEFN XQPINFO.SHRINKFN XQPINFO.EXPANDFN 
			   XQPINFO.ICONFN)
		      (FNS (* FreeMenu functions)
			   XQPINFO.ADD.FMENU XQPINFO.CREATE.FMENU XQPINFO.FMW.CLOSEFN 
			   XQPINFO.FMENU.HANDLER XQPINFO.UPDATE.FMENU XQPINFO.TOGGLE.MENU 
			   XQPINFO.TOGGLE.GRAPH XQPINFO.TOGGLE.HISTORY XQPINFO.TOGGLE.TEXT)
		      (FNS (* Other menu functions)
			   XQPINFO.UPDATE.MENU.DISPLAY XQPINFO.UPDATE.FROM.MENU 
			   XQPINFO.UPDATE.HISTORY XQPINFO.HISTORIC.UPDATE)
		      (FNS (* Interface to GRAPHER)
			   XQPINFO.UPDATE.GRAPH.DISPLAY XQPINFO.UPDATE.FROM.GRAPH 
			   XQPINFO.GET.GRAPH.WINDOW XQPINFO.SHOWGRAPH XQPINFO.INVERT.NODE 
			   XQPINFO.LAYOUTGRAPH)
		      (FNS (* Interface to TEdit)
			   XQPINFO.UPDATE.TEXT.DISPLAY XQPINFO.TITLEMENUFN XQPINFO.OPENTEXTSTREAM 
			   XQPINFO.SHOWSEL XQPINFO.GET.FILENAME)
		      (ADDVARS (BackgroundMenuCommands (XQPInfo [QUOTE (ADD.PROCESS
									 (QUOTE (XQPM.GET.GRAPH
										  T]
								
					      "Open a browser on the Xerox Quintus Prolog Manual")))
		      (VARS (BackgroundMenu))
		      (INITVARS (XQPINFOMODES (QUOTE (TEXT GRAPH)))
				(XQPINFO.HISTORY.LENGTH 20)
				(\XQPINFO.MAX.MENU.LEN 10))
		      (GLOBALVARS XQPINFOMODES XQPINFO.HISTORY.LENGTH \XQPINFO.MAX.MENU.LEN)))
(* * NOTE: This is a hacked-up version of LispCore DInfo recompiled for the Koto Xerox Quintus
 Prolog release. This file was generated by substituting "XQPINFO" for "DINFO" in the text of 
the DInfo source. Some functions have also been hacked out.)

(FILESLOAD TEDIT GRAPHER FREEMENU)
[DECLARE: EVAL@COMPILE 

(DATATYPE XQPINFOGRAPH (NAME NODELST TOPNODEID CURRENTNODE WINDOW USERDATA TEXTPROPS MENUFONT 
			       FREEMENUITEMS LOOKUPFN MENUFN DEFAULTHOST DEFAULTDEVICE DEFAULTDIR))

(RECORD XQPINFONODE (ID LABEL FILE FROMBYTE TOBYTE PARENT CHILDREN NEXTNODE PREVIOUSNODE USERDATA))
]
(/DECLAREDATATYPE (QUOTE XQPINFOGRAPH)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER POINTER POINTER))
		  (QUOTE ((XQPINFOGRAPH 0 POINTER)
			  (XQPINFOGRAPH 2 POINTER)
			  (XQPINFOGRAPH 4 POINTER)
			  (XQPINFOGRAPH 6 POINTER)
			  (XQPINFOGRAPH 8 POINTER)
			  (XQPINFOGRAPH 10 POINTER)
			  (XQPINFOGRAPH 12 POINTER)
			  (XQPINFOGRAPH 14 POINTER)
			  (XQPINFOGRAPH 16 POINTER)
			  (XQPINFOGRAPH 18 POINTER)
			  (XQPINFOGRAPH 20 POINTER)
			  (XQPINFOGRAPH 22 POINTER)
			  (XQPINFOGRAPH 24 POINTER)
			  (XQPINFOGRAPH 26 POINTER)))
		  (QUOTE 28))
(DECLARE: EVAL@COMPILE 
[PUTPROPS XQPINFOGRAPHPROP MACRO
	  (ARGS (LET ((GRAPH (CAR ARGS))
		      (PROP (EVAL (CADR ARGS)))
		      SYSTEM?)
		     [SETQ SYSTEM?
			   (FMEMB PROP
				  (QUOTE (NAME NODELST TOPNODEID CURRENTNODE WINDOW USERDATA 
					       TEXTPROPS MENUFONT FREEMENUITEMS LOOKUPFN MENUFN 
					       DEFAULTHOST DEFAULTDEVICE DEFAULTDIR]
		     (SELECTQ (LENGTH ARGS)
			      [2 (if SYSTEM? then (BQUOTE (fetch (XQPINFOGRAPH , PROP)
								 of , GRAPH))
				     else
				     (BQUOTE (LISTGET (fetch (XQPINFOGRAPH USERDATA)
							     of , GRAPH)
						      ,
						      (KWOTE PROP]
			      [3 (LET ((VALUE (CADDR ARGS)))
				      (if SYSTEM? then (BQUOTE (replace (XQPINFOGRAPH , PROP)
									of , GRAPH with , VALUE))
					  else
					  (BQUOTE (LET ((USERDATA (fetch (XQPINFOGRAPH USERDATA)
									 of , GRAPH)))
						       (if (LISTP USERDATA)
							   then
							   (LISTPUT USERDATA , (KWOTE PROP)
								    , VALUE)
							   else
							   (replace (XQPINFOGRAPH USERDATA)
								    of , GRAPH with
								    (LIST , (KWOTE PROP)
									  , VALUE]
			      (SHOULDNT]
)
(DEFINEQ

(XQPINFO
  [LAMBDA (GRAPH.OR.FILE WINDOW.OR.REGION SETUP.ONLY? NO.FREEMENU?)
                                                             (* drc: "23-Jan-86 17:08")
                                                             (* Starts a XQPInfo browser.
							     All args are optional.)
    (LET ((W (OR (WINDOWP WINDOW.OR.REGION)
		   (AND (REGIONP WINDOW.OR.REGION)
			  (CREATEW WINDOW.OR.REGION "XQPInfo" NIL T))
		   (AND (type? XQPINFOGRAPH GRAPH.OR.FILE)
			  (WINDOWP (fetch (XQPINFOGRAPH WINDOW) of GRAPH.OR.FILE)))
		   (CREATEW NIL "XQPInfo")))
	  GRAPH)
         (OPENW W)
         [SETQ GRAPH (if (NULL GRAPH.OR.FILE)
			   then (ERROR "ILLEGAL ARG" GRAPH.OR.FILE)
			 elseif (type? XQPINFOGRAPH GRAPH.OR.FILE)
			   then GRAPH.OR.FILE
			 else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW W))
					     (XQPINFO.READ.GRAPH GRAPH.OR.FILE]
         (XQPINFO.SETUP.WINDOW GRAPH W NO.FREEMENU?)
         (XQPINFO.CHANGE.GRAPHS GRAPH W)
         (OR SETUP.ONLY? (XQPINFO.UPDATE GRAPH NIL NIL T))
     GRAPH])

(XQPINFO.UPDATE
  [LAMBDA (GRAPH NEW.NODE SEL FORCE?)                        (* drc: "22-Jan-86 14:28")

          (* * Called to visit a NEW.NODE in GRAPH, or to just make sure that the display of GRAPH is current.)


    (LET ([NODE (OR NEW.NODE (fetch (XQPINFOGRAPH CURRENTNODE) of GRAPH)
		      (FASSOC (fetch (XQPINFOGRAPH TOPNODEID) of GRAPH)
				(fetch (XQPINFOGRAPH NODELST) of GRAPH]
	  (PREVIOUS.NODE (fetch (XQPINFOGRAPH CURRENTNODE) of GRAPH))
	  (WINDOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH)))
         (OPENW WINDOW)
         (WINDOWPROP WINDOW (QUOTE XQPINFOGRAPH)
		       GRAPH)
         (OR (FMEMB NODE (fetch (XQPINFOGRAPH NODELST) of GRAPH))
	       (ERROR NODE "NOT IN NODELST"))
         (LET [(FMENU.WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW)))
	       (MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK]
	      [RESETLST (RESETSAVE NIL (LIST (QUOTE RELEASE.MONITORLOCK)
						   MONITORLOCK))
			  (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
			      then                         (* somebody else is messing with this graph.)
				     (FLASHWINDOW WINDOW)
				     (PROMPTPRINT "XQPInfo is busy")
			    elseif (NULL FMENU.WINDOW)
			      then (replace (XQPINFOGRAPH CURRENTNODE) of GRAPH with NODE) 
                                                             (* FreeMenu turned off, so just display text)
				     (XQPINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL)
			    else                           (* We've got a FreeMenu, so update away!)
				   (XQPINFO.UPDATE.FMENU GRAPH NODE)
				   (LET ((STATUS (FM.READSTATE FMENU.WINDOW)))
				        (replace (XQPINFOGRAPH CURRENTNODE) of GRAPH
					   with NODE)
				        (AND (LISTGET STATUS (QUOTE GRAPH))
					       (XQPINFO.UPDATE.GRAPH.DISPLAY GRAPH NODE FORCE?))
				        (AND (LISTGET STATUS (QUOTE MENU))
					       (XQPINFO.UPDATE.MENU.DISPLAY GRAPH NODE))
				        (AND (LISTGET STATUS (QUOTE TEXT))
					       (XQPINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL))
				        (XQPINFO.UPDATE.HISTORY GRAPH NODE SEL (LISTGET
								    STATUS
								    (QUOTE HISTORY]
	      (CLEARW (GETPROMPTWINDOW WINDOW])

(XQPINFOGRAPH
  [LAMBDA (X)                                                (* drc: " 8-Jan-86 11:12")
    (if (type? XQPINFOGRAPH X)
	then X
      elseif (AND (WINDOWP X)
		      (WINDOWPROP X (QUOTE XQPINFOGRAPH)))
      elseif (AND (WINDOWP X)
		      (WINDOWPROP X (QUOTE MAINWINDOW)))
	then (WINDOWPROP (WINDOWPROP X (QUOTE MAINWINDOW))
			     (QUOTE XQPINFOGRAPH])

(XQPINFO.SPECIAL.UPDATE
  [LAMBDA (TYPE GRAPH)                                       (* drc: "22-Jan-86 14:28")

          (* * Do a TYPE update of Graph, where TYPE is one of Top, Parent, Previous or Next.)


    (LET* [(XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))
	   (CURRENT.NODE (fetch (XQPINFOGRAPH CURRENTNODE) of GRAPH))
	   (NEW.NODE (FASSOC (SELECTQ TYPE
					  (Top (fetch (XQPINFOGRAPH TOPNODEID) of GRAPH))
					  (Parent (fetch (XQPINFONODE PARENT) of CURRENT.NODE))
					  (Next (fetch (XQPINFONODE NEXTNODE) of CURRENT.NODE))
					  (Previous (fetch (XQPINFONODE PREVIOUSNODE) of 
										     CURRENT.NODE))
					  NIL)
			       (fetch (XQPINFOGRAPH NODELST) of GRAPH]
          (if (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
				      T)
	      then (if NEW.NODE
			 then (PROCESSPROP (THIS.PROCESS)
					       (QUOTE NAME)
					       (CONCAT "XQPInfo " TYPE))
				(XQPINFO.UPDATE GRAPH NEW.NODE)
		       else                                (* TYPE of Top! or Node! will sound silly here, but 
							     should never happen.)
			      (printout (GETPROMPTWINDOW (fetch (XQPINFOGRAPH WINDOW)
							      of GRAPH))
					T "This node has no " TYPE))
	    else (FLASHWINDOW XQPINFOW)
		   (PROMPTPRINT "XQPInfo is busy"])

(XQPINFO.CHANGE.GRAPHS
  [LAMBDA (NEW.GRAPH WINDOW)                                 (* drc: "23-Jan-86 23:58")

          (* * Will start a browser for NEW.GRAPH on WINDOW. WINDOW is expected to be already setup (by XQPINFO.SETUP.WINDOW)
)


    (WINDOWPROP WINDOW (QUOTE XQPINFOGRAPH)
		  NEW.GRAPH)
    (replace (XQPINFOGRAPH WINDOW) of NEW.GRAPH with WINDOW)
    (WINDOWPROP WINDOW (QUOTE TEDIT.ICON.TITLE)
		  (WINDOWPROP WINDOW (QUOTE TITLE)))
    (LET [(FMENU.WINDOW (XQPINFOGRAPHPROP NEW.GRAPH (QUOTE FMENU.WINDOW]
                                                             (* If the FreeMenu is turned on, need to change the 
							     label next to the Top! button)
         (AND FMENU.WINDOW (FM.CHANGELABEL (FM.ITEMFROMID FMENU.WINDOW (QUOTE TOP))
					       FMENU.WINDOW
					       (fetch (XQPINFONODE LABEL)
						  of (FASSOC (fetch (XQPINFOGRAPH TOPNODEID)
								    of NEW.GRAPH)
								 (fetch (XQPINFOGRAPH NODELST)
								    of NEW.GRAPH])

(XQPINFO.READ.GRAPH
  [LAMBDA (FILE QUIETFLG)                                    (* drc: "21-Jan-86 14:29")
                                                             (* Reads a file written by XQPINFO.WRITE.GRAPH.
							     Returns the XQPInfo graph stored on FILE.)
    (OR QUIETFLG (printout T T "Reading " (FILENAMEFIELD FILE (QUOTE NAME))
			     " graph..."))
    (LET* ((FULLFILENAME (INFILEP FILE))
	   [DATA (CDR (READFILE (OR FULLFILENAME (ERROR "FILE NOT FOUND" FILE]
	   (GRAPH (CREATE XQPINFOGRAPH)))                  (* fields stored on file)
          (replace (XQPINFOGRAPH TOPNODEID) of GRAPH with (LISTGET DATA (QUOTE TOPNODEID))
		     )
          (replace (XQPINFOGRAPH TEXTPROPS) of GRAPH with (LISTGET DATA (QUOTE TEXTPROPS))
		     )
          (replace (XQPINFOGRAPH LOOKUPFN) of GRAPH with (LISTGET DATA (QUOTE LOOKUPFN)))
          (replace (XQPINFOGRAPH MENUFN) of GRAPH with (LISTGET DATA (QUOTE MENUFN)))
          (replace (XQPINFOGRAPH FREEMENUITEMS) of GRAPH with (LISTGET DATA (QUOTE 
										    FREEMENUITEMS)))
          (replace (XQPINFOGRAPH NODELST) of GRAPH with (LISTGET DATA (QUOTE NODELST)))
                                                             (* fields filled in at read time)
          (replace (XQPINFOGRAPH NAME) of GRAPH with (FILENAMEFIELD FULLFILENAME
									      (QUOTE NAME)))
          (replace (XQPINFOGRAPH DEFAULTHOST) of GRAPH with (FILENAMEFIELD FULLFILENAME
										     (QUOTE HOST)))
          (replace (XQPINFOGRAPH DEFAULTDEVICE) of GRAPH with (FILENAMEFIELD FULLFILENAME
										       (QUOTE
											 DEVICE)))
          (replace (XQPINFOGRAPH DEFAULTDIR) of GRAPH with (FILENAMEFIELD FULLFILENAME
										    (QUOTE 
											DIRECTORY)))
          (OR QUIETFLG (printout T "OK."))
      GRAPH])

(XQPINFO.WRITE.GRAPH
  [LAMBDA (GRAPH FILE)                                       (* drc: "21-Jan-86 14:24")
                                                             (* Writes a XQPInfo graph to a file for reading by 
							     XQPINFO.READ.GRAPH. Returns the full file name of the 
							     file.)
                                                             (* dump it out as a props list)
    (WRITEFILE (LIST (QUOTE TOPNODEID)
			 (fetch (XQPINFOGRAPH TOPNODEID) of GRAPH)
			 (QUOTE TEXTPROPS)
			 (fetch (XQPINFOGRAPH TEXTPROPS) of GRAPH)
			 (QUOTE LOOKUPFN)
			 (fetch (XQPINFOGRAPH LOOKUPFN) of GRAPH)
			 (QUOTE MENUFN)
			 (fetch (XQPINFOGRAPH MENUFN) of GRAPH)
			 (QUOTE FREEMENUITEMS)
			 (fetch (XQPINFOGRAPH FREEMENUITEMS) of GRAPH)
			 (QUOTE NODELST)
			 (fetch (XQPINFOGRAPH NODELST) of GRAPH))
		 FILE])

(XQPINFO.DEFAULT.MENU
  [LAMBDA (GRAPH)                                            (* drc: "17-Jan-86 13:53")

          (* * This is the default MENUFN for XQPInfo graphs.)


    (LET ((XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH)))
         (CLEARW (GETPROMPTWINDOW XQPINFOW))
         (LET [(TYPE (MENU (OR (XQPINFOGRAPHPROP GRAPH (QUOTE XQPINFO.MENU))
				   (XQPINFOGRAPHPROP GRAPH (QUOTE XQPINFO.MENU)
						     (create MENU
							       ITEMS ←(QUOTE (("Top" (QUOTE
											 Top)
										       
								"Visit the top node in the graph")
										 ("Parent"
										   (QUOTE Parent)
										   
							   "Visit the parent of the current node")
										 ("Previous"
										   (QUOTE Previous)
										   
								"Visit the node before this node")
										 ("Next "
										   (QUOTE Next)
										   
							     "Visit the node following this node")
										 ("Find"
										   (QUOTE Find)
										   
								   "Search the text of this node")
										 ("Lookup"
										   (QUOTE Lookup)
										   
								"Call the LOOKUPFN of this graph")
										 ("Add FreeMenu"
										   (QUOTE FreeMenu)
										   
							    "Add an extended menu to this window")))
							       CENTERFLG ← T
							       MENUFONT ←(FONTCREATE (QUOTE
											 HELVETICA)
										       10
										       (QUOTE
											 BOLD]
	      (if TYPE
		  then (PROCESSPROP (THIS.PROCESS)
					(QUOTE NAME)
					(CONCAT "XQPInfo " TYPE))
			 (SELECTQ TYPE
				    ((Top Parent Previous Next)
				      (XQPINFO.SPECIAL.UPDATE TYPE GRAPH))
				    (Find (XQPINFO.FIND GRAPH))
				    [Lookup (XQPINFO.LOOKUP GRAPH (QUOTE (LEFT]
				    (FreeMenu (XQPINFO.ADD.FMENU GRAPH)
					      (XQPINFO.UPDATE GRAPH))
				    NIL])

(XQPINFO.FIND
  [LAMBDA (GRAPH BUTTONS)                                    (* drc: "22-Jan-86 14:29")
    (LET ((XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH)))
         (if (NOT (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
					    T))
	     then (FLASHWINDOW XQPINFOW)
		    (PROMPTPRINT "XQPInfo is busy")
	   else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW XQPINFOW))
			       (TERPRI T)
			       (LET ([STRING (if (AND (FMEMB (QUOTE MIDDLE)
								   BUTTONS)
							  (XQPINFOGRAPHPROP GRAPH (QUOTE 
										      FIND.STRING)))
					       else (PROMPTFORWORD "Find: " (XQPINFOGRAPHPROP
									 GRAPH
									 (QUOTE FIND.STRING))
								       NIL NIL NIL (QUOTE TTY)
								       (CONSTANT
									 (CHARCODE (EOL ESCAPE LF]
				     (TEXTSTREAM (WINDOWPROP XQPINFOW (QUOTE TEXTSTREAM)))
				     PAIR)
				    (XQPINFOGRAPHPROP GRAPH (QUOTE FIND.STRING)
						      STRING)
				    (if STRING
					then (PRINTOUT T " Searching...")
					       (if (SETQ PAIR (TEDIT.FIND TEXTSTREAM STRING NIL 
										NIL T))
						   then (printout T "OK.")
							  (TEDIT.NORMALIZECARET
							    TEXTSTREAM
							    (TEDIT.SHOWSEL TEXTSTREAM T
									     (TEDIT.SETSEL
									       TEXTSTREAM
									       (CAR PAIR)
									       (NCHARS STRING)
									       (QUOTE RIGHT)
									       T)))
						 else (printout T "not found.")
							(TEDIT.NORMALIZECARET TEXTSTREAM
										(TEDIT.SETSEL
										  TEXTSTREAM 0 0])

(XQPINFO.LOOKUP
  [LAMBDA (GRAPH BUTTONS)                                    (* drc: "22-Jan-86 14:29")
    (LET ((XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH)))
         (if (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
				     T)
	     then [RESETFORM
		      (TTYDISPLAYSTREAM (GETPROMPTWINDOW XQPINFOW))
		      (LET ((LOOKUPFN (fetch (XQPINFOGRAPH LOOKUPFN) of GRAPH)))
		           (if LOOKUPFN
			       then (CLEARW T)
				      (LET* [(OLD.STRING (XQPINFOGRAPHPROP GRAPH (QUOTE 
										    LOOKUP.STRING)))
					     (STRING (if (AND OLD.STRING (FMEMB (QUOTE MIDDLE)
										      BUTTONS))
							 then OLD.STRING
						       else (PROMPTFORWORD
								"Lookup: " OLD.STRING NIL NIL NIL
								(QUOTE TTY)
								(CONSTANT (CHARCODE (EOL ESCAPE 
											     LF]
					    (XQPINFOGRAPHPROP GRAPH (QUOTE LOOKUP.STRING)
							      STRING)
					    (AND STRING (APPLY* LOOKUPFN STRING GRAPH)))
			     else (PRINTOUT T T "The " (fetch (XQPINFOGRAPH NAME) of GRAPH)
					      " graph has no LOOKUPFN."]
	   else (FLASHWINDOW XQPINFOW)
		  (PROMPTPRINT "XQPInfo is busy"])
)
(DEFINEQ

(XQPINFO.SETUP.WINDOW
  [LAMBDA (GRAPH WINDOW NO.FREEMENU?)                        (* drc: "17-Jan-86 13:53")
    (replace (XQPINFOGRAPH WINDOW) of GRAPH with WINDOW)
    (if (NOT NO.FREEMENU?)
	then (XQPINFO.ADD.FMENU GRAPH))
    (OR (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
	  (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK)
			    (CREATE.MONITORLOCK "XQPInfo")))
    (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK)))
    (XQPINFO.UPDATE.TEXT.DISPLAY GRAPH NIL NIL T)
    (WINDOWADDPROP WINDOW (QUOTE CLOSEFN)
		     (QUOTE XQPINFO.CLOSEFN)
		     T)
    (WINDOWADDPROP WINDOW (QUOTE SHRINKFN)
		     (QUOTE XQPINFO.SHRINKFN))
    (WINDOWADDPROP WINDOW (QUOTE EXPANDFN)
		     (QUOTE XQPINFO.EXPANDFN])

(XQPINFO.CLOSEFN
  [LAMBDA (W)                                                (* drc: "24-Jan-86 00:00")
    (LET [(GRAPH (WINDOWPROP W (QUOTE XQPINFOGRAPH]
         (if (type? XQPINFOGRAPH GRAPH)
	     then (CLOSEF? (WINDOWPROP W (QUOTE TEXTSTREAM)))
		    (CLOSEW (XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW))) 
                                                             (* remove circularity...)
		    (WINDOWPROP W (QUOTE XQPINFOGRAPH)
				  NIL])

(XQPINFO.SHRINKFN
  [LAMBDA (W)                                                (* drc: "17-Jan-86 12:17")
    (CLOSEW (XQPINFOGRAPHPROP (XQPINFOGRAPH W)
				(QUOTE GRAPH.WINDOW])

(XQPINFO.EXPANDFN
  [LAMBDA (W)                                                (* drc: "17-Jan-86 12:20")
    (LET ((GRAPH (XQPINFOGRAPH W)))
         (if (LISTGET (FM.READSTATE (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW)))
			  (QUOTE GRAPH))
	     then (LET [(GRAPHW (XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW]
		         (OPENW GRAPHW)
		         (TOTOPW W)
		         (WINDOWPROP GRAPHW (QUOTE XQPINFOGRAPH)
				       GRAPH])

(XQPINFO.ICONFN
  [LAMBDA (W)                                                (* drc: " 9-Jan-86 17:17")
    (OR (WINDOWPROP WINDOW (QUOTE ICON))
	  (WINDOWPROP WINDOW (QUOTE ICON)
			(TITLEDICONW TEDIT.TITLED.ICON.TEMPLATE (WINDOWPROP WINDOW (QUOTE
										  TITLE))
				       TEDIT.ICON.FONT NIL T))
	  (WINDOWPROP WINDOW (QUOTE ICON])
)
(DEFINEQ

(XQPINFO.ADD.FMENU
  [LAMBDA (GRAPH)                                            (* drc: "21-Jan-86 12:40")

          (* * Add a XQPInfo FreeMenu to WINDOW. then update the FreeMenu's display.)


    (LET [(WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE WINDOW)))
	  (FM.WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW]
         (if [AND (WINDOWP FM.WINDOW)
		      (FMEMB FM.WINDOW (WINDOWPROP WINDOW (QUOTE ATTACHEDWINDOWS]
	     then (OPENW FM.WINDOW)
	   else (REMOVEPROMPTWINDOW WINDOW)
		  (SETQ FM.WINDOW (OR (WINDOWP FM.WINDOW)
					  (XQPINFO.CREATE.FMENU GRAPH)))
		  (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW)
				    FM.WINDOW)
		  (ATTACHWINDOW FM.WINDOW WINDOW)
		  (WINDOWDELPROP FM.WINDOW (QUOTE PASSTOMAINCOMS)
				   (QUOTE CLOSEW))
		  (WINDOWADDPROP FM.WINDOW (QUOTE CLOSEFN)
				   (QUOTE XQPINFO.FMW.CLOSEFN))
		  (XQPINFO.UPDATE.FMENU GRAPH])

(XQPINFO.CREATE.FMENU
  [LAMBDA (ADD.ITEMS)                                        (* drc: "21-Jan-86 13:50")

          (* * Makes a XQPInfo FreeMenu for GRAPH)


    (LET ((ADD.ITEMS (fetch (XQPINFOGRAPH FREEMENUITEMS) of GRAPH))
	  (FONT (OR (FONTP (fetch (XQPINFOGRAPH MENUFONT) of GRAPH))
		      MENUFONT)))
         (FM.FORMATMENU (BQUOTE (((LABEL Node: TYPE TITLE FONT (HELVETICA 10))
				      (ID NODE LABEL "" TYPE TITLE FONT , FONT))
				     ((LABEL Top! SELECTEDFN XQPINFO.FMENU.HANDLER FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Visit the top node")
				      (ID TOP LABEL "" TYPE TITLE FONT , FONT))
				     ((LABEL Parent! SELECTEDFN XQPINFO.FMENU.HANDLER FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Visit the parent of the current node")
				      (ID PARENT LABEL "" TYPE TITLE FONT , FONT))
				     ((LABEL Previous! SELECTEDFN XQPINFO.FMENU.HANDLER FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Visit the node previous to the current node")
				      (ID PREVIOUS LABEL "" TYPE TITLE FONT , FONT))
				     ((LABEL Next! SELECTEDFN XQPINFO.FMENU.HANDLER FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Visit the node after the current node")
				      (ID NEXT LABEL "" TYPE TITLE FONT , FONT))
				     ((LABEL Display: TYPE TITLE FONT (HELVETICA 10))
				      (LABEL Graph ID GRAPH STATE , (MEMB (QUOTE GRAPH)
									    XQPINFOMODES)
					     TYPE TOGGLE SELECTEDFN XQPINFO.TOGGLE.GRAPH FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Toggle display of the graph")
				      (LABEL Menu ID MENU STATE , (MEMB (QUOTE MENU)
									  XQPINFOMODES)
					     TYPE TOGGLE SELECTEDFN XQPINFO.TOGGLE.MENU FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Toggle display of the subnode menu")
				      (LABEL Text ID TEXT STATE , (MEMB (QUOTE TEXT)
									  XQPINFOMODES)
					     TYPE TOGGLE SELECTEDFN XQPINFO.TOGGLE.TEXT FONT
					     (HELVETICA 10 BOLD)
					     MESSAGE "Toggle display of the text of the current node")
				      (LABEL History ID HISTORY STATE , (MEMB (QUOTE HISTORY)
										XQPINFOMODES)
					     TYPE TOGGLE FONT (HELVETICA 10 BOLD)
					     SELECTEDFN XQPINFO.TOGGLE.HISTORY MESSAGE 
					     "Toggle the display of the History Menu"))
				     ,
				     (APPEND (QUOTE ((LABEL Find! SELECTEDFN 
								XQPINFO.FMENU.HANDLER FONT
								(HELVETICA 10 BOLD)
								MESSAGE 
			       "Perform a string search in the selected text of the current node")
							  (LABEL Lookup! SELECTEDFN 
								 XQPINFO.FMENU.HANDLER FONT
								 (HELVETICA 10 BOLD)
								 MESSAGE 
	 "Lookup a term using LOOKUPFN of this graph.  LEFT for new term, MIDDLE to repeat last.")))
					       ADD.ITEMS])

(XQPINFO.FMW.CLOSEFN
  [LAMBDA (W)                                                (* drc: "17-Jan-86 15:33")

          (* * CLOSEFN for a XQPInfo FreeMenu window.)


    (LET* ((XQPINFOW (WINDOWPROP W (QUOTE MAINWINDOW)))
	   (GRAPH (XQPINFOGRAPH XQPINFOW)))
          (if GRAPH
	      then (DETACHWINDOW W)
		     (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW)
				       NIL)
		     (DETACHWINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE SUBNODE.MENU.WINDOW)))
		     (CLOSEW (XQPINFOGRAPHPROP GRAPH (QUOTE SUBNODE.MENU.WINDOW)))
		     (DETACHWINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.MENU.WINDOW)))
		     (CLOSEW (XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW)))
		     (REMOVEPROMPTWINDOW XQPINFOW)
		     (GETPROMPTWINDOW XQPINFOW])

(XQPINFO.FMENU.HANDLER
  [LAMBDA (ITEM WINDOW BUTTONS)                              (* drc: "16-Jan-86 11:42")

          (* * Handle a command from the FreeMenu.)


    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW (QUOTE MAINWINDOW))
			       (QUOTE XQPINFOGRAPH)))
	  (TYPE (MKATOM (SUBSTRING (FM.ITEMPROP ITEM (QUOTE LABEL))
				       1 -2]
         (SELECTQ TYPE
		    ((Top Parent Previous Next)
		      (XQPINFO.SPECIAL.UPDATE TYPE GRAPH))
		    (Find (XQPINFO.FIND GRAPH BUTTONS))
		    (Lookup (XQPINFO.LOOKUP GRAPH BUTTONS))
		    (SHOULDNT])

(XQPINFO.UPDATE.FMENU
  [LAMBDA (GRAPH NEW.NODE)                                   (* drc: "17-Jan-86 12:28")

          (* * Update the display of GRAPH's FreeMenu. If NEW.NODE is not specified, use Top node of GRAPH, and change Top 
	  node title.)


    (LET* [(W (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW)))
	   (NODELST (fetch (XQPINFOGRAPH NODELST) of GRAPH))
	   (NODE (OR NEW.NODE (FASSOC (fetch (XQPINFONODE ID) of (fetch (XQPINFOGRAPH
										    CURRENTNODE)
									    of GRAPH))
					  NODELST)
		       (FASSOC (fetch (XQPINFOGRAPH TOPNODEID) of GRAPH)
				 NODELST]
          [OR NEW.NODE (FM.CHANGELABEL (FM.ITEMFROMID W (QUOTE TOP))
					   W
					   (fetch (XQPINFONODE LABEL)
					      of (FASSOC (fetch (XQPINFOGRAPH TOPNODEID)
								of GRAPH)
							     (fetch (XQPINFOGRAPH NODELST)
								of GRAPH]
          (FM.CHANGELABEL (FM.ITEMFROMID W (QUOTE NODE))
			    W
			    (fetch (XQPINFONODE LABEL) of NODE))
          (FM.CHANGELABEL (FM.ITEMFROMID W (QUOTE PARENT))
			    W
			    (fetch (XQPINFONODE LABEL) of NODE (FASSOC (fetch (XQPINFONODE
											PARENT)
										of NODE)
									     NODELST)))
          (FM.CHANGELABEL (FM.ITEMFROMID W (QUOTE NEXT))
			    W
			    (fetch (XQPINFONODE LABEL) of NODE (FASSOC (fetch (XQPINFONODE
											NEXTNODE)
										of NODE)
									     NODELST)))
          (FM.CHANGELABEL (FM.ITEMFROMID W (QUOTE PREVIOUS))
			    W
			    (fetch (XQPINFONODE LABEL) of NODE (FASSOC (fetch (XQPINFONODE
											PREVIOUSNODE)
										of NODE)
									     NODELST])

(XQPINFO.TOGGLE.MENU
  [LAMBDA (ITEM WINDOW)                                      (* drc: "17-Jan-86 12:31")
    (LET* [(XQPINFOW (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
	   (GRAPH (WINDOWPROP XQPINFOW (QUOTE XQPINFOGRAPH]
          (if (FM.ITEMPROP ITEM (QUOTE STATE))
	      then (XQPINFO.UPDATE.MENU.DISPLAY GRAPH (fetch (XQPINFOGRAPH CURRENTNODE)
							     of GRAPH))
	    else (LET [(SUBNODE.MENU.WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE SUBNODE.MENU.WINDOW]
		        (DETACHWINDOW SUBNODE.MENU.WINDOW)
		        (CLOSEW SUBNODE.MENU.WINDOW])

(XQPINFO.TOGGLE.GRAPH
  [LAMBDA (ITEM WINDOW)                                      (* drc: "23-Jan-86 16:27")
    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW (QUOTE MAINWINDOW))
			       (QUOTE XQPINFOGRAPH]
         [if (FM.ITEMPROP ITEM (QUOTE STATE))
	     then (XQPINFO.UPDATE.GRAPH.DISPLAY GRAPH (fetch (XQPINFOGRAPH CURRENTNODE)
							     of GRAPH))
	   else (CLOSEW (XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW]
     ITEM])

(XQPINFO.TOGGLE.HISTORY
  [LAMBDA (ITEM WINDOW)                                      (* drc: "17-Jan-86 12:37")
    (LET* [(XQPINFOW (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
	   (GRAPH (WINDOWPROP XQPINFOW (QUOTE XQPINFOGRAPH]
          (if (FM.ITEMPROP ITEM (QUOTE STATE))
	      then (XQPINFO.UPDATE.HISTORY GRAPH NIL NIL T)
	    else (LET [(HISTORY.MENU.WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.MENU.WINDOW]
		        (DETACHWINDOW HISTORY.MENU.WINDOW)
		        (CLOSEW HISTORY.MENU.WINDOW])

(XQPINFO.TOGGLE.TEXT
  [LAMBDA (ITEM WINDOW)                                      (* drc: "22-Jan-86 14:29")
    (LET* [(XQPINFOW (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
	   (GRAPH (WINDOWPROP XQPINFOW (QUOTE XQPINFOGRAPH)))
	   (MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK]
          (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
	      then (FLASHWINDOW XQPINFOW)
		     (PROMPTPRINT "XQPInfo is busy")
	    elseif (FM.ITEMPROP ITEM (QUOTE STATE))
	      then (XQPINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (XQPINFOGRAPH CURRENTNODE)
							     of GRAPH))
		     (RELEASE.MONITORLOCK MONITORLOCK)
	    else (XQPINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (XQPINFOGRAPH CURRENTNODE)
							   of GRAPH)
						  NIL T)
		   (RELEASE.MONITORLOCK MONITORLOCK])
)
(DEFINEQ

(XQPINFO.UPDATE.MENU.DISPLAY
  [LAMBDA (GRAPH NODE)                                       (* drc: "21-Jan-86 13:52")
    (LET* [(XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))
	   (WINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE SUBNODE.MENU.WINDOW)))
	   [CHILDREN (DREVERSE (for ID in (fetch (XQPINFONODE CHILDREN) of NODE)
				    bind (NODELST ←(fetch (XQPINFOGRAPH NODELST) of GRAPH))
				    collect (FASSOC ID NODELST]
	   (LENGTH (FLENGTH CHILDREN))
	   (SCROLLABLE (GREATERP LENGTH \XQPINFO.MAX.MENU.LEN))
	   (MENU (create MENU
			     MENUFONT ←(OR (FONTP (fetch (XQPINFOGRAPH MENUFONT)
							 of GRAPH))
					     MENUFONT)
			     ITEMWIDTH ←(WINDOWPROP XQPINFOW (QUOTE WIDTH))
			     CENTERFLG ← T
			     MENUCOLUMNS ← 1
			     MENUOUTLINESIZE ← 0
			     ITEMS ←(for CHILD in CHILDREN collect (LIST (fetch
										   (XQPINFONODE
										     LABEL)
										    of CHILD)
										 CHILD 
							      "Will visit this node if selected."))
			     WHENSELECTEDFN ←(FUNCTION XQPINFO.UPDATE.FROM.MENU]
          (AND WINDOW (PROGN (DETACHWINDOW WINDOW)
				 (CLOSEW WINDOW)))
          (if CHILDREN
	      then (UPDATE/MENU/IMAGE MENU)
		     (SETQ WINDOW (CREATEW (create REGION
							 LEFT ← 0
							 BOTTOM ← 0
							 WIDTH ←(WINDOWPROP XQPINFOW (QUOTE
										WIDTH))
							 HEIGHT ←(HEIGHTIFWINDOW
							   (if SCROLLABLE
							       then (TIMES \XQPINFO.MAX.MENU.LEN
									       (fetch (MENU
											  ITEMHEIGHT)
										  of MENU))
							     else (fetch (MENU IMAGEHEIGHT)
								       of MENU))
							   T))
					       "Subnodes" NIL T))
		     (ADDMENU MENU WINDOW (create POSITION
						      XCOORD ← 0
						      YCOORD ←(if SCROLLABLE
								  then (TIMES
									   (DIFFERENCE 
									    \XQPINFO.MAX.MENU.LEN 
											 LENGTH)
									   (fetch (MENU 
										       ITEMHEIGHT)
									      of MENU))
								else 0))
				T)
		     (ATTACHWINDOW WINDOW XQPINFOW (QUOTE BOTTOM))
		     (REDISPLAYW WINDOW)
		     (XQPINFOGRAPHPROP GRAPH (QUOTE SUBNODE.MENU.WINDOW)
				       WINDOW)
		     (LET [(BITS (fetch (REGION BOTTOM) of (WINDOWPROP WINDOW (QUOTE REGION]
                                                             (* Slide XQPINFOW up if our new menu is off the 
							     screen)
		          (AND (ILESSP BITS 0)
				 (RELMOVEW XQPINFOW (create POSITION
								XCOORD ← 0
								YCOORD ←(IDIFFERENCE 0 BITS])

(XQPINFO.UPDATE.FROM.MENU
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc: "12-Dec-85 14:49")
    (XQPINFO.UPDATE (WINDOWPROP (WINDOWPROP (WFROMMENU MENU)
						  (QUOTE MAINWINDOW))
				    (QUOTE XQPINFOGRAPH))
		      (CADR ITEM])

(XQPINFO.UPDATE.HISTORY
  [LAMBDA (GRAPH NODE SEL DISPLAY?)                          (* drc: "21-Jan-86 13:52")
    (LET* ((XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))
	   (OLDWINDOW (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.MENU.WINDOW)))
	   (OLDITEMS (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.ITEMS)))
	   (NEWITEM (if SEL
			then (LIST (if (LISTP SEL)
					   then (CAR SEL)
					 else SEL)
				       (LIST (fetch (XQPINFONODE ID) of NODE)
					       SEL)
				       "Will re-lookup this term")
		      elseif NODE
			then (LIST (fetch (XQPINFONODE LABEL) of NODE)
				       (LIST (fetch (XQPINFONODE ID) of NODE)
					       SEL)
				       "Will re-visit this node")))
	   (ITEMS (if [AND NEWITEM (NOT (EQUAL NEWITEM (CAR OLDITEMS]
		      then (CONS NEWITEM
				     (for ITEM in OLDITEMS as I from 2 to 
									   XQPINFO.HISTORY.LENGTH
					collect ITEM))
		    else OLDITEMS)))
          (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.ITEMS)
			    ITEMS)
          (AND OLDWINDOW (PROGN (DETACHWINDOW OLDWINDOW)
				    (CLOSEW OLDWINDOW)))
          (AND DISPLAY? ITEMS (LET [(HISTORYW (ATTACHMENU
						  (create MENU
							    MENUFONT ←(OR
							      (FONTP (fetch (XQPINFOGRAPH
										  MENUFONT)
									  of GRAPH))
							      MENUFONT)
							    TITLE ← "History"
							    CENTERFLG ← T
							    MENUCOLUMNS ← 1
							    ITEMS ← ITEMS
							    WHENSELECTEDFN ←(FUNCTION 
							      XQPINFO.HISTORIC.UPDATE))
						  XQPINFOW
						  (QUOTE LEFT)
						  (QUOTE TOP]
				     (XQPINFOGRAPHPROP GRAPH (QUOTE HISTORY.MENU.WINDOW)
						       HISTORYW])

(XQPINFO.HISTORIC.UPDATE
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc: "22-Jan-86 14:34")
    (LET* [(ID (CAADR ITEM))
	   (SEL (CADADR ITEM))
	   (WINDOW (WINDOWPROP (WFROMMENU MENU)
				 (QUOTE MAINWINDOW)))
	   (GRAPH (WINDOWPROP WINDOW (QUOTE XQPINFOGRAPH)))
	   (NODE (FASSOC ID (fetch (XQPINFOGRAPH NODELST) of GRAPH]
          (if (NOT (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
					     T))
	      then (FLASHWINDOW WINDOW)
		     (PROMPTPRINT "XQPInfo is busy")
	    elseif (NULL NODE)
	      then (PRINTOUT (GETPROMPTWINDOW WINDOW)
			       T "This node no longer exists")
	    else (XQPINFO.UPDATE GRAPH NODE SEL])
)
(DEFINEQ

(XQPINFO.UPDATE.GRAPH.DISPLAY
  [LAMBDA (XQPINFO.GRAPH NODE FORCE?)                        (* drc: "17-Jan-86 14:51")
    (LET [(XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of XQPINFO.GRAPH))
	  (LOCATION (CONS (fetch (XQPINFONODE PARENT) of NODE)
			    (fetch (XQPINFONODE CHILDREN) of NODE]
         (if [AND (NOT FORCE?)
		      (EQUAL LOCATION (XQPINFOGRAPHPROP XQPINFO.GRAPH (QUOTE LAST.GRAPH.LOCATION]
	     then                                          (* don't need to relayout grapher display -- just 
							     change which node is inverted.)
		    (XQPINFO.INVERT.NODE (XQPINFO.GET.GRAPH.WINDOW XQPINFO.GRAPH)
					   NODE XQPINFO.GRAPH)
	   else (XQPINFO.SHOWGRAPH (XQPINFO.LAYOUTGRAPH XQPINFO.GRAPH NODE)
				       XQPINFO.GRAPH))
         (XQPINFOGRAPHPROP XQPINFO.GRAPH (QUOTE LAST.GRAPH.LOCATION)
			   LOCATION])

(XQPINFO.UPDATE.FROM.GRAPH
  [LAMBDA (GRAPHER.NODE GRAPH.WINDOW)                        (* drc: "12-Dec-85 18:34")
    (AND GRAPHER.NODE (ADD.PROCESS [BQUOTE (XQPINFO.UPDATE (QUOTE , (WINDOWPROP
									      GRAPH.WINDOW
									      (QUOTE XQPINFOGRAPH)))
								   (QUOTE , (fetch (GRAPHNODE
										       NODEID)
										     of GRAPHER.NODE]
				       (QUOTE NAME)
				       "XQPInfo From Graph"])

(XQPINFO.GET.GRAPH.WINDOW
  [LAMBDA (GRAPH REGION)                                     (* drc: "17-Jan-86 13:51")
    (LET [(W (LET ((XQPINFOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH)))
	          (OR (XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW))
			(XQPINFOGRAPHPROP GRAPH (QUOTE GRAPH.WINDOW)
					  (LET* ((XQPINFOREGION (WINDOWPROP XQPINFOW (QUOTE
										REGION)))
						 (LEFT (DIFFERENCE (DIFFERENCE
								       (fetch (REGION LEFT)
									  of XQPINFOREGION)
								       (fetch (REGION WIDTH)
									  of REGION))
								     10))
						 (BOTTOM (DIFFERENCE (DIFFERENCE
									 (fetch (REGION BOTTOM)
									    of XQPINFOREGION)
									 (fetch (REGION HEIGHT)
									    of REGION))
								       50)))
					        (CREATEW (CREATEREGION (if (GEQ LEFT 0)
									       then LEFT
									     else (RAND 0 10))
									   (if (GEQ BOTTOM 0)
									       then BOTTOM
									     else (RAND 0 10))
									   (fetch (REGION WIDTH)
									      of REGION)
									   (fetch (REGION HEIGHT)
									      of REGION))
							   NIL NIL T]
         [WINDOWPROP W (QUOTE CLOSEFN)
		       (FUNCTION (LAMBDA (W)
			   (WINDOWPROP W (QUOTE XQPINFOGRAPH)
					 NIL]
         (WINDOWPROP W (QUOTE XQPINFOGRAPH)
		       GRAPH)
     W])

(XQPINFO.SHOWGRAPH
  [LAMBDA (GRAPHER.GRAPH XQPINFO.GRAPH)                      (* drc: "21-Jan-86 15:07")
    (LET* [(GRAPH.REGION (GRAPHREGION GRAPHER.GRAPH))
	   (GRAPH.WINDOW (XQPINFO.GET.GRAPH.WINDOW XQPINFO.GRAPH GRAPH.REGION))
	   (WINDOW.REGION (WINDOWPROP GRAPH.WINDOW (QUOTE REGION]
          [SHAPEW GRAPH.WINDOW (LET [(LEFT (fetch (REGION LEFT) of WINDOW.REGION))
				       (BOTTOM (fetch (REGION BOTTOM) of WINDOW.REGION))
				       (HEIGHT (HEIGHTIFWINDOW (fetch (REGION HEIGHT)
								    of GRAPH.REGION)
								 T))
				       (WIDTH (WIDTHIFWINDOW (fetch (REGION WIDTH) of 
										     GRAPH.REGION]
				      (create REGION
						LEFT ← LEFT
						BOTTOM ← BOTTOM
						HEIGHT ←(if (GEQ (IPLUS BOTTOM HEIGHT)
								     SCREENHEIGHT)
							    then (IDIFFERENCE SCREENHEIGHT BOTTOM)
							  else HEIGHT)
						WIDTH ←(if (GEQ (IPLUS LEFT WIDTH)
								    SCREENWIDTH)
							   then (IDIFFERENCE SCREENWIDTH LEFT)
							 else WIDTH]
          [WINDOWPROP GRAPH.WINDOW (QUOTE TITLE)
			(CONCAT (fetch (XQPINFOGRAPH NAME) of XQPINFO.GRAPH)
				  " - "
				  (fetch (XQPINFONODE LABEL) of (fetch (XQPINFOGRAPH 
										      CURRENTNODE)
								       of XQPINFO.GRAPH]
          (SHOWGRAPH GRAPHER.GRAPH GRAPH.WINDOW (FUNCTION XQPINFO.UPDATE.FROM.GRAPH)
		       (FUNCTION XQPINFO.UPDATE.FROM.GRAPH])

(XQPINFO.INVERT.NODE
  [LAMBDA (WINDOW XQPINFO.NODE XQPINFO.GRAPH)                (* drc: "21-Jan-86 20:03")
    (LET* [(NODE (for NODE in (fetch (GRAPH GRAPHNODES) of (WINDOWPROP WINDOW (QUOTE
										   GRAPH)))
		    thereis (EQ (fetch (GRAPHNODE NODEID) of NODE)
				    XQPINFO.NODE)))
	   (LAST.NODE (XQPINFOGRAPHPROP XQPINFO.GRAPH (QUOTE LAST.INVERTED.NODE]
          (XQPINFOGRAPHPROP XQPINFO.GRAPH (QUOTE LAST.INVERTED.NODE)
			    NODE)
          (if (NEQ NODE LAST.NODE)
	      then (replace (GRAPHNODE NODELABELSHADE) of NODE with BLACKSHADE) 
                                                             (* (PRINTDISPLAYNODE NODE (create POSITION XCOORD ← 0 
							     YCOORD ← 0) WINDOW))
		     (replace (GRAPHNODE NODELABELSHADE) of LAST.NODE with WHITESHADE) 
                                                             (* (PRINTDISPLAYNODE LAST.NODE 
							     (create POSITION XCOORD ← 0 YCOORD ← 0) WINDOW))
		     (REDISPLAYW WINDOW)
	    else (OPENW WINDOW])

(XQPINFO.LAYOUTGRAPH
  [LAMBDA (XQPINFO.GRAPH NODE)                               (* drc: "21-Jan-86 19:41")
    (LET* [(WINDOW (fetch (XQPINFOGRAPH WINDOW) of XQPINFO.GRAPH))
	   (FONT (OR (FONTP (fetch (XQPINFOGRAPH MENUFONT) of XQPINFO.GRAPH))
		       MENUFONT))
	   (NODELST (fetch (XQPINFOGRAPH NODELST) of XQPINFO.GRAPH))
	   (CHILDREN (for ID in (fetch (XQPINFONODE CHILDREN) of NODE)
			collect (FASSOC ID NODELST)))
	   [CHILD.GRAPHER.NODES (for CHILD in CHILDREN
				   collect (create GRAPHNODE
						       NODEID ← CHILD
						       NODELABEL ←(fetch (XQPINFONODE LABEL)
								     of CHILD]
	   (GRAPHER.NODE (create GRAPHNODE
				   NODELABELSHADE ← BLACKSHADE
				   NODEID ← NODE
				   TONODES ← CHILDREN
				   NODELABEL ←(fetch (XQPINFONODE LABEL) of NODE]
          (XQPINFOGRAPHPROP XQPINFO.GRAPH (QUOTE LAST.INVERTED.NODE)
			    GRAPHER.NODE)                    (* so XQPINFO.INVERT.NODE will work right)
          (if (fetch (XQPINFONODE PARENT) of NODE)
	      then (LET* ((PARENT (FASSOC (fetch (XQPINFONODE PARENT) of NODE)
					      NODELST))
			    (SIBLINGS (for ID in (fetch (XQPINFONODE CHILDREN) of PARENT)
					 collect (FASSOC ID NODELST)))
			    [SIBLING.GRAPHER.NODES (for SIBLING in SIBLINGS
						      collect (if (EQ (fetch (XQPINFONODE
										       ID)
									       of SIBLING)
									    (fetch (XQPINFONODE
										       ID)
									       of NODE))
								    then GRAPHER.NODE
								  else (create
									   GRAPHNODE
									   NODEID ← SIBLING
									   NODELABEL ←(fetch
									     (XQPINFONODE LABEL)
											 of SIBLING]
			    (PARENT.GRAPHER.NODE (create GRAPHNODE
							   NODEID ← PARENT
							   NODELABEL ←(fetch (XQPINFONODE LABEL)
									 of PARENT)
							   TONODES ← SIBLINGS)))
		           (LAYOUTGRAPH (CONS PARENT.GRAPHER.NODE (NCONC SIBLING.GRAPHER.NODES 
									      CHILD.GRAPHER.NODES))
					  (LIST PARENT)
					  NIL FONT))
	    else (LAYOUTGRAPH (CONS GRAPHER.NODE CHILD.GRAPHER.NODES)
				  (LIST NODE)
				  NIL FONT])
)
(DEFINEQ

(XQPINFO.UPDATE.TEXT.DISPLAY
  [LAMBDA (GRAPH NODE SEL OFF?)                              (* drc: "23-Jan-86 12:38")
    (LET ((WINDOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))
	  (FILENAME (XQPINFO.GET.FILENAME GRAPH NODE))
	  (FROM (fetch (XQPINFONODE FROMBYTE) of NODE))
	  (TO (fetch (XQPINFONODE TOBYTE) of NODE))
	  (PROPS (APPEND (LIST (QUOTE READONLY)
				   T
				   (QUOTE NOTITLE)
				   T
				   (QUOTE TITLEMENUFN)
				   (QUOTE XQPINFO.TITLEMENUFN))
			   (fetch (XQPINFOGRAPH TEXTPROPS) of GRAPH)))
	  (OLD.TEXTSTREAM (WINDOWPROP (fetch (XQPINFOGRAPH WINDOW) of GRAPH)
					(QUOTE TEXTSTREAM)))
	  TEXTSTREAM FULLFILENAME)                           (* Default directory and host.)
         (if (OR OFF? (NULL FILENAME))
	     then (OPENTEXTSTREAM (if OFF?
					  then ""
					else "This node has no text")
				      WINDOW NIL NIL PROPS)
		    (XQPINFOGRAPHPROP GRAPH (QUOTE LAST.TEXT)
				      NIL)
	   elseif (SETQ FULLFILENAME (MKATOM (INFILEP FILENAME)))
	     then (SETQ TEXTSTREAM (XQPINFO.OPENTEXTSTREAM FULLFILENAME WINDOW FROM TO PROPS))
		    (XQPINFO.SHOWSEL TEXTSTREAM SEL)
	   else (OPENTEXTSTREAM (CONCAT "Sorry, can't find the text for this node."
					      (MKSTRING (CHARACTER (CHARCODE CR)))
					      "Missing file is: " FILENAME)
				    WINDOW NIL NIL PROPS)
		  (XQPINFOGRAPHPROP GRAPH (QUOTE LAST.TEXT)
				    NIL))
         (CLOSEF? OLD.TEXTSTREAM)
         (WINDOWPROP WINDOW (QUOTE ICONFN)
		       (QUOTE XQPINFO.ICONFN))
         (WINDOWPROP WINDOW (QUOTE TEDIT.TITLEMENUFN)
		       (QUOTE XQPINFO.TITLEMENUFN])

(XQPINFO.TITLEMENUFN
  [LAMBDA (XQPINFOW)                                         (* drc: "22-Jan-86 14:34")

          (* * This is the TEdit TITLEMENUFN for a XQPInfo Window. Uses the MENUFN of graph, defaulting to 
	  XQPINFO.DEFAULT.MENU.)


    (LET [(GRAPH (WINDOWPROP XQPINFOW (QUOTE XQPINFOGRAPH]
         (if (OBTAIN.MONITORLOCK (XQPINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK))
				     T)
	     then [LET ((MENUFN (fetch (XQPINFOGRAPH MENUFN) of GRAPH)))
		         (if (FGETD MENUFN)
			     then (OR (XQPINFOGRAPHPROP GRAPH (QUOTE FMENU.WINDOW))
					  (XQPINFO.ADD.FMENU GRAPH))
				    (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW XQPINFOW))
						 (APPLY* MENUFN GRAPH))
			   else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW XQPINFOW))
					       (XQPINFO.DEFAULT.MENU GRAPH]
	   else (FLASHWINDOW XQPINFOW)
		  (PROMPTPRINT "XQPInfo is busy"])

(XQPINFO.OPENTEXTSTREAM
  [LAMBDA (FILE WINDOW FROM TO PROPS)                        (* drc: "17-Jan-86 13:42")
    (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW))
		 (LET ((TEXTSTREAM (WINDOWPROP WINDOW (QUOTE TEXTSTREAM)))
		       (THIS.TEXT (LIST FILE FROM TO)))
		      (if (AND (EQUAL THIS.TEXT (XQPINFOGRAPHPROP (XQPINFOGRAPH WINDOW)
									(QUOTE LAST.TEXT)))
				   TEXTSTREAM)
			  then                             (* Same text, and its still there, so do nothing.)
				 TEXTSTREAM
			else (AND TEXTSTREAM (TEDIT.KILL TEXTSTREAM))
			       (CLEARW T)
			       (CLEARW WINDOW)
			       [RESETSAVE NIL (BQUOTE (AND RESETSTATE (WINDOWPROP
								   , WINDOW (QUOTE LAST.TEXT)
								   NIL]
			       (PRINTOUT T "Fetching text from " FILE "...")
			       (PROG1 (OPENTEXTSTREAM FILE WINDOW FROM TO PROPS)
					(PRINTOUT T "OK.")
					(XQPINFOGRAPHPROP (XQPINFOGRAPH WINDOW)
							  (QUOTE LAST.TEXT)
							  THIS.TEXT])

(XQPINFO.SHOWSEL
  [LAMBDA (TEXTSTREAM SEL)                                 (* drc: "16-Jan-86 21:30")
    (if (LISTP SEL)
	then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM (CADR SEL)
								  0))
      elseif (STRINGP SEL)
	then [LET ((CHAR# (TEDIT.FIND TEXTSTREAM SEL)))
		    (if CHAR#
			then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM CHAR#
										  (NCHARS SEL)
										  NIL T]
      else (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM 0 0])

(XQPINFO.GET.FILENAME
  [LAMBDA (GRAPH NODE)                                       (* drc: "10-Jan-86 14:47")

          (* * returns the filename of the documentation for NODE in GRAPH. Defaults HOST and DIRECTORY to that of graph)


    (LET ((FILE (fetch (XQPINFONODE FILE) of NODE)))
         (AND FILE (PACKFILENAME (QUOTE HOST)
				     (OR (FILENAMEFIELD FILE (QUOTE HOST))
					   (fetch (XQPINFOGRAPH DEFAULTHOST) of GRAPH))
				     (QUOTE DEVICE)
				     (OR (FILENAMEFIELD FILE (QUOTE DEVICE))
					   (fetch (XQPINFOGRAPH DEFAULTDEVICE) of GRAPH))
				     (QUOTE DIRECTORY)
				     (OR (FILENAMEFIELD FILE (QUOTE DIRECTORY))
					   (fetch (XQPINFOGRAPH DEFAULTDIR) of GRAPH))
				     (QUOTE BODY)
				     FILE])
)

(ADDTOVAR BackgroundMenuCommands (XQPInfo [QUOTE (ADD.PROCESS (QUOTE (XQPM.GET.GRAPH T]
					    "Open a browser on the Xerox Quintus Prolog Manual"))

(RPAQQ BackgroundMenu NIL)

(RPAQ? XQPINFOMODES (QUOTE (TEXT GRAPH)))

(RPAQ? XQPINFO.HISTORY.LENGTH 20)

(RPAQ? \XQPINFO.MAX.MENU.LEN 10)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS XQPINFOMODES XQPINFO.HISTORY.LENGTH \XQPINFO.MAX.MENU.LEN)
)
(PUTPROPS XQPINFO COPYRIGHT ("Xerox Corporation" 1985 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (4626 19114 (XQPINFO 4636 . 5794) (XQPINFO.UPDATE 5796 . 8215) (XQPINFOGRAPH 8217 . 8667
) (XQPINFO.SPECIAL.UPDATE 8669 . 10117) (XQPINFO.CHANGE.GRAPHS 10119 . 11204) (XQPINFO.READ.GRAPH 
11206 . 13299) (XQPINFO.WRITE.GRAPH 13301 . 14261) (XQPINFO.DEFAULT.MENU 14263 . 16170) (XQPINFO.FIND 
16172 . 17839) (XQPINFO.LOOKUP 17841 . 19112)) (19115 21546 (XQPINFO.SETUP.WINDOW 19125 . 19950) (
XQPINFO.CLOSEFN 19952 . 20465) (XQPINFO.SHRINKFN 20467 . 20665) (XQPINFO.EXPANDFN 20667 . 21155) (
XQPINFO.ICONFN 21157 . 21544)) (21547 31108 (XQPINFO.ADD.FMENU 21557 . 22530) (XQPINFO.CREATE.FMENU 
22532 . 25323) (XQPINFO.FMW.CLOSEFN 25325 . 26134) (XQPINFO.FMENU.HANDLER 26136 . 26752) (
XQPINFO.UPDATE.FMENU 26754 . 28550) (XQPINFO.TOGGLE.MENU 28552 . 29171) (XQPINFO.TOGGLE.GRAPH 29173 . 
29673) (XQPINFO.TOGGLE.HISTORY 29675 . 30234) (XQPINFO.TOGGLE.TEXT 30236 . 31106)) (31109 36735 (
XQPINFO.UPDATE.MENU.DISPLAY 31119 . 33849) (XQPINFO.UPDATE.FROM.MENU 33851 . 34140) (
XQPINFO.UPDATE.HISTORY 34142 . 35955) (XQPINFO.HISTORIC.UPDATE 35957 . 36733)) (36736 44508 (
XQPINFO.UPDATE.GRAPH.DISPLAY 36746 . 37669) (XQPINFO.UPDATE.FROM.GRAPH 37671 . 38128) (
XQPINFO.GET.GRAPH.WINDOW 38130 . 39577) (XQPINFO.SHOWGRAPH 39579 . 41089) (XQPINFO.INVERT.NODE 41091
 . 42198) (XQPINFO.LAYOUTGRAPH 42200 . 44506)) (44509 49790 (XQPINFO.UPDATE.TEXT.DISPLAY 44519 . 46308
) (XQPINFO.TITLEMENUFN 46310 . 47294) (XQPINFO.OPENTEXTSTREAM 47296 . 48360) (XQPINFO.SHOWSEL 48362 . 
48940) (XQPINFO.GET.FILENAME 48942 . 49788)))))
STOP