(FILECREATED "17-Jun-87 18:04:04" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH267.;19 108120 

      changes to:  (FNS NC.OpenCrossFileLinkDestNoteFile NC.GetCrossFileLinkDestCard 
			NC.AskCrossFileLinkMode NC.ComputeCrossFileLinkMode)
		   (VARS RHTPATCH267COMS)

      previous date: "10-Jun-87 22:42:15" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH267.;18)


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

(PRETTYCOMPRINT RHTPATCH267COMS)

(RPAQQ RHTPATCH267COMS ((DECLARE: FIRST (P (NC.LoadFileFromDirectories (QUOTE NCBROWSERCARD))
					     (NC.LoadFileFromDirectories (QUOTE NCSKETCHCARD))))
			  (* * Fix of bug #578: cross-file link to read-only notefile causes stack 
			     overflow. Fixes unreported cross-file links bug whereby deleting an icon 
			     for a cross-file link leaves half link. When cross file link is deleted, 
			     the other end of the link will be deleted too if its notefile is open.)
			  (* * Change to NCGRAPHCARD)
			  (FNS NC.CollectReferencesInGraph)
			  (* * Change to NCSKETCHCARD)
			  (FNS NC.CollectReferencesInSketch)
			  (* * Change to NCTEXTCARD)
			  (FNS NC.CollectReferencesInText)
			  (* * Changes to NCLINKS)
			  (FNS NC.ValidLinkP NC.MakeLink NC.DeleteFromLink NC.DeleteToLink 
			       NC.RelabelLink NC.FileInOrphanBox)
			  (* * Change to NCCARDS)
			  (FNS NC.DeleteNoteCardInternal NC.AssignTitle)
			  (* * Changes to NCCROSSFILELINKS)
			  (FNS NC.OpenCrossFileLinkDestNoteFile NC.CrossFileLinkPutFn 
			       NC.CrossFileLinkGetFn NC.CrossFileLinkEditFn 
			       NC.GetCrossFileLinkDestCard)
			  (RECORDS CrossFileLinkSubstance)
			  (* * New stuff for NCCROSSFILELINKS)
			  (GLOBALVARS NC.NewCrossFileLinksMode)
			  (INITVARS (NC.NewCrossFileLinksMode (QUOTE ASK)))
			  (FNS NC.AskCrossFileLinkMode NC.DeleteCrossFileLinkCard 
			       NC.FetchRemoteCrossFileLinkCard NC.CheckCrossFileLinkCardTitle 
			       NC.CheckCrossFileLinkType NC.MakeCrossFileLinkIconStandIn 
			       NC.ComputeCrossFileLinkMode)
			  (* * PLEASE remove the globalvar NC.NewCrossFileLinksTwoWayFlg from 
			     NCCROSSFILELINKS coms)
			  (* * Changes to NCBROWSERCARD)
			  (FNS NC.GrowLinkLattice NC.MakeBrowserCard NC.UpdateBrowserCard 
			       NC.ExpandBrowserNode NC.ConnectNodesInBrowser 
			       NC.DelBrowserContentsLink)
			  (FNS NC.GetBrowserHashArray NC.GetBrowserNodeID 
			       NC.RemoveBrowserNodeHashArrayEntry)))
(DECLARE: FIRST 
(NC.LoadFileFromDirectories (QUOTE NCBROWSERCARD))
(NC.LoadFileFromDirectories (QUOTE NCSKETCHCARD))
)
(* * Fix of bug #578: cross-file link to read-only notefile causes stack overflow. Fixes 
unreported cross-file links bug whereby deleting an icon for a cross-file link leaves half 
link. When cross file link is deleted, the other end of the link will be deleted too if its 
notefile is open.)

(* * Change to NCGRAPHCARD)

(DEFINEQ

(NC.CollectReferencesInGraph
  (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg)
                                                             (* rht: " 1-Jun-87 22:11")

          (* * Return a list of all links or link icons in graph substance Substance. If CheckAndDeleteFlg, then delete any 
	  links found that are not valid links.)



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



          (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of 
	  ActualLink is a valid card.)


    (DECLARE (GLOBALVARS NC.DeletedLinkImageObject))
    (LET ((Substance (NC.FetchSubstance Card))
	  ActualLink DirtyFlg Links LinkIcon CollectItem)
         (SETQ Links (for GraphNode in (fetch (GRAPH GRAPHNODES) of Substance)
			  when (COND
				   ((NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE
											NODELABEL)
										of GraphNode)))
				     (SETQ ActualLink (NC.FetchLinkFromLinkIcon LinkIcon))
				     (COND
				       ((NULL CheckAndDeleteFlg))
				       ((AND (LISTP CheckAndDeleteFlg)
					       (FMEMB (fetch (Link DestinationCard) of 
										       ActualLink)
							CheckAndDeleteFlg)))
				       ((AND (NC.ValidLinkP ActualLink)
					       (NC.ValidCardP (fetch (Link DestinationCard)
								   of ActualLink))))
				       (T (replace (GRAPHNODE NODELABEL) of GraphNode
					     with NC.DeletedLinkImageObject)
					  (SETQ DirtyFlg T)
					  NIL)))
				   (T NIL))
			  collect (PROGN (SETQ CollectItem (COND
						 (ReturnLinkIconsFlg LinkIcon)
						 (T ActualLink)))
					     (COND
					       ((NULL ReturnLocationsFlg)
						 CollectItem)
					       (T (CONS CollectItem (fetch (GRAPHNODE NODELABEL)
									 of GraphNode)))))))
         (CONS Links DirtyFlg))))
)
(* * Change to NCSKETCHCARD)

(DEFINEQ

(NC.CollectReferencesInSketch
  (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg)
                                                             (* rht: "26-May-87 11:55")

          (* * Return a list of all links in sketch substance Substance. If CheckAndDeleteFlg, then delete any links found 
	  that are not valid links.)



          (* * rht 8/20/85: Rewritten to use Richard's sketch programmer's interface. Eliminates references to sketch 
	  records.)



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



          (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of 
	  ActualLink is a valid card.)


    (LET ((SketchSubstance (NC.FetchSubstance Card))
	  DirtyFlg)
         (CONS (for SketchElt in (SKETCH.LIST.OF.ELEMENTS SketchSubstance
								  (FUNCTION 
								    NC.LinkIconSketchElementP))
		    bind LinkIcon CollectItem ActualLink
		    when (PROGN (SETQ ActualLink (NC.FetchLinkFromLinkIcon (SETQ LinkIcon
										     (
								       SKETCH.IMAGEOBJ.OF.ELEMENT
										       SketchElt))))
				    (COND
				      ((NULL CheckAndDeleteFlg)
                                                             (* No checking required)
					T)
				      ((AND (LISTP CheckAndDeleteFlg)
					      (FMEMB (fetch (Link DestinationCard) of 
										       ActualLink)
						       CheckAndDeleteFlg))
                                                             (* Already checked since ID cached on 
							     CheckAndDeleteFlg list)
					T)
				      ((AND (NC.ValidLinkP ActualLink)
					      (NC.ValidCardP (fetch (Link DestinationCard)
								  of ActualLink)))
                                                             (* Link is valid)
					T)
				      (T                     (* Link is bad. Replace it with the DeletedLink image 
							     object.)
					 (NC.DeleteLinkIconSketchElement SketchElt Card)
					 (SETQ DirtyFlg T)
					 NIL)))
		    collect (SETQ CollectItem (COND
				  (ReturnLinkIconsFlg LinkIcon)
				  (T ActualLink)))
			      (COND
				(ReturnLocationsFlg (CONS CollectItem (SKETCH.POSITION.OF.ELEMENT
							      SketchElt)))
				(T CollectItem)))
		 DirtyFlg))))
)
(* * Change to NCTEXTCARD)

(DEFINEQ

(NC.CollectReferencesInText
  (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg)
                                                             (* rht: " 1-Jun-87 22:11")

          (* * Return a list of all links or link icons in text substance Substance. If CheckAndDeleteFlg, then delete any 
	  links found that are not valid links.)



          (* * fgh 11/13/85 Updated to handle Card object. Eliminated DatabaseStream argument.)



          (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of 
	  ActualLink is a valid card.)


    (DECLARE (GLOBALVARS NC.DeletedLinkImageObject))
    (PROG (ActualLink DirtyFlg Links (Substance (NC.FetchSubstance Card)))
	    (SETQ Links (for ImageObjectDecriptor in (TEDIT.LIST.OF.OBJECTS
							     (TEXTOBJ Substance)
							     (FUNCTION NC.LinkIconImageObjP))
			     when (PROGN (SETQ ActualLink (NC.FetchLinkFromLinkIcon
						 (CAR ImageObjectDecriptor)))
					     (COND
					       ((NULL CheckAndDeleteFlg)
                                                             (* No checking required)
						 T)
					       ((AND (LISTP CheckAndDeleteFlg)
						       (FMEMB (fetch (Link DestinationCard)
								   of ActualLink)
								CheckAndDeleteFlg))
                                                             (* Already checked since ID cached on 
							     CheckAndDeleteFlg list)
						 T)
					       ((AND (NC.ValidLinkP ActualLink)
						       (NC.ValidCardP (fetch (Link 
										  DestinationCard)
									   of ActualLink)))
                                                             (* Link is valid)
						 T)
					       (T            (* Link is bad. Replace it with the DeletedLink image 
							     object.)
						  (create IMAGEOBJ
						     smashing (CAR ImageObjectDecriptor)
								OBJECTDATUM ←(fetch (IMAGEOBJ
											OBJECTDATUM)
										of 
									NC.DeletedLinkImageObject)
								IMAGEOBJPLIST ←(fetch (IMAGEOBJ
											  
										    IMAGEOBJPLIST)
										  of 
									NC.DeletedLinkImageObject)
								IMAGEOBJFNS ←(fetch (IMAGEOBJ
											IMAGEOBJFNS)
										of 
									NC.DeletedLinkImageObject))
						  (SETQ DirtyFlg T)
						  NIL)))
			     collect (COND
					 ((AND ReturnLinkIconsFlg (NOT ReturnLocationsFlg))
					   (CAR ImageObjectDecriptor))
					 ((AND ReturnLinkIconsFlg ReturnLocationsFlg)
					   (CONS (CAR ImageObjectDecriptor)
						   (CADR ImageObjectDecriptor)))
					 ((AND (NOT ReturnLinkIconsFlg)
						 ReturnLocationsFlg)
					   (CONS ActualLink (CADR ImageObjectDecriptor)))
					 (T ActualLink))))
	    (RETURN (CONS Links DirtyFlg)))))
)
(* * Changes to NCLINKS)

