(FILECREATED "23-Jan-87 14:28:27" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH184.;10 37389  

      changes to:  (FNS NC.CardInspectorAttachedMenuWhenSelectedFn)
		   (VARS RHTPATCH184COMS)

      previous date: "23-Jan-87 14:17:57" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH184.;9)


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

(PRETTYCOMPRINT RHTPATCH184COMS)

(RPAQQ RHTPATCH184COMS ((FILES (FROM {QV}<NOTECARDS>1.3K>NEXT)
				 NCREPAIR)
			  (* * Fixes: #401: I&R close inspectors question does not give Yes/No menu. 
			     #402: I&R if you request an inspector for a card whose inspector is 
			     already up, it shouldn't create a new one. #403: I&R can't recover cards 
			     that were created since the last checkpoint. #404: I&R abort may write 
			     stuff after checkpoint. #405: Trying to create new card when index is 
			     full actually puts another entry in the index. This patch probably fixes 
			     bug #346 and may fix #252 as well.)
			  (* * Changes to NCREPAIR)
			  (FNS NC.RobustReadCardPart NC.AtEndOfItemP 
			       NC.CardInspectorAttachedMenuWhenSelectedFn 
			       NC.CardInspectorMenuWhenSelectedFn NC.ScavengeDatabaseFile)
			  (* * Changes to NCDATABASE)
			  (FNS NC.GetNewCard)
			  (* * Changes to NCLOCALDEVICE)
			  (FNS NCLocalDevice.NewCardUID)))
(FILESLOAD (FROM {QV}<NOTECARDS>1.3K>NEXT)
	   NCREPAIR)
(* * Fixes: #401: I&R close inspectors question does not give Yes/No menu. #402: I&R if you 
request an inspector for a card whose inspector is already up, it shouldn't create a new one. 
#403: I&R can't recover cards that were created since the last checkpoint. #404: I&R abort may 
write stuff after checkpoint. #405: Trying to create new card when index is full actually puts 
another entry in the index. This patch probably fixes bug #346 and may fix #252 as well.)

(* * Changes to NCREPAIR)

(DEFINEQ

(NC.RobustReadCardPart
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin EndPtr)     (* rht: "22-Jan-87 17:41")

          (* * 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.)



          (* * fgh 5/1/86 Fixed bug in previous fix. Code was bombing the first time it tried to put something on a 
	  nonexistent assoc list. Put in a COND to create the assoc list if it isn't already created.)



          (* * fgh 7/30/86 Replaced call to NCP.ValidCardType with call to NCP.CardTypeP)



          (* * rht 1/21/87: If card part belongs to a card not in the notefile index, force the new card created to have the 
	  given UID.)


    (DECLARE (GLOBALVARS NC.TitlesIdentifier NC.PropsIdentifier NC.LinksIdentifier 
			     NC.ItemIdentifier))
    (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.CardTypeP 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)
						    (COND
						      ((SETQ UnknownCardTypesSubstancePtrs
							  (WINDOWPROP MessageWin (QUOTE 
								    UNKNOWNCARDTYPESSUBSTANCEPTRS)))
							(LISTPUT UnknownCardTypesSubstancePtrs Type
								   (CONS CurPtr (LISTGET 
								    UnknownCardTypesSubstancePtrs 
											     Type))))
						      (T (WINDOWPROP MessageWin (QUOTE 
								    UNKNOWNCARDTYPESSUBSTANCEPTRS)
								       (LIST Type (LIST CurPtr))))
						      ))
					 (NC.SetScavengerMainDataInfo
					   Card
					   (CONS (LIST CurPtr Date Type (OR SubstanceLength
										  (QUOTE 
										  UNKNOWNCARDTYPE)))
						   (NC.FetchScavengerMainDataInfo Card))))))
			then Card)))))

