(FILECREATED " 8-Jun-87 12:31:14" {QV}<NOTECARDS>1.3K>NEXT>PMIPATCH045.;3 13563  

      changes to:  (VARS PMIPATCH045COMS)
		   (FNS NC.DeleteNoteCardInternal)

      previous date: " 3-Jun-87 16:01:53" {QV}<NOTECARDS>1.3K>NEXT>PMIPATCH045.;1)


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

(PRETTYCOMPRINT PMIPATCH045COMS)

(RPAQQ PMIPATCH045COMS ((* * pmi 6/8/87: Fixes bug #541: Deleted card feedback needed. Added 
			     greying of the card being deleted to NC.SeverExternalLinks, which is 
			     called first and where all of the time-consuming work takes place. Moved 
			     call to NC.GreyCard to beginning of NC.DeleteNoteCardInternal.)
			  (* * Changes to NCCARDS)
			  (FNS NC.DeleteNoteCardInternal NC.SeverExternalLinks)))
(* * pmi 6/8/87: Fixes bug #541: Deleted card feedback needed. Added greying of the card being
 deleted to NC.SeverExternalLinks, which is called first and where all of the time-consuming 
work takes place. Moved call to NC.GreyCard to beginning of NC.DeleteNoteCardInternal.)

(* * Changes to NCCARDS)

(DEFINEQ

(NC.DeleteNoteCardInternal
  (LAMBDA (Card QuietFlg InterestedWindow IgnoreLinksFlg)    (* pmi: " 8-Jun-87 12:26")

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



          (* * rht 1/16/87: Moved call to MarkCardDeletedFn after call to NC.QuitCard.)



          (* * rg 3/11/87 renamed)



          (* * rht 3/13/87: Added QuietFlg, InterestedWindow, and IgnoreLinksFlg args. The latter non-nil causes card 
	  deletion but no link cutting.)



          (* * rht 3/25/87: Now calls NC.CoerceToInterestedWindow.)



          (* * pmi 6/8/87: Moved call to NC.GreyCard to beginning of this function.)


    (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR))
		(RESETSAVE NIL (BQUOTE (NC.SetBeingDeletedFlg , Card NIL)))
		(WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			      (OR (OPENWP InterestedWindow)
				    (SETQ InterestedWindow (NC.CoerceToInterestedWindow Card)))
			      (LET ((WriteLocks (for CardPart
						   in (QUOTE (SUBSTANCE TITLE TOLINKS FROMLINKS 
									    GLOBALTOLINKS PROPLIST))
						   collect (CONS Card CardPart)))
				    ToLinks FromLinks BusyPart)
			           (NC.SetBeingDeletedFlg Card T)

          (* * First grey the card being deleted.)


			           (NC.GreyCard Card)
			           (if (NOT IgnoreLinksFlg)
				       then (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.)


			           (OR QuietFlg (NC.PrintMsg InterestedWindow 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)
				       (if (NOT IgnoreLinksFlg)
					   then (OR QuietFlg (NC.PrintMsg InterestedWindow 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))
						  (OR QuietFlg (NC.PrintMsg InterestedWindow NIL 
										"..done.")))
				       (if (NC.ActiveCardP Card)
					   then (NC.TurnOffDirtyFlgs Card)
						  (NC.CloseAllPropListEditors Card)
						  (NC.QuitCard Card T T))
				       (NC.ApplyFn MarkCardDeletedFn Card)
				       (NC.SetNewCardFlg Card NIL))
				     (T (NC.CardPartBusy (CAR BusyPart)
							   (CDR BusyPart)
							   InterestedWindow))))))))