(DEFINEQ

(NC.ValidLinkP
  (LAMBDA (Link)                                             (* rht: "27-May-87 12:13")
                                                             (* Check Link to see if it is a valid NOTECARDLINK, 
							     incvluding check that the NoteCard specified by 
							     DESTINATIONID is an active card.)

          (* * kirk 15Nov85: deleted use of DatabaseStream)



          (* * rht 7/18/86: Was actually reading in the destination card from notefile! No more.)



          (* * rht 5/27/87: Took out checks for valid source and destination cards.)


    (LET (DestinationCard)
         (AND (type? Link Link)
		(NEQ (fetch (Link UID) of Link)
		       -1)))))

(NC.MakeLink
  (LAMBDA (Window LinkLabel DestinationCard SourceCard DisplayMode AnchorMode Message NoDisplayFlg 
		  LinkToInsertAfter CrossFileLinksMode)      (* rht: "28-May-87 13:39")

          (* * Make a link from (OR Window SourceCard) to DestinationCard with linklabel of LinkLabel)



          (* * rht 1/12/85: If need to create a new card, then now shows card type menu near window of SourceID.)



          (* * rht 1/13/85: Added extra args Message and NoDisplayFlg.)



          (* * rht 3/26/85: Added LinkToInsertAfter arg which should be NIL or a link to insert the new To link after.
	  If NIL, then insert at front of ToLinks.)



          (* * kirk 9/23/85: took out GETPROMPTWINDOW call for asknotecardtype)



          (* * kirk: 14Nov85: changed NC.CoerceToID to to NC.CoerceToCard)



          (* * fgh 11/16/85 Changed from PROG to LET and used COND to contyrol returnmed value.)



          (* * fgh 2/5/86 Changed call DefaultLinkDisplayMode to FetchLinkDisplayMode)



          (* * fgh 6/5/86 Now calls AskLinkLabel if LinkLabel arg is NIL)



          (* * rht 7/4/86: Added check for readonly card.)



          (* * kef 7/17/86: Added calls to grab the write permission on the appropriate card parts.)



          (* * kef 7/22/86: Saves the links on the Destination Card now right away, while still holding onto the FROMLINKS 
	  write lock.)



          (* * fgh 8/30/86 Adpated to use NC.IfCardPartNotBusy.)



          (* * rht 9/29/86: Tossed Ken's call to NC.PutFromLinks; It was the cause of too many nasty breaks.
	  Also made syntactic fixes.)



          (* * rht 10/4/86: Now handles cross file links. New arg CrossFileLinksMode determines whether cross-file link will 
	  be two-way, i.e. will destination card know it's being linked to.)



          (* * rht 11/10/86: Now creates new crossfile link if Destination card is a CrossFileLink card that we didn't just 
	  create.)



          (* * rht 11/14/86: Now checks if non-nil DestinationCard before trying to do cross-filelink stuff.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.)



          (* * rht 12/9/86: Throws out JustCreatedFlg marker stuff.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Fixed bug whereby electing not to open notefile containing crossfilelink dest card caused 
	  break.)



          (* * rht 12/16/86: Now passes Window down to NC.GetCrossFileLinkDestCard.)



          (* * rg 3/18/87 added NCP.WithLockedCards wrapper)



          (* * rht 5/25/87: No longer tries to make two way cross-file links when dest notefile is open read-only.
	  Also assumes that CrossFileLinksMode is one of TWOWAY, ONEWAY or ASK. Now fills in the new 
	  RemoteCrossFileLinkCardUID field of cross file link cards.)


    (DECLARE (GLOBALVARS NC.SelectingSingleCardMenu NC.NewCrossFileLinksMode))
    (OR SourceCard (SETQ SourceCard (NC.CoerceToCard Window)))
    (AND
      (NC.CheckForNotReadOnly SourceCard Window "Can't make links in ")
      (NCP.WithLockedCards
	(LET (Link Type)
	     (OR Window (SETQ Window (NC.FetchWindow SourceCard)))
	     (OR Message (SETQ Message "Please shift-select the Card or Box to be linked to."))
	     (OR LinkLabel (SETQ LinkLabel (NC.AskLinkLabel Window NIL NIL T NIL)))
	     (OR DestinationCard (SETQ DestinationCard (NC.SelectNoteCards
		       T
		       (FUNCTION (LAMBDA (Card)
			   (COND
			     ((NOT (NC.SameCardP Card SourceCard))
			       T)
			     (T (NC.PrintMsg Window T "A Card/Box cannot link to itself. "
					       (CHARACTER 13)
					       "Selection ignored."
					       (CHARACTER 13))
				NIL))))
		       NC.SelectingSingleCardMenu SourceCard Message)))
	     (if (EQ DestinationCard (QUOTE *New% Card*))
		 then (SETQ DestinationCard (AND (SETQ Type (NC.AskNoteCardType
							   (WINDOWREGION Window)))
						       (NC.CoerceToCard (NC.MakeNoteCard
									    Type
									    (fetch (Card NoteFile)
									       of SourceCard)
									    NIL NoDisplayFlg)))))

          (* * If we're trying to link to a CrossFileLink card, then check whether card was just created.
	  If so, then it's the first link, otherwise we make a new CrossFileLink.)


	     (AND DestinationCard (NC.CrossFileLinkCardP DestinationCard)
		    (SETQ DestinationCard (NC.GetCrossFileLinkDestCard DestinationCard Window))
		    (NC.SetUserDataProp DestinationCard (QUOTE JustCreatedFlg)
					  NIL))
	     (if DestinationCard
		 then
		  (NC.IfCardPartNotBusy
		    DestinationCard
		    (QUOTE FROMLINKS)
		    (NC.IfCardPartNotBusy
		      SourceCard
		      (QUOTE TOLINKS)

          (* * If have cross-file link, then make two new crossfilelink cards, one per notefile. Make global link over there 
	  from crossfilelink card to DestinationCard and local link here from SourceCard to crossfilelink card.)


		      (if (NOT (NC.SameNoteFileP (fetch (Card NoteFile) of SourceCard)
						       (fetch (Card NoteFile) of DestinationCard))
				   )
			  then (LET ((CrossFileLinksTwoWayFlg
					 (OR (EQ CrossFileLinksMode (QUOTE TWOWAY))
					       (AND (NULL CrossFileLinksMode)
						      (EQ NC.NewCrossFileLinksMode (QUOTE TWOWAY))
						      )
					       (AND (OR (EQ CrossFileLinksMode (QUOTE ASK))
							    (AND (NULL CrossFileLinksMode)
								   (EQ NC.NewCrossFileLinksMode
									 (QUOTE ASK))))
						      (NC.AskCrossFileLinkMode DestinationCard 
										 Window))))
				       RemoteSourceCard)
				      (if CrossFileLinksTwoWayFlg
					  then (AND (SETQ RemoteSourceCard
							  (NC.CreateCrossFileLinkCard 
										  DestinationCard 
										       SourceCard T))
							(NC.MakeGlobalLink Window LinkLabel 
									     DestinationCard 
									     RemoteSourceCard 
									     DisplayMode)))
				      (SETQ DestinationCard (NC.CreateCrossFileLinkCard 
										       SourceCard 
										  DestinationCard 
									  CrossFileLinksTwoWayFlg))
				      (if RemoteSourceCard
					  then             (* Make the two crossfile link cards know about each 
							     other's UIDs.)
						 (replace (CrossFileLinkSubstance 
								       RemoteCrossFileLinkCardUID)
						    of (NC.FetchSubstance RemoteSourceCard)
						    with (fetch (Card UID) of DestinationCard))
						 (replace (CrossFileLinkSubstance 
								       RemoteCrossFileLinkCardUID)
						    of (NC.FetchSubstance DestinationCard)
						    with (fetch (Card UID) of RemoteSourceCard))
					    )))
		      (SETQ Link (create Link
					     UID ←(NC.MakeUID)
					     SourceCard ← SourceCard
					     DestinationCard ← DestinationCard
					     AnchorMode ← AnchorMode
					     Label ← LinkLabel
					     DisplayMode ←(OR DisplayMode (NC.FetchLinkDisplayMode
								  SourceCard))))
		      (NC.AddToLink Link LinkToInsertAfter)
		      (NC.AddFromLink Link)
		      Link))
	       else NIL))))))

(NC.DeleteFromLink
  (LAMBDA (Link NoOrphanHookFlg)                             (* rht: "27-May-87 14:40")

          (* * This is part of what used to be the innards of NC.DeleteLink.)



          (* * rht 3/26/87: Changed to call NC.DeleteNoteCardInternal with QuietFlg on.)



          (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that DestinationCard is a 
	  valid card. Now calls NC.DeleteCrossFileLinkCard which tries to delete other end of cross-file link if that 
	  notefile is open.)


    (AND (NC.ValidLinkP Link)
	   (LET ((DestinationCard (fetch (Link DestinationCard) of Link)))
	        (AND (NC.ValidCardP DestinationCard)
		       (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of DestinationCard)
							)
				     (NC.DelFromLink Link NoOrphanHookFlg)
				     (NC.DelReferencesToCardFromShowLinks DestinationCard Link)

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


				     (if (NC.CrossFileLinkCardP DestinationCard)
					 then (NC.DeleteCrossFileLinkCard DestinationCard))))))))

(NC.DeleteToLink
  (LAMBDA (Link Don'tDelLinkIconFlg)                         (* rht: "27-May-87 14:40")

          (* * This is part of what used to be the innards of NC.DeleteLink.)



          (* * rht 3/26/87: Changed to call NC.DeleteNoteCardInternal with QuietFlg on.)



          (* * rht 5/27/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that SourceCard is valid 
	  card. Now calls NC.DeleteCrossFileLinkCard which tries to delete other end of cross-file link if that notefile is 
	  open.)


    (AND (NC.ValidLinkP Link)
	   (LET ((SourceCard (fetch (Link SourceCard) of Link)))
	        (AND (NC.ValidCardP SourceCard)
		       (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of SourceCard))
				     (OR Don'tDelLinkIconFlg (NC.DelReferencesToCard SourceCard 
											 Link))
				     (NC.DelToLink Link)
				     (NC.DelReferencesToCardFromShowLinks SourceCard Link)

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


				     (if (NC.CrossFileLinkCardP SourceCard)
					 then (NC.DeleteCrossFileLinkCard SourceCard))))))))

(NC.RelabelLink
  (LAMBDA (LinkOrLinkIcon Window NewLinkLabel ForceRedisplayFlg)
                                                             (* rht: "27-May-87 22:35" pp pp)
                                                             (* Relabel a NoteCard link.
							     Ask user for new label. Update all the proper 
							     references to this link.)

          (* * rht 11/19/84: Fixed so that Card is defined before first use.)



          (* * kirk 14Nov85: deleted use of and LinkID)



          (* * kef 8/8/86: Added obtaining write lock and NC.PutFromLinks.)



          (* * fgh 8/30/86 Adapted to NC.IfCardPartNotBusy)



          (* * rht 9/29/86: Changed Ken's call to NC.CardBeingEditedP to NC.ActiveCardP and other minor mod's.)



          (* * rg 5/15/87 now calls NC.LinksCachedP instead of NC.ActiveCardP)



          (* * rht 5/27/87: Now passes new label through cross file link if its dest notefile is open.)


    (LET (Link LinkIcon Card DestinationCard OldLabel NoteCardType GlobalLinkFlg)
         (if (NC.LinkIconImageObjP LinkOrLinkIcon)
	     then (SETQ Link (NC.FetchLinkFromLinkIcon LinkOrLinkIcon))
		    (SETQ LinkIcon LinkOrLinkIcon)
	   else (SETQ Link LinkOrLinkIcon)
		  (OR (SETQ GlobalLinkFlg (NC.GlobalLinkP Link))
			(SETQ LinkIcon (NC.FetchLinkIconForLink Link))))
         (SETQ Card (fetch (Link SourceCard) of Link))
         (COND
	   ((WINDOWP Window))
	   ((NC.ActiveCardP Card)
	     (SETQ Window (NC.FetchWindow Card))))
         (SETQ DestinationCard (fetch (Link DestinationCard) of Link))
         (NC.IfCardPartNotBusy DestinationCard (QUOTE FROMLINKS)
			       (COND
				 ((NC.SystemLinkLabelP (fetch (Link Label) of Link))
				   (NC.PrintMsg Window T "This is a system maintained pointer."
						  (CHARACTER 13)
						  "You cannot change its label."
						  (CHARACTER 13))
				   (SPAWN.MOUSE)
				   (DISMISS 1500)
				   (NC.ClearMsg Window T))
				 ((SETQ NewLinkLabel (OR NewLinkLabel
							     (NC.AskLinkLabel Window NIL NIL T T)))
				   (SETQ NoteCardType (NC.RetrieveType Card))

          (* * Put new label in Link Icon or global links list)


				   (if GlobalLinkFlg
				       then (for GlobalLink in (NC.FetchGlobalLinks Card)
						 when (NC.SameLinkP GlobalLink Link)
						 do (replace (Link Label) of GlobalLink
							 with NewLinkLabel)
						      (NC.SetLinksDirtyFlg Card T)
						      (RETURN))
				     else (replace (Link Label) of (NC.FetchLinkFromLinkIcon
									   LinkIcon)
					       with NewLinkLabel)
					    (NC.MarkCardDirty Card))

          (* * Update ToLink list of the SourceCard card)


				   (for ToLink in (NC.FetchToLinks Card)
				      when (NC.SameLinkP ToLink Link)
				      do (replace (Link Label) of ToLink with NewLinkLabel)
					   (NC.SetLinksDirtyFlg Card T)
					   (RETURN))

          (* * Update FromLink list of DestinationCard card)


				   (if (NC.LinksCachedP DestinationCard)
				       then (for FromLink in (NC.FetchFromLinks 
										  DestinationCard)
						 when (NC.SameLinkP FromLink Link)
						 do (replace (Link Label) of FromLink
							 with NewLinkLabel)
						      (NC.SetLinksDirtyFlg DestinationCard T)
						      (RETURN))
				     else (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile)
										of DestinationCard))
							  (NC.GetLinks DestinationCard)
							  (for FromLink in (NC.FetchFromLinks
										 DestinationCard)
							     when (NC.SameLinkP FromLink Link)
							     do (replace (Link Label)
								     of FromLink with 
										     NewLinkLabel)
								  (NC.SetLinksDirtyFlg 
										  DestinationCard T)
								  (RETURN))
							  (NC.PutFromLinks DestinationCard)
							  (NC.UncacheLinks DestinationCard)))

          (* * Pass change through cross-file link to other notefile if open.)


				   (if (NC.CrossFileLinkCardP Card)
				       then (LET ((RemoteCrossFileLinkCard (
								  NC.FetchRemoteCrossFileLinkCard
									       Card)))
					           (AND RemoteCrossFileLinkCard
							  (NC.CheckCrossFileLinkType 
									  RemoteCrossFileLinkCard 
										       Card Link))))
				   (if (NC.CrossFileLinkCardP DestinationCard)
				       then (LET ((RemoteCrossFileLinkCard (
								  NC.FetchRemoteCrossFileLinkCard
									       DestinationCard)))
					           (AND RemoteCrossFileLinkCard
							  (NC.CheckCrossFileLinkType 
									  RemoteCrossFileLinkCard 
										  DestinationCard 
										       Link))))

          (* * Update images in SourceCard window)


				   (COND
				     ((AND (NULL ForceRedisplayFlg)
					     (NC.TEditBasedP NoteCardType))
				       (QUOTE CHANGED))
				     ((WINDOWP Window)
				       (NC.UpdateLinkImages Window (fetch (Link DestinationCard)
									of Link))
				       NIL)
				     (T NIL))))))))

