(FILECREATED "19-Sep-85 16:50:40" {DSK2}TABLEBROWSER.;26 62417  

      changes to:  (FNS TB.INSERT.ITEM TB.NTH.ITEM TB.COLLECT.ITEMS TB.FIND.ITEM TB.ITEM.SELECTED? 
			TB.ITEM.DELETED? TB.NUMBER.OF.ITEMS TB.MAP.SELECTED.ITEMS TB.DISPLAY.LINES 
			TB.ITEM.FROM.YCOORD TB.DO.ITEM.SELECTION TB.DECONSIDERRANGE TB.CONSIDERRANGE 
			TB.DESELECTRANGE TB.RECONSIDERRANGE TB.SELECTRANGE TB.FIND.SELECTED.ITEM 
			TB.REV.FIND.SELECTED.ITEM TB.COPYBUTTONEVENTFN TB.FETCHNTH TB.MAKE.BROWSER 
			TB.FLUSH.WINDOW TB.REDISPLAY.ITEMS)
		   (VARS TABLEBROWSERCOMS)
		   (I.S.OPRS selectedfrom)
		   (USERMACROS TB)

      previous date: "11-Sep-85 19:31:09" {DSK2}TABLEBROWSER.;17)


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

(PRETTYCOMPRINT TABLEBROWSERCOMS)

(RPAQQ TABLEBROWSERCOMS ((FNS)
	(COMS (* Entries)
	      (FNS TB.MAKE.BROWSER TB.REPLACE.ITEMS)
	      (FNS TB.DELETE.ITEM TB.UNDELETE.ITEM TB.INSERT.ITEM TB.REMOVE.ITEM TB.NORMALIZE.ITEM 
		   TB.REDISPLAY.ITEMS TB.SELECT.ITEM)
	      (FNS TB.NUMBER.OF.ITEMS TB.NTH.ITEM TB.COLLECT.ITEMS TB.MAP.ITEMS TB.MAP.DELETED.ITEMS 
		   TB.MAP.SELECTED.ITEMS TB.FIND.ITEM TB.ITEM.SELECTED? TB.ITEM.DELETED?)
	      (FNS TB.CLEAR.LINE TB.USERDATA TB.WINDOW))
	(COMS (* Display)
	      (FNS TB.REPAINTFN TB.RESHAPEFN TB.SCROLLFN TB.DISPLAY.LINES TB.PRINT.LINE 
		   TB.FIRST.VISIBLE.ITEM# TB.LAST.VISIBLE.ITEM# TB.ITEM.VISIBLE? TB.YCOORD.FROM.ITEM 
		   TB.ITEM#.FROM.YCOORD TB.ITEM.FROM.YCOORD TB.SHOW.DELETION TB.SHOW.SELECTION 
		   TB.UPDATE.DISPLAY))
	(COMS (* Selection)
	      (FNS TB.BUTTONEVENTFN TB.DO.UNLESS.BUSY TB.DO.ITEM.SELECTION TB.DECONSIDERRANGE 
		   TB.CONSIDERRANGE TB.DESELECTRANGE TB.RECONSIDERRANGE TB.SELECTRANGE 
		   TB.UNDOSELECTION TB.FIND.SELECTED.ITEM TB.REV.FIND.SELECTED.ITEM)
	      (FNS TB.COPYBUTTONEVENTFN TB.SHOW.COPY.SELECTION))
	(COMS (* Misc state change)
	      (FNS TB.BROWSER.BUSY TB.CLOSE/SHRINK TB.CLOSEFN TB.FINISH.CLOSE TB.FLUSH.WINDOW 
		   TB.SET.FONT TB.SHRINKFN TB.EXPANDFN TB.ITEM.UPDATABLE?))
	(COMS (* Misc)
	      (FNS TB.PROCESS TB.FETCHNTH)
	      (VARS TB.DELETEDLINEHEIGHT)
	      (BITMAPS TB.SELECTION.BITMAP)
	      (CURSORS TB.CROSSCURSOR)
	      (DECLARE: EVAL@COMPILE DONTCOPY (FILES (SOURCE)
						     TABLEBROWSERDECLS)
			(CONSTANTS * TOCSTATES)
			(USERMACROS TB)
			(I.S.OPRS selectedfrom)
			(MACROS .COPYKEYDOWNP.)
			(GLOBALVARS TB.CROSSCURSOR TB.SELECTION.BITMAP TB.DELETEDLINEHEIGHT)))
	(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA)
									      (NLAML)
									      (LAMA TB.USERDATA)))
	(INITRECORDS TABLEBROWSER TABLEITEM)
	(SYSRECORDS TABLEBROWSER TABLEITEM)))



(* Entries)

