(FILECREATED "19-Aug-87 15:11:06" {QV}<NOTECARDS>1.3KNEXT>PMIPATCH059.;4 28032  

      changes to:  (FNS NC.ForceDatabaseClose NC.ScavengerPhase1)
		   (VARS PMIPATCH059COMS)

      previous date: "19-Aug-87 11:37:19" {QV}<NOTECARDS>1.3KNEXT>PMIPATCH059.;2)


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

(PRETTYCOMPRINT PMIPATCH059COMS)

(RPAQQ PMIPATCH059COMS ((DECLARE: FIRST (P (NC.LoadFileFromDirectories (QUOTE NCREPAIR))))
			  (* * pmi 8/19/87: fixes another bug with Inspect & Repair introduced by 
			     adding the Event stuff. We originally forgot to do a NOTIFY.EVENT when 
			     aborting from the card inspector menu. Also fixes problem where 
			     NC.ScavengerPhase1 was not returning a notefile if successful. Also adds 
			     call to NC.ResetNoteFileInterface to NC.ForceDatabaseClose, to make it 
			     look closed, since it IS closed.)
			  (* * Changed in NCREPAIR)
			  (FNS NC.CardInspectorAttachedMenuWhenSelectedFn NC.ScavengerPhase1)
			  (* * Changed in NCDATABASE)
			  (FNS NC.ForceDatabaseClose)))
(DECLARE: FIRST 
(NC.LoadFileFromDirectories (QUOTE NCREPAIR))
)
(* * pmi 8/19/87: fixes another bug with Inspect & Repair introduced by adding the Event 
stuff. We originally forgot to do a NOTIFY.EVENT when aborting from the card inspector menu. 
Also fixes problem where NC.ScavengerPhase1 was not returning a notefile if successful. Also 
adds call to NC.ResetNoteFileInterface to NC.ForceDatabaseClose, to make it look closed, since 
it IS closed.)

(* * Changed in NCREPAIR)

(DEFINEQ

(NC.CardInspectorAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* pmi: "18-Aug-87 14:46")

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



          (* * rht 3/14/87: Fixed minor attachwindow bug in call to NC.ScavengerPhase1.)



          (* * pmi 8/18/87: Now gets InspectAndRepairFinishedEvent from the property list of MessageWin.
	  Calls NOTIFY.EVENT on it to signal the end of Scavenging.)


    (DECLARE (GLOBALVARS NC.OffScreenPosition))
    (LET ((MainWin (MAINWINDOW (WFROMMENU Menu)))
	  (Operation (CAR Item))
	  MessageWin NoteFile InspectorWins NextWin MenuWindows SearchString 
	  InspectAndRepairFinishedEvent)
         (SETQ MessageWin (MAINWINDOW MainWin))
         (SETQ MenuWindows (WINDOWPROP MessageWin (QUOTE MENUWINDOWS)))
         (SETQ InspectAndRepairFinishedEvent (WINDOWPROP MessageWin (QUOTE FINISHEDEVENT)))
         (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)
				      (NOTIFY.EVENT InspectAndRepairFinishedEvent))
			       (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))
			       (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.ScavengerPhase1
  (LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg 
			      InterestedWindow)              (* pmi: "19-Aug-87 14:48")

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



          (* * rht 7/7/86: Now passes non-nil Don'tCheckOperationInProgress flg to NC.OpenDatabaseFile.)



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



          (* * rht 9/16/86: Changed call to NC.OpenDatabaseFile so that it won't try to get special cards.)



          (* * rht 10/31/86: Changed call from NC.OpenDatabaseFile to NC.OpenNoteFile. Now returns non-nil if successful.)



          (* * rht 11/13/86: Now passes non-nil Don'tCreateFlg to NC.OpenNoteFile.)



          (* * rht 2/18/87: Added SPAWN.MOUSE call.)



          (* * rht 3/14/87: Now calls new function NC.TotalCardsInNoteFile to compute the total number of cards.)



          (* * pmi 5/20/87: Removed HashArray argument in calls to NC.OpenNoteFile.)



          (* * pmi 7/7/87: Replaced (SPAWN.MOUSE) with (ALLOW.BUTTON.EVENTS). Added InspectAndRepairFinishedEvent argument to
	  be used to signal the end of Scavenging. Added Protection wrapper around the body of this function so that this 
	  notefile can not be accessed while I&R is in progress.)



          (* * rg&pmi 7/15/87 removed protection wrapper)



          (* * rg 8/11/87 protection wrapper moved back down to this level, where we know we have a real NoteFile to protect)



          (* * pmi&rg 8/19/87: fixes problem where this was not returning a notefile if successful.)


    (DECLARE (GLOBALVARS NC.ScavengerAttachedMenuFont NC.ScavengerInteractionWinRegion))
    (PROG (FileName NoteFile NoteFileStream)

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


	    (ALLOW.BUTTON.EVENTS)
	    (if (AND (type? NoteFile FileNameOrNoteFile)
			 (SETQ NoteFileStream (fetch (NoteFile Stream) of FileNameOrNoteFile))
			 (OPENP NoteFileStream))
		then                                       (* This notefile is already open For when we do 
							     recursive call.)
		       (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 NIL NIL 
									    InterestedWindow)))
			    (RETURN NIL))
		     (AND (NULL (SETQ NoteFile
				      (NC.OpenNoteFile FileName T T NIL NIL NIL T T 
							 InterestedWindow NIL NIL NIL NIL T)))
			    (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
					   (CHARACTER 13)
					   "Repair aborted.")
			    (RETURN NIL))
		     (NC.ClearMsg InterestedWindow T))
	    (RETURN
	      (NC.ProtectedNoteFileOperation
		NoteFile "Inspect&Repair" InterestedWindow
		(PROG (UnknownCardTypesList ReasonsList ReasonsHashArray CardsToDelete Menu 
					      MenuItems LinkLabelsNews CardTotal BadNewsList BadBoxes 
					      ExtraBadNews FirstTimeFlg InspectorPendingEvent 
					      NoteFileMenu NoteFileOpsMenuItem CanDoPhase3Flg
					      (InspectAndRepairFinishedEvent (CREATE.EVENT
									       (QUOTE 
								       InspectAndRepairInProgress))))
		        (SETQ CardTotal (NC.TotalCardsInNoteFile 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))        (* Stash InterestedWindow for calls to phase 3 under 
							     menu whenselected fn.)
		        (OR (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW))
			      (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW)
					    InterestedWindow))
                                                             (* 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 
								 InterestedWindow)
					  (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 InterestedWindow)
				 (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 
										 InterestedWindow)))
			  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)
		        (WINDOWPROP ScavengerInteractionWin (QUOTE FINISHEDEVENT)
				      InspectAndRepairFinishedEvent)
		        (WINDOWPROP ScavengerInteractionWin (QUOTE LockProcess)
				      (THIS.PROCESS))
		        (ATTACHMENU (create MENU
						ITEMS ← MenuItems
						WHENSELECTEDFN ←(FUNCTION 
						  NC.MessageWinAttachedMenuWhenSelectedFn)
						MENUFONT ← NC.ScavengerAttachedMenuFont)
				      ScavengerInteractionWin
				      (QUOTE RIGHT)
				      (QUOTE TOP))
		        (AWAIT.EVENT InspectAndRepairFinishedEvent))
		NoteFile)))))
)
(* * Changed in NCDATABASE)