(NC.AtEndOfItemP
  (LAMBDA (Stream EofPtr)                                    (* rht: "22-Jan-87 15:49")

          (* * 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.)



          (* * rht 1/22/87: Now never SETFILEPTR's beyond end of file.)


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

(NC.CardInspectorAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "23-Jan-87 14: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.)



          (* * rht 7/16/86: Added NC.AttachPromptWindow calls. String search is now case INsensitive.)



          (* * rht 1/22/87: Now calls NC.AskYesOrNo instead of NC.AskUser.)


    (DECLARE (GLOBALVARS NC.OffScreenPosition))
    (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))
			    (NC.AskYesOrNo 
				     "Do you really want to abort the Inspect & Repair process? "
					     NIL
					     (QUOTE Yes)
					     T
					     (NC.AttachPromptWindow MessageWin)
					     NIL NIL))
		      (OR (NOT (FMEMB Operation (QUOTE (Abort Done))))
			    (for Win in (SETQ InspectorWins (WINDOWPROP MessageWin
										(QUOTE 
										 INSPECTORWINDOWS)))
			       never (OPENWP Win))
			    (PROG2 (NC.PrintMsg (NC.AttachPromptWindow MessageWin)
						    T "There are open card inspector windows.")
				     (if (NC.AskYesOrNo "Want to close them? " NIL "Yes" NIL
							    (NC.AttachPromptWindow MessageWin))
					 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 NIL (
							     NC.AttachPromptWindow 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
									  (NC.AttachPromptWindow
									    MessageWin)
									  T T NIL))
				       (NC.PrintMsg (NC.AttachPromptWindow MessageWin)
						      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 (U-CASE 
										     SearchString)
										 (U-CASE Title))
								     then (CONCAT (
										  NC.FetchSlotNum
											Card)
										      ": " Title)
								   else NIL)))))
						      (CHARACTER 13))
				       (NC.ClearMsg (NC.AttachPromptWindow MessageWin)
						      T))
			       (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)))))

(NC.CardInspectorMenuWhenSelectedFn
  (LAMBDA (CardPair Menu MouseKey)                           (* rht: "22-Jan-87 18:23")

          (* * Called when a card is selected from main card inspector menu. Pop up menu offering choice of "Inspect" or 
	  "Delete".)



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



          (* * fgh 2/4/86 Fixed bug where delete was no marking the index dirty.)



          (* * rht 1/22/87: Fixed typo in loop that checks open inspector windows.)


    (AND CardPair (LET ((Win (WFROMMENU Menu))
			  (NormalItems (QUOTE ((Inspect (QUOTE Inspect)
							  "Bring up description of card.")
						  (Delete (QUOTE Delete)
							  "Mark this card as deleted."))))
			  (ItemsWithUndelete (QUOTE ((Inspect (QUOTE Inspect)
								"Bring up description of card.")
							(Undelete (QUOTE Undelete)
								  "Undelete this card."))))
			  (ItemsWithoutDelete (QUOTE ((Inspect (QUOTE Inspect)
								 "Bring up description of card."))))
			  (Card (CADR CardPair))
			  DeletedCards NoteFile ExistingWin MessageWin)
		         (SETQ MessageWin (MAINWINDOW Win))
		         (SETQ DeletedCards (WINDOWPROP MessageWin (QUOTE DELETEDCARDS)))
		         (SETQ NoteFile (WINDOWPROP Win (QUOTE NOTEFILE)))
		         (if (EQ MouseKey (QUOTE MIDDLE))
			     then (MENU (create MENU
						      ITEMS ←(LIST (NC.FetchTitleFromScavengerInfo
								       Card))))
			   else (SELECTQ
				    (MENU (create MENU
						      ITEMS ←(COND
							((NC.UndeletableCardP Card)
							  ItemsWithoutDelete)
							((FMEMB Card DeletedCards)
							  ItemsWithUndelete)
							(T NormalItems))))
				    (Inspect (if (SETQ ExistingWin
						     (for InspectorWindow
							in (WINDOWPROP MessageWin (QUOTE 
										 INSPECTORWINDOWS))
							when (AND (OPENWP InspectorWindow)
								      (NC.SameCardP
									Card
									(WINDOWPROP InspectorWindow
										      (QUOTE CARD)))
								      )
							do (RETURN InspectorWindow)))
						 then (FLASHW ExistingWin)
					       else (WINDOWADDPROP MessageWin (QUOTE 
										 INSPECTORWINDOWS)
								       (NC.BuildCardPartsInspector
									 Card NoteFile Win))))
				    (Delete (NC.SetStatus Card (QUOTE DELETED))
					    (WINDOWPROP Win (QUOTE MADECHANGES)
							  T)
					    (WINDOWPROP Win (QUOTE NEEDLINKSCAVENGE)
							  T)
					    (REDISPLAYW Win))
				    (Undelete                (* I wonder if allowing undeletion is dangerous.
							     We shall see.)
					      (NC.SetStatus Card (QUOTE ACTIVE))
                                                             (* Indicate that we made a real change to some card.)
					      (WINDOWPROP Win (QUOTE MADECHANGES)
							    T)
					      (WINDOWPROP Win (QUOTE NEEDLINKSCAVENGE)
							    T)
					      (REDISPLAYW Win))
				    NIL))))))