(NC.FileInOrphanBox
  (LAMBDA (Link DestinationCard)                             (* rht: "29-May-87 01:00")

          (* * Hook card to orphan if this is the last link.)



          (* * rht 7/4/86: Changed to call NC.FetchSpecialCards so that RegistryCard, etc. won't have to be filed somewhere.)



          (* * rg 11/18/86 Added globalvars declaration)



          (* * rht 4/20/87: Changed to work on new cards unless they're displayed on screen. Also removed reference to 
	  long-demised NC.OrphansID.)



          (* * rht 5/28/87: Now calls NC.CardNeedsFilingP, i.e. card should need filing before we gripe.)


    (LET ((SourceCard (fetch (Link SourceCard) of Link)))
         (AND (NC.CardNeedsFilingP DestinationCard)
		(NOT (NC.SameCardP SourceCard DestinationCard))
		(NOT (AND (NC.FetchNewCardFlg DestinationCard)
			      (NC.FetchWindow DestinationCard)))
		(NOT (NC.SameCardP SourceCard (fetch (NoteFile OrphansCard)
						     of (fetch (Card NoteFile) of SourceCard))))
		(COND
		  ((OR (NULL (NC.FetchFromLinks DestinationCard))
			 (for FromLink in (NC.FetchFromLinks DestinationCard)
			    always (NC.SameCardP (fetch (Link SourceCard) of FromLink)
						     DestinationCard)))
		    (NC.PrintMsg NIL T "You have just removed the last link to " (NC.RetrieveTitle
				     DestinationCard)
				   "."
				   (CHARACTER 13)
				   "It is being filed in the Orphan FileBox.")
		    (NC.HookToOrphanCard DestinationCard))
		  ((for FromLink in (NC.FetchFromLinks DestinationCard)
		      never (FMEMB (fetch (Link Label) of FromLink)
				       (QUOTE (SubBox FiledCard))))
		    (NC.PrintMsg NIL T "You have just unfiled " (NC.RetrieveTitle DestinationCard)
				   " from its last filebox."
				   (CHARACTER 13)
				   "It is being filed in the Orphan FileBox.")
		    (NC.HookToOrphanCard DestinationCard))))
     Link)))
)
(* * Change to NCCARDS)

