(FILECREATED "26-Mar-86 12:29:22" {QV}<NOTECARDS>1.3K>RHTPATCH033.;10 66260  

      changes to:  (FNS NC.ExternalizeLinkIconsInSketch NC.CardSubstanceVersionInspector 
			NC.CloseInspectorWindows NC.MessageWinCloseFn NC.CardInspectorCloseFn 
			NC.CardInspectorAttachedMenuWhenSelectedFn NC.ScavengerPhase1 
			NC.LinkIconWhenCopiedFn NC.LinkIconWhenMovedFn)
		   (VARS RHTPATCH033COMS)

      previous date: "24-Mar-86 15:51:46" {QV}<NOTECARDS>1.3K>RHTPATCH033.;7)


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

(PRETTYCOMPRINT RHTPATCH033COMS)

(RPAQQ RHTPATCH033COMS ((* * These fixes are to NCLINKS)
	(FNS NC.LinkIconWhenCopiedFn NC.LinkIconWhenMovedFn)
	(* * This fix is to NCGRAPHCARD)
	(FNS NC.MakeExternalGraphCopy)
	(* * New function for NCREPAIR)
	(FNS NC.CloseInspectorWindows)
	(* * New function for NCSKETCHCARD)
	(FNS NC.ExternalizeLinkIconsInSketch)
	(* * These fixes are to NCREPAIR)
	(FNS NC.AtEndOfItemP NC.RobustReadChar NC.CheckForValidSubstance NC.RobustGetSubstance 
	     NC.ScavengerPhase1 NC.CheckUnknownCardTypes NC.RobustReadCardPart 
	     NC.CardPartsAttachedMenuWhenSelectedFn NC.BuildCardPartsInspector 
	     NC.CardSubstanceVersionInspector NC.ScavengerCleanup 
	     NC.MessageWinAttachedMenuWhenSelectedFn NC.MessageWinCloseFn NC.CardInspectorCloseFn 
	     NC.CardInspectorAttachedMenuWhenSelectedFn)))
(* * These fixes are to NCLINKS)