(DEFINEQ

(NC.ForceDatabaseClose
  (LAMBDA (NoteFile Don'tMenuFlg)                            (* pmi: "19-Aug-87 15:06")

          (* * Really close the database, i.e.. bypass the ADVISE on CLOSEF that prevents closing of the database.)



          (* * rht 1/10/85: Note new kludgey call to \UPDATEOF recommended by Tayloe to avoid truncation problems.)



          (* * rht 2/5/85: Added resetting of NC.UncachingNotCompleted here so it will happen after compact, repair, etc.)



          (* * rht 7/9/85: Added resetting of NC.LinkLabelsDate.)



          (* * rht 11/10/85: Updated to incorporate new NoteFile scheme.)



          (* * kirk 31Dec85: added Don'tMenuFlg)



          (* * rht 1/8/86: Now smashes old notefile object to remove cycles. Don't you love interlisp gc'er?)



          (* * rht 5/1/86: Save Menu on notefile object when smashing.)



          (* * rht 7/6/86: Only closes notefile's stream if there is an open one.)



          (* * fgh 9/1/86 Now saves the Device vector when cleaning up the NoteFile object.)



          (* * pmi 5/19/87: Replaced call to NC.RemoveNoteFileFromHashArray with NC.RemoveNoteFile as part of general 
	  cleanup.)



          (* * pmi 8/19/87: Added call calls to NC.NoticeNoteFile and NC.ResetNoteFileInterface.)


    (CLOSEF? (fetch (NoteFile Stream) of NoteFile))    (* Smash the cardcache and userdata fields of all card
							     objects for this notefile to remove circular links.)
    (ADD.PROCESS (LIST (FUNCTION NC.CleanupCardObjects)
			   (fetch (NoteFile HashArray) of NoteFile)))
    (replace (NoteFile Stream) of NoteFile with NIL)   (* Smash the notefile object so we don't have cycles -
							     card -> notefile -> card.)
                                                             (* Usually we leave shell in notefiles hash array so 
							     there's a record.)
    (create NoteFile smashing NoteFile UID ←(fetch (NoteFile UID) of NoteFile)
				  FullFileName ←(fetch (NoteFile FullFileName) of NoteFile)
				  Menu ←(fetch (NoteFile Menu) of NoteFile)
				  NoteFileDevice ←(fetch (NoteFile NoteFileDevice) of NoteFile))

          (* * Reset the notefile menu icon to look closed.)


    (NC.ResetNoteFileInterface NoteFile)

          (* * Make sure the notefile has been noticed.)


    (NC.NoticeNoteFile NoteFile)
    (if Don'tMenuFlg
	then (NC.RemoveNoteFile NoteFile))
    NoteFile))
)
(PUTPROPS PMIPATCH059 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1562 25324 (NC.CardInspectorAttachedMenuWhenSelectedFn 1572 . 8654) (NC.ScavengerPhase1
 8656 . 25322)) (25359 27950 (NC.ForceDatabaseClose 25369 . 27948)))))
STOP