(FILECREATED "19-Dec-85 19:27:53" {QV}<NOTECARDS>1.3K>RHTPATCH018.;4 19542  

      changes to:  (FNS NC.ScavengeDatabaseFile NC.SetUserDataPropList NC.UserDataAddProp)
		   (VARS RHTPATCH018COMS)

      previous date: "19-Dec-85 16:31:35" {QV}<NOTECARDS>1.3K>RHTPATCH018.;1)


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

(PRETTYCOMPRINT RHTPATCH018COMS)

(RPAQQ RHTPATCH018COMS ((* * New function to put in NCCARDS near NC.SetUserDataProp)
			  (FNS NC.SetUserDataPropList)
			  (* * Redefined function from NCREPAIR.)
			  (FNS NC.ScavengeDatabaseFile)
			  (* * Minor fixes to functions in NCCARDS.)
			  (FNS NC.CollectReferences NC.MakeNoteCard)))
(* * New function to put in NCCARDS near NC.SetUserDataProp)

(DEFINEQ

(NC.SetUserDataPropList
  (LAMBDA (Card PropList)                                    (* rht: "19-Dec-85 16:51")

          (* * Replace the user data prop list of Card.)


    (replace (Card UserData) of Card with PropList)))
)
(* * Redefined function from NCREPAIR.)