(NC.ScavengeDatabaseFile
  (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfBoxesToReconstruct 
			      ListOfCardsNeedingGlobalLinksReconstructed InterestedWindow)
                                                             (* rht: "22-Jan-87 18:34")

          (* Scavenge the database FileName. Essentially throw away all of the information about From and ToLinks and 
	  recreate them by retrieving the link information from the substance of each card and from the list of global links 
	  from the card.)



          (* * rht 8/9/84: Now calls NC.OpenDatabaseFile to do the file open.)



          (* * rht 7/17/85: Changed so can take a stream argument. Also handles link labels. If BadLinkLabelsFlg is non-nil, 
	  then don't try to read current link labels. Just rebuild them from what's out there. Otherwise, only rebuild if 
	  find new any new ones.)



          (* * fgh 22-Jul-85 Takes a list of bad file box cards and reconstructs the file boxes from the From pointer lists 
	  of all the cards in the NoteFile.)



          (* * fgh 30-Jul-85 Takes a list of cards with bad global links and reconstructs the global links list from the From
	  pointer lists of all the cards in the NoteFile.)



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



          (* * rht 12/1/85: Now calls NC.GetMainCardData and NC.GetLinks instead of NC.GetNoteCard.)



          (* * rht 12/19/85: Massive overhaul for sake of speed. Should be wizzier now.)



          (* * fgh 2/4/86 Now works on open NFs. No need to error check since this function should always be called from 
	  earlier phases of the inspect & repaier.)



          (* * fgh 5/21/86 Fixed bug in handling of global links.)



          (* * rht 7/16/86: Added InterestedWindow arg.)



          (* * rht 7/16/86: Now calls NC.PutLinks passing UseOldDatesFlg.)



          (* * rht 9/5/86: Now checks that link is valid before passing it to NC.DelReferencesToCard.)



          (* * rht 10/29/86: Now closes prompt win at end if no filing info to tell.)



          (* * rht 12/10/86: No longer calls NC.GetLinks for cards appearing on the 
	  ListOfCardsNeedingGlobalLinksReconstructed list.)



          (* * rht 1/19/87: Now uses NC.CardNeedsFilingP to check for unfiled cards at the end.)



          (* * rht 1/22/87: Added yet another BLOCK call.)


    (PROG (NoteFile FileName CardTotal NoteCardNumber OldLinkLabels DiscoveredLinkLabels 
		      ReconstructLinks ReconstructGlobalLinks ToBeFiledCards)

          (* * First, take care of checking stream's validity, etc.)


	    (SETQ FileName (if (type? NoteFile NoteFileOrFileName)
				 then (SETQ NoteFile NoteFileOrFileName)
					(fetch (NoteFile FullFileName) of NoteFileOrFileName)
			       else NoteFileOrFileName))   (* Try to open notefile.)
	    (if (NULL (OPENP FileName))
		then (if (NULL (SETQ NoteFile
				       (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL 
							      InterestedWindow)))
			   then (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
						 (CHARACTER 13)
						 "Repair aborted.")
				  (RETURN NIL)))

          (* * If link labels aren't screwed up, then read them in.)


	    (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.RetrieveLinkLabels NoteFile T)))

          (* * Mark every card that needs its global links or substance reconstructed so we don't have to search the lists so
	  much.)


	    (for Card in ListOfCardsNeedingGlobalLinksReconstructed do (NC.SetUserDataProp
									       Card
									       (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)
									       T))
	    (for Box in ListOfBoxesToReconstruct do (NC.SetUserDataProp Box (QUOTE 
									   NeedsReconstructingFlg)
										T))

          (* Read through all NoteCard substances to find actual pointers. Use this to create the To Links list.
	  The list collection function checks to make sure each link is valid.)


	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum)
					       NoteFile)))
	    (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER 13)
			   "Collecting Links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards
	      NoteFile
	      (FUNCTION (LAMBDA (Card)
		  (BLOCK)
		  (SETQ NoteCardNumber (ADD1 NoteCardNumber))
		  (AND (ZEROP (REMAINDER NoteCardNumber 10))
			 (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER
					  13)
					"Collecting Links for item " NoteCardNumber " out of " 
					CardTotal "."))      (* Get global links unless links are unreadable.)
		  (if (NOT (NC.FetchUserDataProp Card (QUOTE NeedsGlobalLinksReconstructedFlg)
						       ))
		      then (NC.GetLinks Card))
		  (if (NC.FetchUserDataProp Card (QUOTE NeedsReconstructingFlg))
		      then                                 (* Card substance and links will be reconstructed so 
							     no need to try to read substance.)
			     (if (NOT (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
				 then (NC.SetUserDataProp Card (QUOTE ScavengerToLinks)
							      (NC.FetchGlobalLinks Card))
					(NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks)
							      (NC.FetchGlobalLinks Card)))
			     (NC.DeactivateCard Card T)
		    else (NC.GetMainCardData Card)
			   (NC.ActivateCard Card)
			   (if (EQ (NC.FetchStatus Card)
				       (QUOTE ACTIVE))
			       then                        (* Collect links having active destinations.
							     Delete the others.)
				      (NC.SetUserDataProp
					Card
					(QUOTE ScavengerToLinks)
					(NCONC (for Link in (CAR (NC.CollectReferences
									   Card))
						    eachtime (BLOCK)
						    when (if (EQ (NC.FetchStatus
									 (fetch (Link 
										  DestinationCard)
									    of Link))
								       (QUOTE ACTIVE))
							     else (AND (type? Link Link)
									   (NC.DelReferencesToCard
									     Card Link))
								    NIL)
						    collect Link)
						 (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
						   else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
										(NC.FetchGlobalLinks
										  Card))
							  (NC.FetchGlobalLinks Card))))
				      (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
					else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
								     (NC.FetchGlobalLinks Card)))

          (* If there are file boxes to be reconstructed, then look thru the From links to see if this card was filed in one 
	  of the to-be-reconstructed boxes)


				      (AND ListOfBoxesToReconstruct
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.ChildLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE NeedsReconstructingFlg)))
						do (push ReconstructLinks Link)))

          (* If there are global links to be reconstructed, then look thru the From links to see if this card had a global 
	  link from a card whose global links need reconstructing.)


				      (AND ListOfCardsNeedingGlobalLinksReconstructed
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.GlobalLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
						do (push ReconstructGlobalLinks Link)))
				      (NC.DeactivateCard Card T))))))

          (* * Reconstruct any cards as requested)


	    (for BoxToReconstruct in ListOfBoxesToReconstruct eachtime (BLOCK)
	       do                                          (* Make a new file box using the given card.)
		    (NC.MakeNoteCard (QUOTE FileBox)
				       NoteFile "Untitled: Reconstructed during repair" T NIL 
				       BoxToReconstruct)

          (* File cards whose from links indicate that they used to be filed in this file box. Also add these new links to 
	  collected ToLinks.)


		    (NC.SetUserDataProp BoxToReconstruct (QUOTE ScavengerToLinks)
					  (APPEND (NC.FetchUserDataProp BoxToReconstruct
									    (QUOTE ScavengerToLinks)
									    )
						    (for Link in ReconstructLinks
						       eachtime (BLOCK)
						       when (NC.SameCardP BoxToReconstruct
									      (fetch (Link 
										       SourceCard)
										 of Link))
						       collect (NC.MakeChildLink
								   (fetch (Link DestinationCard)
								      of Link)
								   BoxToReconstruct NIL))))
                                                             (* Put the card away)
		    (NC.PutMainCardData BoxToReconstruct)
		    (NC.DeactivateCard BoxToReconstruct T))

          (* * Reconstruct any global link lists as required)


	    (for Link in ReconstructGlobalLinks bind ThisCardsToLinks ThisCardsGlobalLinks 
							   SourceCard
	       eachtime (BLOCK)
	       do (SETQ SourceCard (fetch (Link SourceCard) of Link)) 
                                                             (* Add it to the GlobalLinks list for its source card 
							     unless it's already there.)
		    (if (for GlobalLink in (SETQ ThisCardsGlobalLinks (NC.FetchUserDataProp
						     SourceCard
						     (QUOTE ScavengerGlobalLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link GlobalLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerGlobalLinks)
						     (CONS Link ThisCardsGlobalLinks)))
                                                             (* Add it to the source card's ToLinks list unless 
							     it's already there)
		    (if (for ToLink in (SETQ ThisCardsToLinks (NC.FetchUserDataProp
						 SourceCard
						 (QUOTE ScavengerToLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link ToLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerToLinks)
						     (CONS Link ThisCardsToLinks))))

          (* * Compute the From Links list by "inverting" the To Links list)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Inverting links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			     (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			     (AND (ZEROP (REMAINDER NoteCardNumber 100))
				    (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						   (CHARACTER 13)
						   "Inverting links for item " NoteCardNumber 
						   " out of "
						   CardTotal "."))
			     (if (EQ (NC.FetchStatus Card)
					 (QUOTE ACTIVE))
				 then (for Link in (NC.FetchUserDataProp Card (QUOTE 
										 ScavengerToLinks))
					   bind DestinationCard LinkLabel eachtime (BLOCK)
					   do              (* Add this ToLink as a FromLink for the link's 
							     destination card.)
						(NC.SetUserDataProp (SETQ DestinationCard
									(fetch (Link 
										  DestinationCard)
									   of Link))
								      (QUOTE ScavengerFromLinks)
								      (CONS Link
									      (NC.FetchUserDataProp
										DestinationCard
										(QUOTE 
									       ScavengerFromLinks))))
                                                             (* Accumulate the link labels into a list.)
						(if (NOT (FMEMB (SETQ LinkLabel
									(fetch (Link Label)
									   of Link))
								      DiscoveredLinkLabels))
						    then (push DiscoveredLinkLabels LinkLabel)))))
			   ))

          (* * Reset all of the To and From Links lists in the database)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Rewriting links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			     (BLOCK)
			     (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			     (AND (ZEROP (REMAINDER NoteCardNumber 10))
				    (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						   (CHARACTER 13)
						   "Rewriting links for item " NoteCardNumber 
						   " out of "
						   CardTotal "."))
			     (if (EQ (NC.FetchStatus Card)
					 (QUOTE ACTIVE))
				 then (NC.SetGlobalLinks Card (NC.FetchUserDataProp
							       Card
							       (QUOTE ScavengerGlobalLinks)))
					(NC.SetToLinks Card (NC.FetchUserDataProp Card
										      (QUOTE 
										 ScavengerToLinks)))
					(NC.SetFromLinks Card (NC.FetchUserDataProp Card
											(QUOTE
											  
									       ScavengerFromLinks)))
                                                             (* Check whether this card isn't filed anywhere.)
					(if (NC.CardNeedsFilingP Card)
					    then (push ToBeFiledCards Card))
					(NC.PutLinks Card T))
                                                             (* Clean any junk off the card.)
			     (NC.DeactivateCard Card T)
			     (NC.SetUserDataPropList Card NIL))))

          (* * File any unfiled cards in the ToBeFiled box.)


	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow T "Filing " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box ...")
		       (NCP.FileCards ToBeFiledCards (fetch (NoteFile ToBeFiledCard)
							  of NoteFile)))
                                                             (* Rewrite link labels if we've found any new ones.)
	    (if (LDIFFERENCE DiscoveredLinkLabels OldLinkLabels)
		then (NC.StoreLinkLabels NoteFile (UNION DiscoveredLinkLabels OldLinkLabels)))
                                                             (* Clean up and get out.)
	    (NC.CheckpointDatabase NoteFile T)
	    (NC.ForceDatabaseClose NoteFile)
	    (NC.PrintMsg InterestedWindow T "Repair Completed for " (FULLNAME FileName)
			   ".")
	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow NIL "Filed " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box.")
	      else (NC.ClearMsg InterestedWindow T)))))
)
(* * Changes to NCDATABASE)