(DEFINEQ

(TB.MAKE.BROWSER
  [LAMBDA (ITEMS WINDOWSPEC PROPS)                           (* bvm: "12-Sep-85 18:30")

          (* * Build a browser window, which consists of three attached windows: the main BROWSERWINDOW, the BROWSERMENUWINDOW
	  containing the menu, and a BROWSERPROMPTWINDOW for displaying random info)


    (PROG ((LINESPERITEM 1)
	   FONT PRINTFN COPYFN CLOSEFN AFTERCLOSEFN TITLE COLUMNS USERDATA WINDOW USERPROPS BROWSER)
          (DECLARE (SPECVARS FONT PRINTFN COPYFN CLOSEFN AFTERCLOSEFN TITLE COLUMNS USERDATA 
			     LINESPERITEM))                  (* For SET below)
          [for TAIL on PROPS by (CDDR TAIL)
	     do (SELECTQ (CAR TAIL)
			 ((FONT PRINTFN COPYFN CLOSEFN AFTERCLOSEFN TITLE COLUMNS USERDATA 
				LINESPERITEM)
			   (SET (CAR TAIL)
				(CADR TAIL)))
			 (push USERPROPS (LIST (CAR TAIL)
					       (CADR TAIL]
          (SETQ WINDOW (DECODE.WINDOW.ARG WINDOWSPEC NIL NIL TITLE))
          (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)
		      (SETQ BROWSER (create TABLEBROWSER
					    TBWINDOW ← WINDOW
					    TBFONT ← FONT
					    TBLOCK ←(CREATE.MONITORLOCK (OR (WINDOWPROP WINDOW
											(QUOTE TITLE))
									    "Table Browser"))
					    TB#LINESPERITEM ←(OR LINESPERITEM 1)
					    TBCOLUMNS ← COLUMNS
					    TBPRINTFN ← PRINTFN
					    TBCOPYFN ← COPYFN
					    TBCLOSEFN ← CLOSEFN
					    TBAFTERCLOSEFN ← AFTERCLOSEFN
					    TBUSERDATA ← USERDATA)))
          (TB.REPLACE.ITEMS BROWSER ITEMS)
          (WINDOWPROP WINDOW (QUOTE SCROLLFN)
		      (FUNCTION TB.SCROLLFN))
          (WINDOWPROP WINDOW (QUOTE REPAINTFN)
		      (FUNCTION TB.REPAINTFN))
          (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN)
		      (FUNCTION TB.BUTTONEVENTFN))
          (WINDOWPROP WINDOW (QUOTE RIGHTBUTTONFN)
		      (FUNCTION TB.BUTTONEVENTFN))
          (WINDOWPROP WINDOW (QUOTE COPYBUTTONEVENTFN)
		      (FUNCTION TB.COPYBUTTONEVENTFN))
          (WINDOWADDPROP WINDOW (QUOTE CLOSEFN)
			 (FUNCTION TB.CLOSEFN))
          (WINDOWADDPROP WINDOW (QUOTE SHRINKFN)
			 (FUNCTION TB.SHRINKFN))
          (WINDOWADDPROP WINDOW (QUOTE RESHAPEFN)
			 (FUNCTION TB.RESHAPEFN))
          (DSPLEFTMARGIN TB.LEFT.MARGIN WINDOW)
          (replace (TABLEBROWSER TBREADY) of BROWSER with T)
          (RETURN BROWSER])

(TB.REPLACE.ITEMS
  [LAMBDA (BROWSER NEWITEMS)                                 (* bvm: " 8-Sep-85 16:17")
    (LET ((#ITEMS (LENGTH NEWITEMS))
	  FIRSTSEL)
         (replace (TABLEBROWSER TBITEMS) of BROWSER with NEWITEMS)
         (replace (TABLEBROWSER TB#ITEMS) of BROWSER with #ITEMS)
         (replace (TABLEBROWSER TB#DELETED) of BROWSER with (for ITEM in NEWITEMS
							       count (fetch TIDELETED of ITEM)))
         (COND
	   ((SETQ FIRSTSEL (TB.FIND.SELECTED.ITEM BROWSER 1 #ITEMS))
	     (replace (TABLEBROWSER TBFIRSTSELECTEDITEM) of BROWSER with FIRSTSEL)
	     (replace (TABLEBROWSER TBLASTSELECTEDITEM) of BROWSER with (TB.REV.FIND.SELECTED.ITEM
									  BROWSER
									  (ADD1 FIRSTSEL)
									  #ITEMS)))
	   (T (replace (TABLEBROWSER TBFIRSTSELECTEDITEM) of BROWSER with (ADD1 #ITEMS))
	      (replace (TABLEBROWSER TBLASTSELECTEDITEM) of BROWSER with 0)))
         (TB.SET.FONT BROWSER])
)
(DEFINEQ

(TB.DELETE.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 8-Sep-85 23:34")
    (COND
      ((NOT (fetch (TABLEITEM TIDELETED) of ITEM))
	(replace (TABLEITEM TIDELETED) of ITEM with T)
	(add (fetch (TABLEBROWSER TB#DELETED) of BROWSER)
	     1)
	(TB.SHOW.DELETION BROWSER ITEM (fetch (TABLEBROWSER TBWINDOW) of BROWSER)
			  (QUOTE REPLACE])

(TB.UNDELETE.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: "10-Sep-85 12:26")
    (COND
      ((fetch (TABLEITEM TIDELETED) of ITEM)
	(replace (TABLEITEM TIDELETED) of ITEM with NIL)
	(add (fetch (TABLEBROWSER TB#DELETED) of BROWSER)
	     -1)
	(COND
	  ((AND (TB.ITEM.VISIBLE? BROWSER ITEM)
		(TB.ITEM.UPDATABLE? BROWSER ITEM))
	    (LET ((WINDOW (fetch (TABLEBROWSER TBWINDOW) of BROWSER)))
	         (TB.SHOW.DELETION BROWSER ITEM WINDOW (QUOTE ERASE))
                                                             (* reprint the line sans deletion mark)
	         (TB.PRINT.LINE BROWSER ITEM WINDOW (fetch (TABLEBROWSER TBPRINTFN) of BROWSER])

(TB.INSERT.ITEM
  [LAMBDA (BROWSER NEWITEM BEFOREITEM)                       (* bvm: "19-Sep-85 15:17")

          (* * Inserts NEWITEM in TABLEBROWSER before item BEFOREITEM or at the end if BEFOREITEM is NIL)


    (LET ((OLDITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER))
	  (LASTITEM# (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
	  BEFORE# TAIL N)
         [COND
	   (BEFOREITEM [SETQ BEFORE# (COND
			   ((FIXP BEFOREITEM))
			   ((type? TABLEITEM BEFOREITEM)
			     (fetch TI# of BEFOREITEM))
			   (T (\ILLEGAL.ARG BEFOREITEM]
		       (COND
			 ((GREATERP BEFORE# LASTITEM#)
			   (\ILLEGAL.ARG BEFOREITEM)))

          (* * Need to change the following if TBITEMS representation changes)


		       (RPLNODE (SETQ TAIL (NTH OLDITEMS BEFORE#))
				NEWITEM
				(CONS (CAR TAIL)
				      (CDR TAIL)))
		       (for ITEM in TAIL as I from BEFORE# do (replace TI# of ITEM with I)))
	   (T                                                (* Inserting at end)
	      (replace TI# of NEWITEM with (SETQ BEFORE# (ADD1 LASTITEM#)))

          (* * Need to change the following if TBITEMS representation changes)


	      (replace (TABLEBROWSER TBITEMS) of BROWSER with (NCONC1 OLDITEMS NEWITEM]
         (replace (TABLEBROWSER TB#ITEMS) of BROWSER with (ADD1 LASTITEM#))
         (COND
	   ((fetch TIDELETED of NEWITEM)
	     (add (fetch (TABLEBROWSER TB#DELETED) of BROWSER)
		  1)))

          (* * Update first & last selected item if they fall after the insertion, or if the new item is selected)


         [COND
	   ((IGEQ (SETQ N (fetch TBFIRSTSELECTEDITEM of BROWSER))
		  BEFORE#)
	     (replace TBFIRSTSELECTEDITEM of BROWSER with (COND
							    ((fetch TISELECTED of NEWITEM)
							      BEFORE#)
							    (T (ADD1 N]
         (COND
	   ((IGEQ (SETQ N (fetch TBLASTSELECTEDITEM of BROWSER))
		  BEFORE#)
	     (replace TBLASTSELECTEDITEM of BROWSER with (ADD1 N)))
	   ((fetch TISELECTED of NEWITEM)
	     (replace TBLASTSELECTEDITEM of BROWSER with BEFORE#)))
         (TB.UPDATE.DISPLAY BROWSER BEFORE# (QUOTE INSERT])

(TB.REMOVE.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 8-Sep-85 16:44")

          (* * Removes ITEM from TABLEBROWSER)


    (LET ((OLDITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER))
	  (LASTITEM# (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
	  [ITEM# (COND
		   ((type? TABLEITEM ITEM)
		     (fetch TI# of ITEM))
		   (T (\ILLEGAL.ARG ITEM]
	  N TAIL)

          (* * Need to change the following if TBITEMS representation changes)


         [COND
	   [(EQ ITEM# 1)
	     (replace (TABLEBROWSER TBITEMS) of BROWSER with (SETQ TAIL (CDR OLDITEMS]
	   (T (RPLACD (SETQ TAIL (NTH OLDITEMS (SUB1 ITEM#)))
		      (SETQ TAIL (CDDR TAIL]
         (for ITEM in TAIL as I from ITEM# do (replace TI# of ITEM with I))
         (replace (TABLEBROWSER TB#ITEMS) of BROWSER with (SUB1 LASTITEM#))
         (COND
	   ((fetch TIDELETED of ITEM)
	     (add (fetch (TABLEBROWSER TB#DELETED) of BROWSER)
		  -1)))

          (* * Update first & last selected item if they fall after the deletion or if the old item is selected)


         [COND
	   ((IGEQ (SETQ N (fetch TBFIRSTSELECTEDITEM of BROWSER))
		  ITEM#)
	     (replace TBFIRSTSELECTEDITEM of BROWSER with (COND
							    ((fetch TISELECTED of ITEM)
							      (OR (TB.FIND.SELECTED.ITEM BROWSER 
											 ITEM#)
								  LASTITEM#))
							    (T (SUB1 N]
         [COND
	   ((IGEQ (SETQ N (fetch TBLASTSELECTEDITEM of BROWSER))
		  ITEM#)
	     (replace TBLASTSELECTEDITEM of BROWSER with (COND
							   ((fetch TISELECTED of ITEM)
							     (OR (TB.REV.FIND.SELECTED.ITEM BROWSER 
											    ITEM#)
								 0))
							   (T (SUB1 N]
         (TB.UPDATE.DISPLAY BROWSER ITEM# (QUOTE REMOVE])

(TB.NORMALIZE.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 9-Sep-85 00:40")
    (PROG ((WINDOW (fetch (TABLEBROWSER TBWINDOW) of BROWSER))
	   (YPOS (TB.YCOORD.FROM.ITEM BROWSER ITEM))
	   CLIPREGION)
          (COND
	    ((OR (IGREATERP (fetch (REGION BOTTOM) of (SETQ CLIPREGION (DSPCLIPPINGREGION NIL WINDOW))
				   )
			    YPOS)
		 (ILESSP (fetch (REGION TOP) of CLIPREGION)
			 YPOS))
	      (SCROLLBYREPAINTFN WINDOW 0 (IPLUS (fetch (REGION BOTTOM) of CLIPREGION)
						 (IQUOTIENT (fetch (REGION HEIGHT) of CLIPREGION)
							    2)
						 (IMINUS YPOS])

(TB.REDISPLAY.ITEMS
  [LAMBDA (BROWSER FIRSTITEM LASTITEM)                       (* bvm: "12-Sep-85 00:20")
    (LET [(REGION (DSPCLIPPINGREGION NIL (fetch (TABLEBROWSER TBWINDOW) of BROWSER]
         (TB.DISPLAY.LINES BROWSER (IMAX (COND
					   ((NULL FIRSTITEM)
					     1)
					   ((FIXP FIRSTITEM))
					   ((type? TABLEITEM FIRSTITEM)
					     (fetch TI# of FIRSTITEM))
					   (T (\ILLEGAL.ARG FIRSTITEM)))
					 (TB.FIRST.VISIBLE.ITEM# BROWSER REGION))
			   (IMIN (COND
				   ((NULL LASTITEM)
				     (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
				   ((FIXP LASTITEM))
				   ((type? TABLEITEM LASTITEM)
				     (fetch TI# of LASTITEM))
				   (T (\ILLEGAL.ARG LASTITEM)))
				 (TB.LAST.VISIBLE.ITEM# BROWSER REGION])

(TB.SELECT.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 9-Sep-85 00:39")
    (PROG ((N (fetch (TABLEITEM TI#) of ITEM)))
          (TB.SELECTRANGE BROWSER N N T)
          (TB.SHOW.SELECTION BROWSER ITEM (QUOTE REPLACE])
)
(DEFINEQ

(TB.NUMBER.OF.ITEMS
  [LAMBDA (BROWSER TYPE)                                     (* bvm: " 8-Sep-85 16:42")
    (SELECTQ TYPE
	     (NIL (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
	     (DELETED (fetch (TABLEBROWSER TB#DELETED) of BROWSER))
	     (SELECTED (for ITEM selectedfrom BROWSER sum 1))
	     (\ILLEGAL.ARG TYPE])

(TB.NTH.ITEM
  [LAMBDA (BROWSER N)                                        (* bvm: "13-Sep-85 19:24")
    (COND
      ((AND (GEQ N 1)
	    (LEQ N (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)))
	(TB.FETCHNTH (fetch (TABLEBROWSER TBITEMS) of BROWSER)
		     N])

(TB.COLLECT.ITEMS
  [LAMBDA (BROWSER PREDFN)                                   (* bvm: "13-Sep-85 16:37")
    (SELECTQ PREDFN
	     (DELETED (SETQ PREDFN (FUNCTION TB.ITEM.DELETED?)))
	     (SELECTED (SETQ PREDFN (FUNCTION TB.ITEM.SELECTED?)))
	     NIL)
    (for ITEM in (fetch (TABLEBROWSER TBITEMS) of BROWSER) collect ITEM
       when (OR (NULL PREDFN)
		(APPLY* PREDFN BROWSER ITEM])

(TB.MAP.ITEMS
  [LAMBDA (BROWSER MAPFN NULLFN)                             (* bvm: "11-Sep-85 19:30")

          (* * Apply MAPFN to each item in TABLEBROWSER -- args (TABLEBROWSER ITEM))


    (LET ((ITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER)))
         (COND
	   (ITEMS (for ITEM in ITEMS do (APPLY* MAPFN BROWSER ITEM)))
	   (NULLFN (APPLY* NULLFN BROWSER])

(TB.MAP.DELETED.ITEMS
  [LAMBDA (BROWSER MAPFN NULLFN)                             (* bvm: " 8-Sep-85 17:38")

          (* * Apply MAPFN to each deleted item in TABLEBROWSER -- args (TABLEBROWSER ITEM))


    (COND
      ((NEQ (fetch TB#DELETED of BROWSER)
	    0)
	(for ITEM in (fetch (TABLEBROWSER TBITEMS) of BROWSER) when (fetch TIDELETED of ITEM)
	   do (APPLY* MAPFN BROWSER ITEM)))
      (NULLFN                                                (* Nothing deleted)
	      (APPLY* NULLFN BROWSER])

(TB.MAP.SELECTED.ITEMS
  [LAMBDA (BROWSER MAPFN NULLFN)                             (* bvm: "13-Sep-85 16:41")

          (* * Apply MAPFN to each selected item in TABLEBROWSER -- args (TABLEBROWSER ITEM))


    (LET ((ITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER))
	  (ITEM# (SUB1 (fetch (TABLEBROWSER TBFIRSTSELECTEDITEM) of BROWSER)))
	  (LASTITEM# (fetch (TABLEBROWSER TBLASTSELECTEDITEM) of BROWSER))
	  ITEM)
         (COND
	   ((ILESSP ITEM# LASTITEM#)
	     (until (IGREATERP (add ITEM# 1)
			       LASTITEM#)
		when (fetch (TABLEITEM TISELECTED) of (SETQ ITEM (TB.FETCHNTH ITEMS ITEM#)))
		do (APPLY* MAPFN BROWSER ITEM)))
	   (NULLFN                                           (* Nothing selected)
		   (APPLY* NULLFN BROWSER])

(TB.FIND.ITEM
  [LAMBDA (BROWSER PREDFN FIRST# LAST# BACKWARDSFLG)         (* bvm: "13-Sep-85 16:41")

          (* * Returns the first item in the designated range satisfying (PREDFN browser item); range defaults to whole 
	  browser)


    (LET ((LO (COND
		(FIRST# (IMAX FIRST# 1))
		(T 1)))
	  [HI (COND
		(LAST# (IMIN LAST# (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)))
		(T (fetch (TABLEBROWSER TB#ITEMS) of BROWSER]
	  (ITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER))
	  I END INCREMENT ITEM)
         (COND
	   ((ILEQ LO HI)
	     (COND
	       (BACKWARDSFLG (SETQ I (ADD1 HI))
			     (SETQ END LO)
			     (SETQ INCREMENT -1))
	       (T (SETQ I (SUB1 LO))
		  (SETQ END HI)
		  (SETQ INCREMENT 1)))
	     (SELECTQ PREDFN
		      (DELETED (SETQ PREDFN (FUNCTION TB.ITEM.DELETED?)))
		      (SELECTED (SETQ PREDFN (FUNCTION TB.ITEM.SELECTED?)))
		      NIL)
	     (when [APPLY* PREDFN BROWSER (SETQ ITEM (TB.FETCHNTH ITEMS (add I INCREMENT]
		do (RETURN ITEM) repeatuntil (EQ I END])

(TB.ITEM.SELECTED?
  [LAMBDA (BROWSER ITEM)                                     (* bvm: "13-Sep-85 16:35")
    (fetch TISELECTED of ITEM])

(TB.ITEM.DELETED?
  [LAMBDA (BROWSER ITEM)                                     (* bvm: "13-Sep-85 16:34")
    (fetch TIDELETED of ITEM])
)
(DEFINEQ

(TB.CLEAR.LINE
  [LAMBDA (BROWSER ITEM LEFT WIDTH)                          (* bvm: " 9-Sep-85 00:40")

          (* * Clears the contents of ITEM's line starting at xpos LEFT for width WIDTH. Defaults to whole line)


    (BLTSHADE WHITESHADE (fetch (TABLEBROWSER TBWINDOW) of BROWSER)
	      (OR LEFT 0)
	      (IDIFFERENCE (TB.YCOORD.FROM.ITEM BROWSER ITEM)
			   (fetch (TABLEBROWSER TBFONTDESCENT) of BROWSER))
	      WIDTH
	      (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER)
	      (QUOTE REPLACE])

(TB.USERDATA
  [LAMBDA ARGS                                               (* bvm: " 9-Sep-85 00:16")
    (COND
      ((NEQ ARGS 0)
	(LET ((BROWSER (ARG ARGS 1)))
	     (PROG1 (fetch (TABLEBROWSER TBUSERDATA) of BROWSER)
		    (COND
		      ((GREATERP ARGS 1)
			(replace (TABLEBROWSER TBUSERDATA) of BROWSER with (ARG ARGS 2])

(TB.WINDOW
  [LAMBDA (BROWSER)                                          (* bvm: " 8-Sep-85 18:27")
    (FETCH (TABLEBROWSER TBWINDOW) OF BROWSER])
)



(* Display)

(DEFINEQ

(TB.REPAINTFN
  [LAMBDA (WINDOW REGION)                                    (* bvm: "10-Sep-85 13:00")
    (PROG [(BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER]
          (AND (NEQ (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)
		    0)
	       (RESETLST (COND
			   ((OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
						T T)
			     (TB.DISPLAY.LINES BROWSER (TB.FIRST.VISIBLE.ITEM# BROWSER REGION)
					       (TB.LAST.VISIBLE.ITEM# BROWSER REGION)))
			   (T (TB.BROWSER.BUSY BROWSER])

(TB.RESHAPEFN
  [LAMBDA (WINDOW OLDIMAGEBM OLDREGION)                      (* bvm: "10-Sep-85 13:00")
    (RESETLST (PROG ((BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)))
		     (REGION (DSPCLIPPINGREGION NIL WINDOW))
		     ITEM#)
		    [COND
		      ((NOT (OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
						T T))        (* Browser is busy, have to wait until it is ready.
							     But don't tie up mouse!)
			(ALLOW.BUTTON.EVENTS)
			(OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
					    NIL T))
		      ((NOT (fetch (TABLEBROWSER TBREADY) of BROWSER))
                                                             (* Browser not functional)
			(RETURN (RESHAPEBYREPAINTFN WINDOW OLDIMAGEBM OLDREGION]
		    (SETQ ITEM# (TB.FIRST.VISIBLE.ITEM# BROWSER REGION))
		    (TB.SET.FONT BROWSER)
		    (WYOFFSET (ITIMES (SUB1 ITEM#)
				      (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER))
			      WINDOW)
		    (TB.DISPLAY.LINES BROWSER ITEM# (TB.LAST.VISIBLE.ITEM# BROWSER REGION])

(TB.SCROLLFN
  [LAMBDA (WINDOW DX DY CONTINUOUSFLG)                       (* bvm: " 8-Sep-85 16:42")

          (* * only scroll if can get the monitor lock * *)


    (RESETLST (PROG [(BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER]
		    (COND
		      ((OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
					   T T)
			(SCROLLBYREPAINTFN WINDOW DX DY CONTINUOUSFLG))
		      (T (TB.BROWSER.BUSY BROWSER])

(TB.DISPLAY.LINES
  [LAMBDA (BROWSER FIRST# LAST#)                             (* bvm: "13-Sep-85 16:41")
    (for ITEM# from (IMAX FIRST# 1) to (IMIN LAST# (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
       bind (WINDOW ←(fetch (TABLEBROWSER TBWINDOW) of BROWSER))
	    (ITEMS ←(fetch (TABLEBROWSER TBITEMS) of BROWSER))
	    (MAXXPOS ←(fetch (TABLEBROWSER TBMAXXPOS) of BROWSER))
	    (PRINTFN ←(fetch (TABLEBROWSER TBPRINTFN) of BROWSER))
	    EXTENTCHANGED ITEM HERE EXTENT
       do (SETQ ITEM (TB.FETCHNTH ITEMS ITEM#))
	  (TB.PRINT.LINE BROWSER ITEM WINDOW PRINTFN)        (* keep track of maximum width printed to, so window's 
							     EXTENT is always right)
	  (COND
	    ((ILESSP MAXXPOS (SETQ HERE (DSPXPOSITION NIL WINDOW)))
	      (SETQ MAXXPOS HERE)
	      (SETQ EXTENTCHANGED T)))
       finally (COND
		 (EXTENTCHANGED (replace (TABLEBROWSER TBMAXXPOS) of BROWSER with MAXXPOS)
				(replace (REGION WIDTH) of (SETQ EXTENT (fetch (TABLEBROWSER TBEXTENT)
									   of BROWSER))
				   with MAXXPOS)
				(WINDOWPROP WINDOW (QUOTE EXTENT)
					    EXTENT])

(TB.PRINT.LINE
  [LAMBDA (BROWSER ITEM WINDOW PRINTFN)                      (* bvm: " 9-Sep-85 17:52")
    (LET ((YPOS (TB.YCOORD.FROM.ITEM BROWSER ITEM)))
         (MOVETO TB.LEFT.MARGIN YPOS WINDOW)
         (POSITION WINDOW 0)
         (APPLY* PRINTFN BROWSER ITEM WINDOW)
         [TB.SHOW.SELECTION BROWSER ITEM (COND
			      ((fetch (TABLEITEM TISELECTED) of ITEM)
				(QUOTE REPLACE))
			      (T (QUOTE ERASE]
         (COND
	   ((fetch (TABLEITEM TIDELETED) of ITEM)
	     (TB.SHOW.DELETION BROWSER ITEM WINDOW (QUOTE REPLACE])

(TB.FIRST.VISIBLE.ITEM#
  [LAMBDA (BROWSER REGION)                                   (* bvm: " 8-Sep-85 16:42")
                                                             (* Computes number of the first item in TABLEBROWSER 
							     that is visible in REGION)
    (IMAX 1 (IQUOTIENT (IDIFFERENCE (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
				    (IPLUS (fetch (REGION TOP) of REGION)
					   (fetch (TABLEBROWSER TBFONTDESCENT) of BROWSER)))
		       (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER])

(TB.LAST.VISIBLE.ITEM#
  [LAMBDA (BROWSER REGION)                                   (* bvm: " 8-Sep-85 16:42")
                                                             (* Computes number of the last item in TABLEBROWSER 
							     that is visible in REGION)
    (IMIN (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)
	  (IQUOTIENT (IPLUS (IDIFFERENCE (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
					 (IDIFFERENCE (fetch (REGION BOTTOM) of REGION)
						      (fetch (TABLEBROWSER TBFONTASCENT)
							 of BROWSER)))
			    (SUB1 (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER)))
		     (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER])

(TB.ITEM.VISIBLE?
  [LAMBDA (BROWSER ITEM)                                     (* bvm: "10-Sep-85 12:18")

          (* * True if ITEM is visible in window of BROWSER)


    (LET [(YPOS (TB.YCOORD.FROM.ITEM BROWSER ITEM))
	  (CLIP (DSPCLIPPINGREGION NIL (fetch (TABLEBROWSER TBWINDOW) of BROWSER]
         (AND (IGEQ (IDIFFERENCE YPOS (fetch (TABLEBROWSER TBFONTDESCENT) of BROWSER))
		    (fetch (REGION BOTTOM) of CLIP))
	      (ILEQ (IPLUS YPOS (fetch (TABLEBROWSER TBFONTASCENT) of BROWSER))
		    (fetch (REGION TOP) of CLIP])

(TB.YCOORD.FROM.ITEM
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 9-Sep-85 00:40")
    (IDIFFERENCE (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
		 (ITIMES (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER)
			 (OR (FIXP ITEM)
			     (fetch (TABLEITEM TI#) of ITEM])

(TB.ITEM#.FROM.YCOORD
  [LAMBDA (BROWSER YPOS)                                     (* bvm: " 9-Sep-85 00:41")
    (PROG [(N (IQUOTIENT (IPLUS (IDIFFERENCE (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
					     YPOS)
				(fetch (TABLEBROWSER TBFONTASCENT) of BROWSER))
			 (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER]
          (RETURN (COND
		    ((ILEQ N 0)
		      1)
		    (T (IMIN N (fetch (TABLEBROWSER TB#ITEMS) of BROWSER])

(TB.ITEM.FROM.YCOORD
  [LAMBDA (BROWSER YPOS)                                     (* bvm: "13-Sep-85 16:41")
    (PROG [(N (IQUOTIENT (IPLUS (IDIFFERENCE (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
					     YPOS)
				(fetch (TABLEBROWSER TBFONTASCENT) of BROWSER))
			 (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER]
          (RETURN (TB.FETCHNTH (fetch (TABLEBROWSER TBITEMS) of BROWSER)
			       (COND
				 ((ILEQ N 0)
				   1)
				 (T (IMIN N (fetch (TABLEBROWSER TB#ITEMS) of BROWSER])

(TB.SHOW.DELETION
  [LAMBDA (BROWSER ITEM WINDOW OPERATION)                    (* bvm: " 9-Sep-85 00:40")

          (* * Draws or erases, for OPERATION = REPLACE or ERASE, the line indicating that ITEM is deleted)


    (BLTSHADE BLACKSHADE WINDOW TB.LEFT.MARGIN (IDIFFERENCE (IPLUS (TB.YCOORD.FROM.ITEM BROWSER ITEM)
								   (LRSH (fetch (TABLEBROWSER 
										     TBFONTASCENT)
									    of BROWSER)
									 1))
							    (LRSH TB.DELETEDLINEHEIGHT 1))
	      NIL TB.DELETEDLINEHEIGHT OPERATION])

(TB.SHOW.SELECTION
  [LAMBDA (BROWSER ITEM OPERATION)                           (* bvm: " 9-Sep-85 00:40")

          (* * Displays or erases, per OPERATION = REPLACE or ERASE, the mark indicating that ITEM is selected)


    (BITBLT TB.SELECTION.BITMAP 0 0 (fetch (TABLEBROWSER TBWINDOW) of BROWSER)
	    0
	    (IPLUS (TB.YCOORD.FROM.ITEM BROWSER ITEM)
		   (LRSH (fetch (TABLEBROWSER TBFONTASCENT) of BROWSER)
			 1)
		   -5)
	    NIL NIL (QUOTE INPUT)
	    OPERATION])

(TB.UPDATE.DISPLAY
  [LAMBDA (BROWSER FROMITEM# TYPE)                           (* bvm: "10-Sep-85 13:10")

          (* * Updates the display window appropriately after a TYPE operation (REMOVE or INSERT) on TABLEBROWSER that affects
	  items starting at FROMITEM#)


    (PROG ((WINDOW (fetch (TABLEBROWSER TBWINDOW) of BROWSER))
	   (EXTENT (fetch (TABLEBROWSER TBEXTENT) of BROWSER))
	   (LASTITEM# (fetch (TABLEBROWSER TB#ITEMS) of BROWSER))
	   (FONTHEIGHT (fetch (TABLEBROWSER TBFONTHEIGHT) of BROWSER))
	   (YPOS (IDIFFERENCE (TB.YCOORD.FROM.ITEM BROWSER FROMITEM#)
			      (fetch (TABLEBROWSER TBFONTDESCENT) of BROWSER)))
	   DELTA HEIGHT LAST# CLIP BOTTOM EXTENTBOTTOM)      (* YPOS is the bottom of the line corresponding to 
							     FROMITEM#)
          [add (fetch (REGION HEIGHT) of EXTENT)
	       (SETQ DELTA (SELECTQ TYPE
				    (REMOVE (IMINUS FONTHEIGHT))
				    (INSERT FONTHEIGHT)
				    (SHOULDNT]
          (COND
	    ([IGREATERP YPOS (fetch (REGION TOP) of (SETQ CLIP (DSPCLIPPINGREGION NIL WINDOW]
                                                             (* Changed item above top of window, so no visible 
							     change -- just cheat the origin appropriately)
	      (add (fetch (TABLEBROWSER TBORIGIN) of BROWSER)
		   DELTA))
	    (T                                               (* Changed item visible or below bottom of window, so 
							     bottom of extent changes)
	       (replace (REGION BOTTOM) of EXTENT with (SETQ EXTENTBOTTOM (IDIFFERENCE
							   (fetch (REGION BOTTOM) of EXTENT)
							   DELTA)))
	       (COND
		 ((ILEQ (IPLUS YPOS FONTHEIGHT)
			(SETQ BOTTOM (fetch (REGION BOTTOM) of CLIP)))
                                                             (* Below bottom of window, so we're done)
		   )
		 ((TB.ITEM.UPDATABLE? BROWSER FROMITEM#)     (* If window is visible, update it now)
		   (SELECTQ TYPE
			    (INSERT                          (* Push down display, redisplay item FROMITEM#)
				    (BITBLT WINDOW 0 (IPLUS BOTTOM FONTHEIGHT)
					    WINDOW 0 BOTTOM (fetch (REGION WIDTH) of EXTENT)
					    (IDIFFERENCE YPOS BOTTOM)
					    (QUOTE INPUT)
					    (QUOTE REPLACE))
				    (TB.DISPLAY.LINES BROWSER FROMITEM# FROMITEM#))
			    [REMOVE                          (* Pull up display, redisplay last visible item)
				    (BITBLT WINDOW 0 BOTTOM WINDOW 0 (IPLUS BOTTOM FONTHEIGHT)
					    (fetch (REGION WIDTH) of EXTENT)
					    (IDIFFERENCE YPOS BOTTOM)
					    (QUOTE INPUT)
					    (QUOTE REPLACE))
				    (TB.DISPLAY.LINES BROWSER (SETQ LAST#
							(IPLUS FROMITEM# (IQUOTIENT (IDIFFERENCE
										      YPOS BOTTOM)
										    FONTHEIGHT)))
						      (ADD1 LAST#))
                                                             (* May have to display two lines if the bottom line of 
							     window was a half line)
				    (COND
				      ((GREATERP EXTENTBOTTOM BOTTOM)
                                                             (* Clear everything below the extent)
					(BLTSHADE WHITESHADE WINDOW 0 BOTTOM NIL (IDIFFERENCE 
										     EXTENTBOTTOM 
											   BOTTOM)
						  (QUOTE REPLACE]
			    (SHOULDNT])
)



(* Selection)

(DEFINEQ

(TB.BUTTONEVENTFN
  [LAMBDA (WINDOW)                                           (* bvm: " 6-Sep-85 15:23")
    (TOTOPW WINDOW)
    (LET (FN)
         (COND
	   ((INSIDEP (DSPCLIPPINGREGION NIL WINDOW)
		     (LASTMOUSEX WINDOW)
		     (LASTMOUSEY WINDOW))
	     (TB.DO.UNLESS.BUSY WINDOW (FUNCTION TB.DO.ITEM.SELECTION)))
	   ((LASTMOUSESTATE (ONLY RIGHT))
	     (DOWINDOWCOM WINDOW))
	   ([AND (LASTMOUSESTATE (ONLY MIDDLE))
		 (SETQ FN (fetch (TABLEBROWSER TBTITLEEVENTFN) of (WINDOWPROP WINDOW (QUOTE 
										     TABLEBROWSER]
	     (TB.DO.UNLESS.BUSY WINDOW FN])

(TB.DO.UNLESS.BUSY
  [LAMBDA (WINDOW FN ARGUMENT)                               (* bvm: " 8-Sep-85 16:42")
    (RESETLST (PROG [(BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER]
		    (COND
		      ((AND (fetch (TABLEBROWSER TBREADY) of BROWSER)
			    (OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
						T T))
			(APPLY* FN WINDOW BROWSER ARGUMENT])

(TB.DO.ITEM.SELECTION
  [LAMBDA (WINDOW)                                           (* bvm: "10-Sep-85 18:31")
    (DECLARE (GLOBALVARS LASTMOUSEBUTTONS)
	     (SPECVARS SELECTIONSTATE BROWSER ITEMS FIRSTVISIBLE# LASTVISIBLE#))
    (PROG ((BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)))
	   ITEMS SELECTIONREGION FIRST# LAST# FIRSTVISIBLE# LASTVISIBLE# SELECTIONSTATE NEWSELECTION 
	   OLDSELECTION SEL# OLDSEL# CTRLDOWN OLDLASTMOUSEBUTTONS ITEM LASTX LASTY)
          (COND
	    ((EQ (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)
		 0)                                          (* Nothing to select)
	      (RETURN)))
          (SETQ SELECTIONREGION (DSPCLIPPINGREGION NIL WINDOW))
          (SETQ LAST# (fetch TBLASTSELECTEDITEM of BROWSER))
          (SETQ FIRST# (fetch TBFIRSTSELECTEDITEM of BROWSER))
          (SETQ FIRSTVISIBLE# (TB.FIRST.VISIBLE.ITEM# BROWSER SELECTIONREGION))
          (SETQ LASTVISIBLE# (TB.LAST.VISIBLE.ITEM# BROWSER SELECTIONREGION))
          (SETQ ITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER))

          (* * keep looping until all mouse buttons are up * *)


          (do (GETMOUSESTATE)
	      (COND
		[[NOT (INSIDEP SELECTIONREGION (SETQ LASTX (LASTMOUSEX WINDOW))
			       (SETQ LASTY (LASTMOUSEY WINDOW]

          (* I would like to just return here and let the next window take over, but current mouse arrangement means I'll 
	  never get control back unless user lets up on mouse)


		  (COND
		    ((NEQ SELECTIONSTATE TS.IDLE)
		      (TB.UNDOSELECTION)
		      (SETQ OLDSELECTION)))
		  (COND
		    ((LASTMOUSESTATE UP)
		      (RETURN))
		    (T (BLOCK]
		((LASTMOUSESTATE UP)                         (* Make selection permanent)
		  (AND OLDSELECTION (SETQ OLDSEL# (fetch TI# of OLDSELECTION)))
		  (SELECTC SELECTIONSTATE
			   (TS.REPLACING (for ITEM selectedfrom BROWSER
					    do (replace TISELECTED of ITEM with NIL))
					 (replace TISELECTED of OLDSELECTION with T)
					 (replace TBFIRSTSELECTEDITEM of BROWSER
					    with (replace TBLASTSELECTEDITEM of BROWSER with OLDSEL#))
					 )
			   (TS.ADDING (TB.SELECTRANGE BROWSER OLDSEL# OLDSEL# T))
			   (TS.REMOVING (TB.DESELECTRANGE BROWSER OLDSEL# OLDSEL#))
			   (TS.EXTENDING.HI (TB.SELECTRANGE BROWSER (ADD1 LAST#)
							    OLDSEL# CTRLDOWN))
			   (TS.EXTENDING.LO (TB.SELECTRANGE BROWSER OLDSEL# (SUB1 FIRST#)
							    CTRLDOWN))
			   (TS.SHRINKING.HI (TB.DESELECTRANGE BROWSER (ADD1 OLDSEL#)
							      LAST#))
			   (TS.SHRINKING.LO (TB.DESELECTRANGE BROWSER FIRST# (SUB1 OLDSEL#)))
			   NIL)
		  (RETURN))
		[(AND NIL                                    (* In a special column))
		  (COND
		    ((NEQ SELECTIONSTATE TS.IDLE)
		      (TB.UNDOSELECTION)
		      (SETQ OLDSELECTION]
		((OR (NEQ (SETQ NEWSELECTION (TB.ITEM.FROM.YCOORD BROWSER LASTY))
			  OLDSELECTION)
		     (NEQ LASTMOUSEBUTTONS OLDLASTMOUSEBUTTONS))
		  [COND
		    [(AND (fetch TIUNSELECTABLE of NEWSELECTION)
			  (NOT (LASTMOUSESTATE RIGHT)))      (* Can't select that item, so revert to idle)
		      (COND
			((NEQ SELECTIONSTATE TS.IDLE)
			  (TB.UNDOSELECTION]
		    ((LASTMOUSESTATE LEFT)                   (* Set (change) the selection to this single item)
		      (COND
			((EQ SELECTIONSTATE TS.REPLACING)
			  (TB.SHOW.SELECTION BROWSER OLDSELECTION (QUOTE ERASE)))
			(T (TB.DECONSIDERRANGE FIRSTVISIBLE# LASTVISIBLE#)
			   (SETQ SELECTIONSTATE TS.REPLACING)))
		      (TB.SHOW.SELECTION BROWSER NEWSELECTION (QUOTE REPLACE)))
		    [(LASTMOUSESTATE MIDDLE)                 (* Add or remove this item to the selection)
		      (COND
			[(KEYDOWNP (QUOTE CTRL))             (* Deselect this item)
			  (SELECTC SELECTIONSTATE
				   (TS.REMOVING (TB.SHOW.SELECTION BROWSER OLDSELECTION (QUOTE 
											  REPLACE)))
				   (TS.IDLE)
				   (TB.UNDOSELECTION))
			  (SETQ SELECTIONSTATE (COND
			      ((fetch TISELECTED of NEWSELECTION)
				(TB.SHOW.SELECTION BROWSER NEWSELECTION (QUOTE ERASE))
				TS.REMOVING)
			      (T TS.IDLE]
			(T (SELECTC SELECTIONSTATE
				    (TS.ADDING (TB.SHOW.SELECTION BROWSER OLDSELECTION (QUOTE ERASE)))
				    (TS.IDLE)
				    (TB.UNDOSELECTION))
			   (SETQ SELECTIONSTATE (COND
			       ((NOT (fetch TISELECTED of NEWSELECTION))
				 (TB.SHOW.SELECTION BROWSER NEWSELECTION (QUOTE REPLACE))
				 TS.ADDING)
			       (T TS.IDLE]
		    ((LASTMOUSESTATE RIGHT)                  (* Extend: either up or down, or shrink a selection.
							     This is messy)
		      (SETQ SEL# (fetch TI# of NEWSELECTION))
		      (SETQ OLDSEL# (AND OLDSELECTION (fetch TI# of OLDSELECTION)))
		      (SELECTC SELECTIONSTATE
			       [TS.EXTENDING.HI (COND
						  ((IGREATERP SEL# OLDSEL#)
                                                             (* Extend further)
						    (TB.CONSIDERRANGE (ADD1 OLDSEL#)
								      SEL# CTRLDOWN))
						  (T         (* Shrinking back)
						     (TB.RECONSIDERRANGE (ADD1 (COND
										 ((IGREATERP SEL# 
											    LAST#)
										   SEL#)
										 (T (SETQ 
										   SELECTIONSTATE 
										      TS.IDLE)
										    LAST#)))
									 OLDSEL#]
			       [TS.EXTENDING.LO (COND
						  ((ILESSP SEL# OLDSEL#)
                                                             (* Extend further)
						    (TB.CONSIDERRANGE SEL# (SUB1 OLDSEL#)
								      CTRLDOWN))
						  (T         (* Shrinking back)
						     (TB.RECONSIDERRANGE OLDSEL#
									 (SUB1 (COND
										 ((ILESSP SEL# FIRST#)
										   SEL#)
										 (T (SETQ 
										   SELECTIONSTATE 
										      TS.IDLE)
										    FIRST#]
			       [TS.SHRINKING.HI (COND
						  [(IGEQ SEL# OLDSEL#)
                                                             (* Shrinking less)
						    (TB.RECONSIDERRANGE (ADD1 OLDSEL#)
									(COND
									  ((ILESSP SEL# LAST#)
									    SEL#)
									  (T (SETQ SELECTIONSTATE 
									       TS.IDLE)
									     LAST#]
						  ((IGEQ SEL# FIRST#)
                                                             (* Shrinking further)
						    (TB.DECONSIDERRANGE (ADD1 SEL#)
									OLDSEL#))
						  (T         (* Too far to shrink)
						     (TB.RECONSIDERRANGE FIRST# LAST#)
						     (SETQ SELECTIONSTATE TS.IDLE]
			       [TS.SHRINKING.LO (COND
						  ((ILEQ SEL# OLDSEL#)
                                                             (* Shrinking less)
						    (TB.RECONSIDERRANGE (COND
									  ((IGREATERP SEL# FIRST#)
									    SEL#)
									  (T (SETQ SELECTIONSTATE 
									       TS.IDLE)
									     FIRST#))
									(SUB1 OLDSEL#)))
						  ((ILEQ SEL# LAST#)
                                                             (* Shrinking further)
						    (TB.DECONSIDERRANGE OLDSEL# (SUB1 SEL#)))
						  (T         (* Too far to shrink)
						     (TB.RECONSIDERRANGE FIRST# LAST#)
						     (SETQ SELECTIONSTATE TS.IDLE]
			       (COND
				 ((NOT (IGREATERP FIRST# LAST#))
				   (COND
				     ((NEQ SELECTIONSTATE TS.IDLE)
				       (TB.UNDOSELECTION)))
				   (SETQ CTRLDOWN (KEYDOWNP (QUOTE CTRL)))
				   (SETQ SELECTIONSTATE (COND
				       ((IGREATERP SEL# LAST#)
					 (TB.CONSIDERRANGE (ADD1 LAST#)
							   SEL# CTRLDOWN)
					 TS.EXTENDING.HI)
				       ((ILESSP SEL# FIRST#)
					 (TB.CONSIDERRANGE SEL# (SUB1 FIRST#)
							   CTRLDOWN)
					 TS.EXTENDING.LO)
				       ((IGREATERP SEL# (LRSH (IPLUS LAST# FIRST#)
							      1))
					 (TB.DECONSIDERRANGE (ADD1 SEL#)
							     LAST#)
					 TS.SHRINKING.HI)
				       (T (TB.DECONSIDERRANGE FIRST# (SUB1 SEL#))
					  TS.SHRINKING.LO]
		  (SETQ OLDLASTMOUSEBUTTONS LASTMOUSEBUTTONS)
		  (SETQ OLDSELECTION NEWSELECTION])

(TB.DECONSIDERRANGE
  [LAMBDA (FIRST# LAST#)                                     (* bvm: "13-Sep-85 16:41")

          (* * Change display so that items from FIRST# to LAST# are marked as unselected.)


    (DECLARE (USEDFREE BROWSER ITEMS FIRSTVISIBLE# LASTVISIBLE#))
    (for I from (IMAX FIRST# FIRSTVISIBLE#) to (IMIN LAST# LASTVISIBLE#)
       do (TB.SHOW.SELECTION BROWSER (TB.FETCHNTH ITEMS I)
			     (QUOTE ERASE])

(TB.CONSIDERRANGE
  [LAMBDA (FIRST# LAST# EVENIFDELETED)                       (* bvm: "13-Sep-85 16:41")

          (* * Change display so that items from FIRST# to LAST# are marked as selected. Deleted items are not selected unless
	  EVENIFDELETED is true)


    (DECLARE (USEDFREE BROWSER ITEMS FIRSTVISIBLE# LASTVISIBLE#))
    (for I from (IMAX FIRST# FIRSTVISIBLE#) to (IMIN LAST# LASTVISIBLE#) bind ITEM
       do (SETQ ITEM (TB.FETCHNTH ITEMS I))
	  (COND
	    ([AND (NOT (fetch TIUNSELECTABLE of ITEM))
		  (OR EVENIFDELETED (NOT (fetch TIDELETED of ITEM]
	      (TB.SHOW.SELECTION BROWSER ITEM (QUOTE REPLACE])

(TB.DESELECTRANGE
  [LAMBDA (BROWSER FIRST# LAST#)                             (* bvm: "13-Sep-85 16:41")

          (* * Mark internally items FIRST# thru LAST# as unselected. Keeps TBFIRSTSELECTEDITEM and TBLASTSELECTEDITEM up to 
	  date. Assumes display has already been appropriately modified)


    (COND
      ((ILEQ FIRST# LAST#)
	(PROG ((ITEMS (fetch TBITEMS of BROWSER)))
	      (for I from FIRST# to LAST# do (replace TISELECTED of (TB.FETCHNTH ITEMS I)
						with NIL))
	      (COND
		[(EQ FIRST# (fetch TBFIRSTSELECTEDITEM of BROWSER))
		  (replace TBFIRSTSELECTEDITEM of BROWSER
		     with (COND
			    ((TB.FIND.SELECTED.ITEM BROWSER (ADD1 LAST#)
						    (fetch TBLASTSELECTEDITEM of BROWSER)))
			    (T (replace TBLASTSELECTEDITEM of BROWSER with 0)
                                                             (* Null selection indicated by first GT last.)
			       (ADD1 (fetch (TABLEBROWSER TB#ITEMS) of BROWSER]
		((EQ LAST# (fetch TBLASTSELECTEDITEM of BROWSER))
		  (replace TBLASTSELECTEDITEM of BROWSER with (OR (TB.REV.FIND.SELECTED.ITEM
								    BROWSER
								    (fetch TBFIRSTSELECTEDITEM
								       of BROWSER)
								    (SUB1 FIRST#))
								  1])

(TB.RECONSIDERRANGE
  [LAMBDA (FIRST# LAST#)                                     (* bvm: "13-Sep-85 16:41")

          (* * Change display so that messages from FIRST# to LAST# are marked as selected or unselected according to the 
	  truth of the matter.)


    (DECLARE (USEDFREE BROWSER ITEMS FIRSTVISIBLE# LASTVISIBLE#))
    (for I from (IMAX FIRST# FIRSTVISIBLE#) to (IMIN LAST# LASTVISIBLE#) bind ITEM
       do (TB.SHOW.SELECTION BROWSER (SETQ ITEM (TB.FETCHNTH ITEMS I))
			     (COND
			       ((fetch TISELECTED of ITEM)
				 (QUOTE REPLACE))
			       (T (QUOTE ERASE])

(TB.SELECTRANGE
  [LAMBDA (BROWSER FIRST# LAST# EVENIFDELETED)               (* bvm: "13-Sep-85 16:41")

          (* * Mark internally items FIRST# thru LAST# as selected. Do not select deleted messages unless EVENIFDELETED is 
	  true. Keeps TBFIRSTSELECTEDITEM and TBLASTSELECTEDITEM up to date. Assumes display has already been appropriately 
	  modified)


    (PROG ((ITEMS (fetch TBITEMS of BROWSER))
	   (FIRSTSEL (fetch TBFIRSTSELECTEDITEM of BROWSER))
	   (LASTSEL (fetch TBLASTSELECTEDITEM of BROWSER))
	   ITEM)
          [for I from FIRST# to LAST#
	     do (SETQ ITEM (TB.FETCHNTH ITEMS I))
		(COND
		  ([AND (NOT (fetch TIUNSELECTABLE of ITEM))
			(OR EVENIFDELETED (NOT (fetch TIDELETED of ITEM]
		    (replace TISELECTED of ITEM with T]
          (COND
	    ((OR (IGREATERP FIRSTSEL LASTSEL)
		 (ILESSP FIRST# (fetch TBFIRSTSELECTEDITEM of BROWSER)))
	      (replace TBFIRSTSELECTEDITEM of BROWSER with FIRST#)))
          (COND
	    ((OR (IGREATERP FIRSTSEL LASTSEL)
		 (IGREATERP LAST# (fetch TBLASTSELECTEDITEM of BROWSER)))
	      (replace TBLASTSELECTEDITEM of BROWSER with LAST#])

(TB.UNDOSELECTION
  [LAMBDA NIL                                                (* bvm: " 6-Sep-85 15:04")

          (* * Restore browser to state before any selections were attempted)


    (DECLARE (USEDFREE FIRSTVISIBLE# LASTVISIBLE# SELECTIONSTATE))
    (TB.RECONSIDERRANGE FIRSTVISIBLE# LASTVISIBLE#)
    (SETQ SELECTIONSTATE TS.IDLE])

(TB.FIND.SELECTED.ITEM
  [LAMBDA (BROWSER FIRST# LAST#)                             (* bvm: "13-Sep-85 16:41")
    (find I from (OR FIRST# 1) to (OR LAST# (fetch TB#ITEMS of BROWSER))
       bind (ITEMS ←(fetch TBITEMS of BROWSER)) suchthat (fetch TISELECTED of (TB.FETCHNTH ITEMS I])

(TB.REV.FIND.SELECTED.ITEM
  [LAMBDA (BROWSER FIRST# LAST#)                             (* bvm: "13-Sep-85 16:41")
    (find I from (OR LAST# (fetch TB#ITEMS of BROWSER)) to (OR FIRST# 1) by -1
       bind (ITEMS ←(fetch TBITEMS of BROWSER)) suchthat (fetch TISELECTED of (TB.FETCHNTH ITEMS I])
)
(DEFINEQ

(TB.COPYBUTTONEVENTFN
  [LAMBDA (WINDOW)                                           (* bvm: "13-Sep-85 16:41")

          (* * copy select an item from the window.)


    (PROG ((BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)))
	   ITEMS SELECTIONREGION COPYFN CURRENTITEM NEWITEM LASTX LASTY)
          [COND
	    ([OR (NULL (SETQ COPYFN (fetch (TABLEBROWSER TBCOPYFN) of BROWSER)))
		 (NULL (SETQ ITEMS (fetch (TABLEBROWSER TBITEMS) of BROWSER]
	      (RETURN (TOTOPW WINDOW]
          (SETQ SELECTIONREGION (DSPCLIPPINGREGION NIL WINDOW))
      LP  (TOTOPW WINDOW)
          (SETQ NEWITEM (AND (INSIDEP SELECTIONREGION (SETQ LASTX (LASTMOUSEX WINDOW))
				      (SETQ LASTY (LASTMOUSEY WINDOW)))
			     (TB.ITEM#.FROM.YCOORD BROWSER LASTY)))
          [COND
	    ((NEQ CURRENTITEM NEWITEM)
	      (COND
		(CURRENTITEM                                 (* turn off old selection.)
			     (TB.SHOW.COPY.SELECTION BROWSER CURRENTITEM)))
	      (COND
		((SETQ CURRENTITEM NEWITEM)
		  (TB.SHOW.COPY.SELECTION BROWSER CURRENTITEM]
                                                             (* wait for a button up or move out of region)
      LP2 (BLOCK)
          (COND
	    ((NOT (.COPYKEYDOWNP.))                          (* Finished, copy selected item)
	      [COND
		(CURRENTITEM (TB.SHOW.COPY.SELECTION BROWSER CURRENTITEM)
			     (APPLY* COPYFN BROWSER (TB.FETCHNTH ITEMS CURRENTITEM]
	      (RETURN))
	    ((MOUSESTATE UP)                                 (* button up, no action)
	      (GO LP2))
	    (T (GO LP])

(TB.SHOW.COPY.SELECTION
  [LAMBDA (BROWSER ITEM)                                     (* bvm: " 9-Sep-85 00:40")

          (* * underline this item in browser)


    (LET ((WINDOW (fetch (TABLEBROWSER TBWINDOW) of BROWSER)))
         (BLTSHADE GRAYSHADE WINDOW TB.LEFT.MARGIN (IDIFFERENCE (TB.YCOORD.FROM.ITEM BROWSER ITEM)
								(fetch (TABLEBROWSER TBFONTDESCENT)
								   of BROWSER))
		   NIL 2 (QUOTE INVERT])
)



(* Misc state change)

(DEFINEQ

(TB.BROWSER.BUSY
  [LAMBDA (BROWSER)                                          (* bvm: " 8-Sep-85 16:42")
    (RESETFORM (CURSOR TB.CROSSCURSOR)
	       (BLOCK 1000])

(TB.CLOSE/SHRINK
  [LAMBDA (WINDOW FLG)                                       (* bvm: " 9-Sep-85 00:42")
    (RESETLST (PROG ((BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)))
		     HOW?)
		    (RETURN (COND
			      ((OBTAIN.MONITORLOCK (fetch (TABLEBROWSER TBLOCK) of BROWSER)
						   T T)
				(COND
				  ((AND (SETQ HOW? (fetch (TABLEBROWSER TBCLOSEFN) of BROWSER))
					(SETQ HOW? (APPLY* HOW? BROWSER WINDOW FLG)))
				    [COND
				      ((NEQ HOW? (QUOTE DON'T))
					(TB.PROCESS (LIST HOW? (KWOTE BROWSER)
							  (KWOTE WINDOW)
							  (KWOTE FLG))
						    (QUOTE TB.UPDATE]
				    (QUOTE DON'T))
				  (T (TB.FINISH.CLOSE BROWSER WINDOW FLG T)
				     NIL)))
			      (T (printout PROMPTWINDOW T "Browser is busy, can't close")
				 (QUOTE DON'T])

(TB.CLOSEFN
  [LAMBDA (WINDOW)                                           (* bvm: " 6-Sep-85 12:25")
    (TB.CLOSE/SHRINK WINDOW (QUOTE CLOSE])

(TB.FINISH.CLOSE
  [LAMBDA (BROWSER WINDOW CLOSEFLG DONTCLOSE)                (* bvm: " 9-Sep-85 00:42")

          (* * Takes care of closing/shrinking WINDOW after an update or expunge. DONTCLOSE is true if neither occurred, in 
	  which case we are being called directly from the CLOSEFN and should not close/shrink the window ourselves)


    (WITH.MONITOR (fetch (TABLEBROWSER TBLOCK) of BROWSER)
		  (SELECTQ CLOSEFLG
			   (CLOSE (SETQ WINDOW (TB.FLUSH.WINDOW BROWSER WINDOW))
				  (OR DONTCLOSE (CLOSEW WINDOW)))
			   (SHRINK (WINDOWADDPROP WINDOW (QUOTE EXPANDFN)
						  (FUNCTION TB.EXPANDFN))
				   (WINDOWDELPROP WINDOW (QUOTE SHRINKFN)
						  (FUNCTION TB.SHRINKFN))
				   (OR DONTCLOSE (SHRINKW WINDOW)))
			   NIL])

(TB.FLUSH.WINDOW
  [LAMBDA (BROWSER WINDOW)                                   (* bvm: "11-Sep-85 21:59")
    (WINDOWDELPROP WINDOW (QUOTE CLOSEFN)
		   (FUNCTION TB.CLOSEFN))
    [ERSETQ (LET ((FN (fetch (TABLEBROWSER TBAFTERCLOSEFN) of BROWSER)))
	         (AND FN (APPLY* FN BROWSER WINDOW]
    (replace (TABLEBROWSER TBITEMS) of BROWSER with (replace (TABLEBROWSER TBWINDOW) of BROWSER
						       with NIL))
    (WINDOWPROP WINDOW (QUOTE TABLEBROWSER)
		NIL)
    (OR (OPENWP WINDOW)
	(OPENWP (WINDOWPROP WINDOW (QUOTE ICONWINDOW])

(TB.SET.FONT
  [LAMBDA (BROWSER FONT)                                     (* bvm: " 9-Sep-85 00:48")

          (* * Sets/changes font of TABLEBROWSER to be FONT. Clears window. Caller is responsible for repainting window)


    (PROG ((FONTGIVEN FONT)
	   (WINDOW (fetch (TABLEBROWSER TBWINDOW) of BROWSER))
	   WIDTH HEIGHT TOTALHEIGHT ASCENT ORIGIN FN)
          (CLEARW WINDOW)
          [SETQ FONT (FONTCREATE (OR FONT (fetch (TABLEBROWSER TBFONT) of BROWSER)
				     (DSPFONT NIL WINDOW]
          (DSPFONT FONT WINDOW)
          (DSPRIGHTMARGIN MAX.SMALLP WINDOW)
          (LINELENGTH (LRSH MAX.SMALLP 1)
		      WINDOW)
          (replace (TABLEBROWSER TBFONT) of BROWSER with FONT)
          [replace (TABLEBROWSER TBFONTHEIGHT) of BROWSER with (SETQ HEIGHT (FONTPROP FONT
										      (QUOTE HEIGHT]
          [replace (TABLEBROWSER TBFONTASCENT) of BROWSER with (SETQ ASCENT (FONTPROP FONT
										      (QUOTE ASCENT]
          (replace (TABLEBROWSER TBFONTDESCENT) of BROWSER with (FONTPROP FONT (QUOTE DESCENT)))
          (replace (TABLEBROWSER TBORIGIN) of BROWSER with (SETQ ORIGIN (IPLUS (DSPYPOSITION NIL 
											   WINDOW)
									       ASCENT)))
          (SETQ TOTALHEIGHT (ITIMES (fetch (TABLEBROWSER TB#ITEMS) of BROWSER)
				    HEIGHT))
          (WINDOWPROP WINDOW (QUOTE EXTENT)
		      (replace (TABLEBROWSER TBEXTENT) of BROWSER
			 with (create REGION
				      LEFT ← 0
				      BOTTOM ←(IDIFFERENCE ORIGIN TOTALHEIGHT)
				      WIDTH ←(SETQ WIDTH (WINDOWPROP WINDOW (QUOTE WIDTH)))
				      HEIGHT ← TOTALHEIGHT)))
          (replace (TABLEBROWSER TBMAXXPOS) of BROWSER with WIDTH)
          (COND
	    ((AND FONTGIVEN (SETQ FN (fetch (TABLEBROWSER TBFONTCHANGEFN) of BROWSER)))
                                                             (* Notify application program of font change)
	      (APPLY* FN BROWSER WINDOW])

(TB.SHRINKFN
  [LAMBDA (WINDOW)                                           (* bvm: " 6-Sep-85 12:14")
    (TB.CLOSE/SHRINK WINDOW (QUOTE SHRINK])

(TB.EXPANDFN
  [LAMBDA (WINDOW)                                           (* bvm: "10-Sep-85 13:00")

          (* * If browser changed while it was shrunk, update display accordingly)


    (LET [(BROWSER (WINDOWPROP WINDOW (QUOTE TABLEBROWSER]
         (WITH.MONITOR (fetch (TABLEBROWSER TBLOCK) of BROWSER)
		       (LET ((FIRSTCHANGEDITEM# (fetch (TABLEBROWSER TBUPDATEFROMHERE) of BROWSER))
			     REGION FN)                      (* Restore SHRINKFN prop if necessary)
			    (WINDOWADDPROP WINDOW (QUOTE SHRINKFN)
					   (FUNCTION TB.SHRINKFN)
					   T)
			    (COND
			      (FIRSTCHANGEDITEM#             (* Browser has changed since shrinking)
						 [COND
						   ((AND (EQ FIRSTCHANGEDITEM# 0)
							 (SETQ FN (fetch (TABLEBROWSER 
										 TBAFTEREXPUNGEFN)
								     of BROWSER)))
                                                             (* After expunge)
						     (APPLY* FN BROWSER WINDOW))
						   (T (TB.DISPLAY.LINES BROWSER
									[IMAX FIRSTCHANGEDITEM#
									      (TB.FIRST.VISIBLE.ITEM#
										BROWSER
										(SETQ REGION
										  (DSPCLIPPINGREGION
										    NIL WINDOW]
									(TB.LAST.VISIBLE.ITEM# 
											  BROWSER 
											   REGION]
						 (replace (TABLEBROWSER TBUPDATEFROMHERE)
						    of BROWSER with NIL])

(TB.ITEM.UPDATABLE?
  [LAMBDA (BROWSER ITEM)                                     (* bvm: "10-Sep-85 12:26")

          (* * True if window of BROWSER is open. If false, we update the TBUPDATEFROMHERE field, denoting that we should 
	  repaint window when it is opened)


    (COND
      ((OPENWP (fetch (TABLEBROWSER TBWINDOW) of BROWSER)))
      (T [LET ((N (fetch (TABLEBROWSER TBUPDATEFROMHERE) of BROWSER)))
	      (COND
		([OR (NULL N)
		     (IGREATERP N (OR (FIXP ITEM)
				      (SETQ ITEM (fetch TI# of ITEM]
                                                             (* Mark browser for display update after being 
							     unshrunk)
		  (replace (TABLEBROWSER TBUPDATEFROMHERE) of BROWSER with ITEM]
	 NIL])
)



(* Misc)

(DEFINEQ

(TB.PROCESS
  [LAMBDA (FORM NAME ALLOWLOGOUT RESTARTABLE)                (* bvm: "25-Mar-84 17:16")

          (* * Creates a process running FORM which by default is not restartable and will not permit LOGOUT while it is 
	  running)


    (ADD.PROCESS FORM (QUOTE NAME)
		 NAME
		 (QUOTE RESTARTABLE)
		 (OR RESTARTABLE (QUOTE NO))
		 (QUOTE BEFOREEXIT)
		 (COND
		   (ALLOWLOGOUT NIL)
		   (T (QUOTE DON'T])

(TB.FETCHNTH
  [LAMBDA (ITEMS N)                                          (* bvm: " 6-Sep-85 11:42")
    (CAR (NTH ITEMS N])
)

(RPAQQ TB.DELETEDLINEHEIGHT 1)

(RPAQ TB.SELECTION.BITMAP (READBITMAP))
(8 10
"L@@@"
"N@@@"
"O@@@"
"OH@@"
"OL@@"
"OH@@"
"O@@@"
"N@@@"
"L@@@"
"@@@@")
(RPAQ TB.CROSSCURSOR (CURSORCREATE (READBITMAP) 8 8))
(16 16
"L@@C"
"N@@G"
"G@@N"
"CHAL"
"ALCH"
"@NG@"
"@GN@"
"@CL@"
"@CL@"
"@GN@"
"@NG@"
"ALCH"
"CHAL"
"G@@N"
"N@@G"
"L@@C")(DECLARE: EVAL@COMPILE DONTCOPY 
(FILESLOAD (SOURCE)
	   TABLEBROWSERDECLS)


(RPAQQ TOCSTATES ((TS.IDLE 0)
		  (TS.REPLACING 1)
		  (TS.ADDING 2)
		  (TS.REMOVING 3)
		  (TS.EXTENDING.HI 4)
		  (TS.EXTENDING.LO 5)
		  (TS.SHRINKING.HI 6)
		  (TS.SHRINKING.LO 7)))
(DECLARE: EVAL@COMPILE 

(RPAQQ TS.IDLE 0)

(RPAQQ TS.REPLACING 1)

(RPAQQ TS.ADDING 2)

(RPAQQ TS.REMOVING 3)

(RPAQQ TS.EXTENDING.HI 4)

(RPAQQ TS.EXTENDING.LO 5)

(RPAQQ TS.SHRINKING.HI 6)

(RPAQQ TS.SHRINKING.LO 7)

(CONSTANTS (TS.IDLE 0)
	   (TS.REPLACING 1)
	   (TS.ADDING 2)
	   (TS.REMOVING 3)
	   (TS.EXTENDING.HI 4)
	   (TS.EXTENDING.LO 5)
	   (TS.SHRINKING.HI 6)
	   (TS.SHRINKING.LO 7))
)


(ADDTOVAR USERMACROS (TB NIL (R? MAILFOLDER TABLEBROWSER)
			 (R? BROWSERMARKXPOSITION TB.LEFT.MARGIN)
			 (R? FOLDERLOCK TBLOCK)
			 (R? MSGDESCRIPTOR ITEM)
			 (R? LAFITEMSG TABLEITEM)
			 (R? MESSAGEDESCRIPTORS TBITEMS)
			 (R? LASTSELECTEDMESSAGE TBLASTSELECTEDITEM)
			 (R? FIRSTSELECTEDMESSAGE TBFIRSTSELECTEDITEM)
			 (R? FIRSTVISIBLEMESSAGE TB.FIRST.VISIBLE.ITEM#)
			 (R? LASTVISIBLEMESSAGE TB.LAST.VISIBLE.ITEM#)
			 (R? #OFMESSAGES TB#ITEMS)
			 (R? # TI#)
			 (R? SELECTED? TISELECTED)
			 (R? DELETED? TIDELETED)
			 (R? message item)
			 (R? MSG ITEM)
			 (R? MESSAGES ITEMS)
			 (R? MESSAGE#.TO.YPOS TB.YCOORD.FROM.ITEM)
			 (R? YPOS.TO.MESSAGE# TB.ITEM#.FROM.YCOORD)
			 (R? NTHMESSAGE TB.FETCHNTH)
			 (R? selectedin selectedfrom)
			 (R? BROWSER TB)
			 (R? LAFITE. TB.)
			 (R? LAFITE TB.)
			 (R? \LAFITE. TB.)
			 (R? \LAFITE TB.)
			 (R? LA. TB.)
			 (R? LAB. TB.)))

(ADDTOVAR EDITCOMSA TB)

(DECLARE: EVAL@COMPILE 
[I.S.OPR (QUOTE selectedfrom)
	 NIL
	 (QUOTE (bind ($$ITEMS ← (fetch (TABLEBROWSER TBITEMS)
					of BODY))
		      ($$ITEM# ← (SUB1 (fetch (TABLEBROWSER TBFIRSTSELECTEDITEM)
					      of BODY)))
		      ($$ITEMLAST ← (fetch (TABLEBROWSER TBLASTSELECTEDITEM)
					   of BODY))
		      until
		      (IGREATERP (add $$ITEM# 1)
				 $$ITEMLAST)
		      when
		      (fetch (TABLEITEM TISELECTED)
			     of
			     (SETQ I.V. (TB.FETCHNTH $$ITEMS $$ITEM#]
)

(DECLARE: EVAL@COMPILE 
[PUTPROPS .COPYKEYDOWNP. MACRO (NIL (OR (KEYDOWNP (QUOTE LSHIFT))
					(KEYDOWNP (QUOTE RSHIFT))
					(KEYDOWNP (QUOTE COPY]
)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS TB.CROSSCURSOR TB.SELECTION.BITMAP TB.DELETEDLINEHEIGHT)
)
)
(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS 

(ADDTOVAR NLAMA )

(ADDTOVAR NLAML )

(ADDTOVAR LAMA TB.USERDATA)
)
(/DECLAREDATATYPE (QUOTE TABLEBROWSER)
		  (QUOTE (FLAG FLAG FLAG FLAG FLAG FLAG FLAG FLAG POINTER WORD WORD WORD WORD WORD 
			       WORD WORD WORD WORD WORD POINTER POINTER POINTER POINTER POINTER 
			       POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
			       POINTER POINTER POINTER POINTER POINTER))
		  (QUOTE ((TABLEBROWSER 0 (FLAGBITS . 0))
			  (TABLEBROWSER 0 (FLAGBITS . 16))
			  (TABLEBROWSER 0 (FLAGBITS . 32))
			  (TABLEBROWSER 0 (FLAGBITS . 48))
			  (TABLEBROWSER 0 (FLAGBITS . 64))
			  (TABLEBROWSER 0 (FLAGBITS . 80))
			  (TABLEBROWSER 0 (FLAGBITS . 96))
			  (TABLEBROWSER 0 (FLAGBITS . 112))
			  (TABLEBROWSER 0 POINTER)
			  (TABLEBROWSER 2 (BITS . 15))
			  (TABLEBROWSER 3 (BITS . 15))
			  (TABLEBROWSER 4 (BITS . 15))
			  (TABLEBROWSER 5 (BITS . 15))
			  (TABLEBROWSER 6 (BITS . 15))
			  (TABLEBROWSER 7 (BITS . 15))
			  (TABLEBROWSER 8 (BITS . 15))
			  (TABLEBROWSER 9 (BITS . 15))
			  (TABLEBROWSER 10 (BITS . 15))
			  (TABLEBROWSER 11 (BITS . 15))
			  (TABLEBROWSER 12 POINTER)
			  (TABLEBROWSER 14 POINTER)
			  (TABLEBROWSER 16 POINTER)
			  (TABLEBROWSER 18 POINTER)
			  (TABLEBROWSER 20 POINTER)
			  (TABLEBROWSER 22 POINTER)
			  (TABLEBROWSER 24 POINTER)
			  (TABLEBROWSER 26 POINTER)
			  (TABLEBROWSER 28 POINTER)
			  (TABLEBROWSER 30 POINTER)
			  (TABLEBROWSER 32 POINTER)
			  (TABLEBROWSER 34 POINTER)
			  (TABLEBROWSER 36 POINTER)
			  (TABLEBROWSER 38 POINTER)
			  (TABLEBROWSER 40 POINTER)
			  (TABLEBROWSER 42 POINTER)
			  (TABLEBROWSER 44 POINTER)
			  (TABLEBROWSER 46 POINTER)))
		  (QUOTE 48))
(/DECLAREDATATYPE (QUOTE TABLEITEM)
		  (QUOTE (FLAG FLAG FLAG FLAG FLAG FLAG FLAG FLAG POINTER WORD WORD))
		  [QUOTE ((TABLEITEM 0 (FLAGBITS . 0))
			  (TABLEITEM 0 (FLAGBITS . 16))
			  (TABLEITEM 0 (FLAGBITS . 32))
			  (TABLEITEM 0 (FLAGBITS . 48))
			  (TABLEITEM 0 (FLAGBITS . 64))
			  (TABLEITEM 0 (FLAGBITS . 80))
			  (TABLEITEM 0 (FLAGBITS . 96))
			  (TABLEITEM 0 (FLAGBITS . 112))
			  (TABLEITEM 0 POINTER)
			  (TABLEITEM 2 (BITS . 15))
			  (TABLEITEM 3 (BITS . 15]
		  (QUOTE 4))
[ADDTOVAR SYSTEMRECLST

(DATATYPE TABLEBROWSER ((TBREADY FLAG)
			(NIL 7 FLAG)
			(TBITEMS POINTER)
			(TB#ITEMS WORD)
			(TB#DELETED WORD)
			(TB#LINESPERITEM WORD)
			(TBFIRSTSELECTEDITEM WORD)
			(TBLASTSELECTEDITEM WORD)
			(NIL WORD)
			(TBMAXXPOS WORD)
			(TBFONTHEIGHT WORD)
			(TBFONTASCENT WORD)
			(TBFONTDESCENT WORD)
			(TBWINDOW POINTER)
			(TBLOCK POINTER)
			(TBUSERDATA POINTER)
			(TBFONT POINTER)
			(TBEXTENT POINTER)
			(TBUPDATEFROMHERE POINTER)
			(TBCOLUMNS POINTER)
			(TBPRINTFN POINTER)
			(TBCOPYFN POINTER)
			(TBFONTCHANGEFN POINTER)
			(TBCLOSEFN POINTER)
			(TBAFTERCLOSEFN POINTER)
			(TBTITLEEVENTFN POINTER)
			(TBAFTEREXPUNGEFN POINTER)
			(TBORIGIN POINTER)
			(NIL POINTER)
			(NIL POINTER)
			(NIL POINTER)))

(DATATYPE TABLEITEM ((TISELECTED FLAG)
		     (TIDELETED FLAG)
		     (TIUNDELETABLE FLAG)
		     (TIUNSELECTABLE FLAG)
		     (NIL 4 FLAG)
		     (TIDATA POINTER)
		     (TI# WORD)
		     (NIL WORD)))
]
(PUTPROPS TABLEBROWSER COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2668 6245 (TB.MAKE.BROWSER 2678 . 5182) (TB.REPLACE.ITEMS 5184 . 6243)) (6246 13633 (
TB.DELETE.ITEM 6256 . 6689) (TB.UNDELETE.ITEM 6691 . 7457) (TB.INSERT.ITEM 7459 . 9828) (
TB.REMOVE.ITEM 9830 . 11816) (TB.NORMALIZE.ITEM 11818 . 12508) (TB.REDISPLAY.ITEMS 12510 . 13346) (
TB.SELECT.ITEM 13348 . 13631)) (13634 18053 (TB.NUMBER.OF.ITEMS 13644 . 14011) (TB.NTH.ITEM 14013 . 
14313) (TB.COLLECT.ITEMS 14315 . 14767) (TB.MAP.ITEMS 14769 . 15178) (TB.MAP.DELETED.ITEMS 15180 . 
15754) (TB.MAP.SELECTED.ITEMS 15756 . 16591) (TB.FIND.ITEM 16593 . 17741) (TB.ITEM.SELECTED? 17743 . 
17897) (TB.ITEM.DELETED? 17899 . 18051)) (18054 19176 (TB.CLEAR.LINE 18064 . 18626) (TB.USERDATA 18628
 . 19010) (TB.WINDOW 19012 . 19174)) (19197 31168 (TB.REPAINTFN 19207 . 19778) (TB.RESHAPEFN 19780 . 
20933) (TB.SCROLLFN 20935 . 21404) (TB.DISPLAY.LINES 21406 . 22657) (TB.PRINT.LINE 22659 . 23264) (
TB.FIRST.VISIBLE.ITEM# 23266 . 23835) (TB.LAST.VISIBLE.ITEM# 23837 . 24557) (TB.ITEM.VISIBLE? 24559 . 
25170) (TB.YCOORD.FROM.ITEM 25172 . 25507) (TB.ITEM#.FROM.YCOORD 25509 . 26011) (TB.ITEM.FROM.YCOORD 
26013 . 26588) (TB.SHOW.DELETION 26590 . 27145) (TB.SHOW.SELECTION 27147 . 27667) (TB.UPDATE.DISPLAY 
27669 . 31166)) (31191 46347 (TB.BUTTONEVENTFN 31201 . 31842) (TB.DO.UNLESS.BUSY 31844 . 32264) (
TB.DO.ITEM.SELECTION 32266 . 40707) (TB.DECONSIDERRANGE 40709 . 41188) (TB.CONSIDERRANGE 41190 . 41914
) (TB.DESELECTRANGE 41916 . 43298) (TB.RECONSIDERRANGE 43300 . 43964) (TB.SELECTRANGE 43966 . 45261) (
TB.UNDOSELECTION 45263 . 45631) (TB.FIND.SELECTED.ITEM 45633 . 45981) (TB.REV.FIND.SELECTED.ITEM 45983
 . 46345)) (46348 48547 (TB.COPYBUTTONEVENTFN 46358 . 48081) (TB.SHOW.COPY.SELECTION 48083 . 48545)) (
48578 55805 (TB.BROWSER.BUSY 48588 . 48773) (TB.CLOSE/SHRINK 48775 . 49662) (TB.CLOSEFN 49664 . 49822)
 (TB.FINISH.CLOSE 49824 . 50636) (TB.FLUSH.WINDOW 50638 . 51265) (TB.SET.FONT 51267 . 53404) (
TB.SHRINKFN 53406 . 53566) (TB.EXPANDFN 53568 . 54982) (TB.ITEM.UPDATABLE? 54984 . 55803)) (55823 
56435 (TB.PROCESS 55833 . 56291) (TB.FETCHNTH 56293 . 56433)))))
STOP