(FILECREATED "13-Nov-86 17:49:22" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH148.;1 15525  

      changes to:  (VARS RHTPATCH148COMS))


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

(PRETTYCOMPRINT RHTPATCH148COMS)

(RPAQQ RHTPATCH148COMS ((* * Fix so that deleting cards doesn't fuss with their link icons.)
			  (* * Changes to NCLINKS)
			  (FNS NC.SmartDeleteLinks NC.DeleteLink)
			  (* * Changes to NCCARDS)
			  (FNS NC.DeleteNoteCard)))
(* * Fix so that deleting cards doesn't fuss with their link icons.)

(* * Changes to NCLINKS)

(DEFINEQ

(NC.SmartDeleteLinks
  (LAMBDA (ListOfLinks QuietFlg InterestedWindow Don'tPutToBeDeletedCardsFlg)
                                                             (* rht: "13-Nov-86 17:21")

          (* * Delete a bunch of links efficiently. Sort so that links with same source bunch together.
	  This way, only read and write each source card once. If a card has the AboutToBeDeletedFlg UID prop set and 
	  Don'tPutToBeDeletedCardsFlg is non-nil, then don't put it down to the file even if changes were made.
	  Just throw away its cache.)



          (* * rht 10/17/86: Now passes non-nil NoOrphanHookFlg to NC.DeleteLink unless destination card is marked as about 
	  to be deleted.)



          (* * rht 11/4/86: Now takes Don'tCreateDeletedImageObjFlg arg.)



          (* * rht 11/13/86: Undid change of 11/4/86. Now passes non-nil Don'tDelLinkIconFlg to NC.DeleteLink instead like it
	  used to.)


    (LET (DestCardsw/oLinksCached NumLinksToDelete)

          (* * For each destination card, make sure its links are cached. At the same time, collect these cards for future 
	  uncaching.)


         (SETQ DestCardsw/oLinksCached (for Link in ListOfLinks bind DestCard
					    when (NOT (NC.LinksCachedP (SETQ DestCard
									       (fetch (Link 
										  DestinationCard)
										  of Link))))
					    collect (NC.GetLinks DestCard)
						      DestCard))

          (* * Sort the List of links so that links with same source cards bunch together.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Sorting " (SETQ NumLinksToDelete
					 (LENGTH ListOfLinks))
				       " links prior to deletion."))
         (SORT ListOfLinks (FUNCTION (LAMBDA (Link1 Link2)
		     (LESSP (fetch (Card IndexLoc) of (fetch (Link SourceCard) of Link1))
			      (fetch (Card IndexLoc) of (fetch (Link SourceCard) of Link2)))))
		 )

          (* * Now bring up source cards one at a time and do the delete of the links.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Deleting links: 1 out of " 
				       NumLinksToDelete " ..."))
         (for Link in ListOfLinks as i from 1 bind PreviousSourceCard WasNotActiveFlg 
							     SavedFromLinks HadLinksCachedFlg
	    eachtime (BLOCK) when (NC.ValidLinkP Link)
	    do (OR QuietFlg (if (ZEROP (REMAINDER i 10))
				    then (NC.PrintMsg InterestedWindow T "Deleting links: " i 
							  " out of "
							  NumLinksToDelete " ...")))
		 (LET ((SourceCard (fetch (Link SourceCard) of Link)))
		      (if (NOT (NC.SameCardP SourceCard PreviousSourceCard))
			  then                             (* Write down changes to previous card's substance.)
				 (if WasNotActiveFlg
				     then                  (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
					    (if (AND Don'tPutToBeDeletedCardsFlg
							 (NC.UIDGetProp (fetch (Card UID)
									     of PreviousSourceCard)
									  (QUOTE 
									      AboutToBeDeletedFlg)))
						then       (* Throw away cache if card about to be deleted.)
						       (NC.DeactivateCard PreviousSourceCard)
					      else (NC.CardSaveFn PreviousSourceCard T)
						     (NC.QuitCard PreviousSourceCard NIL T NIL NIL 
								    NIL NIL T))
                                                             (* Recache links for previous card if they were cached
							     before.)
					    (if HadLinksCachedFlg
						then (NC.GetLinks PreviousSourceCard)))
                                                             (* Cache card and overwrite from links with previously
							     cached ones.)
				 (if (SETQ WasNotActiveFlg (NOT (NC.ActiveCardP SourceCard)))
				     then                  (* Save cached from links for this card.)
					    (SETQ SavedFromLinks (if (SETQ HadLinksCachedFlg
									   (NC.LinksCachedP 
										       SourceCard))
								       then (NC.FetchFromLinks
										SourceCard)))
					    (NC.GetNoteCard SourceCard)
					    (if HadLinksCachedFlg
						then (NC.SetFromLinks SourceCard SavedFromLinks)))
			    )
		      (NC.DeleteLink Link (NC.UIDGetProp (fetch (Card UID)
								of (fetch (Link DestinationCard)
									of Link))
							     (QUOTE AboutToBeDeletedFlg))
				       (NC.UIDGetProp (fetch (Card UID)
							   of (fetch (Link SourceCard)
								   of Link))
							(QUOTE AboutToBeDeletedFlg)))
		      (SETQ PreviousSourceCard SourceCard))
	    finally (if (AND WasNotActiveFlg (NC.ValidCardP PreviousSourceCard))
			  then                             (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
				 (if (AND Don'tPutToBeDeletedCardsFlg (NC.UIDGetProp
						(fetch (Card UID) of PreviousSourceCard)
						(QUOTE AboutToBeDeletedFlg)))
				     then                  (* Throw away cache if card about to be deleted.)
					    (NC.DeactivateCard PreviousSourceCard)
				   else (NC.CardSaveFn PreviousSourceCard T)
					  (NC.QuitCard PreviousSourceCard NIL T NIL NIL NIL NIL T))
                                                             (* Recache links for previous card if they were cached
							     before.)
				 (if HadLinksCachedFlg
				     then (NC.GetLinks PreviousSourceCard))))

          (* * Finally, write down links for cards whose links have changed and whose links weren't cached when this function
	  was called.)


         (for DestCard in DestCardsw/oLinksCached eachtime (BLOCK) when (
									    NC.FetchLinksDirtyFlg
										    DestCard)
	    do (NC.PutLinks DestCard))
         (OR QuietFlg (NC.ClearMsg InterestedWindow T)))))

(NC.DeleteLink
  (LAMBDA (Link NoOrphanHookFlg Don'tDelLinkIconFlg)         (* rht: "13-Nov-86 17:16")

          (* * Delete a link with the option of not putting an orphan hook in case of last filing link.
	  Also option of not deleting link icon from the source card's substance.)



          (* * fgh 5/2/86 Included calls to NC.DelReferencesToCardFromShowLinks in order to clean up ShowLinks windows when 
	  links are deleted.)



          (* * kef 7/17/86: Added the requirement that the write permissions be obtained for the TOLINKS of the Source Card 
	  and the FROMLINKS of the Destination Card.)



          (* * kef 7/22/86: Puts the links for the Destination Card now right away while we are still holding onto the write 
	  lock for the FROMLINKS.)



          (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding 
	  whether or not to setup the release of the write lock afterwards.)



          (* * fgh 8/30/86 Adpated to use NC.IfCardPartNotBusy. Note use of ERROR!. Unfortunately, it appears that the only 
	  way to keep TEDIT from deleting the Link's Image Object is to bail out but good. The control structure here works 
	  because NC.IfCardPartNotBusy returns NIL if the CardPart is busy. The Ts at the end as the last SExpr in each call 
	  to NC.IfCardPartNotBusy insure that NC.IfCardPartNotBusy returns non-NIL otherwise.)



          (* * rht 9/29/86: Removed the call to NC.PutFromLinks. Looks to me like it'll get called anyway by NC.DelFromLink 
	  if necessary.)



          (* * rht 10/6/86: Delete crossfilelink cards when their links are deleted.)



          (* * rht 11/4/86: Now takes Don'tCreateDeletedImageObjFlg arg.)



          (* * rht 11/13/86: Undid my change of 11/4/86.)


    (AND (NC.ValidLinkP Link)
	   (LET ((SourceCard (fetch (Link SourceCard) of Link))
		 (DestinationCard (fetch (Link DestinationCard) of Link))
		 BusyCardPart)
	        (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of SourceCard))
			      (OR (NC.IfCardPartNotBusy DestinationCard (QUOTE FROMLINKS)
							  (OR (NC.IfCardPartNotBusy
								  DestinationCard
								  (QUOTE TOLINKS)
								  (OR Don'tDelLinkIconFlg
									(NC.DelReferencesToCard
									  SourceCard Link))
								  (NC.DelFromLink Link 
										  NoOrphanHookFlg)
								  (NC.DelToLink Link)
								  (
							      NC.DelReferencesToCardFromShowLinks
								    SourceCard Link)
								  (
							      NC.DelReferencesToCardFromShowLinks
								    DestinationCard Link)

          (* * This UID replacement is worrisome. Does it mean that link deletion can't be undone?)


								  (replace (Link UID) of Link
								     with -1)
								  T)
								(ERROR!))
							  T)
				    (ERROR!)))

          (* * Delete cross file link cards when their links are deleted.)


	        (if (NC.CrossFileLinkCardP DestinationCard)
		    then (NC.DeleteNoteCard DestinationCard))
	        (if (NC.CrossFileLinkCardP SourceCard)
		    then (NC.DeleteNoteCard SourceCard))))))
)
(* * Changes to NCCARDS)

(DEFINEQ

(NC.DeleteNoteCard
  (LAMBDA (Card)                                             (* rht: "13-Nov-86 17:40")

          (* * Delete a single note card from a NoteFile)



          (* * rht 8/11/86 Now calls NC.DeleteReferencesToCardFromShowLinks to smash any link icons in show links menus 
	  pointing to this card.)



          (* * kef 7/28/86: Added code to obtain all of the write locks deemed necessary.)



          (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding 
	  whether or not to setup the release of the write lock afterwards.)



          (* * kef 7/31/86: Added the nesting of the obtaining writelocks with deactivating the card.)



          (* * fgh 8/30/86 Translated APPLY* to NC.ApplyFn. Made cosmetic changes in FOR loop concewrning WriteLocks.)


    (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR))
		(RESETSAVE NIL (BQUOTE (NC.SetBeingDeletedFlg , Card NIL)))
		(WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			      (LET ((WriteLocks (for CardPart
						   in (QUOTE (SUBSTANCE TITLE TOLINKS FROMLINKS 
									    GLOBALTOLINKS PROPLIST))
						   collect (CONS Card CardPart)))
				    ToLinks FromLinks Window BusyPart PromptWindow)
			           (NC.SetBeingDeletedFlg Card T)
			           (SETQ ToLinks (NC.RetrieveToLinks Card))
			           (SETQ FromLinks (NC.RetrieveFromLinks Card))
			           (for ToLink in ToLinks
				      do (NCONC WriteLocks (for CardPart
								  in (QUOTE (TOLINKS FROMLINKS 
										    GLOBALTOLINKS))
								  collect
								   (CONS (fetch (Link 
										  DestinationCard)
									      of ToLink)
									   CardPart))))
			           (for FromLink in FromLinks
				      do (NCONC WriteLocks (for CardPart
								  in (QUOTE (SUBSTANCE TOLINKS 
											FROMLINKS 
										    GLOBALTOLINKS))
								  collect
								   (CONS (fetch (Link SourceCard)
									      of FromLink)
									   CardPart))))

          (* * The for... loop that follows is the condition that we can obtain all of the write locks on all of the card 
	  parts collected in WriteLocks. If we obtain a writelock, setup a RESETSAVE to release it upon exit.
	  Then finally, if we do obtain a write lock, return T so that the for loop's "always" condition is satisfied.
	  If we don't obtain a write lock for a given card part, save that one as a variable so we can report it to the user.
	  Then return NIL, so that the for loop's "always" condition is not satisfied, and we bump out of the for loop.)


			           (NC.PrintMsg (SETQ PromptWindow (NC.AttachPromptWindow
						      (NC.FetchWindow Card)))
						  T "Collecting write locks...")
			           (COND
				     ((for WriteLock in WriteLocks bind WLCard WLCardPart
					 when (NC.ValidCardP (SETQ WLCard (CAR WriteLock)))
					 always (SETQ WLCardPart (CDR WriteLock))
						  (COND
						    ((NC.ApplyFn ObtainWritePermissionFn WLCard 
								 WLCardPart)
						      (RESETSAVE NIL
								   (BQUOTE
								     (APPLY* , (fetch
										 (Card 
									 ReleaseWritePermissionFn)
										    of WLCard)
									       , WLCard , WLCardPart))
								   )
						      T)
						    (T (SETQ BusyPart WriteLock)
						       NIL)))

          (* * Call off to the MarkCardDeletedFn specific to the NoteFile.)


				       (RESETSAVE (for CardPart
						       in (QUOTE (SUBSTANCE TOLINKS GLOBALTOLINKS 
										PROPLIST))
						       do (NC.ApplyFn ObtainWritePermissionFn Card 
									CardPart))
						    (BQUOTE (NC.DeactivateCard , Card T)))
				       (NC.ApplyFn MarkCardDeletedFn Card)
				       (NC.SetToLinks Card NIL)
				       (NC.SetFromLinks Card NIL)
				       (NC.PrintMsg PromptWindow NIL 
						      "Removing links to and from other cards...")
				       (for ToLink in ToLinks when (NC.ValidLinkP ToLink)
					  do (NC.DelFromLink ToLink)
					       (NC.DelReferencesToCardFromShowLinks
						 (fetch (Link DestinationCard) of ToLink)
						 ToLink))
				       (for FromLink in FromLinks when (NC.ValidLinkP 
											 FromLink)
					  do (NC.DelToLink FromLink)
					       (NC.DelReferencesToCard (fetch (Link SourceCard)
									    of FromLink)
									 Card)
					       (NC.DelReferencesToCardFromShowLinks
						 (fetch (Link SourceCard) of FromLink)
						 FromLink))
				       (NC.PrintMsg PromptWindow NIL "..done.")
				       (COND
					 ((NC.ActiveCardP Card)
					   (NC.TurnOffDirtyFlgs Card)
					   (SETQ Window (NC.FetchWindow Card))
					   (AND Window (NC.GreyCard Card))
					   (NC.CloseAllPropListEditors Card)
					   (NC.QuitCard Card T T NIL T)))
				       (NC.SetNewCardFlg Card NIL))
				     (T (NC.CardPartBusy (CAR BusyPart)
							   (CDR BusyPart)
							   PromptWindow))))))))
)
(PUTPROPS RHTPATCH148 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (574 10131 (NC.SmartDeleteLinks 584 . 6838) (NC.DeleteLink 6840 . 10129)) (10163 15443 (
NC.DeleteNoteCard 10173 . 15441)))))
STOP