(DEFINEQ

(NC.DeleteNoteCardInternal
  (LAMBDA (Card QuietFlg InterestedWindow IgnoreLinksFlg)    (* rht: " 8-Jun-87 23:47")

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



          (* * rht 5/27/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that DestinationCard and 
	  SourceCard are valid cards.)



          (* * 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 Window 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 bind DestCard
						     when (AND (NC.ValidLinkP ToLink)
								   (NC.ValidCardP
								     (SETQ DestCard
								       (fetch (Link DestinationCard)
									  of ToLink))))
						     do (NC.DelFromLink ToLink)
							  (NC.DelReferencesToCardFromShowLinks
							    DestCard ToLink))
						  (for FromLink in FromLinks bind SourceCard
						     when (AND (NC.ValidLinkP FromLink)
								   (NC.ValidCardP
								     (SETQ SourceCard
								       (fetch (Link SourceCard)
									  of FromLink))))
						     do (NC.DelToLink FromLink)
							  (NC.DelReferencesToCard SourceCard Card)
							  (NC.DelReferencesToCardFromShowLinks
							    SourceCard 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.AssignTitle
  (LAMBDA (CardIdentifier NoClearMsgFlg NewTitle InterestedWindow)
                                                             (* rht: "29-May-87 15:49")

          (* * Change the title of the card specified by the WindowOrTextStreamOrID)



          (* * rht 2/1/85: Changed from NC.PutTitle to NC.SetTitleDirtyFlg, unless card is not active.
	  We shouldn't be writing to the notefile until save time.)



          (* * fgh 11/11/85: Added support for CardID, CardInfo and noteFile objects. Also entered call to Nc.StoreTitle.)



          (* * fgh 6/9/86 Added code to check to make sure that another operation is not in progress on this card when this 
	  fn is called.)



          (* * fgh 6/13/86 Now spawns mouse in case called under MOUSE process.)



          (* * fgh 6/27/86 returns T if completed okay.)



          (* * rht 7/4/86: Added check for readonly card.)



          (* * kef 7/16/86: Added obtain write permission.)



          (* * kef 7/24/86: Doesn't release the write lock if this is a new card.)



          (* * 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 Converted to use NC.IfCardPartNotBusy.)



          (* * rg 3/3/87 Enlarged scope of NC.ProtectedCardOperation)



          (* * rht 3/23/87: Now takes InterestedWindow arg.)



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



          (* * rht 5/27/87: Now passes title through cross-file link card if dest notefile is open.)



          (* * rht 5/29/87: Now uncaches links if they weren't cached when we came in.)


    (ALLOW.BUTTON.EVENTS)
    (LET ((Card (NC.CoerceToCard CardIdentifier))
	  OldTitle Window)
         (NC.ProtectedCardOperation
	   Card "Assign Title" NIL
	   (NC.IfCardPartNotBusy Card (QUOTE TITLE)
				 (OR InterestedWindow (SETQ InterestedWindow (
					   NC.CoerceToInterestedWindow Card)))
				 (if (NC.CheckForNotReadOnly Card InterestedWindow 
							      "Can't change titles for cards in ")
				     then
				      (COND
					((SETQ NewTitle
					    (OR (STRINGP NewTitle)
						  (AND NewTitle (OR (LITATOM NewTitle)
									(NUMBERP NewTitle))
							 (MKSTRING NewTitle))
						  (NC.AskUser (CONCAT 
								  "Enter the title for this card"
									  (CHARACTER 13))
								"-->  "
								(COND
								  ((AND (STREQUAL (SETQ 
											OldTitle
											(
										 NC.RetrieveTitle
											  Card))
										      "Untitled")
									  (NC.FetchNewCardFlg
									    Card))
								    NIL)
								  (T OldTitle))
								(NULL NoClearMsgFlg)
								InterestedWindow)))
					  (NC.SetTitle Card NewTitle)

          (* * Now do a PutTitle so that anyone else coming along will pick up on the new title. The only exception is if 
	  this card hasn't been written to the NoteFile yet, which is true when the NewCardFlg is T. In that case, we can't 
	  put the title down yet, so just mark it dirty.)


					  (COND
					    ((fetch (Card NewCardFlg) of Card)
					      (NC.SetTitleDirtyFlg Card T))
					    (T (NC.PutTitle Card)
					       (NC.SetTitleDirtyFlg Card NIL)))
					  (AND (WINDOWP (SETQ Window (NC.FetchWindow Card)))
						 (WINDOWPROP Window (QUOTE TITLE)
							       NewTitle))
					  (LET ((LinksWereCachedFlg (NC.LinksCachedP Card)))
					       (if (NOT LinksWereCachedFlg)
						   then (NC.GetLinks Card))
					       (for FromLink in (NC.FetchFromLinks Card)
						  do (LET ((ContainingCard (fetch (Link 
										       SourceCard)
										of FromLink))
							     RemoteCrossFileLinkCard)
							    (if (AND (NC.CrossFileLinkCardP
									   ContainingCard)
									 (SETQ 
									  RemoteCrossFileLinkCard
									   (
								  NC.FetchRemoteCrossFileLinkCard
									     ContainingCard)))
								then (
								   NC.CheckCrossFileLinkCardTitle
									 RemoteCrossFileLinkCard Card)
							      else (AND (NC.ActiveCardP 
										   ContainingCard)
									    (WINDOWP (
										   NC.FetchWindow
											 
										   ContainingCard))
									    (NC.UpdateLinkImages
									      ContainingCard Card)))))
					       (if (NOT LinksWereCachedFlg)
						   then (NC.UncacheLinks Card)))
					  T))
				   else NIL))))))
)
(* * Changes to NCCROSSFILELINKS)

(DEFINEQ

(NC.OpenCrossFileLinkDestNoteFile
  (LAMBDA (DestNoteFile DestFileName InterestedWindow CrossFileLinkCard)
                                                             (* rht: " 8-Jun-87 11:39")

          (* * If DestNoteFile is an open notefile, then fine. Otherwise get file names from user and keep trying to open 
	  until she gives up.)



          (* * rht 5/25/87: Minor change: no longer passes InterestedWindow to NC.OpenNoteFile.)



          (* * rht 6/3/87: Now calls new function NC.AskUserWithMenu. Added CrossFileLinkCard argument whose title is used to
	  construct Message.)



          (* * rht 6/8/87: Now computes WasOpenPromptWindowFlg)


    (OR InterestedWindow (NC.CoerceToInterestedWindow CrossFileLinkCard))
    (LET ((WasOpenPromptWindowFlg (NC.PromptWindowOpenP InterestedWindow)))
         (if (NCP.OpenNoteFileP DestNoteFile)
	     then DestNoteFile
	   else (LET ((MenuItems (QUOTE (Read/Write Read-Only Don't% Open))))
		       (for while (OR DestFileName (SETQ DestFileName
					      (NC.AskUser "File name to try opening: " NIL NIL T 
							    InterestedWindow WasOpenPromptWindowFlg)))
			  do (LET ((Message (if (NC.ValidCardP CrossFileLinkCard)
						  then (CONCAT "Open " DestFileName 
								   " to look for '"
								   (NC.RetrieveTitle 
										CrossFileLinkCard)
								   "'?")
						else (CONCAT "OPEN " DestFileName "?")))
				     ReadOnlyOpenFlg)
				    (if (AND (SELECTQ (NC.AskUserWithMenu MenuItems Message 
										 InterestedWindow 
									   WasOpenPromptWindowFlg T)
							    (Read/Write (SETQ ReadOnlyOpenFlg NIL)
									T)
							    (Read-Only (SETQ ReadOnlyOpenFlg T))
							    (Don't% Open (RETURN NIL))
							    (RETURN NIL))
						 (NCP.OpenNoteFileP (SETQ DestNoteFile
									(NC.OpenNoteFile
									  (OR DestNoteFile 
										DestFileName)
									  NIL NIL NIL NIL NIL NIL NIL 
									  NIL NIL NIL NIL 
									  ReadOnlyOpenFlg))))
					then (RETURN DestNoteFile)
				      else (NC.PrintMsg InterestedWindow T "Couldn't open " 
							    DestFileName "." (CHARACTER 13))
					     (SETQ DestFileName (SETQ DestNoteFile NIL))
					     (if (NOT (NC.AskYesOrNo 
						     "Want to try opening a different notefile? "
									   " -- " "Yes" NIL 
									   InterestedWindow 
									   WasOpenPromptWindowFlg))
						 then (RETURN NIL))))))))))

(NC.CrossFileLinkPutFn
  (LAMBDA (Card Stream)                                      (* rht: "27-May-87 15:07")

          (* * Put crossfilelink substance)



          (* * rht 11/1/86: Now uses our readtable when printing.)



          (* * rht 5/27/87: Changed to write down new fields RemoteCrossFileLinkCardUID and CrossFileLinkTwoWayFlg of 
	  CrossFileLinkSubstance record.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (LET ((Substance (NC.FetchSubstance Card)))
         (NC.WriteUID Stream (fetch (CrossFileLinkSubstance CrossFileLinkDestCardUID)
				  of Substance))
         (NC.WriteUID Stream (fetch (CrossFileLinkSubstance CrossFileLinkDestNoteFileUID)
				  of Substance))
         (NC.WriteUID Stream (fetch (CrossFileLinkSubstance RemoteCrossFileLinkCardUID)
				  of Substance))
         (PRINT (fetch (CrossFileLinkSubstance CrossFileLinkDestFileHint) of Substance)
		  Stream NC.OrigReadTable)
         (PRINT (fetch (CrossFileLinkSubstance CrossFileLinkTwoWayFlg) of Substance)
		  Stream NC.OrigReadTable))
    1))

(NC.CrossFileLinkGetFn
  (LAMBDA (Card Length Stream VersionNum)                    (* rht: "27-May-87 15:06")

          (* * Get the crossfilelink substance from the disk)



          (* * rht 11/1/86: Now uses our readtable when reading.)



          (* * rht 5/27/87: Now reads in new format of CrossFileLinkSubstance record with two new fields.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (if (LEQ VersionNum 0)
	then (create CrossFileLinkSubstance
			 CrossFileLinkDestCardUID ←(NC.ReadUID Stream)
			 CrossFileLinkDestNoteFileUID ←(NC.ReadUID Stream)
			 CrossFileLinkDestFileHint ←(READ Stream NC.OrigReadTable))
      else (create CrossFileLinkSubstance
		       CrossFileLinkDestCardUID ←(NC.ReadUID Stream)
		       CrossFileLinkDestNoteFileUID ←(NC.ReadUID Stream)
		       RemoteCrossFileLinkCardUID ←(NC.ReadUID Stream)
		       CrossFileLinkDestFileHint ←(READ Stream NC.OrigReadTable)
		       CrossFileLinkTwoWayFlg ←(READ Stream NC.OrigReadTable)))))

(NC.CrossFileLinkEditFn
  (LAMBDA (Card Substance RegionOrPosition TypeSpecificArgs)
                                                             (* rht: "27-May-87 18:34")

          (* * Given a CrossFileLink Substance, try to find the corresponding destination card in the destination notefile 
	  and bring it up.)



          (* * rht 11/13/86: Now updates title of crossfile link card to be the same as destination card if necessary.)



          (* * rht 5/27/87: Now calls NC.CheckCrossFileLinkCardTitle.)


    (LET ((DestinationCard (NC.GetCrossFileLinkDestCard Card))
	  DestinationCardTitle)
         (if DestinationCard
	     then (NC.CheckCrossFileLinkCardTitle Card DestinationCard)
		    (NC.EditNoteCard DestinationCard RegionOrPosition TypeSpecificArgs)))))

(NC.GetCrossFileLinkDestCard
  (LAMBDA (CrossFileLinkCard InterestedWindow Don'tOpenDestNoteFileFlg)
                                                             (* rht: " 8-Jun-87 11:39")

          (* * Find the notefile corresponding to this crossfilelink and try to open it if not already open.
	  Then look for the card in there having the given UID. Return NIL if failed for any reason.)



          (* * rht 11/10/86: Make sure CrossFileLinkCard is cached before fetching substance.)



          (* * rht 11/19/86: Now rips off version number from destination notefile hint.)



          (* * rht 12/11/86: Now checks that destination card is not deleted.)



          (* * rht 12/16/86: Now takes InterestedWindow argument.)



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



          (* * rht 3/27/87: Now calls NC.OpenCrossFileLinkDestNoteFile.)



          (* * rht 5/27/87: New arg Don'tOpenDestNoteFileFlg. If non-nil, then destination notefile has to be already open.)



          (* * rht 6/4/87: Now passes CrossFileLinkCard to NC.OpenCrossFileLinkDestNoteFile.)



          (* * rht 6/8/87: Now computes WasOpenPromptWindowFlg)


    (LET ((Title (NC.FetchTitle CrossFileLinkCard))
	  (SourceNoteFile (fetch (Card NoteFile) of CrossFileLinkCard))
	  Substance DestNoteFileUID DestFileHint DestCardUID DestNoteFile DestFileName Card 
	  WasOpenPromptWindowFlg)
         (OR InterestedWindow (SETQ InterestedWindow (NC.CoerceToInterestedWindow 
										   SourceNoteFile)))
         (SETQ WasOpenPromptWindowFlg (NC.PromptWindowOpenP InterestedWindow))
         (if (NOT (NC.ActiveCardP CrossFileLinkCard))
	     then (NC.GetNoteCard CrossFileLinkCard))
         (SETQ Substance (NC.FetchSubstance CrossFileLinkCard))
         (SETQ DestCardUID (fetch (CrossFileLinkSubstance CrossFileLinkDestCardUID) of 
											Substance))
         (SETQ DestNoteFileUID (fetch (CrossFileLinkSubstance CrossFileLinkDestNoteFileUID)
				    of Substance))
         (SETQ DestFileHint (fetch (CrossFileLinkSubstance CrossFileLinkDestFileHint)
				 of Substance))
         (SETQ DestNoteFile (NC.NoteFileFromNoteFileUID DestNoteFileUID))
         (SETQ DestFileName (OR (AND (type? NoteFile DestNoteFile)
					   (fetch (NoteFile FullFileName) of DestNoteFile))
				    DestFileHint))
         (for while (if Don'tOpenDestNoteFileFlg
			    then (NCP.OpenNoteFileP DestNoteFile)
			  else (SETQ DestNoteFile (NC.OpenCrossFileLinkDestNoteFile 
										     DestNoteFile 
										     DestFileName 
										 InterestedWindow 
										CrossFileLinkCard)))
	    bind NewFileName
	    do (if (NC.ValidCardP (SETQ Card (NC.CardFromUID DestCardUID DestNoteFile)))
		     then (if (NOT (EQUAL (SETQ NewFileName (fetch (NoteFile FullFileName)
									 of DestNoteFile))
						  (FULLNAME (fetch (CrossFileLinkSubstance 
									CrossFileLinkDestFileHint)
								 of Substance))))
				then (replace (CrossFileLinkSubstance CrossFileLinkDestFileHint)
					  of Substance with (PACKFILENAME (QUOTE VERSION)
										NIL
										(QUOTE BODY)
										NewFileName))
				       (NC.MarkCardDirty CrossFileLinkCard))
			    (RETURN Card)
		   else (if Don'tOpenDestNoteFileFlg
			      then (RETURN NIL)
			    else (NC.PrintMsg InterestedWindow T 
						  "Couldn't find destination card in "
						  DestFileName "." (CHARACTER 13))
				   (if (NOT (NC.AskYesOrNo 
						     "Want to try opening a different notefile? "
								 " -- " "Yes" NIL InterestedWindow 
								 WasOpenPromptWindowFlg))
				       then (RETURN NIL)
				     else (SETQ DestNoteFile (SETQ DestFileName NIL)))))))))
)
[DECLARE: EVAL@COMPILE 

(DATATYPE CrossFileLinkSubstance (CrossFileLinkDestCardUID CrossFileLinkDestNoteFileUID 
							     CrossFileLinkDestFileHint (
							       CrossFileLinkTwoWayFlg FLAG)
							     RemoteCrossFileLinkCardUID))
]
(/DECLAREDATATYPE (QUOTE CrossFileLinkSubstance)
		  (QUOTE (POINTER POINTER POINTER FLAG POINTER))
		  (QUOTE ((CrossFileLinkSubstance 0 POINTER)
			  (CrossFileLinkSubstance 2 POINTER)
			  (CrossFileLinkSubstance 4 POINTER)
			  (CrossFileLinkSubstance 4 (FLAGBITS . 0))
			  (CrossFileLinkSubstance 6 POINTER)))
		  (QUOTE 8))
(* * New stuff for NCCROSSFILELINKS)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.NewCrossFileLinksMode)
)

(RPAQ? NC.NewCrossFileLinksMode (QUOTE ASK))
(DEFINEQ

(NC.AskCrossFileLinkMode
  (LAMBDA (DestCard InterestedWindow)                        (* rht: "28-May-87 13:54")

          (* * Ask the user whether to make the link be twoway or oneway. Return T if user says two-way.
	  If dest notefile is open read-only, then only choice is one-way so don't ask.)


    (LET* ((NoteFile (fetch (Card NoteFile) of DestCard))
	   (FullFileName (fetch (NoteFile FullFileName) of NoteFile)))
          (if (NC.ReadOnlyNoteFileP NoteFile)
	      then NIL
	    else (NC.AskYesOrNo (CONCAT "Okay to make cross-file link to '" (NC.RetrieveTitle
						DestCard)
					      "' in '"
					      (FILENAMEFIELD FullFileName (QUOTE NAME))
					      ";"
					      (FILENAMEFIELD FullFileName (QUOTE VERSION))
					      "' be TWOWAY?"
					      (CHARACTER 13)
					      
				  "(otherwise leaves no record of link in destination notefile) ")
				    NIL "Yes" T InterestedWindow)))))

(NC.DeleteCrossFileLinkCard
  (LAMBDA (CrossFileLinkCard)                                (* rht: "27-May-87 21:54")

          (* * Delete the crossfile link card. If it's a twoway crossfile link, and its "twin" is in an open notefile, then 
	  delete the cross file link over there.)


    (LET ((DestCard (NC.FetchRemoteCrossFileLinkCard CrossFileLinkCard)))
         (if DestCard
	     then (NC.DeleteNoteCardInternal DestCard T))
         (NC.DeleteNoteCardInternal CrossFileLinkCard T))))

(NC.FetchRemoteCrossFileLinkCard
  (LAMBDA (CrossFileLinkCard)                                (* rht: "27-May-87 21:54")

          (* * Return the remote "twin" of CrossFileLinkCard if its notefile is open.)


    (LET ((CrossFileLinkSubstance (NCP.CardSubstance CrossFileLinkCard))
	  DestCard RemoteCrossFileLinkCardUID NoteFileUID NoteFile)
         (if (AND (fetch (CrossFileLinkSubstance CrossFileLinkTwoWayFlg) of 
									   CrossFileLinkSubstance)
		      (SETQ RemoteCrossFileLinkCardUID (fetch (CrossFileLinkSubstance 
								       RemoteCrossFileLinkCardUID)
							    of CrossFileLinkSubstance))
		      (type? UID (SETQ NoteFileUID (fetch (CrossFileLinkSubstance 
								     CrossFileLinkDestNoteFileUID)
							  of CrossFileLinkSubstance)))
		      (NCP.OpenNoteFileP (SETQ NoteFile (NC.NoteFileFromNoteFileUID NoteFileUID)
					     ))
		      (NC.ValidCardP (SETQ DestCard (NC.CardFromUID RemoteCrossFileLinkCardUID 
									  NoteFile))))
	     then DestCard
	   else NIL))))

(NC.CheckCrossFileLinkCardTitle
  (LAMBDA (CrossFileLinkCard DestinationCard)                (* rht: "27-May-87 21:47")

          (* * If titles don't agree, change crossfilelink card title to match.)


    (LET ((DestinationCardTitle (NC.RetrieveTitle DestinationCard)))
         (if (NOT (STREQUAL DestinationCardTitle (NC.RetrieveTitle CrossFileLinkCard)))
	     then (NC.AssignTitle CrossFileLinkCard NIL DestinationCardTitle)))))

(NC.CheckCrossFileLinkType
  (LAMBDA (RemoteCrossFileLinkCard LocalCrossFileLinkCard Link)
                                                             (* rht: "27-May-87 22:33")

          (* * If link types don't agree, change remote crossfilelink type to match.)


    (LET ((RemoteDestCard (NC.GetCrossFileLinkDestCard LocalCrossFileLinkCard NIL T))
	  (LinkLabel (fetch (Link Label) of Link))
	  RemoteLink NoteFile)
         (if RemoteDestCard
	     then (SETQ RemoteLink (OR (for FromLink in (NC.RetrieveFromLinks 
									  RemoteCrossFileLinkCard)
						when (NC.SameCardP (fetch (Link SourceCard)
									  of FromLink)
								       RemoteDestCard)
						do (RETURN FromLink))
					     (for ToLink in (NC.RetrieveToLinks 
									  RemoteCrossFileLinkCard)
						when (NC.SameCardP (fetch (Link DestinationCard)
									  of ToLink)
								       RemoteDestCard)
						do (RETURN ToLink))))
		    (if (NOT (EQ (fetch (Link Label) of RemoteLink)
				       LinkLabel))
			then (if (NOT (NCP.ValidLinkTypeP LinkLabel (SETQ NoteFile
								    (fetch (Card NoteFile)
								       of RemoteCrossFileLinkCard)))
					    )
				   then (NCP.CreateLinkType LinkLabel NoteFile))
			       (NC.RelabelLink RemoteLink NIL LinkLabel))))))

(NC.MakeCrossFileLinkIconStandIn
  (LAMBDA (CrossFileLinkCard)                                (* rht: "27-May-87 23:39")

          (* * Return an imageobj to act as a standin for a cross file link.)


    (DECLARE (GLOBALVARS NC.ExternalPutLinkIconImageFns))
    (IMAGEOBJCREATE (CONCAT "[[ Cross-file link to '" (NC.RetrieveTitle CrossFileLinkCard)
				"' ]]")
		      NC.ExternalPutLinkIconImageFns)))

(NC.ComputeCrossFileLinkMode
  (LAMBDA (RemoteCard CrossFileLinkModePropList InterestedWindow)
                                                             (* rht: " 6-Jun-87 16:19")

          (* * If we've already made cross file links to RemoteCard's notefile, then it'll be registered on 
	  CrossFileLinkModePropList. Otherwise, consult global var, possibly ask user, and register her answer on 
	  CrossFileLinkModePropList.)



          (* * rht 6/6/87: Changed so that check of globalvar happens before check of CrossFileLinkModePropList.)


    (DECLARE (GLOBALVARS NC.NewCrossFileLinksMode))
    (LET ((NoteFile (fetch (Card NoteFile) of RemoteCard))
	  Mode)
         (COND
	   ((FMEMB NC.NewCrossFileLinksMode (QUOTE (TWOWAY ONEWAY)))
	     NC.NewCrossFileLinksMode)
	   ((FMEMB NoteFile CrossFileLinkModePropList)
	     (LISTGET CrossFileLinkModePropList NoteFile))
	   (T (SETQ Mode (if (NC.AskCrossFileLinkMode RemoteCard InterestedWindow)
			       then (QUOTE TWOWAY)
			     else (QUOTE ONEWAY)))
	      (LISTPUT CrossFileLinkModePropList NoteFile Mode)
	      Mode)))))
)
(* * PLEASE remove the globalvar NC.NewCrossFileLinksTwoWayFlg from NCCROSSFILELINKS coms)

(* * Changes to NCBROWSERCARD)

(DEFINEQ

(NC.GrowLinkLattice
  (LAMBDA (RootCardsList CurrentGraph ListOfLinkLabels GraphCard RemainingSearchDepth)
                                                             (* rht: "29-May-87 01:46")

          (* Grow a lattice by following the links from RootID card among ListOfLinkLabels. Lattice will be fed to 
	  LAYOUTGRAPH, so for each note card encountered by following the links just fill in the ID, LABEL and daughter IDs)



          (* * rht 8/3/84: Changed so as to also follow from links if they are present (prefixed by "←") on 
	  ListOfLinkLabels.)



          (* * rht 10/4/84: Now stores the link label on the prop list of the NODEID of the graph under the property name of 
	  the destination ID. This is so that links can be drawn with dashing depending on the link's label.)



          (* * rht 3/8/85: Added RemainingSearchDepth arg to limit the lattice growth to given depth.)



          (* * rht 8/9/85: Changed so that backward links are no longer stored as a separate link type.
	  Rather they're told apart from forward links by being stored on the destination node's prop list.)



          (* * rht 4/4/85: Now first arg can be either a root Card or an existing graphnode. If the latter, then we're 
	  expanding an existing graph below that node. If the former than we're starting a new lattice.)



          (* * rht 10/17/85: Changed from a recursive depth-first algorithm to a loop-driven breadth-first alg.)



          (* * rht 11/17/85: Handles new card and notefile objects.)



          (* * rht 5/26/87: Now tries to follow cross-file links.)


    (LET (CardsAndDepthsQueue)                               (* Make the queue contain pairs of root Card and depth
							     remaining to search.)
         (SETQ CardsAndDepthsQueue (for Card in RootCardsList collect (CONS Card 
									     RemainingSearchDepth)))
                                                             (* Make it a TCONC list for fast appending to the 
							     end.)
         (SETQ CardsAndDepthsQueue (CONS CardsAndDepthsQueue (LAST CardsAndDepthsQueue)))

          (* * Do breadth-first search using the queue IDsAndDepthsQueue.)


         (for bind CardAndDepth Card RemainingSearchDepth ToLinks FromLinks DestinationIDs 
		       GraphNodeID GraphNode
	    eachtime (BLOCK)                             (* Grab and take apart 1st pair on queue.)
		       (SETQ CardAndDepth (CAAR CardsAndDepthsQueue))
		       (SETQ Card (CAR CardAndDepth))
		       (SETQ RemainingSearchDepth (CDR CardAndDepth)) 
                                                             (* Remove the front pair from the queue.)
		       (RPLACA CardsAndDepthsQueue (CDAR CardsAndDepthsQueue)) 
                                                             (* If that was the last pair, then start queue over 
							     fresh.)
		       (if (NULL (CAR CardsAndDepthsQueue))
			   then (SETQ CardsAndDepthsQueue NIL))
	    while Card unless (NC.SameCardP Card GraphCard)
	    do
	     (SETQ GraphNodeID (NC.GetBrowserNodeID GraphCard Card)) 
                                                             (* Go grab this ID's links.)
	     (if (NC.ActiveCardP Card)
		 then (SETQ ToLinks (NC.FetchToLinks Card))
			(SETQ FromLinks (NC.FetchFromLinks Card))
	       else (NC.GetLinks Card)
		      (SETQ ToLinks (NC.FetchToLinks Card))
		      (SETQ FromLinks (NC.FetchFromLinks Card)))
	     (if (IGREATERP RemainingSearchDepth 0)
		 then                                      (* Crush the ID's proplist.)
		  (if (NOT (NC.GraphNodeIDGetProp GraphNodeID (QUOTE TouchedFlg)))
		      then (NC.SmashGraphNodeIDProps GraphNodeID)
			     (NC.GraphNodeIDPutProp GraphNodeID (QUOTE TouchedFlg)
						      T))
		  (SETQ DestinationIDs
		    (NCONC (for Link in ToLinks bind DestID DestVisitedFlg DestTouchedFlg 
							     ThisWayLinkFlg OtherWayLinkFlg
				eachtime (BLOCK)
					   (if (SETQ ThisWayLinkFlg (NC.LinkLabelP Link 
										 ListOfLinkLabels))
					       then (SETQ DestID
							(NC.GetBrowserNodeID
							  GraphCard
							  (LET ((DestCard (fetch (Link 
										  DestinationCard)
									     of Link)))
							       (if (NC.CrossFileLinkCardP 
											 DestCard)
								   then (OR (
								      NC.GetCrossFileLinkDestCard
										  DestCard)
										DestCard)
								 else DestCard))))
						      (SETQ DestVisitedFlg (NC.GraphNodeIDGetProp
							  DestID
							  (QUOTE VisitedFlg)))
						      (SETQ DestTouchedFlg (NC.GraphNodeIDGetProp
							  DestID
							  (QUOTE TouchedFlg)))
						      (SETQ OtherWayLinkFlg (NC.ReverseLinkLabelP
							  Link ListOfLinkLabels)))
				when ThisWayLinkFlg unless (AND DestVisitedFlg OtherWayLinkFlg)
				collect                    (* Record presence of this link.)
					  (NC.UIDAddProp GraphNodeID DestID (fetch (Link Label)
										 of Link)
							   T)
					  DestID)
			     (for Link in FromLinks bind DestID DestTouchedFlg DestVisitedFlg 
							       ThisWayLinkFlg OtherWayLinkFlg 
							       SourceCard
				eachtime
				 (BLOCK)
				 (if (AND (SETQ ThisWayLinkFlg (NC.ReverseLinkLabelP Link 
										 ListOfLinkLabels))
					      (NOT (NC.SameCardP
						       GraphCard
						       (SETQ SourceCard
							 (LET ((SrcCard (fetch (Link SourceCard)
									   of Link)))
							      (if (NC.CrossFileLinkCardP SrcCard)
								  then (OR (
								      NC.GetCrossFileLinkDestCard
										 SrcCard)
									       SrcCard)
								else SrcCard))))))
				     then (SETQ DestID (NC.GetBrowserNodeID GraphCard 
										  SourceCard))
					    (SETQ DestVisitedFlg (NC.GraphNodeIDGetProp
						DestID
						(QUOTE VisitedFlg)))
					    (SETQ DestTouchedFlg (NC.GraphNodeIDGetProp
						DestID
						(QUOTE TouchedFlg)))
					    (SETQ OtherWayLinkFlg (NC.LinkLabelP Link 
										 ListOfLinkLabels)))
				when ThisWayLinkFlg unless (AND DestVisitedFlg OtherWayLinkFlg)
				collect 

          (* Crush the dest node's prop list if it's never been touched. But if dest node is a fringe node for this search, 
	  don't have to clear the whole proplist.)


					  (if (NOT DestTouchedFlg)
					      then (if (EQ 1 RemainingSearchDepth)
							 then (NC.GraphNodeIDRemProp DestID 
										      GraphNodeID)
						       else (NC.SmashGraphNodeIDProps DestID)
							      (NC.GraphNodeIDPutProp DestID
										       (QUOTE
											 TouchedFlg)
										       T)))
                                                             (* Record presence of this link.)
					  (NC.UIDAddProp DestID GraphNodeID (fetch (Link Label)
										 of Link)
							   T)
					  DestID)))
		  (SETQ DestinationIDs (DREMOVE (NC.GetBrowserNodeID GraphCard GraphCard)
						    (INTERSECTION DestinationIDs DestinationIDs)))
	       else (SETQ DestinationIDs NIL))
	     (NC.GraphNodeIDPutProp GraphNodeID (QUOTE VisitedFlg)
				      T)

          (* * Create new node and add to graph unless we're working on a node already in the graph.)


	     (if (SETQ GraphNode (FASSOC GraphNodeID CurrentGraph))
		 then                                      (* If node is in graph, but we won't expand further, 
							     then leave it's destination IDs alone.)
			(AND (GREATERP RemainingSearchDepth 0)
			       (replace (GRAPHNODE TONODES) of GraphNode with DestinationIDs))
	       else (SETQ CurrentGraph
			(NCONC CurrentGraph
				 (LIST (create GRAPHNODE
						   NODEID ← GraphNodeID
						   TONODES ← DestinationIDs
						   NODELABEL ← Card)))))

          (* * Attach new IDs to end of queue.)


	     (for DestinationID in DestinationIDs bind DestCard
		eachtime (BLOCK)
			   (SETQ DestCard (NC.CardFromBrowserNodeID DestinationID))
		unless (OR (NC.GraphNodeIDGetProp DestinationID (QUOTE VisitedFlg))
			       (for CardAndDepth in (CAR CardsAndDepthsQueue) eachtime
										     (BLOCK)
				  thereis (NC.SameCardP DestCard (CAR CardAndDepth))))
		do (SETQ CardsAndDepthsQueue (TCONC CardsAndDepthsQueue (CONS DestCard
										      (SUB1 
									     RemainingSearchDepth)))))
	   )
     CurrentGraph)))

(NC.MakeBrowserCard
  (LAMBDA (Card Title NoDisplayFlg ParamList)                (* rht: " 4-Jun-87 11:49")

          (* Make a browser card with id Card using root at RootID and the link following predictae specified by Predicate.
	  IF Root and/or ListOfLinkLabels not specified, ask the user.)



          (* * rht 8/3/84: Changed to call NC.AskLinkLabel with its ReverseLinkLabel parameter set to T.)



          (* * fgh 10/2/84 Changed Link Icons to be image objects in NodeLabel of Graph Npodes rather than annotations on 
	  graph nodes.)



          (* * rht 10/19/84: Fixed setting up of browser card's prop list in case NoDisplayFlg is T so we have no Window.
	  Now NC.MakeLinksLegend returns the label pairs.)



          (* * rht 11/27/84: Removed the WINDOWADDPROP call to put NC.GraphCardCloseFn on the CLOSEFN of the window.
	  This causes trouble. NC.QuitCard will get put on by NC.MakeNoteCard and that's enough.)



          (* * rht 1/3/85: Now puts a dummy region of the right size if the NoDisplayFlg is on.)



          (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.)



          (* * rht 2/14/85: Added VerticalFlg and made BrowserSpecs get put on browser's proplist in all cases.)



          (* * rht 4/1/85: Now calls NC.AskBrowserSpecs with additional Don'tAskFlg in case of call from Programmer's 
	  interface.)



          (* * rht 11/17/85: Updated to handle new card and notefile objects.)



          (* * rht 2/7/86: Now gets browser format, etc. via fetch/set fns.)



          (* * rht 5/6/86: Took out call to NC.SetupTitleBarMenu.)



          (* * rht 5/8/86: Added calls to rig title bar properly.)



          (* * rht 7/10/86: Now passes ListOfLinkLabels to NC.AskBrowserSpecs.)



          (* * rht 9/19/86: Mod to above fix. Now calls NC.MakeNewCardWindow a new fn that creates window and hangs Card off 
	  windowprop.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection. Also added GLOBALVARS 
	  statement.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a 
	  standin for a cross file link icon.)



          (* * rg 3/18/87 added NC.CardSelectionOperation wrapper)



          (* * rht 3/20/87: Removed needless call to NC.ActivateCard.)



          (* * rg 4/2/87 changed wrapper to NCP.WithLockedCards and added NC.IfAllCardsFree wrapper)



          (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when 
	  GrowLinkLattice wasn't able to follow into the remote notefile.)


    (DECLARE (GLOBALVARS NC.SubBoxLinkLabel NC.BrowserContentsLinkLabel NC.SpecialBrowserSpecsFlg 
			     NC.*Graph*BrowserFormat NC.SelectingBrowserSourceMenu))
    (NCP.WithLockedCards
      (PROG ((RootCards (MKLIST (LISTGET ParamList (QUOTE ROOTCARDS))))
	       (ListOfLinkLabels (LISTGET ParamList (QUOTE LINKTYPES)))
	       (BrowserFormat (LISTGET ParamList (QUOTE FORMAT)))
	       (Depth (LISTGET ParamList (QUOTE DEPTH)))
	       (CardType (NC.RetrieveType Card))
	       Lattice RootNodes Window Graph SpecialBrowserSpecs BrowserSpecs DropVirtualNodesFlg)
	      (NC.IfAllCardsFree
		(NC.LockListOfCards RootCards "Make Browser Card")
		(COND
		  ((NULL NoDisplayFlg)
		    (SETQ Window (NC.MakeNewCardWindow Card (OR Title "Untitled")))
		    (WINDOWADDPROP Window (QUOTE SHRINKFN)
				     (FUNCTION NC.GraphCardShrinkFn))))
		(if (NULL RootCards)
		    then (SETQ RootCards (if NoDisplayFlg
						 then (LIST NIL)
					       else (NC.SelectNoteCards NIL NIL 
								    NC.SelectingBrowserSourceMenu 
									    Window 
		      "Please shift-select the Cards and/or Boxes the browser should start from."
									    T))))
		(COND
		  ((EQ RootCards (QUOTE DON'T))
		    (NC.DeactivateCard Card)
		    (CLOSEW Window)
		    (RETURN)))
		(NC.HoldTTYProcess)
		(SETQ BrowserSpecs (NC.AskBrowserSpecs Window Card ListOfLinkLabels Depth 
							   BrowserFormat T (if (OR ParamList 
										     NoDisplayFlg)
									       then (QUOTE 
											  DONTASK))))
		(COND
		  ((NULL BrowserSpecs)
		    (NC.DeactivateCard Card)
		    (CLOSEW Window)
		    (RETURN)))
		(SETQ ListOfLinkLabels (CAR BrowserSpecs))
		(SETQ Depth (CADR BrowserSpecs))
		(SETQ BrowserFormat (CADDR BrowserSpecs))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
		(if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		    then (SETQ DropVirtualNodesFlg T))
		(SETQ SpecialBrowserSpecs (COND
		    (NC.SpecialBrowserSpecsFlg (NC.AskSpecialBrowserSpecs Window))
		    (T (create SPECIALBROWSERSPECS))))
		(OR NoDisplayFlg (NC.PrintMsg Window T (CHARACTER 13)
						  "Computing browser graph. Please wait. ..."))
                                                             (* Create new browser hash array)
		(NC.GetBrowserHashArray Card)              (* Compute lattice breakdth-first starting from 
							     roots.)
		(SETQ Lattice (NC.GrowLinkLattice RootCards NIL ListOfLinkLabels Card Depth))
		(SETQ RootNodes (for RootCard in RootCards collect (NC.GetBrowserNodeID
									     Card RootCard)))
		(OR NoDisplayFlg (WINDOWPROP Window (QUOTE NoteCardObject)
						 Card))

          (* * Link destination id information stored in NodeLabel field into a LinkIcon for display)


		(for Node in Lattice bind NodeID (CrossFileLinkModePropList
						  ←(LIST (fetch (Card NoteFile) of Card)
							   NIL))
		   eachtime (BLOCK)
		   do (replace (GRAPHNODE NODELABEL) of Node
			   with (LET (NewLink)
				       (if (AND (NOT (NC.CrossFileLinkCardP
							     (fetch (GRAPHNODE NODELABEL)
								of Node)))
						    (SETQ NewLink
						      (NC.MakeLink Window 
								     NC.BrowserContentsLinkLabel
								     (fetch (GRAPHNODE NODELABEL)
									of Node)
								     Card NIL NIL NIL NIL NIL
								     (NC.ComputeCrossFileLinkMode
								       (fetch (GRAPHNODE NODELABEL)
									  of Node)
								       CrossFileLinkModePropList 
								       Window))))
					   then (NC.MakeLinkIcon NewLink)
					 else (NC.MakeCrossFileLinkIconStandIn
						  (fetch (GRAPHNODE NODELABEL) of Node)))))
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
			(SETQ NodeID (fetch (GRAPHNODE NODEID) of Node))
			(NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID)
						 (QUOTE TouchedFlg))
			(NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID)
						 (QUOTE VisitedFlg)))
		(SETQ Graph (if (AND Lattice RootNodes)
				  then (LAYOUTGRAPH Lattice RootNodes (SUBST (QUOTE LATTICE)
										   
									  NC.*Graph*BrowserFormat 
										   BrowserFormat)
							(fetch (SPECIALBROWSERSPECS Font)
							   of SpecialBrowserSpecs)
							(fetch (SPECIALBROWSERSPECS MotherD)
							   of SpecialBrowserSpecs)
							(fetch (SPECIALBROWSERSPECS PersonalD)
							   of SpecialBrowserSpecs)
							(fetch (SPECIALBROWSERSPECS FamilyD)
							   of SpecialBrowserSpecs))
				else (create GRAPH)))
		(NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
								       DropVirtualNodesFlg))
		(OR NoDisplayFlg (NC.PrintMsg Window NIL "Done!"))
		(NC.SetSubstance Card Graph)
		(NC.SetBrowserLinkLabels Card (OR ListOfLinkLabels (LIST NC.SubBoxLinkLabel)))
		(NC.SetBrowserRoots Card RootCards)
		(NC.SetBrowserFormat Card BrowserFormat)
		(NC.SetBrowserDepth Card Depth)
		(NC.SetSpecialBrowserSpecs Card SpecialBrowserSpecs)
		(COND
		  (NoDisplayFlg (RETURN Card)))
		(WINDOWPROP Window (QUOTE GRAPH)
			      Graph)
		(NC.InstallTitleBarLeftMenu Window CardType)
		(NC.InstallTitleBarMiddleMenu Window CardType)
		(NC.RelayoutBrowserCard Window)
		(RETURN Window))))))

(NC.UpdateBrowserCard
  (LAMBDA (Window)                                           (* rht: " 4-Jun-87 11:50")

          (* * rht 10/14/84: Added call to DETACHALLWINDOWS to close any existing links legend window and prompt window.
	  Also added call to NC.MakeLinksLegend to make a new attached legend menu.)



          (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.)



          (* * rht 2/14/85: Added ability to respecify roots and link labels before recomputing graph.)



          (* * rht 3/8/85: Modified to use new browser props stored on card's proplist as of release 1.2.)



          (* * rht 3/17/85: Now takes OnlyLayoutFlg argument. If set, then don't recompute lattice or ask about root nodes.)



          (* * rht 11/17/85: updated to handle new card and notefile objects.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.)



          (* * rht 3/7/86: Now only closes the Links legend menu attached window.)



          (* * rht 6/10/86: Moved code to delete links legend menu and code to make new browser hash array to after 
	  questioning user about respecifying roots.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a 
	  standin for a cross file link icon.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)



          (* * rg 3/18/87 added NC.CardSelectionOperation wrapper)



          (* * rht 3/19/87: Fixed the part that calls NC.MakeLink so it really only rebuilds links if they've changed.)



          (* * rg 4/1/87 changed CANCELLED to DON'T)



          (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when 
	  GrowLinkLattice wasn't able to follow into the remote notefile.)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Recompute Browser Card" NIL
	   (NCP.WithLockedCards
	     (PROG (LinkLabels RootCards RootNodes Lattice LinkIcon Graph GraphNodes NodeLabel 
				 BrowserSpecs BrowserFormat DropVirtualNodesFlg Depth 
				 SpecialBrowserSpecs OldLabelNodes OldRootCards)
		     (SETQ RootCards (NC.FetchBrowserRoots Card))
		     (NC.IfAllCardsFree
		       (NC.LockListOfCards RootCards "Update Browser Card")
		       (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
		       (SETQ BrowserFormat (OR (NC.FetchBrowserFormat Card)
						   (QUOTE (LATTICE))))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
		       (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
			   then (SETQ DropVirtualNodesFlg T))
		       (SETQ Depth (OR (NC.FetchBrowserDepth Card)
					   999999))
		       (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card)
							 (create SPECIALBROWSERSPECS)))
		       (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									     (WINDOWPROP
									       Window
									       (QUOTE GRAPH)))))
                                                             (* Get new roots.)
		       (if (OR (NULL RootCards)
				   (NC.AskYesOrNo "Want to respecify roots? " "--" "No" T Window T 
						    NIL))
			   then (NC.BrowserFlipRoots Window Card GraphNodes (SETQ OldRootCards 
							   RootCards))
				  (SETQ RootCards (NC.SelectNoteCards NIL NIL 
								    NC.SelectingBrowserSourceMenu 
									  Window (CONCAT
									    
		      "Please shift-select the Cards and/or Boxes the browser should start from."
									    (CHARACTER 13)
									    
							       "(Current roots are highlighted.)")
									  T))
				  (NC.BrowserFlipRoots Window Card GraphNodes OldRootCards)
				  (COND
				    ((EQ RootCards (QUOTE DON'T))
				      (RETURN))))          (* Get rid of the links legend menu attached window.)
		       (for Win in (ATTACHEDWINDOWS Window) when (WINDOWPROP Win
										       (QUOTE
											 
										  LINKSLEGENDWINP))
			  do (DETACHWINDOW Win)
			       (CLOSEW Win))               (* Smash the current hash array, putting a fresh one 
							     in its place.)
		       (NC.GetBrowserHashArray Card)
		       (NC.PrintMsg Window T (CHARACTER 13)
				      "Computing browser graph. Please wait. ...")
                                                             (* Compute lattice breadth-first from the roots.)
		       (SETQ Lattice (NC.GrowLinkLattice RootCards NIL LinkLabels Card Depth))
		       (SETQ RootNodes (for RootCard in RootCards collect (
									      NC.GetBrowserNodeID
										    Card RootCard)))
		       (NC.SetPropListDirtyFlg Card T)     (* Remove all links that are in the old browser graph 
							     but not in the new one)
		       (for Node in GraphNodes eachtime (BLOCK)
			  unless (for LatticeNode in Lattice bind (CardForNode
									    ←(
									 NC.CardFromBrowserNodeID
									      (
									   NC.CoerceToGraphNodeID
										Node)))
				      thereis (NC.SameCardP CardForNode (
								  NC.CardFromBrowserNodeID
								  (NC.CoerceToGraphNodeID 
										      LatticeNode))))
			  do (LET ((NodeLabel (fetch (GRAPHNODE NODELABEL) of Node)))
				    (COND
				      ((NC.LinkIconImageObjP NodeLabel)
					(NC.DeleteLink (NC.FetchLinkFromLinkIcon NodeLabel)
							 T T))
				      ((STRINGP NodeLabel)
                                                             (* Collect the label nodes from the old browser.)
					(SETQ OldLabelNodes (CONS Node OldLabelNodes))))))
                                                             (* Create Links for all nodes in the new browser graph
							     but not in the old one.)
		       (for Node in Lattice eachtime (BLOCK)
			  bind (CrossFileLinkModePropList ←(LIST (fetch (Card NoteFile)
									of Card)
								     NIL))
			  do
			   (LET ((NodeID (fetch (GRAPHNODE NODEID) of Node))
				 (OldNode (for GraphNode in GraphNodes
					     bind (CardForNode ←(NC.CardFromBrowserNodeID
								   (NC.CoerceToGraphNodeID Node)))
					     when (NC.SameCardP CardForNode (
								      NC.CardFromBrowserNodeID
								      (NC.CoerceToGraphNodeID
									GraphNode)))
					     do (RETURN GraphNode))))
			        (if OldNode
				    then (replace (GRAPHNODE NODELABEL) of Node
					      with (fetch (GRAPHNODE NODELABEL) of OldNode))
				  else
				   (replace (GRAPHNODE NODELABEL) of Node
				      with
				       (LET (NewLink)
					    (if (AND (NOT (NC.CrossFileLinkCardP
								  (fetch (GRAPHNODE NODELABEL)
								     of Node)))
							 (SETQ NewLink
							   (NC.MakeLink Window 
								      NC.BrowserContentsLinkLabel
									  (fetch (GRAPHNODE 
											NODELABEL)
									     of Node)
									  Card NIL NIL NIL NIL NIL
									  (
								      NC.ComputeCrossFileLinkMode
									    (fetch (GRAPHNODE
										       NODELABEL)
									       of Node)
									    CrossFileLinkModePropList 
									    Window))))
						then (NC.MakeLinkIcon NewLink)
					      else (NC.MakeCrossFileLinkIconStandIn
						       (fetch (GRAPHNODE NODELABEL) of Node))))))
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
			        (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg))
			        (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg))))
                                                             (* Throw in the label nodes from the old browser.)
		       (SETQ Lattice (NCONC Lattice OldLabelNodes))
                                                             (* For each old label node, take away nonexistent 
							     fromnodes and save the label nodes that no longer have
							     any from nodes.)
		       (for OldLabelNode in OldLabelNodes eachtime (BLOCK)
			  do (replace (GRAPHNODE FROMNODES) of OldLabelNode
				  with (for FromNodeID in (fetch (GRAPHNODE FROMNODES)
								   of OldLabelNode)
					    bind FromNode eachtime (BLOCK)
					    when (SETQ FromNode (FASSOC FromNodeID Lattice))
					    collect        (* If the From node isn't a label node, then add to 
							     its Tonode list.)
						      (if (NC.LinkIconImageObjP
							      (fetch (GRAPHNODE NODELABEL)
								 of FromNode))
							  then (replace (GRAPHNODE TONODES)
								    of FromNode
								    with
								     (CONS (fetch (GRAPHNODE
											NODEID)
										of OldLabelNode)
									     (fetch (GRAPHNODE
											TONODES)
										of FromNode))))
						      FromNodeID))
                                                             (* For the old label node's ToNodes, just need to 
							     remove any for ToNodes that no longer exist.)
			       (replace (GRAPHNODE TONODES) of OldLabelNode
				  with (for ToNodeID in (fetch (GRAPHNODE TONODES)
								 of OldLabelNode)
					    bind ToNode eachtime (BLOCK)
					    when (SETQ ToNode (FASSOC ToNodeID Lattice))
					    collect        (* If the To node isn't a label node, then add to its 
							     FromNode list.)
						      (if (NC.LinkIconImageObjP
							      (fetch (GRAPHNODE NODELABEL)
								 of ToNode))
							  then (replace (GRAPHNODE FROMNODES)
								    of ToNode
								    with
								     (CONS (fetch (GRAPHNODE
											NODEID)
										of OldLabelNode)
									     (fetch (GRAPHNODE
											FROMNODES)
										of ToNode))))
						      ToNodeID)))
                                                             (* Layout graph, including as roots any non-virtual 
							     nodes with no from nodes to avoid disconnected 
							     graphs.)
		       (SETQ Graph (if (AND Lattice RootNodes)
					 then (LAYOUTGRAPH
						  Lattice
						  (for Node in Lattice bind NodeID
						     eachtime (BLOCK)
								(SETQ NodeID
								  (OR (NC.CoerceToGraphNodeID
									  Node)
									(fetch (GRAPHNODE NODEID)
									   of Node)))
						     when (OR (FMEMB NodeID RootNodes)
								  (NULL (fetch (GRAPHNODE 
											FROMNODES)
									     of Node)))
						     collect NodeID)
						  (SUBST (QUOTE LATTICE)
							   NC.*Graph*BrowserFormat BrowserFormat)
						  (fetch (SPECIALBROWSERSPECS Font) of 
									      SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS MotherD)
						     of SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS PersonalD)
						     of SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS FamilyD)
						     of SpecialBrowserSpecs))
				       else (create GRAPH)))
                                                             (* Build links legend and fix up TONODES in the 
							     graph.)
		       (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									      DropVirtualNodesFlg))
		       (NC.SetBrowserRoots Card RootCards)
		       (NC.SetBrowserDepth Card Depth)
		       (WINDOWPROP Window (QUOTE GRAPH)
				     Graph)
		       (NC.RelayoutBrowserCard Window))))))))

(NC.ExpandBrowserNode
  (LAMBDA (Window)                                           (* rht: " 4-Jun-87 11:50")

          (* * Ask user to choose a node in the browser and recompute the part of the lattice under that node to the given 
	  depth. And relayout the graph. The code is just a modification of the NC.UpdateBrowserCard code.)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.)



          (* * rht 6/10/86: No longer does relayout after expand. Uses NC.LayoutNewBrowserNodes to compute proper locations 
	  of new nodes. Also calls NC.ShowBrowserGraph.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)



          (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when 
	  GrowLinkLattice wasn't able to follow into the remote notefile.)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Expand Node of Browser Card" NIL
	   (PROG (NodeToExpand LinkLabels RootCards RootNodes Lattice LinkIcon OldToNodePairs Graph 
				 GraphNodes NodeLabel OldNode Link BrowserSpecs BrowserFormat 
				 DropVirtualNodesFlg Depth SpecialBrowserSpecs SavedLabelNodes 
				 NewNodes)
	           (SETQ RootCards (NC.FetchBrowserRoots Card))
	           (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
	           (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
	           (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		       then (SETQ DropVirtualNodesFlg T))
	           (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card)
						     (create SPECIALBROWSERSPECS)))
	           (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH)))))
                                                             (* If there aren't any nodes in graph, then get out 
							     pronto.)
	           (if (NULL GraphNodes)
		       then (NC.PrintMsg Window T "No nodes to expand.")
			      (DISMISS 1000)
			      (NC.ClearMsg Window T)
			      (RETURN NIL))                (* Create hash array if haven't already.)
	           (NC.GetBrowserHashArray Card Graph)
	           (NC.PrintMsg Window T "Pick node to expand." (CHARACTER 13))
                                                             (* Note call to the grapher function READ/NODE to 
							     select a graph node.)
	           (SETQ NodeToExpand (READ/NODE GraphNodes Window))
                                                             (* Can't expand a label node.)
	           (if (NOT (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of 
										     NodeToExpand)))
		       then (NC.PrintMsg NIL T "Sorry, can't expand a label node.")
			      (FLASHW PROMPTWINDOW)
			      (NC.ClearMsg Window T)
			      (RETURN))
	           (SETQ Depth (MKATOM (NC.AskUser "Depth to expand (type integer or INF): " 
							 "--"
							 1 T Window NIL NIL T)))
	           (COND
		     ((EQ Depth (QUOTE INF))
		       (SETQ Depth MAX.FIXP))
		     ((NOT (AND (FIXP Depth)
				    (GREATERP Depth 0)))
		       (NC.PrintMsg Window T "Depth must be an integer greater than 0 or INF.")
		       (RETURN)))
	           (NC.PrintMsg Window T (CHARACTER 13)
				  "Augmenting browser graph. Please wait. ...")
                                                             (* Save the nodes pointed to by the chosen node that 
							     are label nodes. GrowLinkLattice will trash those, so 
							     we restore afterwards.)
	           (SETQ SavedLabelNodes (for ToNode in (fetch (GRAPHNODE TONODES)
								 of NodeToExpand)
					      eachtime (BLOCK)
					      when (AND (NOT (EQ (CAR ToNode)
									 LINKPARAMS))
							    (NOT (NC.LinkIconImageObjP ToNode)))
					      collect ToNode))
                                                             (* Increase link lattice from chosen node to given 
							     depth.)
	           (SETQ Lattice (NC.GrowLinkLattice (LIST (NC.CardFromBrowserNodeID
								   (fetch (GRAPHNODE NODEID)
								      of NodeToExpand)))
							 (APPEND GraphNodes)
							 LinkLabels Card Depth))
	           (AND SavedLabelNodes (replace (GRAPHNODE TONODES) of NodeToExpand
					     with (APPEND SavedLabelNodes (fetch (GRAPHNODE
											 TONODES)
										 of NodeToExpand))))
	           (SETQ RootNodes (for RootCard in RootCards collect (NC.GetBrowserNodeID
										Card RootCard)))
	           (NC.SetPropListDirtyFlg Card T)         (* Create Links for all nodes in the new browser graph
							     but not in the old one.)
	           (for Node in Lattice bind NodeID (CrossFileLinkModePropList
						     ←(LIST (fetch (Card NoteFile) of Card)
							      NIL))
		      do (COND
			     ((SETQ OldNode (FASSOC (SETQ NodeID (OR (NC.CoerceToGraphNodeID
									       Node)
									     (fetch (GRAPHNODE
											NODEID)
										of Node)))
							GraphNodes))
			       (replace (GRAPHNODE NODELABEL) of Node with (fetch
										   (GRAPHNODE 
											NODELABEL)
										    of OldNode)))
			     (T (replace (GRAPHNODE NODELABEL) of Node
				   with (LET (NewLink)
					       (if (AND (NOT (NC.CrossFileLinkCardP
								     (fetch (GRAPHNODE NODELABEL)
									of Node)))
							    (SETQ NewLink
							      (NC.MakeLink
								Window NC.BrowserContentsLinkLabel
								(fetch (GRAPHNODE NODELABEL)
								   of Node)
								Card NIL NIL NIL NIL NIL
								(NC.ComputeCrossFileLinkMode
								  (fetch (GRAPHNODE NODELABEL)
								     of Node)
								  CrossFileLinkModePropList Window))))
						   then (NC.MakeLinkIcon NewLink)
						 else (NC.MakeCrossFileLinkIconStandIn
							  (fetch (GRAPHNODE NODELABEL)
							     of Node)))))
                                                             (* Make a list of all new nodes.)
				(push NewNodes Node)))     (* Throw away virtual node info.)
			   (AND NodeID (replace (GRAPHNODE NODEID) of Node with NodeID)) 
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
			   (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg))
			   (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg)) 
                                                             (* Smash all the unnecessary junk off existing nodes, 
							     letting LAYOUTGRAPH and NC.MakeLinksLegend recompute.)
			   (replace (GRAPHNODE TONODES) of Node
			      with (for ToNode in (fetch (GRAPHNODE TONODES) of Node)
					bind ToNodeID eachtime (BLOCK)
					collect (if (SETQ ToNodeID (NC.CoerceToGraphNodeID
							    ToNode))
						      then 
                                                             (* Throw away link parameterlist info.)
                                                             (* Throw away link dashing info.)
							     (NC.GraphNodeIDPutProp
							       NodeID ToNodeID
							       (for LabelPair
								  in (NC.GraphNodeIDGetProp
									 NodeID ToNodeID)
								  collect (OR (CAR LabelPair)
										  LabelPair)))
							     (NC.GraphNodeIDPutProp
							       ToNodeID NodeID
							       (for LabelPair
								  in (NC.GraphNodeIDGetProp
									 ToNodeID NodeID)
								  collect (OR (CAR LabelPair)
										  LabelPair)))
							     ToNodeID
						    else ToNode))))
                                                             (* LAYOUTGRAPH doesn't like duplicate nodes.
							     These get created when virtual nodes are turned into 
							     regular nodes.)
	           (SETQ Lattice (NC.RemoveDuplicateNodesFromGraph Lattice))
	           (NC.RebuildFromNodesInGraph Lattice)
	           (AND NewNodes (NC.LayoutNewBrowserNodes NodeToExpand NewNodes BrowserFormat 
							       SpecialBrowserSpecs))
	           (replace (GRAPH GRAPHNODES) of Graph with Lattice)
                                                             (* Build links legend and fix up TONODES in the 
							     graph.)
	           (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									  DropVirtualNodesFlg))
	           (WINDOWPROP Window (QUOTE GRAPH)
				 Graph)                      (* Display the graph.)
	           (NC.ShowBrowserGraph Graph Window)
	           (NC.SetSubstance Card Graph)
	           (NC.MarkCardDirty Card)
	           (NC.ClearMsg Window T))))))

(NC.ConnectNodesInBrowser
  (LAMBDA (Window)                                           (* rht: "29-May-87 00:13")

          (* * Draw any links, from the current link set, between any pairs of nodes currently being shown in the browser.)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns. Also fixed one last old call to 
	  GETPROPLIST on a NodeID.)



          (* * rht 3/2/86: Added WINDOWPROP for SCROLLFN and RESHAPEFN.)



          (* * fgh 5/21/86 Updated reinstallation of title bar menus after SHOWGRAPH to use new title bar menu mechanism.)



          (* * rht 6/10/86: Now calls NC.ShowBrowserGraph.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)



          (* * rht 5/28/87: Modified to handle cross-file links.)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Reconnect Browser Card" NIL
	   (PROG (LinkLabels Graph GraphNodes BrowserFormat DropVirtualNodesFlg NodeIDs)
	           (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
	           (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
	           (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		       then (SETQ DropVirtualNodesFlg T))
	           (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH)))))
                                                             (* Create hash array if haven't already.)
	           (NC.GetBrowserHashArray Card Graph)     (* check graph node size against image box size.)
	           (NC.GraphLinkIconUpdateCheck Card Window Graph NIL)
                                                             (* These are the workhorse loops that rebuild the 
							     TONODES of each nonvirtual node.)
                                                             (* First smash all the nodeID's proplists and 
							     accumulate nodeIDs.)
	           (SETQ NodeIDs (for Node in GraphNodes bind NodeID eachtime (BLOCK)
				      when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL)
									of Node))
				      collect (NC.SmashGraphNodeIDProps (SETQ NodeID
									      (
									   NC.CoerceToGraphNodeID
										Node)))
						NodeID))     (* Throw away duplicates obtained from virtual nodes.)
	           (SETQ NodeIDs (INTERSECTION NodeIDs NodeIDs))

          (* Next accumulate all linktypes on the from node's proplist using the To node's graphnodeID as prop name.
	  We do the analogous thing for backward links, but notice that we ignore backward linktypes that also appear in the 
	  list in their forward version.)


	           (for NodeID in NodeIDs bind RealCard
		      do (for Link in (NC.RetrieveToLinks (SETQ RealCard (
								      NC.CardFromBrowserNodeID
								      NodeID)))
			      bind DestNodeID eachtime (BLOCK) when (NC.LinkLabelP Link 
										       LinkLabels)
			      when (LET ((DestCard (fetch (Link DestinationCard) of Link)))
				          (SETQ DestNodeID (NC.GetBrowserNodeID
					      Card
					      (if (NC.CrossFileLinkCardP DestCard)
						  then (OR (NC.GetCrossFileLinkDestCard 
											 DestCard 
											   Window)
							       DestCard)
						else DestCard)))
				          (SETQ DestNodeID (for ID in NodeIDs
								when (NC.SameUIDP DestNodeID ID)
								do (RETURN ID))))
			      do (NC.UIDAddProp NodeID DestNodeID (fetch (Link Label)
									 of Link)
						    T))
			   (for Link in (NC.RetrieveFromLinks RealCard) bind SourceNodeID
			      eachtime (BLOCK) when (AND (NC.ReverseLinkLabelP Link 
										       LinkLabels)
								 (NOT (NC.LinkLabelP Link 
										       LinkLabels)))
			      when (LET ((SourceCard (fetch (Link SourceCard) of Link)))
				          (SETQ SourceNodeID (NC.GetBrowserNodeID
					      Card
					      (if (NC.CrossFileLinkCardP SourceCard)
						  then (OR (NC.GetCrossFileLinkDestCard 
										       SourceCard 
											   Window)
							       SourceCard)
						else SourceCard)))
				          (SETQ SourceNodeID (for ID in NodeIDs
								  when (NC.SameUIDP SourceNodeID 
											ID)
								  do (RETURN ID))))
			      do (NC.UIDAddProp SourceNodeID NodeID (fetch (Link Label)
									   of Link)
						    T)))
	           (for Node in GraphNodes bind NodeID OldToNodeIDs eachtime (BLOCK)
		      unless (LISTP (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node)))
		      when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of Node))
		      do                                   (* Accumulate the old NodeIDs, possibly virtual, from 
							     the TONODES list.)
			   (SETQ OldToNodeIDs (for ToNode in (fetch (GRAPHNODE TONODES)
								      of Node)
						   collect (if (EQ (CAR ToNode)
									 LINKPARAMS)
								 then (CADR ToNode)
							       else ToNode)))

          (* The trick here is to use a virtual node for this ToNode if one was used before, otherwise just the ToNodeID.
	  Also throw in the label nodes that were in the TONODES list before.)


			   (replace (GRAPHNODE TONODES) of Node
			      with (NCONC (for ToNodeID on (
							 NC.ComputeBrowserSavedLinkingInfoForNode
								     NodeID)
						 by (CDDR ToNodeID) eachtime (BLOCK)
						 collect (OR (for OldToNodeID in OldToNodeIDs
								    thereis
								     (AND (LISTP OldToNodeID)
									    (EQ (CAR ToNodeID)
										  (CAR OldToNodeID))
									    OldToNodeID))
								 (CAR ToNodeID)))
					      (for ToNodeID in OldToNodeIDs eachtime (BLOCK)
						 unless (NC.SameCardP Card (
									 NC.CardFromBrowserNodeID
									    (NC.CoerceToGraphNodeID
									      ToNodeID)))
						 collect ToNodeID))))
	           (NC.RebuildFromNodesInGraph GraphNodes)
	           (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									  DropVirtualNodesFlg))
                                                             (* Display the graph.)
	           (NC.ShowBrowserGraph Graph Window)
	           (NC.SetSubstance Card (WINDOWPROP Window (QUOTE GRAPH)))
	           (NC.MarkCardDirty Card)
	           (NC.ClearMsg Window T))))))

(NC.DelBrowserContentsLink
  (LAMBDA (GraphCard DestCard)                               (* rht: "26-May-87 01:52")

          (* * Delete the browsercontents link connecting GraphCard and DestID.)



          (* * rht 11/17/85: updated to handle new card and notefile formats.)



          (* * rht 4/30/86: Now checks to make sure there's a link to delete.)



          (* * rht 5/26/87: Now handles cross-file browsercontents links.)


    (LET ((Links (NCP.GetLinks GraphCard DestCard NC.BrowserContentsLinkLabel)))
         (if (CDR Links)
	     then (NC.ReportError "NC.DelBrowserContentsLink" (CONCAT 
						       "Multiple browser contents links between "
									    (NC.FetchTitle 
											GraphCard)
									    " and "
									    (NC.FetchTitle DestCard)
									    ))
		    NIL)
         (if Links
	     then (NC.DeleteLink (CAR Links)
				     NIL T)
	   else                                            (* Could be that it's a cross file browsercontents 
							     link.)
		  (for Link in (NCP.GetLinks GraphCard NIL NC.BrowserContentsLinkLabel)
		     bind CrossFileLinkCard (DestCardUID ←(fetch (Card UID) of DestCard))
		     when (AND (NC.CrossFileLinkCardP (SETQ CrossFileLinkCard
							      (fetch (Link DestinationCard)
								 of Link)))
				   (NC.SameUIDP DestCardUID (fetch (CrossFileLinkSubstance 
									 CrossFileLinkDestCardUID)
								 of (NCP.CardSubstance 
										CrossFileLinkCard))))
		     do (RETURN (NC.DeleteLink Link T T)))))))
)
(DEFINEQ

(NC.GetBrowserHashArray
  (LAMBDA (BrowserCard Graph)                                (* rht: "10-Jun-87 22:41")

          (* * Build and install a hash array mapping cards to browsernode UIDs, unless one's already there.
	  If Graph argument is nil, then make a new hash array smashing any existin one.)



          (* * rht 4/30/86: Now makes sure we're not working with a label node instead of a card node.)



          (* * rht 6/1/87: Changed hash array to map from card UIDs to graph node ids rather than from card objects to graph 
	  node ids.)



          (* * rht 6/10/87: Now checks that CardObject on GraphNodeID is valid card before stashing in hash array.)


    (DECLARE (GLOBALVARS NC.BrowserHashArraySize))
    (if (AND Graph (NC.HashArrayFromBrowserCard BrowserCard))
      else (LET ((HashArray (NC.CreateUIDHashArray NC.BrowserHashArraySize)))
	          (NC.SetUserDataProp BrowserCard (QUOTE BrowserHashArray)
					HashArray)
	          (AND Graph (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph)
				  bind GraphNodeID eachtime (BLOCK) when (SETQ GraphNodeID
										   (
									   NC.CoerceToGraphNodeID
										     GraphNode))
				  do (LET ((CardObject (NC.GraphNodeIDGetProp GraphNodeID
										  (QUOTE CardObject)
										  )))
					    (if (NC.ValidCardP CardObject)
						then (PUTHASH (fetch (Card UID) of CardObject)
								  GraphNodeID HashArray)))))))))

(NC.GetBrowserNodeID
  (LAMBDA (BrowserCard NodeCard)                             (* rht: " 1-Jun-87 21:42")

          (* * Create a browser node atom from a new UID. Hang the card object off as a property for those who need it.)



          (* * rht 11/18/85: Now checks to see if NodeCard already appears in graph before creating a new GraphNodeID.
	  Use the browser hash array to do the lookup.)



          (* * rht 6/1/87: Changed hash array to map from card UIDs to graph node ids rather than from card objects to graph 
	  node ids.)


    (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard))
	  (NodeCardUID (fetch (Card UID) of NodeCard))
	  NewUID)
         (if (GETHASH NodeCardUID HashArray)
	   else (NC.GraphNodeIDPutProp (SETQ NewUID (NC.MakeBrowserNodeUID))
					   (QUOTE CardObject)
					   NodeCard)
		  (PUTHASH NodeCardUID NewUID HashArray)
		  NewUID))))

(NC.RemoveBrowserNodeHashArrayEntry
  (LAMBDA (BrowserCard NodeCard)                             (* rht: " 1-Jun-87 21:40")

          (* * Remove the entry for given card from given browser's hash array.)



          (* * rht 6/1/87: Now expects hash array to map from card UIDs to graph node ids rather than from card objects to 
	  graph node ids.)


    (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard)))
         (if HashArray
	     then (PUTHASH (fetch (Card UID) of NodeCard)
			       NIL HashArray)))))
)
(PUTPROPS RHTPATCH267 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2857 4863 (NC.CollectReferencesInGraph 2867 . 4861)) (4899 7324 (
NC.CollectReferencesInSketch 4909 . 7322)) (7358 10299 (NC.CollectReferencesInText 7368 . 10297)) (
10331 28389 (NC.ValidLinkP 10341 . 11078) (NC.MakeLink 11080 . 18594) (NC.DeleteFromLink 18596 . 19772
) (NC.DeleteToLink 19774 . 20976) (NC.RelabelLink 20978 . 26331) (NC.FileInOrphanBox 26333 . 28387)) (
28420 39545 (NC.DeleteNoteCardInternal 28430 . 34803) (NC.AssignTitle 34805 . 39543)) (39586 49191 (
NC.OpenCrossFileLinkDestNoteFile 39596 . 42161) (NC.CrossFileLinkPutFn 42163 . 43302) (
NC.CrossFileLinkGetFn 43304 . 44365) (NC.CrossFileLinkEditFn 44367 . 45188) (
NC.GetCrossFileLinkDestCard 45190 . 49189)) (49935 56083 (NC.AskCrossFileLinkMode 49945 . 50935) (
NC.DeleteCrossFileLinkCard 50937 . 51466) (NC.FetchRemoteCrossFileLinkCard 51468 . 52561) (
NC.CheckCrossFileLinkCardTitle 52563 . 53038) (NC.CheckCrossFileLinkType 53040 . 54460) (
NC.MakeCrossFileLinkIconStandIn 54462 . 54898) (NC.ComputeCrossFileLinkMode 54900 . 56081)) (56218 
104935 (NC.GrowLinkLattice 56228 . 65138) (NC.MakeBrowserCard 65140 . 73905) (NC.UpdateBrowserCard 
73907 . 86506) (NC.ExpandBrowserNode 86508 . 96075) (NC.ConnectNodesInBrowser 96077 . 103282) (
NC.DelBrowserContentsLink 103284 . 104933)) (104936 108038 (NC.GetBrowserHashArray 104946 . 106507) (
NC.GetBrowserNodeID 106509 . 107468) (NC.RemoveBrowserNodeHashArrayEntry 107470 . 108036)))))
STOP