(DEFINEQ

(NC.ScavengeDatabaseFile
  (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfBoxesToReconstruct 
			      ListOfCardsNeedingGlobalLinksReconstructed)
                                                             (* rht: "19-Dec-85 19:22")

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


    (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))
	    (if (OPENP FileName)
		then (NC.PrintMsg NIL T FileName " is an already open file." (CHARACTER 13))
		       (RETURN NIL))                       (* Try to open notefile.)
	    (if (NULL (SETQ NoteFile (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL NIL 
								  T)))
		then (NC.PrintMsg NIL NIL "Couldn't open " FileName "." (CHARACTER 13)
				      "Repair aborted."
				      (CHARACTER 13))
		       (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 NIL T "Rebuilding notefile links." (CHARACTER 13)
			   "Collecting Links for item " 1 " out of " CardTotal "." (CHARACTER
			     13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile
			   (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 10))
				      (NC.PrintMsg NIL T "Rebuilding notefile links." (CHARACTER
						       13)
						     "Collecting Links for item " NoteCardNumber 
						     " out of "
						     CardTotal "." (CHARACTER 13)))
			       (if (NC.FetchUserDataProp Card (QUOTE NeedsReconstructingFlg))
				   then                    (* Card substance and links will be reconstructed so 
							     no need to try to read substance.)
					  (NC.GetLinks Card)
					  (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.GetLinks 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)
					       (for Link in (CAR (NC.CollectReferences Card))
						  eachtime (BLOCK)
						  when (if (EQ (NC.FetchStatus
								       (fetch (Link DestinationCard)
									  of Link))
								     (QUOTE ACTIVE))
							   else (NC.DelReferencesToCard Card Link)
								  NIL)
						  collect Link))
					     (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 NIL T "Repairing NoteFile." (CHARACTER 13)
			   "Inverting links for item " 1 " out of " CardTotal "." (CHARACTER 13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 100))
				      (NC.PrintMsg NIL T "Repairing NoteFile." (CHARACTER 13)
						     "Inverting links for item " NoteCardNumber 
						     " out of "
						     CardTotal "." (CHARACTER 13)))
			       (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 NIL T "Repairing NoteFile." (CHARACTER 13)
			   "Rewriting links for item " 1 " out of " CardTotal "." (CHARACTER 13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 10))
				      (NC.PrintMsg NIL T "Repairing NoteFile." (CHARACTER 13)
						     "Rewriting links for item " NoteCardNumber 
						     " out of "
						     CardTotal "." (CHARACTER 13)))
			       (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 (AND (NOT (NC.UndeletableCardP Card))
						       (for Link in (NC.FetchFromLinks Card)
							  eachtime (BLOCK) never (
										    NC.ChildLinkP
											 Link)))
					      then (push ToBeFiledCards Card))
					  (NC.PutLinks Card))
                                                             (* 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 NIL T "Filing " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box ..."
				      (CHARACTER 13))
		       (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 NIL T "Repair Completed for " (FULLNAME FileName)
			   "."
			   (CHARACTER 13))
	    (if ToBeFiledCards
		then (NC.PrintMsg NIL NIL "Filed " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box.")))))
)
(* * Minor fixes to functions in NCCARDS.)

(DEFINEQ

(NC.CollectReferences
  (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg)
                                                             (* rht: "19-Dec-85 19:09")

          (* * Collect all the links in a card specified by ID. RETURNS the CONS of a list of link identifiers {described 
	  below} and a dirtyflg that is non-NIL if the Substance of ID has been modified {i.e., when a non-valid link is 
	  found and CheckAndDeleteFlg is NIL}. IF CheckAndDeleteFlg is non-NIL checks for valid links and deletes those that 
	  are not valid. If ReturnLinkIconsFlg is NIL, returns link icons. Otherwise, returns links. If ReturnLinkIconsFlg is
	  NIL, returns just the links/link icons. Otherwise, returns the CONS of link/link icon and the type-specific 
	  location of the link icon in the card.)



          (* * fgh 11/12/85 Updated to handle Card objects.)



          (* * rht 12/19/85: Fixed to handle types with no CollectReferencesFn defined.)


    (COND
      ((NC.ActiveCardP Card)
	(LET ((CollectReferencesFn (NC.CollectReferencesFn (NC.RetrieveType Card))))
	     (if CollectReferencesFn
		 then (APPLY* (NC.CollectReferencesFn (NC.RetrieveType Card))
				  Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg))))
      (T (NC.ReportError "NC.CollectReferences" (CONCAT "Attempt to call with inactive card:  " 
							    Card))))))

(NC.MakeNoteCard
  (LAMBDA (NoteCardType NoteFile Title NoDisplayFlg TypeSpecificArgs Card)
                                                             (* rht: "19-Dec-85 15:40")
                                                             (* Make a new note card of type NoteCardType.
							     If type note specified, ask the user.)

          (* * rht 2/1/85: Added call to NC.MarkCardDirty.)



          (* * fgh 10/15/85 Added extra DatabaseStream argument for use by caching mechanism)



          (* * fgh 11/11/85: Updated to handle new Card object.)


    (LET (ReturnValue Window)
         (COND
	   ((SETQ NoteCardType (OR NoteCardType (NC.AskNoteCardType (fetch (NoteFile Menu)
									     of NoteFile))))
	     (SETQ Card (OR (AND (NC.CardP Card)
				       Card)
				(NC.GetNewCard NoteFile)))
	     (NC.SetNewCardFlg Card T)
	     (NC.ActivateCard Card)
	     (NC.SetType Card NoteCardType)
	     (COND
	       ((OR (NULL (ERSETQ (SETQ ReturnValue (APPLY* (NC.MakeCardFn NoteCardType)
								      Card Title NoDisplayFlg 
								      TypeSpecificArgs))))
		      (NULL ReturnValue))
		 (NC.MarkCardDeleted Card)
		 (NC.DeactivateCard Card T))
	       (T (SETQ Window (WINDOWP ReturnValue))
		  (COND
		    ((NULL (NC.RetrieveTitle Card))
		      (SETQ Title (NC.SetTitle Card (SETQ Title (COND
						       ((STRINGP Title)
							 Title)
						       ((AND Title (OR (LITATOM Title)
									   (NUMBERP Title)))
							 (MKSTRING Title))
						       (T "Untitled")))))
		      (AND Window (WINDOWPROP Window (QUOTE TITLE)
						  Title)))
		    (T (NC.SetTitle Card (MKSTRING (NC.RetrieveTitle Card)))))
		  (COND
		    (Window (WINDOWADDPROP Window (QUOTE CLOSEFN)
					     (FUNCTION NC.QuitCard)
					     (QUOTE FIRST))
			    (WINDOWPROP Window (QUOTE NoteCardObject)
					  Card)))
		  (NC.SetTitleDirtyFlg Card T)             (* Reset the type in case of recursive calls change 
							     the type. Always want the highest level type in a 
							     recursive descent)
		  (NC.SetType Card NoteCardType)           (* Insure that a link ptr is set up during the first 
							     save)
		  (NC.SetLinksDirtyFlg Card T)
		  (NC.SetPropListDirtyFlg Card T)          (* Mark that substance is dirty.)
		  (NC.MarkCardDirty Card T)))
	     ReturnValue)))))
)
(PUTPROPS RHTPATCH018 COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (753 1014 (NC.SetUserDataPropList 763 . 1012)) (1061 15367 (NC.ScavengeDatabaseFile 1071
 . 15365)) (15417 19460 (NC.CollectReferences 15427 . 16884) (NC.MakeNoteCard 16886 . 19458)))))
STOP