(DEFINEQ

(NC.LinkIconWhenCopiedFn
  (LAMBDA (ImageObject ToWindowStream FromTextStream ToTextStream)
                                                             (* rht: "24-Mar-86 10:34")

          (* * Called when copying a link icon from FromTextStream to ToWindowStream. Sets the necessary link information up 
	  for card corresponding to ToWindowStream.)



          (* * rht 11/18/84: Major hacking. Now checks for all sorts of illegal cases. Either goes ahead with copy, converts 
	  link type to "Unspecified", or deletes the new "invisible" link. The latter will change when imageobj fns can 
	  return DON'T.)



          (* * rht 12/12/84: now does RETFROM instead of adding processes to delete imageobj's. This is cleaner, but still 
	  ugly.)



          (* * rht 3/25/85: Fixed to handle copies within a sketch card. That is indicated by nullity of the two textstream 
	  args.)



          (* * rht 3/24/86: Changed call to NC.CoerceToID to NC.CoerceToCard)


    (PROG (Label (Link (NC.FetchLinkFromLinkIcon ImageObject))
		   SourceCard DestinationCard NewSourceCard NewLabel NewDisplayMode OldDisplayMode
		   (ImageObjectCopy (IMAGEOBJPROP ImageObject (QUOTE ImageObjectCopy)))
		   (Window (AND ToWindowStream (WFROMDS ToWindowStream T)))
		   (InTEditCopyFlg (COND
				     ((STKPOS (QUOTE TEDIT.COPY))
				       T)))
		   InsertPos)
	    (SETQ Label (fetch (Link Label) of Link))
	    (SETQ SourceCard (fetch (Link SourceCard) of Link))
	    (SETQ DestinationCard (fetch (Link DestinationCard) of Link))
	    (SETQ OldDisplayMode (fetch (Link DisplayMode) of Link))
	    (SETQ NewSourceCard (COND
		((WINDOWP Window)
		  (NC.CoerceToCard Window))
		((TEXTSTREAMP ToTextStream)
		  (NC.CoerceToCard ToTextStream))))
	    (COND
	      ((AND (NULL FromTextStream)
		      (NULL ToTextStream))                 (* We must be moving within a sketch.)
		(SETQ NewSourceCard SourceCard))
	      ((TEXTSTREAMP ToTextStream)                  (* If it's a text copy, then compute position to 
							     insert link at.)
		(SETQ InsertPos (NC.CharPosFromTextObject (TEXTOBJ ToTextStream)))))
	    (COND
	      ((NULL NewSourceCard)                        (* Trying to copy to a non NoteCard stream)
		(NC.PrintMsg Window NIL (CONCAT "Tried to copy a NoteCards link icon" 
						    " to a non-NoteCards stream."
						    (CHARACTER 13)))
		(NC.CoerceToExternalPutLinkIcon ImageObjectCopy SourceCard DestinationCard Label)
		(RETURN NIL))
	      ((NULL (NC.LinksSupportedP NewSourceCard (QUOTE (Local))))
		(NC.PrintMsg Window NIL (CONCAT "Tried to copy a NoteCards link icon" 
						    " to a NoteCard that"
						    " does not support links!!."
						    (CHARACTER 13)
						    "Tsk. Tsk."
						    (CHARACTER 13)))
		(COND
		  (InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					     NIL T))
		  (T (RETURN (QUOTE DON'T)))))
	      ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		      (NEQ (NC.RetrieveType NewSourceCard)
			     (QUOTE FileBox)))             (* Copy from filebox to non-filebox.)
		(NC.PrintMsg NIL NIL (CONCAT 
				       "Tried to copy filedcard or subbox link to a non-filebox."
						 (CHARACTER 13)
						 "Link type of copy set to 'Unspecified'."
						 (CHARACTER 13)))
		(SETQ NewLabel NC.UnspecifiedLinkLabel)
		(SETQ NewDisplayMode (create LINKDISPLAYMODE
					  copying OldDisplayMode SHOWTITLEFLG ← T SHOWLINKTYPEFLG ← 
						    T)))
	      ((AND (NEQ (NC.RetrieveType SourceCard)
			     (QUOTE FileBox))
		      (EQ (NC.RetrieveType NewSourceCard)
			    (QUOTE FileBox)))              (* Copy from non-filebox to filebox.)
		(NC.PrintMsg NIL NIL (CONCAT "Can't copy links from non-filebox to filebox."
						 (CHARACTER 13)
						 "Try using 'PutCardsHere'."
						 (CHARACTER 13)))
		(COND
		  (InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					     NIL T))
		  (T (RETURN (QUOTE DON'T)))))
	      ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		      (EQ NewSourceCard SourceCard))       (* Copy within same filebox.)
		(NC.PrintMsg NIL NIL (CONCAT 
					  "Can't copy links within a FileBox.  Try move instead."
						 (CHARACTER 13)))
		(COND
		  (InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					     NIL T))
		  (T (RETURN (QUOTE DON'T)))))
	      ((AND (EQ (NC.RetrieveType NewSourceCard)
			    (QUOTE FileBox))
		      (for Link1 in (NC.FetchToLinks NewSourceCard)
			 thereis (AND (NC.ChildLinkP Link1)
					  (EQ DestinationCard (fetch (Link DestinationCard)
								   of Link1)))))
                                                             (* Copy to a filebox already containing this child.)
		(NC.PrintMsg NIL NIL (CONCAT (NC.RetrieveTitle DestinationCard)
						 " not copied: already appears as a child of "
						 (NC.RetrieveTitle NewSourceCard)
						 (CHARACTER 13)))
		(COND
		  (InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					     NIL T))
		  (T (RETURN (QUOTE DON'T)))))
	      ((AND (EQ Label (QUOTE SubBox))
		      (OR (EQ NewSourceCard DestinationCard)
			    (NOT (NC.NotDaughterP DestinationCard NewSourceCard
						      (FUNCTION NC.ChildLinkP)))))
                                                             (* Copy to a filebox causes a cycle.)
		(NC.PrintMsg NIL NIL (CONCAT "Couldn't copy " Link " because of subbox cycle."
						 (CHARACTER 13)))
		(COND
		  (InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					     NIL T))
		  (T (RETURN (QUOTE DON'T)))))
	      ((AND (FMEMB Label NC.SystemLinkLabels)
		      (NOT (FMEMB Label (QUOTE (FiledCard SubBox))))
		      (NEQ NewSourceCard SourceCard))      (* Copy of system link outside of own card.)
		(NC.PrintMsg NIL NIL (CONCAT "Tried to copy system link." (CHARACTER 13)
						 "Link type of copy set to 'Unspecified'."
						 (CHARACTER 13)))
		(SETQ NewLabel NC.UnspecifiedLinkLabel)
		(SETQ NewDisplayMode (create LINKDISPLAYMODE
					  copying OldDisplayMode SHOWTITLEFLG ← T SHOWLINKTYPEFLG ← 
						    T))))
	    (NC.FillInLinkIcon ImageObjectCopy (OR NewLabel Label)
				 DestinationCard NewSourceCard (OR NewDisplayMode OldDisplayMode)
				 (NC.LinkAtCharPos InsertPos ToTextStream)))))

(NC.LinkIconWhenMovedFn
  (LAMBDA (ImageObject ToWindowStream FromTextStream ToTextStream)
                                                             (* rht: "24-Mar-86 10:36")

          (* * Called when moving a link icon from FromTextStream to ToWindowStream. Sets the necessary link information up 
	  for card corresponding to ToWindowStream.)



          (* * rht 11/18/84: Major hacking. Now checks for all sorts of illegal cases. Either goes ahead with move, converts 
	  link type to "Unspecified", or deletes the new "invisible" link. The code is very similar to 
	  NC.LinkIconWhenCopiedFn except that within-filebox moves are allowed. Also when aborting a move, we must insert a 
	  copy of the link back to take the place of the deleted original. This will all change when imageobj fns can return 
	  DON'T.)



          (* * rht 12/12/84: Now just RETFROM's rather than doing the addprocess stuff. Should be cleaner, but still ugly.)



          (* * kirk 15Nov85: deleted use of PSA.Database)



          (* * rht 3/24/86: Changed call to NC.CoerceToID to NC.CoerceToCard)


    (LET (Label (Link (NC.FetchLinkFromLinkIcon ImageObject))
		SourceCard DestinationCard NewSourceCard NewLabel NewDisplayMode OldDisplayMode
		(Window (AND ToWindowStream (WFROMDS ToWindowStream T)))
		InsertPos)
         (SETQ Label (fetch (Link Label) of Link))
         (SETQ NewSourceCard (COND
	     ((WINDOWP Window)
	       (NC.CoerceToCard Window))
	     ((TEXTSTREAMP ToTextStream)
	       (NC.CoerceToCard ToTextStream))))
         (SETQ SourceCard (fetch (Link SourceCard) of Link))
         (SETQ DestinationCard (fetch (Link DestinationCard) of Link))
         (SETQ OldDisplayMode (fetch (Link DisplayMode) of Link))
         (COND
	   ((AND (NULL FromTextStream)
		   (NULL ToTextStream))                    (* We must be moving within a sketch.)
	     (SETQ NewSourceCard SourceCard))
	   ((TEXTSTREAMP ToTextStream)                     (* If it's a text copy, then compute position to 
							     insert link at.)
	     (SETQ InsertPos (NC.CharPosFromTextObject (TEXTOBJ ToTextStream)))))
         (COND
	   ((NULL NewSourceCard)                           (* Trying to copy to a non NoteCard stream)
	     (NC.PrintMsg Window NIL (CONCAT "Tried to move a NoteCards link icon" 
						 " to a non-NoteCards stream!!."
						 (CHARACTER 13)
						 "Tsk. Tsk."
						 (CHARACTER 13)))
	     (RETFROM (QUOTE TEDIT.MOVE)
			NIL T))
	   ((NULL (NC.LinksSupportedP NewSourceCard (QUOTE (Local))))
	     (NC.PrintMsg Window NIL (CONCAT "Tried to move a NoteCards link icon" 
						 " to a NoteCard that"
						 " does not support links!!."
						 (CHARACTER 13)
						 "Tsk. Tsk."
						 (CHARACTER 13)))
	     (RETFROM (QUOTE TEDIT.MOVE)
			NIL T))
	   ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		   (NEQ (NC.RetrieveType NewSourceCard)
			  (QUOTE FileBox)))                (* Move from filebox to non-filebox.)
	     (NC.PrintMsg NIL NIL (CONCAT 
				       "Tried to move filedcard or subbox link to a non-filebox."
					      (CHARACTER 13)
					      "Link type of copy set to 'Unspecified'."
					      (CHARACTER 13)))
	     (SETQ NewLabel NC.UnspecifiedLinkLabel)
	     (SETQ NewDisplayMode (create LINKDISPLAYMODE
				       copying OldDisplayMode SHOWTITLEFLG ← T SHOWLINKTYPEFLG ← T))
	     )
	   ((AND (NEQ (NC.RetrieveType SourceCard)
			  (QUOTE FileBox))
		   (EQ (NC.RetrieveType NewSourceCard)
			 (QUOTE FileBox)))                 (* Move from non-filebox to filebox.)
	     (NC.PrintMsg NIL NIL (CONCAT "Can't move links from non-filebox to filebox."
					      (CHARACTER 13)
					      "Try using PutCardsHere."
					      (CHARACTER 13)))
	     (RETFROM (QUOTE TEDIT.MOVE)
			NIL T))
	   ((AND (EQ (NC.RetrieveType NewSourceCard)
			 (QUOTE FileBox))
		   (NEQ NewSourceCard SourceCard)
		   (for Link1 in (NC.FetchToLinks NewSourceCard)
		      thereis (AND (NC.ChildLinkP Link1)
				       (EQ DestinationCard (fetch (Link DestinationCard)
								of Link1)))))
                                                             (* Move to a filebox already containing this child.)
	     (NC.PrintMsg NIL NIL (CONCAT (NC.RetrieveTitle DestinationCard)
					      " not moved: already appears as a child of "
					      (NC.RetrieveTitle NewSourceCard)
					      (CHARACTER 13)))
	     (RETFROM (QUOTE TEDIT.MOVE)
			NIL T))
	   ((AND (EQ Label (QUOTE SubBox))
		   (NEQ NewSourceCard SourceCard)
		   (OR (EQ NewSourceCard DestinationCard)
			 (NOT (NC.NotDaughterP DestinationCard NewSourceCard
						   (FUNCTION NC.ChildLinkP)))))
                                                             (* Move to a filebox causes a cycle.)
	     (NC.PrintMsg NIL NIL (CONCAT "Couldn't move " Link " because of subbox cycle."
					      (CHARACTER 13)))
	     (RETFROM (QUOTE TEDIT.MOVE)
			NIL T))
	   ((AND (FMEMB Label NC.SystemLinkLabels)
		   (NOT (FMEMB Label (QUOTE (FiledCard SubBox))))
		   (NEQ NewSourceCard SourceCard))         (* Move of system link outside of own card.)
	     (NC.PrintMsg NIL NIL (CONCAT "Tried to copy system link." (CHARACTER 13)
					      "Link type of copy set to 'Unspecified'."
					      (CHARACTER 13)))
	     (SETQ NewLabel NC.UnspecifiedLinkLabel)
	     (SETQ NewDisplayMode (create LINKDISPLAYMODE
				       copying OldDisplayMode SHOWTITLEFLG ← T SHOWLINKTYPEFLG ← T))
	     ))
         (IMAGEOBJPROP ImageObject (QUOTE LinkBeingMoved)
			 Link)
         (NC.FillInLinkIcon ImageObject (OR NewLabel Label)
			      DestinationCard NewSourceCard (OR NewDisplayMode OldDisplayMode)
			      (NC.LinkAtCharPos InsertPos ToTextStream)))))
)
(* * This fix is to NCGRAPHCARD)

(DEFINEQ

(NC.MakeExternalGraphCopy
  (LAMBDA (Graph)                                            (* rht: "24-Mar-86 15:50")

          (* * Make a copy of Graph in which each link icon nodelabel has been replaced by a copy of itself and MoveNodeFn, 
	  etc. are replaced by NIL.)



          (* * rht 3/24/86: Now creates new graphnodes via "using" instead of "copying" to preserve EQness of UIDs.)


    (create GRAPH
	      DIRECTEDFLG ←(fetch (GRAPH DIRECTEDFLG) of Graph)
	      SIDESFLG ←(fetch (GRAPH SIDESFLG) of Graph)
	      GRAPHNODES ←(for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph)
			     bind Box NewNode Label
			     collect (LET (NewLinkIcon)
					    (PROG1 (SETQ NewNode
						       (create GRAPHNODE
							  using
							   GraphNode NODELABEL ←(if
							     (NC.LinkIconImageObjP
							       (SETQ Label (fetch (GRAPHNODE
											NODELABEL)
										of GraphNode)))
										    then
										     (SETQ 
										      NewLinkIcon
										       (
										NC.LinkIconCopyFn
											 Label))
										  else
										   (COPY Label))))
						     (if NewLinkIcon
							 then (SETQ Box
								  (NC.ExternalPutLinkIconImageBoxFn
								    NewLinkIcon NIL NIL NIL))
								(replace (GRAPHNODE NODEHEIGHT)
								   of NewNode
								   with (fetch (IMAGEBOX YSIZE)
									     of Box))
								(replace (GRAPHNODE NODEWIDTH)
								   of NewNode
								   with (fetch (IMAGEBOX XSIZE)
									     of Box)))))))))
)
(* * New function for NCREPAIR)

(DEFINEQ

(NC.CloseInspectorWindows
  (LAMBDA (MessageWin)                                       (* rht: "24-Mar-86 18:25")

          (* * Close any open inspector windows.)


    (for InspectorWin in (WINDOWPROP MessageWin (QUOTE INSPECTORWINDOWS))
       when (OPENWP InspectorWin) do (CLOSEW InspectorWin))
    (WINDOWPROP MessageWin (QUOTE INSPECTORWINDOWS)
		  NIL)))
)
(* * New function for NCSKETCHCARD)

(DEFINEQ

(NC.ExternalizeLinkIconsInSketch
  (LAMBDA (Sketch)                                           (* rht: "26-Mar-86 12:26")

          (* * Smashes all link icons in Sketch with external link icons.)


    (for SketchElement in (SKETCH.LIST.OF.ELEMENTS Sketch (FUNCTION NC.LinkIconSketchElementP)
							 T)
       do (LET* ((LinkIcon (SKETCH.IMAGEOBJ.OF.ELEMENT SketchElement))
		   (Link (NC.FetchLinkFromLinkIcon LinkIcon)))
	          (NC.CoerceToExternalPutLinkIcon LinkIcon (fetch (Link SourceCard) of Link)
						    (fetch (Link DestinationCard) of Link)
						    (fetch (Link Label) of Link))))
    Sketch))
)
(* * These fixes are to NCREPAIR)

(DEFINEQ

(NC.AtEndOfItemP
  (LAMBDA (Stream EofPtr)                                    (* rht: "22-Mar-86 16:01")

          (* * Return T if at the end of an item. That means either we're at the end of the file, or there's a # at the 
	  current location.)



          (* * rht 12/1/85: Updated to handle new notefile and card object formats. Ripped out the kludgy check for NOBIND 
	  litatom. Also now handles the 3 byte length info at start of every card part header.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  HashPtr)
         (OR EofPtr (SETQ EofPtr (GETEOFPTR Stream)))
                                                             (* Skip past the card part length.)
         (SETFILEPTR Stream (SETQ HashPtr (PLUS 3 OldPtr)))
         (if (OR (GEQ HashPtr EofPtr)
		     (EQ (CHARACTER (BIN Stream))
			   (QUOTE #)))
	     then (SETFILEPTR Stream OldPtr)
		    T
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadChar
  (LAMBDA (Stream)                                           (* rht: "22-Mar-86 16:01")

          (* * Try to read a character, In an NLSETQ so we won't see error messages. The RESETVAR is so that no breaks will 
	  occur. This returns list of the one element read or NIL if unsuccessful read.)


    (RESETVAR HELPFLAG NIL (NLSETQ (CHARACTER (BIN Stream))))))

(NC.CheckForValidSubstance
  (LAMBDA (Stream EofPtr Card CardType ReadSubstanceFlg)     (* rht: "22-Mar-86 17:29")

          (* * Check whether we've got a valid substance at current pos in Stream. Check for a valid StartPtr and EndPtr.
	  If ReadSubstanceFlg is non-nil, then do robust get of the substance. Return length of substance or nil.)



          (* * rht 12/1/85: Updated to handle new notefile format in MainCardData card part.)



          (* * rht 3/22/86: Now handles substance version numbers.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  Length EndPtr)
         (OR EofPtr (SETQ EofPtr (GETEOFPTR Stream)))
         (if (AND (LESSP OldPtr (DIFFERENCE EofPtr 3))
		      (SETQ Length (NC.ReadPtr Stream 3))
		      (LEQ (SETQ EndPtr (PLUS OldPtr 4 Length))
			     EofPtr)
		      (OR (NOT ReadSubstanceFlg)
			    (NOT (NCP.ValidCardType CardType))
			    (NC.RobustGetSubstance Card Length Stream (NC.GetPtr Stream 1)))
		      (SETFILEPTR Stream EndPtr)
		      Length)
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustGetSubstance
  (LAMBDA (Card Length Stream SubstanceVersion)              (* rht: "22-Mar-86 16:47")

          (* * Try to get substance robustly. RESETVAR prevents breaks. Returns either substance or nil if unsuccessful.)



          (* * rht 12/1/85: Updated to use card and notefile format.)



          (* * fgh 2/5/86 Added call to NC.ApplyFn)



          (* * rht 3/22/86: Now passes substance version #s and Stream to GetFn.)


    (RESETVAR HELPFLAG NIL (NLSETQ (NC.ApplyFn GetFn Card Length Stream SubstanceVersion)))))

(NC.ScavengerPhase1
  (LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg)
                                                             (* rht: "22-Mar-86 19:10")

          (* * This is the first phase of the scavenger. Runs over entire data portion of the notefile, accumulating pointers
	  to healthy parts of cards. Then runs over index array asking user what to do with bad or outdated pointers.
	  If ReadSubstancesFlg is non-nil then it'll do robust gets of the substances. This slows things down, but makes 
	  checking more comprehensive.)



          (* * rht 12/7/85: Updated to handle new notefile and card object formats.)



          (* * rht 3/22/86: No longer hangs bad cards off proplist of Reason atoms. Uses local var ReasonsHashArray instead.
	  NC.ScavengerPhase1 no longer hanging on completion of phase 3)


    (PROG (FileName NoteFile UnknownCardTypesList ReasonsList ReasonsHashArray CardsToDelete Menu 
		      MenuItems LinkLabelsNews CardTotal BadNewsList BadBoxes ExtraBadNews 
		      FirstTimeFlg InspectorPendingEvent NoteFileMenu NoteFileOpsMenuItem 
		      CanDoPhase3Flg)

          (* * First, take care of opening notefile if needed.)


	    (if (AND (type? NoteFile FileNameOrNoteFile))
		then                                       (* There's already an open notefile to repair.)
		       (SETQ NoteFile FileNameOrNoteFile)
	      else                                         (* Get file name and open the file if conditions are 
							     okay.)
		     (SETQ FileName FileNameOrNoteFile)
		     (AND (NULL FileName)
			    (NULL (SETQ FileName (NC.DatabaseFileName 
					   "What is the name of the NoteFile to Inspect&Repair? "
									    NIL T)))
			    (RETURN NIL))
		     (AND (NULL (SETQ NoteFile
				      (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T)))
			    (NC.PrintMsg NIL NIL "Couldn't open " FileName "." (CHARACTER 13)
					   "Repair aborted."
					   (CHARACTER 13))
			    (RETURN NIL))
		     (NC.PrintMsg NIL NIL "Done."))
	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
                                                             (* Build a window for talking to the user if one 
							     wasn't passed in.)
	    (if (WINDOWP ScavengerInteractionWin)
		then (CLEARW ScavengerInteractionWin)
	      else (SETQ ScavengerInteractionWin (CREATEW NC.ScavengerInteractionWinRegion 
							      "Inspect&Repair Interaction Window"
								NIL T))
                                                             (* This flg indicates that we're in the first call to 
							     the scavenger.)
		     (SETQ FirstTimeFlg T)
		     (WINDOWADDPROP ScavengerInteractionWin (QUOTE CLOSEFN)
				      (FUNCTION NC.MessageWinCloseFn)
				      T))                    (* Get all relevant info about the data area of the 
							     notefile onto the cards' prop lists.)
	    (if (OR (NOT FirstTimeFlg)
			(EQ (NC.GetScavengerInfo NoteFile ReadSubstancesFlg 
						     ScavengerInteractionWin)
			      (QUOTE SUCCESS)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE NOTEFILE)
				     NoteFile)
		       (WINDOWPROP ScavengerInteractionWin (QUOTE CARDTOTAL)
				     CardTotal)
	      else                                         (* Something's wrong. Couldn't get scavenger info.
							     Bail out.)
		     (NC.ScavengerCleanup ScavengerInteractionWin)
		     (CLOSEW ScavengerInteractionWin)
		     (RETURN NIL))

          (* * Check the list of card types that are undefined to see if user has loaded a definition since the last time we 
	  checked. If he has, then go try to read the substance card parts for those newly defined card types.)


	    (NC.CheckUnknownCardTypes NoteFile ReadSubstancesFlg ScavengerInteractionWin)

          (* * Next step is to run down the in-core index and find those cards having pointers to bad items in the data area.
	  We also need to look for undefined card types and for pointers past the checkpoint pointer.
	  However, we can reuse old bad news list if nothing has changed.)


	    (if (OR FirstTimeFlg RecheckBadCardsFlg (WINDOWPROP ScavengerInteractionWin
								      (QUOTE NEEDCHECKPOINT)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE ORIGINALBADNEWSLIST)
				     (SETQ BadNewsList (NC.BuildBadCardsList NoteFile 
									  ScavengerInteractionWin 
										 FirstTimeFlg)))
	      else (SETQ BadNewsList (WINDOWPROP ScavengerInteractionWin (QUOTE 
									      ORIGINALBADNEWSLIST))))

          (* * Okay, now all the troublesome IDs and the reasons for their troubles are recorded in BadNewsList.
	  We next need to get directives from the user as to what to do for each problem card.)


	    (NC.RepositionWindowIfNeeded ScavengerInteractionWin)
                                                             (* If there's bad news for link labels then take off 
							     list and store in a local var.)
	    (if (SETQ LinkLabelsNews (for BadCardEntry in BadNewsList
					    bind (LinkLabelsCard ←(fetch (NoteFile LinkLabelsCard)
								       of NoteFile))
					    eachtime (BLOCK) when (NC.SameCardP 
										   LinkLabelsCard
											(CAR 
										     BadCardEntry))
					    do (RETURN BadCardEntry)))
		then (SETQ BadNewsList (DREMOVE LinkLabelsNews BadNewsList)))
                                                             (* Accumulate general statistics on the problems.)
	    (SETQ ReasonsHashArray (HASHARRAY 100))
	    (for BadNews in BadNewsList bind Card Type eachtime (BLOCK)
	       unless (FMEMB (CADR BadNews)
				 (QUOTE (DELETED FREE)))
	       do (SETQ Card (CAR BadNews))
		    (for Reason in (CDDDR BadNews) eachtime (BLOCK)
		       do (PUTHASH Reason (CONS Card (GETHASH Reason ReasonsHashArray))
				       ReasonsHashArray)
			    (if (NOT (FMEMB Reason ReasonsList))
				then (SETQ ReasonsList (CONS Reason ReasonsList)))
			    (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				then                       (* Accumulate the list of unknown card types for 
							     nondeleted cards.)
				       (if (NOT (FMEMB (SETQ Type (
								 NC.FetchTypeFromScavengerInfo
								 Card))
							     UnknownCardTypesList))
					   then (push UnknownCardTypesList Type)))))
                                                             (* Build the menu entries that we know will be present
							     regardless of which cards are bad.)
	    (SETQ MenuItems (QUOTE ((Abort (QUOTE Abort)
					       "Quit this Inspect&Repair operation.")
					 (Recheck% Bad% Cards (QUOTE Recheck% Bad% Cards)
							      
	    "Recompute bad cards list.  Useful if you've just loaded some card type definitions.")
					 (Inspect% Cards (QUOTE Inspect% Cards)
							 "Bring up the cards inspector menu."
							 (SUBITEMS (Include% Deleted% Cards
								     (QUOTE Include% Deleted% Cards)
								     
								"Throw in deleted cards as well.")))))
	      )                                              (* Print a message if news on link labels is worse 
							     than just past checkpoint.)
	    (if (AND LinkLabelsNews (NOT (EQUAL (CDDDR LinkLabelsNews)
							(QUOTE (MAINDATAPASTCHKPT)))))
		then (push ExtraBadNews LinkLabelsNews)
		       (NC.PrintMsg ScavengerInteractionWin NIL "The link types are bad."
				      (CHARACTER 13)
				      
"If you don't back them up to a previous version, then phase 3 of Inspect&Repair will rebuild them."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Collect any fileboxes that have bad substances.)
	    (if (SETQ BadBoxes (LET (Boxes)
				        (SETQ BadNewsList
					  (for News in BadNewsList bind Box eachtime
										   (BLOCK)
					     unless (if (AND (EQ (
								    NC.FetchTypeFromScavengerInfo
									   (SETQ Box (CAR News)))
									 (QUOTE FileBox))
								   (FMEMB (QUOTE BADMAINDATA)
									    (CDDDR News)))
							  then (push Boxes Box) 
                                                             (* If nothing else is wrong with those boxes, then 
							     take off bad news list.)
								 (EQ (LENGTH (CDDDR News))
								       1)
							else NIL)
					     collect News))
				    Boxes))
		then (NC.PrintMsg ScavengerInteractionWin NIL "Fileboxes "
				      (for Box in BadBoxes collect (
								   NC.FetchTitleFromScavengerInfo
									   Box))
				      " have bad substance(s)."
				      (CHARACTER 13)
				      
"If you don't delete them or back up to a previous version, then phase 3 of Inspect&Repair will rebuild their contents."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Print out totals of active and deleted cards.)
	    (LET ((ActivesTotal 0)
		  (DeletedsTotal 0))
	         (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
				    (SELECTQ (NC.FetchStatus Card)
					       (ACTIVE (SETQ ActivesTotal (ADD1 ActivesTotal)))
					       (DELETED (SETQ DeletedsTotal (ADD1 DeletedsTotal)))
					       NIL))))
	         (NC.PrintMsg ScavengerInteractionWin NIL "Out of " CardTotal " cards:"
				(CHARACTER 13)
				"there are " ActivesTotal " active cards and " DeletedsTotal 
				" deleted cards."
				(CHARACTER 13)))
	    (if ReasonsList
		then                                       (* Print out messages for bad cards.)
		       (NC.PrintMsg ScavengerInteractionWin NIL "Of the non-deleted ones,"
				      (CHARACTER 13))
		       (for Reason in ReasonsList eachtime (BLOCK)
			  do (NC.PrintMsg ScavengerInteractionWin NIL (LENGTH (GETHASH Reason 
										 ReasonsHashArray))
					      " have "
					      (GETPROP Reason (QUOTE ReasonString))
					      (CHARACTER 13))
			       (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				   then (NC.PrintMsg ScavengerInteractionWin NIL 
							 "The unknown types are: "
							 UnknownCardTypesList "." (CHARACTER 13))))
	      else (NC.PrintMsg ScavengerInteractionWin NIL "All non-deleted cards look okay."
				    (CHARACTER 13)))

          (* Only allow continuation to phase 3 of repair, links rebuilding, if there's no bad news that can't be fixed.
	  We can fix bad proplist, titles or links. We can also fix even bad substances if they're for fileboxes.)


	    (if (for News in BadNewsList eachtime (BLOCK)
		     unless (FMEMB (CADR News)
				       (QUOTE (DELETED FREE)))
		     unless (EQ (NC.FetchTypeFromScavengerInfo (CAR News))
				    (QUOTE FileBox))
		     never (INTERSECTION (CDDDR News)
					     (QUOTE (BADMAINDATA UNKNOWNCARDTYPE))))
		then                                       (* Add the appropriate menu items.)
		       (if (NOT (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)))
			   then (SETQ MenuItems (CONS (QUOTE (End% Inspect&Repair
								       (QUOTE End% Inspect&Repair)
								       
				      "This exits Inspect&Repair normally, closing the notefile."))
							    MenuItems)))
		       (SETQ CanDoPhase3Flg T)
		       (SETQ MenuItems (CONS (QUOTE (Continue% Repair (QUOTE Continue% Repair)
									    
					       "Complete Inspect&Repair by rebuilding the links."))
						 MenuItems)))
                                                             (* Make sure a checkpoint will happen before 
							     continuing to phase 3 if there are any card parts 
							     beyond the checkpt pointer.)
	    (if (INTERSECTION ReasonsList (QUOTE (MAINDATAPASTCHKPT LINKSPASTCHKPT 
									  TITLEPASTCHKPT 
									  PROPLISTPASTCHKPT)))
		then (AND CanDoPhase3Flg (NC.PrintMsg ScavengerInteractionWin NIL 
		  "'Continue Repair' will integrate any card part versions beyond chkpt pointer."
							    (CHARACTER 13)))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDCHECKPOINT)
				     T))                     (* Ugliness! Have to cache all these vars on window so
							     that attached menu's whenselectedfn will be able to 
							     grab them.)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADNEWSLIST)
			  BadNewsList)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE EXTRABADNEWS)
			  ExtraBadNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE LINKSLABELSNEWS)
			  LinkLabelsNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADBOXES)
			  BadBoxes)
	    (ATTACHMENU (create MENU
				    ITEMS ← MenuItems
				    WHENSELECTEDFN ←(FUNCTION 
				      NC.MessageWinAttachedMenuWhenSelectedFn)
				    MENUFONT ← NC.ScavengerAttachedMenuFont)
			  ScavengerInteractionWin
			  (QUOTE RIGHT)
			  (QUOTE TOP)))))

(NC.CheckUnknownCardTypes
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin)            (* rht: "22-Mar-86 18:13")

          (* * Check whether any of the card types on UnknownCardTypes have suddenly become defined. If so, then go try to 
	  read the substances of cards of that type and update ScavengerArray. Return the new UnknownCardTypesList.)



          (* * rht 10/18/85: Now fixes the windowprop of MessageWin here. Also returns the list of newly found types, or NIL 
	  if none.)



          (* * rht 12/7/85: Modified to reflect new card and notefile object formats.)



          (* * rht 3/22/86: substance ptrs for bad card types are no longer put on card type's prop list.
	  Now they're stored in an assoc list hung off a WINDOWPROP.)


    (LET ((UnknownCardTypes (WINDOWPROP MessageWin (QUOTE UNKNOWNCARDTYPESLIST)))
	  (UnknownCardTypesSubstancePtrs (WINDOWPROP MessageWin (QUOTE 
								    UNKNOWNCARDTYPESSUBSTANCEPTRS)))
	  (Stream (fetch (NoteFile Stream) of NoteFile))
	  OkayTypes)
         (for Type in UnknownCardTypes bind (EndPtr ←(GETEOFPTR Stream)) eachtime (BLOCK)
	    when (NCP.ValidCardType Type)
	    do (push OkayTypes Type)
		 (for SubstancePtr in (LISTGET UnknownCardTypesSubstancePtrs Type)
		    do (SETFILEPTR Stream SubstancePtr)
			 (NC.RobustReadCardPart NoteFile ReadSubstancesFlg MessageWin EndPtr))
		 (LISTPUT UnknownCardTypesSubstancePtrs Type NIL))
         (if OkayTypes
	     then (WINDOWPROP MessageWin (QUOTE UNKNOWNCARDTYPESLIST)
				  (LDIFFERENCE UnknownCardTypes OkayTypes)))
     OkayTypes)))

(NC.RobustReadCardPart
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin EndPtr)     (* rht: "22-Mar-86 18:13")

          (* * Assume stream is positioned at start of a card part. Try to read one and modify scavenger array according to 
	  what we find.)



          (* * rht 9/17/85: Now returns ID rather than litatom SUCCESS is wins.)



          (* * rht 12/1/85: Updated to handle new notefile and card object formats.)



          (* * rht 3/22/86: substance ptrs for bad card types are no longer put on card type's prop list.
	  Now they're stored in an assoc list hung off a WINDOWPROP.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  IdentifierAndVersionNum IdentifierAtom Date UID Card Title ToLinks FromLinks GlobalLinks 
	  PropList Type SubstanceLength CardPartLength CurPtr UnknownCardTypesSubstancePtrs)
         (OR EndPtr (SETQ EndPtr (GETEOFPTR Stream)))
         (SETQ CurPtr (GETFILEPTR Stream))
         (if (AND (SETQ CardPartLength (NC.ReadPtr Stream 3))
		      (LEQ (PLUS CurPtr CardPartLength)
			     EndPtr)
		      (SETQ IdentifierAndVersionNum (NC.RobustReadItemIdentifier Stream))
		      (if (GEQ (CDR IdentifierAndVersionNum)
				   1)
			  then (SETQ Date (NC.RobustReadDate Stream))
			else T)
		      (SETQ UID (NC.RobustReadUID Stream))
		      (SETQ Card (OR (NC.CardFromUID UID NoteFile)
					 (NC.GetNewCard NoteFile NIL UID))))
	     then (SETQ Date (CAR Date))
		    (SETQ IdentifierAtom (CAR IdentifierAndVersionNum))
		    (if (COND
			    ((EQ IdentifierAtom NC.TitlesIdentifier)
                                                             (* Hoping to get a healthy title.)
			      (if (AND (SETQ Title (NC.RobustReadString Stream))
					   (NC.AtEndOfItemP Stream EndPtr))
				  then (NC.SetScavengerTitleInfo Card
								     (CONS (LIST CurPtr Date 
										     Title)
									     (
								       NC.FetchScavengerTitleInfo
									       Card)))))
			    ((EQ IdentifierAtom NC.PropsIdentifier)
                                                             (* Hoping to get a healthy prop list.)
			      (if (AND (SETQ PropList (NC.RobustReadList Stream))
					   (NC.AtEndOfItemP Stream))
				  then (NC.SetScavengerPropListInfo
					   Card
					   (CONS (LIST CurPtr Date (LENGTH (CAR PropList)))
						   (NC.FetchScavengerPropListInfo Card)))))
			    ((EQ IdentifierAtom NC.LinksIdentifier)
                                                             (* Hoping to get healthy links.
							     Try to read three lists: ToLinks, FromLinks, and 
							     Global links.)
			      (if (AND (SETQ ToLinks (NC.RobustReadLinks Stream NoteFile))
					   (SETQ FromLinks (NC.RobustReadLinks Stream NoteFile))
					   (SETQ GlobalLinks (NC.RobustReadLinks Stream NoteFile))
					   (NC.AtEndOfItemP Stream EndPtr))
				  then (NC.SetScavengerLinksInfo
					   Card
					   (CONS (LIST CurPtr Date (LIST (LENGTH
										 (CAR ToLinks))
									       (LENGTH
										 (CAR FromLinks))
									       (LENGTH
										 (CAR GlobalLinks)))
							   )
						   (NC.FetchScavengerLinksInfo Card)))))
			    ((EQ IdentifierAtom NC.ItemIdentifier)
                                                             (* Hoping to get healthy substance.)
			      (if (AND (SETQ Type (CAR (NC.RobustReadAtom Stream)))
					   (NC.RobustReadRegion Stream EndPtr)
					   (SETQ SubstanceLength (NC.CheckForValidSubstance
					       Stream EndPtr Card Type ReadSubstancesFlg))
					   (NC.AtEndOfItemP Stream))
				  then (if (NOT (NCP.ValidCardType Type))
					     then          (* Code for this card part type has not been loaded.)
						    (WINDOWADDPROP MessageWin (QUOTE 
									     UNKNOWNCARDTYPESLIST)
								     Type)
                                                             (* Save the pointer to the substance card part on an 
							     assoc list)
						    (WINDOWPROP MessageWin (QUOTE 
								    UNKNOWNCARDTYPESSUBSTANCEPTRS)
								  (LISTPUT (SETQ 
								    UnknownCardTypesSubstancePtrs
									       (WINDOWPROP
										 MessageWin
										 (QUOTE 
								    UNKNOWNCARDTYPESSUBSTANCEPTRS)))
									     Type
									     (CONS CurPtr
										     (LISTGET
										       
								    UnknownCardTypesSubstancePtrs 
										       Type)))))
					 (NC.SetScavengerMainDataInfo
					   Card
					   (CONS (LIST CurPtr Date Type (OR SubstanceLength
										  (QUOTE 
										  UNKNOWNCARDTYPE)))
						   (NC.FetchScavengerMainDataInfo Card))))))
			then Card)))))

(NC.CardPartsAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "22-Mar-86 18:22")

          (* * Called from the upper attached menu of the card parts menu. Contains options on what to do with changes to 
	  versions of this card. Can RESET to original versions, UPDATE by returning the new versions selected, ABORT, or 
	  DELETE the card.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)


    (LET ((MainWin (MAINWINDOW (WFROMMENU Menu)))
	  Menus OldItemNums Card CardsMenuWindow)
         (SETQ Menus (WINDOWPROP MainWin (QUOTE CARDPARTSMENUS)))
         (SETQ OldItemNums (WINDOWPROP MainWin (QUOTE CARDPARTSMENUOLDITEMNUMS)))
         (SETQ Card (WINDOWPROP MainWin (QUOTE CARD)))
         (SETQ CardsMenuWindow (WINDOWPROP MainWin (QUOTE CARDSMENUWINDOW)))
         (SELECTQ (CAR Item)
		    (RESET (for Menu in Menus as OldItemNum in OldItemNums bind Items
				do                         (* First unshade currently shaded item, then shade the
							     original one.)
				     (SETQ Items (fetch (MENU ITEMS) of Menu))
				     (SHADEITEM (CAR (FNTH Items (GETMENUPROP Menu
										      (QUOTE 
										       CURITEMNUM))))
						  Menu)
				     (SHADEITEM (CAR (FNTH Items OldItemNum))
						  Menu NC.LightShade)
				     (PUTMENUPROP Menu (QUOTE CURITEMNUM)
						    OldItemNum)))
		    (CANCEL (CLOSEW MainWin))
		    (DELETE (NC.SetStatus Card (QUOTE DELETED))
			    (CLOSEW MainWin)               (* Indicate that we made a real change to some card.)
			    (WINDOWPROP CardsMenuWindow (QUOTE MADECHANGES)
					  T)
			    (WINDOWPROP CardsMenuWindow (QUOTE NEEDLINKSCAVENGE)
					  T)
			    (REDISPLAYW CardsMenuWindow))
		    (UNDELETE                                (* I wonder if allowing undeletion is dangerous.
							     We shall see.)
			      (NC.SetStatus Card (QUOTE ACTIVE))
			      (CLOSEW MainWin)             (* Indicate that we made a real change to some card.)
			      (WINDOWPROP CardsMenuWindow (QUOTE MADECHANGES)
					    T)
			      (WINDOWPROP CardsMenuWindow (QUOTE NEEDLINKSCAVENGE)
					    T)
			      (REDISPLAYW CardsMenuWindow))
		    (UPDATE                                  (* Change the card locs for each card part that user 
							     has decided to change.)
			    (for Menu in Menus as OldItemNum in OldItemNums as SetLocFn
			       in (QUOTE (NC.SetTitleLoc NC.SetMainLoc NC.SetLinksLoc 
							       NC.SetPropListLoc))
			       bind CurItemNum when (NEQ OldItemNum (SETQ CurItemNum
								 (GETMENUPROP Menu (QUOTE 
										       CURITEMNUM))))
			       do (APPLY* SetLocFn Card (CADAR (FNTH (fetch (MENU ITEMS)
										of Menu)
									     CurItemNum)))
                                                             (* Indicate that we made a real change to some card.)
				    (WINDOWPROP CardsMenuWindow (QUOTE MADECHANGES)
						  T)         (* Changes to links or substance require a link 
							     scavenge.)
				    (if (FMEMB SetLocFn (QUOTE (NC.SetMainLoc NC.SetLinksLoc))
						   )
					then (WINDOWPROP CardsMenuWindow (QUOTE 
										 NEEDLINKSCAVENGE)
							     T)))
			    (CLOSEW MainWin))
		    NIL))))

(NC.BuildCardPartsInspector
  (LAMBDA (Card NoteFile CardsMenuWindow)                    (* rht: "22-Mar-86 18:23")

          (* * Build an attached group of menus for the 4 card parts: substance, links, title, and proplist.
	  These contain items for each version of that part of Card found on Stream. The highlighted item is the one 
	  currently pointed to. Return a list of user's changes.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)


    (LET ((CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (CardType (NC.FetchTypeFromScavengerInfo Card))
	  (CardStatus (NC.FetchStatus Card))
	  MenusAndItemNums MainWindow Menus OldItemNums)
         (SETQ MenusAndItemNums (LIST (NC.BuildTitlesInspectorMenu Card CardType CheckptPtr)
					  (NC.BuildSubstancesInspectorMenu Card CardType CheckptPtr 
									     CardsMenuWindow)
					  (NC.BuildLinksInspectorMenu Card CheckptPtr)
					  (NC.BuildPropListsInspectorMenu Card CheckptPtr)))
         (SETQ Menus (for MenuAndItemNum in MenusAndItemNums collect (CAR MenuAndItemNum)))
         (SETQ OldItemNums (for MenuAndItemNum in MenusAndItemNums collect (CDR 
										   MenuAndItemNum)))
                                                             (* Titles menu occupies main window.
							     Rest of menus are attached in order below.)
         (SETQ MainWindow (ADDMENU (CAR Menus)
				       NIL
				       (GETBOXPOSITION (fetch (MENU IMAGEWIDTH)
							    of (CAR Menus))
							 (fetch (MENU IMAGEHEIGHT)
							    of (CAR Menus))
							 NIL NIL NIL "Position the card parts menu."))
	   )
         (for Menu in (CDR Menus) do (ATTACHWINDOW (ADDMENU Menu)
							     MainWindow
							     (QUOTE BOTTOM)
							     (QUOTE LEFT)))
                                                             (* Save menus and item numbers of original 
							     selections.)
         (WINDOWPROP MainWindow (QUOTE CARDPARTSMENUS)
		       Menus)
         (WINDOWPROP MainWindow (QUOTE CARDPARTSMENUOLDITEMNUMS)
		       OldItemNums)
         (WINDOWPROP MainWindow (QUOTE NOTEFILE)
		       NoteFile)
         (WINDOWPROP MainWindow (QUOTE CARD)
		       Card)
         (WINDOWPROP MainWindow (QUOTE CARDSMENUWINDOW)
		       CardsMenuWindow)                      (* Shade the original selections.)
         (for Menu in Menus as ItemNum in OldItemNums
	    do (SHADEITEM (CAR (FNTH (fetch (MENU ITEMS) of Menu)
					     ItemNum))
			      Menu NC.LightShade)
		 (PUTMENUPROP Menu (QUOTE CURITEMNUM)
				ItemNum))
         (ATTACHWINDOW (ADDMENU (create
				      MENU
				      ITEMS ←(BQUOTE
					((UPDATE (QUOTE UPDATE)
						 "Change to indicated versions for this card.")
					 (CANCEL (QUOTE CANCEL)
						 
					 "Quit this card parts inspector, throwing away changes.")
					 (RESET (QUOTE RESET)
						  
				       "Go back to original version of card parts for this card.")
					 ,@(if (NOT (NC.UndeletableCardP Card))
					       then (LIST (if (EQ CardStatus (QUOTE DELETE))
								  then (QUOTE
									   (UNDELETE (QUOTE 
											 UNDELETE)
										     
	      "Undelete this card, restoring to indicated or most recent versions of card parts."))
								else (QUOTE (DELETE (QUOTE
											  DELETE)
											
								     "Mark this card as deleted.")))))
					 ))
				      MENUFONT ← NC.CardInspectorAttachedMenuFont
				      MENUBORDERSIZE ← 1
				      MENUOUTLINESIZE ← 1
				      CENTERFLG ← T
				      MENUROWS ← 1
				      WHENSELECTEDFN ←(FUNCTION 
					NC.CardPartsAttachedMenuWhenSelectedFn)))
			 MainWindow
			 (QUOTE TOP)
			 (QUOTE LEFT))
     MainWindow)))

(NC.CardSubstanceVersionInspector
  (LAMBDA (Card SubstanceInfo)                               (* rht: "26-Mar-86 12:26")

          (* * Fill in a SUBSTANCEDATA record and bring up an inspector on it.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * rht 3/22/86: Fixed to handle substance version nums. Now calls NC.ApplyFn and handles Hash card types.
	  Also changed the way text, graph, and sketch cards are handled.)


    (LET ((NoteFile (fetch (Card NoteFile) of Card))
	  Stream Type WindowTitle Sketch SketchObjDatum Length SubstanceVersionNum ListMenu 
	  TempStream StartLoc)                               (* Position file at main card data.
							     Hopefully no need to check validity of what we're 
							     reading.)
         (SETFILEPTR (SETQ Stream (fetch (NoteFile Stream) of NoteFile))
		       (CAR SubstanceInfo))
         (NC.ReadCardPartHeader Card NC.ItemIdentifier)
         (NC.SetType Card (SETQ Type (CAR (NC.RobustReadAtom Stream))))
         (NC.RobustReadRegion Stream (GETEOFPTR Stream))
         (SETQ Length (NC.ReadPtr Stream 3))
         (SETQ SubstanceVersionNum (NC.ReadPtr Stream 1))
         (SETQ WindowTitle (CONCAT Type ": " (NC.ShaveTitleString (
								   NC.FetchTitleFromScavengerInfo
									  Card))
				       " | Date: "
				       (CADR SubstanceInfo)))
                                                             (* Unfortunately, can only inspect system-defined 
							     substances now.)
         (COND
	   ((NC.IsSubTypeOfP Type (QUOTE Text))          (* This is so that user edits a copy of the text and 
							     can't affect original.)
	     (COPYBYTES Stream (SETQ TempStream (OPENSTREAM (QUOTE {NODIRCORE})
								  (QUOTE BOTH)
								  (QUOTE NEW)))
			  (SETQ StartLoc (GETFILEPTR Stream))
			  (PLUS StartLoc Length))
	     (OPENTEXTSTREAM (COPYTEXTSTREAM (OPENTEXTSTREAM TempStream)
						 T)
			       (CREATEW (PROGN (NC.PrintMsg NIL T 
							   "Choose region for Text card display.")
						   (GETREGION))
					  WindowTitle)))
	   ((NC.IsSubTypeOfP Type (QUOTE Graph))
	     (SHOWGRAPH (NC.MakeExternalGraphCopy (NC.ApplyFn GetFn Card Length Stream 
								  SubstanceVersionNum))
			  (CREATEW (PROGN (NC.PrintMsg NIL T 
							  "Choose region for Graph card display.")
					      (GETREGION))
				     WindowTitle)
			  NIL NIL NIL T))
	   ((NC.IsSubTypeOfP Type (QUOTE Sketch))
	     (SETQ Sketch (NC.ApplyFn GetFn Card Length Stream SubstanceVersionNum))
	     (SKETCHW.CREATE (NC.ExternalizeLinkIconsInSketch Sketch)
			       (NC.FetchRegionViewed Card)
			       (PROGN (NC.PrintMsg NIL T "Choose region for Sketch card display.")
					(GETREGION))
			       WindowTitle
			       (NC.FetchScale Card)))
	   ((NC.IsSubTypeOfP Type (QUOTE List))
	     (SETQ ListMenu (create MENU
					ITEMS ←(NC.ApplyFn GetFn Card Length Stream 
							   SubstanceVersionNum)
					TITLE ← WindowTitle))
	     (ADDMENU ListMenu NIL (GETBOXPOSITION (fetch (MENU IMAGEWIDTH) of ListMenu)
						       (fetch (MENU IMAGEHEIGHT) of ListMenu)
						       NIL NIL NIL 
						       "Choose region for List card display.")))
	   ((NC.IsSubTypeOfP Type (QUOTE Hash))
	     (WINDOWPROP (INSPECT (NC.ApplyFn GetFn Card Length Stream SubstanceVersionNum))
			   (QUOTE TITLE)
			   WindowTitle))
	   (T (NC.PrintMsg NIL T 
	  "Sorry, can only inspect card types inheriting from Text, Graph, Sketch, List or Hash.")))))
)

(NC.ScavengerCleanup
  (LAMBDA (MessageWin)                                       (* rht: "22-Mar-86 19:08")

          (* * Abort the scavenger by closing the notefile without checkpointing.)



          (* * rht 12/8/85: Updated to handle new notefile and card object formats.)



          (* * rht 3/22/86: Took out NOTIFY.EVENT stuff since NC.ScavengerPhase1 is no longer hanging on completion of phase 
	  3.0)


    (LET ((NoteFile (WINDOWPROP MessageWin (QUOTE NOTEFILE))))
         (if (OPENP (fetch (NoteFile Stream) of NoteFile))
	     then (NC.ForceDatabaseClose NoteFile)
		    (NC.PrintMsg NIL T "Repair of " (fetch (NoteFile FullFileName) of NoteFile)
				   " aborted.")))))

(NC.MessageWinAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "22-Mar-86 19:10")

          (* * Called when selecting from the attached menu to the main message window.)



          (* * rht 9/17/85: Now gets MaxIDNum from WINDOWPROP of MessageWin and uses it for looping through cards.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object fomats.)



          (* * rht 3/22/86: Took out NOTIFY.EVENT stuff since NC.ScavengerPhase1 is no longer hanging on completion of phase 
	  3.0)


    (LET ((MenuWin (WFROMMENU Menu))
	  (Operation (CAR Item))
	  MessageWin NoteFile InspectorWins BadNewsList ExtraBadNews)
         (SETQ MessageWin (MAINWINDOW MenuWin))
         (SETQ NoteFile (WINDOWPROP MessageWin (QUOTE NOTEFILE)))
         (SETQ BadNewsList (WINDOWPROP MessageWin (QUOTE BADNEWSLIST)))
         (SETQ ExtraBadNews (WINDOWPROP MessageWin (QUOTE EXTRABADNEWS)))
         (SELECTQ Operation
		    (Abort (if (NC.AskYesOrNo 
				     "Do you really want to abort the Inspect & Repair process? "
						  NIL
						  (QUOTE Yes)
						  T
						  (NC.AttachPromptWindow MenuWin)
						  T NIL)
			       then                        (* Bail out.)
				      (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
						       (FUNCTION NC.MessageWinCloseFn))
				      (CLOSEW MessageWin)
				      (NC.ScavengerCleanup MessageWin)))
		    (Recheck% Bad% Cards                     (* Rerun the end of phase1.)
					 (DETACHWINDOW MenuWin)
					 (CLOSEW MenuWin)
					 (NC.ScavengerPhase1 NoteFile NIL MessageWin T))
		    (Inspect% Cards                          (* Bring up the big card inspector menu.)
				    (DETACHWINDOW MenuWin)
				    (CLOSEW MenuWin)
				    (NC.BuildCardInspectorMenu
				      (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
							 Card))
						     (FUNCTION (LAMBDA (Card)
							 (AND (FMEMB (NC.FetchStatus Card)
									 (QUOTE (ACTIVE BADPOINTER 
											  NIL)))
								(NOT (NC.WorthlessCardP Card))))))
				      (APPEND ExtraBadNews BadNewsList)
				      NoteFile MessageWin))
		    (Include% Deleted% Cards                 (* Like above except include also the deleted cards.)
					     (DETACHWINDOW MenuWin)
					     (CLOSEW MenuWin)
					     (NC.BuildCardInspectorMenu
					       (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
								  Card))
							      (FUNCTION (LAMBDA (Card)
								  (AND (FMEMB
									   (NC.FetchStatus Card)
									   (QUOTE (ACTIVE 
										       BADPOINTER NIL 
											  DELETED)))
									 (NOT (NC.WorthlessCardP
										  Card))))))
					       (APPEND ExtraBadNews BadNewsList)
					       NoteFile MessageWin))
		    (Continue% Repair                        (* If changes were made, then checkpoint the 
							     notefile.)
				      (if (NEQ (NC.CheckForBadLinksAndTitlesAndPropLists 
											 NoteFile 
										       MessageWin 
										      BadNewsList)
						   (QUOTE ABORT))
					  then (if (WINDOWPROP MessageWin (QUOTE 
										   NEEDCHECKPOINT))
						     then (NC.CheckpointDatabase NoteFile))
						 (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
								  (FUNCTION NC.MessageWinCloseFn))
						 (CLOSEW MessageWin) 
                                                             (* Rebuild the links.)
						 (NC.ScavengeDatabaseFile NoteFile
									    (WINDOWPROP
									      MessageWin
									      (QUOTE 
										  LINKSLABELSNEWS))
									    (WINDOWPROP
									      MessageWin
									      (QUOTE BADBOXES))
									    (WINDOWPROP
									      MessageWin
									      (QUOTE 
									      CARDSWITHLINKSRESET)))))
		    (End% Inspect&Repair                     (* Don't have to scavenge links.
							     Close up gracefully.)
					 (NC.CheckForBadLinksAndTitlesAndPropLists NoteFile 
										     MessageWin 
										     BadNewsList)
					 (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
							  (FUNCTION NC.MessageWinCloseFn))
					 (CLOSEW MessageWin)
					 (NC.CloseDatabaseFile NoteFile))
		    NIL))))

(NC.MessageWinCloseFn
  (LAMBDA (MainWin)                                          (* rht: "24-Mar-86 18:29")

          (* * Runs when main message win is closed. Checks whether user means to abort and closes each card inspector 
	  window.)



          (* * rht 12/8/85: Modified to reflect new notefile format.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 3/24/86: Added call to NC.CloseInspectorWindows.)


    (if (NC.AskYesOrNo "Do you really want to abort the Inspect & Repair process? " NIL
			   (QUOTE Yes)
			   T
			   (NC.AttachPromptWindow MainWin)
			   T NIL)
	then (NC.CloseInspectorWindows MainWin)
	       (for MenuWin in (WINDOWPROP MainWin (QUOTE MENUWINDOWS))
		  do (WINDOWDELPROP MenuWin (QUOTE CLOSEFN)
					(FUNCTION NC.CardInspectorCloseFn))
		       (DETACHWINDOW MenuWin)
		       (CLOSEW MenuWin))
	       (MOVEW MainWin NC.OffScreenPosition)
	       (NC.ScavengerCleanup MainWin)
      else (QUOTE DON'T))))

(NC.CardInspectorCloseFn
  (LAMBDA (Win Don'tAskFlg)                                  (* rht: "24-Mar-86 18:29")

          (* * Closing inspector window is just like selecting "abort" from attached menu, i.e. abort the repair process.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 3/24/86: Added call to NC.CloseInspectorWindows.)


    (LET ((MainWin (MAINWINDOW Win)))
         (if (OR Don'tAskFlg (NC.AskUser 
				     "Do you really want to abort the Inspect & Repair process? "
					       NIL
					       (QUOTE Yes)
					       T
					       (NC.AttachPromptWindow MainWin)
					       T NIL))
	     then (DETACHWINDOW Win)
		    (NC.CloseInspectorWindows MainWin)
		    (for MenuWin in (WINDOWPROP MainWin (QUOTE MENUWINDOWS))
		       unless (EQ MenuWin Win)
		       do (WINDOWDELPROP MenuWin (QUOTE CLOSEFN)
					     (FUNCTION NC.CardInspectorCloseFn))
			    (DETACHWINDOW MenuWin)
			    (CLOSEW MenuWin))
		    (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
				     (FUNCTION NC.MessageWinCloseFn))
		    (CLOSEW MainWin)
		    (MOVEW Win NC.OffScreenPosition)
		    (NC.ScavengerCleanup MainWin)
	   else (QUOTE DON'T)))))

(NC.CardInspectorAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "24-Mar-86 18:27")

          (* * Called when leaving the main cards inspector menu. User is either aborting the scavenge or absorbing changes 
	  and continuing. In latter case, we need to recompute scavenger array to check for if she has fixed whatever 
	  problems there were. If so, then continue with link scavenge.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 3/24/86: Added call to NC.CloseInspectorWindows.)


    (LET ((MainWin (MAINWINDOW (WFROMMENU Menu)))
	  (Operation (CAR Item))
	  MessageWin NoteFile InspectorWins NextWin MenuWindows SearchString)
         (SETQ MessageWin (MAINWINDOW MainWin))
         (SETQ MenuWindows (WINDOWPROP MessageWin (QUOTE MENUWINDOWS)))
         (if (AND (OR (NEQ Operation (QUOTE ABORT))
			    (PROGN (NC.AskYesOrNo 
				     "Do you really want to abort the Inspect & Repair process? "
						      NIL
						      (QUOTE Yes)
						      T
						      (NC.AttachPromptWindow MainWin)
						      T NIL)))
		      (OR (NOT (FMEMB Operation (QUOTE (ABORT DONE))))
			    (for Win in (SETQ InspectorWins (WINDOWPROP MessageWin
										(QUOTE 
										 INSPECTORWINDOWS)))
			       never (OPENWP Win))
			    (PROG2 (NC.PrintMsg NIL T "There are open card inspector windows.")
				     (if (NC.YesP (NC.AskUser "Want to close them? " NIL "Yes" 
								    NIL NIL T NIL T))
					 then (for Win in InspectorWins when (OPENWP Win)
						   do (CLOSEW Win))
						T))))
	     then (SETQ NoteFile (WINDOWPROP MainWin (QUOTE NOTEFILE)))
		    (SELECTQ Operation
			       (Abort (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
						       (FUNCTION NC.CardInspectorCloseFn))
				      (NC.CardInspectorCloseFn MainWin T)
				      (CLOSEW MainWin))
			       (Done (DETACHWINDOW MainWin)
				     (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
						      (FUNCTION NC.CardInspectorCloseFn))
				     (NC.CloseInspectorWindows MessageWin)
				     (for MenuWin in (WINDOWPROP MessageWin (QUOTE 
										      MENUWINDOWS))
					unless (EQ MenuWin MainWin)
					do (WINDOWDELPROP MenuWin (QUOTE CLOSEFN)
							      (FUNCTION NC.CardInspectorCloseFn))
					     (CLOSEW MenuWin))
				     (if (WINDOWPROP MainWin (QUOTE MADECHANGES))
					 then (WINDOWPROP MessageWin (QUOTE NEEDCHECKPOINT)
							      T))
				     (WINDOWPROP MessageWin (QUOTE NEEDLINKSCAVENGE)
						   (OR (WINDOWPROP MessageWin (QUOTE 
										 NEEDLINKSCAVENGE))
							 (WINDOWPROP MainWin (QUOTE 
										 NEEDLINKSCAVENGE))))
				     (CLOSEW MainWin)

          (* This "recursive" call will check to make sure everything is okay before invoking link scavenge.
	  I'm calling with ReadSubstancesFlg off, even if this call had it on. That's because we don't want it to be so slow 
	  on the second go-around.)


				     (NC.ScavengerPhase1 NoteFile NIL MessageWin))
			       (Search 

          (* Simple-minded search for titles of cards containing the given search string. User is asked for string in the 
	  prompt window, but answer appears in MessageWin for easy access.)


				       (SETQ SearchString
					 (NC.AskUser "Search string? " NIL NIL T NIL T T NIL))
				       (NC.PrintMsg NIL T "Searching ... ")
				       (NC.PrintMsg MessageWin NIL 
						      "Card titles containing string '"
						      SearchString "': "
						      (NC.MapCards
							NoteFile
							(FUNCTION (LAMBDA (Card PredicateResult)
							    PredicateResult))
							(FUNCTION (LAMBDA (Card)
							    (LET ((Title (
								   NC.FetchTitleFromScavengerInfo
									   Card)))
							         (if (STRPOS SearchString Title)
								     then (CONCAT (
										  NC.FetchSlotNum
											Card)
										      ": " Title)
								   else NIL)))))
						      (CHARACTER 13))
				       (NC.PrintMsg NIL NIL "Done."))
			       (Previous% Page               (* Get previous menu window by accessing list of 
							     windows cached on MessageWin.)
					       (DETACHWINDOW MainWin)
					       (MOVEW MainWin NC.OffScreenPosition)
					       (ATTACHWINDOW (SETQ NextWin
								 (if (EQ MainWin (CAR 
										      MenuWindows))
								     then (CAR (LAST 
										      MenuWindows))
								   else (CAR (NLEFT
										   MenuWindows 1
										   (FMEMB MainWin 
										      MenuWindows)))))
							       MessageWin
							       (QUOTE BOTTOM)
							       (QUOTE LEFT)))
			       (Next% Page                   (* Get next menu window by accessing list of windows 
							     cached on MessageWin.)
					   (DETACHWINDOW MainWin)
					   (MOVEW MainWin NC.OffScreenPosition)
					   (ATTACHWINDOW (SETQ NextWin
							     (if (EQ MainWin (CAR (LAST
											  MenuWindows)
											))
								 then (CAR MenuWindows)
							       else (CADR (FMEMB MainWin 
										      MenuWindows))))
							   MessageWin
							   (QUOTE BOTTOM)
							   (QUOTE LEFT)))
			       (First% Page                  (* Get first menu window by accessing list of windows 
							     cached on MessageWin.)
					    (if (EQ MainWin (SETQ NextWin (CAR MenuWindows)))
						then (FLASHW MainWin)
					      else (DETACHWINDOW MainWin)
						     (MOVEW MainWin NC.OffScreenPosition)
						     (ATTACHWINDOW NextWin MessageWin (QUOTE
								       BOTTOM)
								     (QUOTE LEFT))))
			       NIL)))))
)
(PUTPROPS RHTPATCH033 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1411 14370 (NC.LinkIconWhenCopiedFn 1421 . 8161) (NC.LinkIconWhenMovedFn 8163 . 14368))
 (14410 16073 (NC.MakeExternalGraphCopy 14420 . 16071)) (16112 16539 (NC.CloseInspectorWindows 16122
 . 16537)) (16582 17276 (NC.ExternalizeLinkIconsInSketch 16592 . 17274)) (17317 66178 (NC.AtEndOfItemP
 17327 . 18341) (NC.RobustReadChar 18343 . 18755) (NC.CheckForValidSubstance 18757 . 19900) (
NC.RobustGetSubstance 19902 . 20476) (NC.ScavengerPhase1 20478 . 34229) (NC.CheckUnknownCardTypes 
34231 . 35935) (NC.RobustReadCardPart 35937 . 40947) (NC.CardPartsAttachedMenuWhenSelectedFn 40949 . 
44556) (NC.BuildCardPartsInspector 44558 . 48571) (NC.CardSubstanceVersionInspector 48573 . 52384) (
NC.ScavengerCleanup 52386 . 53145) (NC.MessageWinAttachedMenuWhenSelectedFn 53147 . 57565) (
NC.MessageWinCloseFn 57567 . 58653) (NC.CardInspectorCloseFn 58655 . 60055) (
NC.CardInspectorAttachedMenuWhenSelectedFn 60057 . 66176)))))
STOP