(DEFINEQ

(NC.GetNewCard
  (LAMBDA (NoteFile Type OverrideUID)                        (* rht: "22-Jan-87 11:46")

          (* * See NCLocalDevice.NewCardUID.)



          (* * kef 7/17/86: Updated to use the device vector function to grab an IndexLoc in the local case, and the UID in 
	  all cases.)



          (* * kef 8/4/86: Now takes Type argument and passes it onto the NewCardUIDFn)



          (* * fgh 8/31/86 Changed APPLY* to NC.ApplyFn.)



          (* * rht 1/22/87: Added OverrideUID argument. Use with GREAT care!)


    (LET ((Card (create Card
			  NoteFile ← NoteFile
			  UID ← OverrideUID))
	  ReturnValue)
         (COND
	   ((type? Card (SETQ ReturnValue (NC.ApplyFn NewCardUIDFn Card Type)))
	     (NC.InstallCardInNoteFile Card NoteFile))
	   (T (NC.ReportError (QUOTE NC.GetNewCard)
				ReturnValue)))
     Card)))
)
(* * Changes to NCLOCALDEVICE)

(DEFINEQ

(NCLocalDevice.NewCardUID
  (LAMBDA (Card)                                             (* rht: "22-Jan-87 17:36")

          (* * The local single user device vector function, which installs the UID and IndexLoc into the Card Object.)



          (* * kef 8/6/86: Incorporated kirk's change: Kirk 7/25/86: Fixed overflow check to catch GEQ, gave warning message 
	  a window to show message, changed warning message and changed break call to ERROR!.)



          (* * rht 1/22/87: Now only calls NC.MakeUID if Card doesn't already have one. Made small change to calculation of 
	  PercentUsed. Prevented NextIndexNum from being incremented in the case of full index.)


    (LET ((NoteFile (fetch (Card NoteFile) of Card))
	  NextIndexNum IndexSize IndexNumsFreeList IndexNum PercentUsed NumUsed)
         (SETQ NextIndexNum (fetch (NoteFile NextIndexNum) of NoteFile))
         (SETQ IndexSize (fetch (NoteFile HashArraySize) of NoteFile))
         (SETQ IndexNumsFreeList (fetch (NoteFile IndexNumsFreeList) of NoteFile))
         (if (GREATERP (SETQ PercentUsed (FIX (TIMES 100 (FQUOTIENT
								 (SETQ NumUsed (DIFFERENCE
								     NextIndexNum
								     (LENGTH IndexNumsFreeList)))
								 IndexSize))))
			   90)
	     then (if (GREATERP NumUsed IndexSize)
			then (NC.PrintMsg (WFROMMENU (fetch (NoteFile Menu) of NoteFile))
					      T "Card slots for " (fetch (NoteFile FullFileName)
								     of NoteFile)
					      " are full."
					      (CHARACTER 13)
					      "You must compact the NoteFile now to get more.")
			       (ERROR!)
		      else (NC.PrintMsg (WFROMMENU (fetch (NoteFile Menu) of NoteFile))
					    T "Card slots for " (fetch (NoteFile FullFileName)
								   of NoteFile)
					    " are " PercentUsed "%% full." (CHARACTER 13)
					    "Please compact the NoteFile soon.")))
         (if IndexNumsFreeList
	     then (SETQ IndexNum (pop IndexNumsFreeList))
		    (replace (NoteFile IndexNumsFreeList) of NoteFile with IndexNumsFreeList)
	   else (SETQ IndexNum NextIndexNum)
		  (replace (NoteFile NextIndexNum) of NoteFile with (ADD1 NextIndexNum)))
         (replace (Card IndexLoc) of Card with (NC.NoteFileLocFromIndexNum IndexNum))
         (replace (Card IndexDirtyFlg) of Card with T)
         (OR (type? UID (fetch (Card UID) of Card))
	       (replace (Card UID) of Card with (NC.MakeUID)))
     Card)))
)
(PUTPROPS RHTPATCH184 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1881 33656 (NC.RobustReadCardPart 1891 . 7528) (NC.AtEndOfItemP 7530 . 8596) (
NC.CardInspectorAttachedMenuWhenSelectedFn 8598 . 15265) (NC.CardInspectorMenuWhenSelectedFn 15267 . 
18407) (NC.ScavengeDatabaseFile 18409 . 33654)) (33691 34598 (NC.GetNewCard 33701 . 34596)) (34636 
37307 (NCLocalDevice.NewCardUID 34646 . 37305)))))
STOP