(NC.SeverExternalLinks
  (LAMBDA (ListOfCards QuietFlg InterestedWindow)            (* pmi: " 8-Jun-87 09:44")

          (* * Delete all links in ListOfCards to or from cards not in ListOfCards. Furthermore, do it efficiently by caching
	  an external card only long enough to delete all the links between it and ListOfCards. Note that we depend on the 
	  fact that every card in ListOfCards has its AboutToBeDeletedFlg set.)



          (* * rht&pmi 5/29/87: Now passes non-nil LeaveCachedFlg to NC.RetrieveToLinks and NC.RetrieveFromLinks.
	  Not sure if this is really necessary.)



          (* * pmi 6/8/87: Added call to NC.GreyCard to grey cards being deleted before deleting all of their links.)


    (LET (LinksToSever NumLinksToSever)
         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Gathering external links of "
				       (LENGTH ListOfCards)
				       " cards."))
         (SETQ LinksToSever (NC.UnionListsOfLinks
	     (for Card in ListOfCards
		join                                       (* Grey the cards being deleted.)
		       (NC.GreyCard Card)
		       (for Link in (NC.RetrieveToLinks Card T)
			  unless (NC.UIDGetProp (fetch (Card UID) of (fetch (Link 
										  DestinationCard)
										of Link))
						    (QUOTE AboutToBeDeletedFlg))
			  collect Link))
	     (for Card in ListOfCards join (for Link in (NC.RetrieveFromLinks Card T)
						    unless (NC.UIDGetProp
							       (fetch (Card UID)
								  of (fetch (Link SourceCard)
									  of Link))
							       (QUOTE AboutToBeDeletedFlg))
						    collect Link))))

          (* * Now sort links so that links with same external anchor card are grouped together. Furthermore, the links 
	  having that anchor card has source card are grouped before the ones having that card as destination card.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Sorting " (SETQ NumLinksToSever
					 (LENGTH LinksToSever))
				       " links prior to severing."))
         (SORT LinksToSever (FUNCTION (LAMBDA (Link1 Link2)
		     (LET (DestCard1 DestCard2 ExtCard1 ExtCard2 Link1SourceIsExtFlg)
		          (SETQ ExtCard1 (if (NC.UIDGetProp (fetch (Card UID)
								     of (SETQ DestCard1
									    (fetch (Link 
										  DestinationCard)
									       of Link1)))
								  (QUOTE AboutToBeDeletedFlg))
					       then (SETQ Link1SourceIsExtFlg T)
						      (fetch (Link SourceCard) of Link1)
					     else DestCard1))
		          (SETQ ExtCard2 (if (NC.UIDGetProp (fetch (Card UID)
								     of (SETQ DestCard2
									    (fetch (Link 
										  DestinationCard)
									       of Link2)))
								  (QUOTE AboutToBeDeletedFlg))
					       then (fetch (Link SourceCard) of Link2)
					     else DestCard2))
		          (if (NC.SameCardP ExtCard1 ExtCard2)
			      then Link1SourceIsExtFlg
			    else (LESSP (fetch (Card IndexLoc) of ExtCard1)
					    (fetch (Card IndexLoc) of ExtCard2)))))))

          (* * Now walk down the list of links one by one activating the external anchor cards as needed.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Severing links: 1 out of " NumLinksToSever 
				       " ..."))
         (for Link in LinksToSever as i from 1 bind PreviousExtCard WasNotActiveFlg 
							      PreviousExtCardIsSourceFlg
	    eachtime (BLOCK) when (NC.ValidLinkP Link)
	    do (OR QuietFlg (if (ZEROP (REMAINDER i 10))
				    then (NC.PrintMsg InterestedWindow T "Severing links: " i 
							  " out of "
							  NumLinksToSever " ...")))
		 (LET (ExtCard ExtCardIsSourceFlg)
		      (SETQ ExtCard (if (NC.UIDGetProp (fetch (Card UID)
								of (fetch (Link DestinationCard)
									of Link))
							     (QUOTE AboutToBeDeletedFlg))
					  then (SETQ ExtCardIsSourceFlg T)
						 (fetch (Link SourceCard) of Link)
					else (fetch (Link DestinationCard) of Link)))
		      (if (NOT (NC.SameCardP ExtCard PreviousExtCard))
			  then                             (* Write down changes to previous external card's 
							     substance.)
				 (if WasNotActiveFlg
				     then (if PreviousExtCardIsSourceFlg
						then       (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
						       (NC.CardSaveFn PreviousExtCard T)
						       (NC.QuitCard PreviousExtCard NIL T NIL NIL 
								      NIL T)
					      else (NC.PutLinks PreviousExtCard)))
                                                             (* If ExtCard not active, then cache.)
				 (if (SETQ WasNotActiveFlg (NOT (NC.ActiveCardP ExtCard)))
				     then (if ExtCardIsSourceFlg
						then       (* Cache whole card if it's the link's source.)
						       (NC.GetNoteCard ExtCard)
					      else         (* Else only need the links since we're deleting the 
							     from link.)
						     (NC.GetLinks ExtCard))))
                                                             (* Delete the appropriate half of the link.)
		      (if ExtCardIsSourceFlg
			  then (NC.DeleteToLink Link)
			else (NC.DeleteFromLink Link))
		      (replace (Link UID) of Link with -1)
		      (SETQ PreviousExtCard ExtCard)
		      (SETQ PreviousExtCardIsSourceFlg ExtCardIsSourceFlg))
	    finally (if (AND WasNotActiveFlg (NC.ValidCardP PreviousExtCard))
			  then (if PreviousExtCardIsSourceFlg
				     then                  (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
					    (NC.CardSaveFn PreviousExtCard T)
					    (NC.QuitCard PreviousExtCard NIL T NIL NIL NIL T)
				   else (NC.PutLinks PreviousExtCard)))))))
)
(PUTPROPS PMIPATCH045 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1090 13481 (NC.DeleteNoteCardInternal 1100 . 7160) (NC.SeverExternalLinks 7162 . 13479)
))))
STOP