(FILECREATED "25-Oct-85 01:15:54" {QV}<NOTECARDS>RELEASE1.2I>NCLINKS.;35 122833 

      changes to:  (FNS NC.InsertLinkBeforeMarker NC.MakeAContentsHook)

      previous date: "20-Oct-85 15:21:31" {QV}<NOTECARDS>RELEASE1.2I>NCLINKS.;34)


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

(PRETTYCOMPRINT NCLINKSCOMS)

(RPAQQ NCLINKSCOMS ((E (SETQ NC.SystemDate (DATE))
		       (PUTPROP (QUOTE NC.SystemDate)
				(QUOTE NewestFile)
				(ROOTFILENAME (FULLNAME (OUTPUT)))))
	(* * Internal variables)
	(GLOBALVARS NC.NoDeleteImageFns NC.SystemLinkLabels NC.InitialLinkLabels NC.SubBoxLinkLabel 
		    NC.FiledCardLinkLabel NC.BrowserContentsLinkLabel NC.ListContentsLinkLabel 
		    NC.SourceLinkLabel NC.UnspecifiedLinkLabel NC.UCASESystemLinkLabels 
		    NC.DocBackPtrLinkLabel NC.LinkIndexBackPtrLinkLabel NC.LinkIconImageFns 
		    NC.LinkIconMiddleButtonMenu NC.LinkDisplayModesStylesheet 
		    MINIMUM.VISIBLE.SCALE.FACTOR DEFAULT.VISIBLE.SCALE.FACTOR TEDIT.DEFAULT.FONT 
		    PSA.Database)
	(VARS (NC.SubBoxLinkLabel (QUOTE SubBox))
	      (NC.FiledCardLinkLabel (QUOTE FiledCard))
	      (NC.BrowserContentsLinkLabel (QUOTE BrowserContents))
	      (NC.ListContentsLinkLabel (QUOTE ListContents))
	      (NC.SourceLinkLabel (QUOTE Source))
	      (NC.UnspecifiedLinkLabel (QUOTE Unspecified))
	      (NC.DocBackPtrLinkLabel (QUOTE DocBackPtr))
	      (NC.LinkIndexBackPtrLinkLabel (QUOTE LinkIndexBackPtr))
	      (NC.SystemLinkLabels (LIST NC.SourceLinkLabel NC.ListContentsLinkLabel 
					 NC.BrowserContentsLinkLabel NC.FiledCardLinkLabel 
					 NC.SubBoxLinkLabel NC.DocBackPtrLinkLabel 
					 NC.LinkIndexBackPtrLinkLabel))
	      (NC.UCASESystemLinkLabels (FOR Label in NC.SystemLinkLabels collect (U-CASE Label)))
	      (NC.InitialLinkLabels (APPEND (QUOTE (Comment Remark Question Rebuttal Argument 
							    Unspecified))
					    NC.SystemLinkLabels)))
	(* * Links mechanism)
	(RECORDS NOTECARDLINK LINKDISPLAYMODE)
	(FNS NC.GlobalLinkP NC.ChildLinkP NC.ContentsLinkP NC.SubContentsLinkP NC.ReverseLinkLabelP 
	     NC.GetNewLinkID NC.MakeGlobalLink NC.AddFromLink NC.AddLinkToGraphCard 
	     NC.AddLinkToSketchCard NC.InsertLinkInSketch NC.AddLinkToTextCard NC.AddLinksToTextCard 
	     NC.InsertLinkInText NC.InsertLinksInText NC.AddSourceLink NC.AddToLink NC.DelFromLink 
	     NC.DelToLink NC.DelReferencesToCard NC.DelReferencesToCardFromGlobalList 
	     NC.DelReferencesToCardFromGraph NC.DelReferencesToCardFromSketch 
	     NC.DelReferencesToCardFromText NC.DeletedLinkDisplayFn NC.DeletedLinkGetFn 
	     NC.DeletedLinkImageBoxFn NC.DeletedLinkPutFn NC.DeletedLinkImageObjP 
	     NC.CheckForOrphanDelete NC.HookToOrphanCard NC.InsertLinkBeforeMarker NC.LinkLabelP 
	     NC.MakeAContentsHook NC.InsertLinkInOrdering NC.IDAlphOrder NC.MakeLink 
	     NC.MakeContentsHooks NC.RelabelLink NC.SystemLinkLabelP NC.ValidLinkP NC.MakeChildLink 
	     NC.SameLinks NC.AddGlobalLinkToCard NC.AddGlobalLinksToCard 
	     NC.ChangeCardTitleFromLinkIcon)
	(* * New Display Mode format)
	(FNS NC.CheckDisplayModeFormat NC.MakeNewDisplayMode NC.DisplayModeFromStylesheetSelections 
	     NC.StylesheetSelectionsFromDisplayMode NC.CheckLinkRecordFormat)
	(GLOBALVARS NC.MenuItems/DisplayModeValues)
	(VARS (NC.MenuItems/DisplayModeValues (QUOTE (Yes T No NIL Float FLOAT Yes T No NIL Float 
							  FLOAT Yes T No NIL Float FLOAT))))
	(* * New fns to support No-Link cards/substances)
	(FNS NC.LinksSupportedP NC.LinkAnchorModesFromType)
	(* * This stuff supports the "push-copy" method of copying links in NC)
	(FNS NC.PushCopyLinkIcon)
	(* * Link display icons)
	(FNS NC.SetLinkInLinkIcon NC.FetchLinkIconForLink NC.MakeLinkIcon NC.LinkIconButtonEventInFn 
	     NC.LinkIconDisplayFn NC.LinkIconImageBoxFn NC.LinkIconImageObjP NC.LinkIconPutFn 
	     NC.LinkIconGetFn NC.LinkIconMiddleButtonFn NC.LinkIconWhenCopiedFn 
	     NC.LinkIconWhenDeletedFn NC.LinkIconWhenInsertedFn NC.LinkIconWhenMovedFn 
	     NC.FetchLinkFromLinkIcon NC.ChangeLinkDisplayMode NC.DefaultLinkDisplayMode 
	     NC.UpdateLinkImages NC.UpdateLinkImagesInGraph NC.UpdateLinkImagesInSketch 
	     NC.UpdateLinkImagesInText NC.LinkIconCopyFn NC.GetTypeIcon NC.LinkAtCharPos 
	     NC.CharPosFromTextObject)
	(FNS NC.FillInLinkIcon NC.InvisibleLinkImageBoxFn NC.InvisibleLinkPutFn NC.InvisibleLinkGetFn)
	(* * New stuff for allowing put to work from TEdit.)
	(GLOBALVARS NC.ExternalPutLinkIconImageFns)
	(VARS (NC.ExternalPutLinkIconImageFns (IMAGEFNSCREATE (FUNCTION 
								  NC.ExternalPutLinkIconDisplayFn)
							      (FUNCTION 
								 NC.ExternalPutLinkIconImageBoxFn)
							      (FUNCTION NC.ExternalPutLinkIconPutFn)
							      (FUNCTION NC.ExternalPutLinkIconGetFn)
							      NIL
							      (FUNCTION NILL))))
	(FNS NC.ExternalPutLinkIconDisplayFn NC.ExternalPutLinkIconImageBoxFn 
	     NC.ExternalPutLinkIconPutFn NC.ExternalPutLinkIconGetFn NC.CoerceToExternalPutLinkIcon)
	(* * Stuff to register our image object for intermezzo.)
	(FNS NC.RegisterPlaceMarkerImageObj)
	(P (NC.RegisterPlaceMarkerImageObj))
	(* * Stuff for handling link icons in sketches.)
	(FNS NC.LinkIconSketchElementP NC.DeleteLinkIconSketchElement)
	(* * Icons representing notecards types.)
	(BITMAPS NC.FileBoxIcon NC.GraphCardIcon NC.SketchCardIcon NC.TextCardIcon NC.TypelessIcon)
	(GLOBALVARS NC.FileBoxIcon NC.GraphCardIcon NC.SketchCardIcon NC.TextCardIcon NC.TypelessIcon)
	))
(* * Internal variables)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.NoDeleteImageFns NC.SystemLinkLabels NC.InitialLinkLabels NC.SubBoxLinkLabel 
	    NC.FiledCardLinkLabel NC.BrowserContentsLinkLabel NC.ListContentsLinkLabel 
	    NC.SourceLinkLabel NC.UnspecifiedLinkLabel NC.UCASESystemLinkLabels 
	    NC.DocBackPtrLinkLabel NC.LinkIndexBackPtrLinkLabel NC.LinkIconImageFns 
	    NC.LinkIconMiddleButtonMenu NC.LinkDisplayModesStylesheet MINIMUM.VISIBLE.SCALE.FACTOR 
	    DEFAULT.VISIBLE.SCALE.FACTOR TEDIT.DEFAULT.FONT PSA.Database)
)

(RPAQQ NC.SubBoxLinkLabel SubBox)

(RPAQQ NC.FiledCardLinkLabel FiledCard)

(RPAQQ NC.BrowserContentsLinkLabel BrowserContents)

(RPAQQ NC.ListContentsLinkLabel ListContents)

(RPAQQ NC.SourceLinkLabel Source)

(RPAQQ NC.UnspecifiedLinkLabel Unspecified)

(RPAQQ NC.DocBackPtrLinkLabel DocBackPtr)

(RPAQQ NC.LinkIndexBackPtrLinkLabel LinkIndexBackPtr)

(RPAQ NC.SystemLinkLabels (LIST NC.SourceLinkLabel NC.ListContentsLinkLabel 
				NC.BrowserContentsLinkLabel NC.FiledCardLinkLabel NC.SubBoxLinkLabel 
				NC.DocBackPtrLinkLabel NC.LinkIndexBackPtrLinkLabel))

(RPAQ NC.UCASESystemLinkLabels (FOR Label in NC.SystemLinkLabels collect (U-CASE Label)))

(RPAQ NC.InitialLinkLabels (APPEND (QUOTE (Comment Remark Question Rebuttal Argument Unspecified))
				   NC.SystemLinkLabels))
(* * Links mechanism)

[DECLARE: EVAL@COMPILE 

(TYPERECORD NOTECARDLINK (LINKID SOURCEID DESTINATIONID ANCHORMODE LINKLABEL DISPLAYMODE)
			 (TYPE? (AND (EQ (LENGTH DATUM)
					 7)
				     (NC.IDP (fetch (NOTECARDLINK SOURCEID) of DATUM))
				     (NC.IDP (fetch (NOTECARDLINK DESTINATIONID) of DATUM)))))

(TYPERECORD LINKDISPLAYMODE (SHOWTITLEFLG SHOWLINKTYPEFLG ATTACHBITMAPFLG)
			    (TYPE? (EQ (LENGTH DATUM)
				       4)))
]
(DEFINEQ

(NC.GlobalLinkP
  (LAMBDA (Link)                                             (* fgh: "16-Oct-84 12:55")

          (* * Return T if Link is a Global to Global link)


    (EQ (QUOTE GlobalGlobal)
	(fetch (NOTECARDLINK ANCHORMODE) of Link))))

(NC.ChildLinkP
  (LAMBDA (Link)                                             (* rht: " 1-Aug-84 09:34")

          (* * Is link either to a filed card or sub filebox?)


    (OR (NC.ContentsLinkP Link)
	(NC.SubContentsLinkP Link))))

(NC.ContentsLinkP
  (LAMBDA (Link)                                             (* NoteCards% User " 5-Jun-84 17:28")
    (COND
      ((EQ NC.FiledCardLinkLabel (fetch (NOTECARDLINK LINKLABEL) of Link))
	T)
      (T NIL))))

(NC.SubContentsLinkP
  (LAMBDA (Link)                                             (* NoteCards% User " 5-Jun-84 17:28")
    (COND
      ((EQ NC.SubBoxLinkLabel (fetch (NOTECARDLINK LINKLABEL) of Link))
	T)
      (T NIL))))

(NC.ReverseLinkLabelP
  (LAMBDA (Link ListOfLabels)                                (* rht: " 4-Sep-84 20:49")
                                                             (* Is the reverse of Link, i.e. with "←" prefix 
							     attached, present on ListOfLabels?)

          (* * rht 9/4/84: Modified so as to return the linklabel found or nil.)


    (PROG ((Label (fetch (NOTECARDLINK LINKLABEL) of Link)))
          (RETURN (COND
		    ((FMEMB (PACK* (QUOTE ←)
				   Label)
			    (OR (LISTP ListOfLabels)
				(LIST ListOfLabels)))
		      Label))))))

(NC.GetNewLinkID
  (LAMBDA (DatabaseStream NoUpdateFlg)                       (* rht: " 1-Feb-85 20:33")

          (* * Get a new link id for DatabaseStream)


    (PROG ((NewID (STREAMPROP DatabaseStream (QUOTE NCNEXTLINKID))))
          (OR NoUpdateFlg (STREAMPROP DatabaseStream (QUOTE NCNEXTLINKID)
				      (ADD1 NewID)))
          (RETURN NewID))))

(NC.MakeGlobalLink
  (LAMBDA (Window LinkLabel DestinationID SourceID DisplayMode)
                                                             (* rht: "26-Mar-85 11:48")

          (* * Make a new global link from DestinationID to SourceID with label LinkLabel and display mode DisplayMode.
	  Window is optional if SourceID is specified, otherwise it is required.)



          (* * rht 11/9/84: Now checks result of NC.MakeLink before building link.)


    (PROG ((Link (NC.MakeLink Window LinkLabel DestinationID SourceID DisplayMode (QUOTE GlobalGlobal)
			      NIL NIL (QUOTE ATEND))))
          (AND Link (NC.SetGlobalLinks SourceID (CONS Link (NC.FetchGlobalLinks SourceID))))
          (RETURN Link))))

(NC.AddFromLink
  (LAMBDA (Link DatabaseStream)                              (* fgh: " 5-Oct-84 18:43")

          (* * Add Link to the FromLinks of the appropraite card on DatbaseStream)


    (PROG ((ID (fetch (NOTECARDLINK DESTINATIONID) of Link)))
          (COND
	    ((NC.ActiveCardP ID)
	      (NC.SetFromLinks ID (CONS Link (NC.FetchFromLinks ID)))
	      (NC.SetLinksDirtyFlg ID T))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream "NC.AddFromLink")
			     (NC.GetLinks ID DatabaseStream)
			     (NC.SetFromLinks ID (CONS Link (NC.FetchFromLinks ID)))
			     (NC.SetLinksDirtyFlg ID T)
			     (NC.PutLinks ID DatabaseStream))
	       (NC.SetFromLinks ID NIL)
	       (NC.SetToLinks ID NIL)))
          (RETURN Link))))

(NC.AddLinkToGraphCard
  (LAMBDA (Window)                                           (* fgh: "25-Oct-84 00:06")
                                                             (* Add a NOTECARD link to a graph card.
							     Pass the fact that this is a link-add to 
							     NC.GraphAddNodeFn via the NoteCardInsertingLink window 
							     property)
    (WINDOWPROP Window (QUOTE NoteCardInsertingLink)
		T)
    (EDITADDNODE Window)))

(NC.AddLinkToSketchCard
  (LAMBDA (SketchWindow)                                     (* fgh: "15-Feb-85 22:15")
                                                             (* Called from a SKETCH window to add a new NoteCard 
							     Link Icon to the sketch)

          (* * rht 11/9/84: Now checks result of NC.MakeLink before building link.)


    (PROG ((Label (NC.AskLinkLabel SketchWindow NIL NIL T T))
	   Link)
          (RETURN (AND Label (SETQ Link (NC.MakeLink SketchWindow Label NIL NIL NIL))
		       (NC.InsertLinkInSketch SketchWindow Link))))))

(NC.InsertLinkInSketch
  (LAMBDA (SketchWindow Link SketchWindowPosition)           (* rht: " 1-Oct-85 22:32")

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



          (* * rht 10/1/85: Now checks that chosen position is actually within sketch, otherwise aborts by deleting link.)


    (LET ((LinkIcon (NC.MakeLinkIcon Link))
       (Scale (SKETCHW.SCALE SketchWindow))
       SketchIcon Size Position)
      (SETQ Size (IMAGEBOXSIZE LinkIcon))
      (SETQ Position (OR (POSITIONP SketchWindowPosition)
			 (GETBOXPOSITION (fetch (IMAGEBOX XSIZE) of Size)
					 (fetch (IMAGEBOX YSIZE) of Size)
					 NIL NIL SketchWindow)))
      (if (INSIDEP (DSPCLIPPINGREGION NIL SketchWindow)
		   Position)
	  then (SETQ SketchIcon (SKETCH.IMAGE.OBJECT.ELEMENT LinkIcon Scale Position))
	       (SKETCH.ADD.ELEMENT SketchIcon SketchWindow)
	       SketchIcon
	else (NCP.DeleteLinks Link)
	     NIL))))

(NC.AddLinkToTextCard
  (LAMBDA (TextStream)                                       (* fgh: "28-Sep-84 18:54")
                                                             (* Called from a TEXT TEdit window to add a new link to
							     the text.)
    (PROG ((Label (NC.AskLinkLabel (WINDOW.FROM.TEDIT.THING TextStream)
				   NIL NIL T T)))
          (AND Label (RETURN (NC.InsertLinkInText TextStream Label NIL NIL NIL))))))

(NC.AddLinksToTextCard
  (LAMBDA (TextStream)                                       (* rht: "21-Nov-84 15:20")

          (* * Called from a TEXT TEdit window to add multiple links to the text.)


    (PROG ((Label (NC.AskLinkLabel (WINDOW.FROM.TEDIT.THING TextStream)
				   NIL NIL T T)))
          (AND Label (RETURN (NC.InsertLinksInText TextStream Label))))))

(NC.InsertLinkInText
  (LAMBDA (TextStream LinkOrLinkLabel DestinationID SourceID DisplayMode CharacterPosition)
                                                             (* rht: "27-Jun-85 15:34")

          (* * Add a link image object (and hence a link) to the text specified by TextStream. Link has LinkLabel, goes to 
	  DestinationID and has DisplayMode. Returns the Link inserted.)



          (* * rht 11/9/84: Now checks result of NC.MakeLink before building link.)



          (* * rht 3/26/85: Now uses insert position to calculate the link after which to insert new link and passes this to 
	  NC.MakeLink.)


    (PROG ((Window (WINDOW.FROM.TEDIT.THING TextStream))
	   (TextObject (TEXTOBJ TextStream))
	   Link InsertPos)
          (RETURN (COND
		    ((SETQ InsertPos (OR (if (AND (FIXP CharacterPosition)
						  (ILEQ CharacterPosition (fetch (TEXTOBJ TEXTLEN)
									     of TextObject)))
					     then CharacterPosition)
					 (NC.CharPosFromTextObject TextObject)))
		      (if (SETQ Link (COND
			      ((type? NOTECARDLINK LinkOrLinkLabel)
				LinkOrLinkLabel)
			      (T (NC.MakeLink Window LinkOrLinkLabel DestinationID SourceID 
					      DisplayMode NIL NIL NIL (NC.LinkAtCharPos InsertPos 
										       TextStream)))))
			  then (TEDIT.SETSEL TextObject InsertPos 0 (QUOTE LEFT))
			       (TEDIT.INSERT.OBJECT (NC.MakeLinkIcon Link)
						    (TEXTSTREAM TextObject)
						    InsertPos))
		      Link)
		    (T (NC.ReportError "NC.InsertLinkInText" 
				       "No selection set when inserting link image object.")
		       NIL))))))

(NC.InsertLinksInText
  (LAMBDA (TextStream LinkLabel)                             (* rht: "15-Feb-85 15:55")

          (* * Add several links to the text all with the same link label.)


    (PROG (Window SourceID DestinationIDs)
          (SETQ SourceID (NC.IDFromWindow (SETQ Window (WINDOW.FROM.TEDIT.THING TextStream))))
          (SETQ DestinationIDs (NC.SelectNoteCards NIL (FUNCTION (LAMBDA (CardID)
						       (COND
							 ((NEQ CardID SourceID)
							   T)
							 (T (NC.PrintMsg (NC.FetchWindow SourceID)
									 T 
							    "A Card/Box cannot point to itself. "
									 (CHARACTER 13)
									 "Selection ignored."
									 (CHARACTER 13))
							    NIL))))
						   NC.SelectingMultipleCardsMenu SourceID NIL 
					     "Please select the Cards or Boxes to be pointed to."))
          (NC.ClearMsg Window T)
          (for DestinationID in DestinationIDs do (NC.InsertLinkInText TextStream LinkLabel 
								       DestinationID SourceID NIL)))))

(NC.AddSourceLink
  (LAMBDA (ID DestinationID DatabaseStream)                  (* fgh: " 2-Oct-84 15:43")
                                                             (* Add a source link from card ID to card DestinationID
							     in DatabaseStream)
    (COND
      ((NEQ DestinationID (QUOTE NC00000))
	(NC.SetGlobalLinks ID (for Link in (NC.FetchGlobalLinks ID)
				 unless (EQ (fetch (NOTECARDLINK DESTINATIONID) of Link)
					    (QUOTE NC00000))
				 collect Link))
	(NC.MakeGlobalLink NIL NC.SourceLinkLabel DestinationID ID (QUOTE Title)))
      (T (NC.SetGlobalLinks ID (CONS (create NOTECARDLINK
					     DESTINATIONID ←(QUOTE NC00000)
					     LINKLABEL ← NC.SourceLinkLabel)
				     (NC.FetchGlobalLinks ID)))))
    NIL))

(NC.AddToLink
  (LAMBDA (Link DatabaseStream LinkToInsertAfter)            (* rht: " 2-Oct-85 14:13")

          (* * Add Link to the ToLinks of the appropriate card on DatabaseStream)



          (* * rht 3/26/85: Added LinkToInsertAfter arg which is either NIL, ATEND, or a link after which to insert new link.
	  If NIL, then insert at front of list. If ATEND then insert at end.)


    (PROG (ToLinks (ID (fetch (NOTECARDLINK SOURCEID) of Link)))
          (COND
	    ((NC.ActiveCardP ID)
	      (SETQ ToLinks (NC.FetchToLinks ID))
	      (COND
		((AND ToLinks (type? NOTECARDLINK LinkToInsertAfter))
                                                             (* Destructively insert after a given link.)
		  (for RestOfToLinks on ToLinks bind (LinkToInsertAfterLinkID ←(fetch (NOTECARDLINK
											LINKID)
										  of 
										LinkToInsertAfter))
		     thereis (EQP LinkToInsertAfterLinkID (fetch (NOTECARDLINK LINKID)
							     of (CAR RestOfToLinks)))
		     finally (if RestOfToLinks
				 then (RPLACD RestOfToLinks (CONS Link (CDR RestOfToLinks)))
			       else (NC.SetToLinks ID (NCONC1 ToLinks Link)))))
		((EQ LinkToInsertAfter (QUOTE ATEND))        (* Destructively insert at the end.)
		  (NC.SetToLinks ID (NCONC1 ToLinks Link)))
		(T                                           (* Stick it at the front.)
		   (NC.SetToLinks ID (CONS Link ToLinks))))
	      (NC.SetLinksDirtyFlg ID T))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream "NC.AddFromLink")
			     (NC.GetLinks ID DatabaseStream)
			     (SETQ ToLinks (NC.FetchToLinks ID))
			     (COND
			       ((AND ToLinks (type? NOTECARDLINK LinkToInsertAfter))
                                                             (* Destructively insert after a given link.)
				 (for RestOfToLinks on ToLinks bind (LinkToInsertAfterLinkID
								      ←(fetch (NOTECARDLINK LINKID)
									  of LinkToInsertAfter))
				    thereis (EQP LinkToInsertAfterLinkID (fetch (NOTECARDLINK LINKID)
									    of (CAR RestOfToLinks)))
				    finally (if RestOfToLinks
						then (RPLACD RestOfToLinks (CONS Link (CDR 
										    RestOfToLinks)))
					      else (NC.SetToLinks ID (NCONC1 ToLinks Link)))))
			       ((EQ LinkToInsertAfter (QUOTE ATEND))
                                                             (* Destructively insert at the end.)
				 (NC.SetToLinks ID (NCONC1 ToLinks Link)))
			       (T                            (* Stick it at the front.)
				  (NC.SetToLinks ID (CONS Link ToLinks))))
			     (NC.SetLinksDirtyFlg ID T)
			     (NC.PutLinks ID DatabaseStream))
	       (NC.SetFromLinks ID NIL)
	       (NC.SetToLinks ID NIL)))
          (RETURN Link))))

(NC.DelFromLink
  (LAMBDA (Link DatabaseStream NoOrphanHookFlg)              (* fgh: " 8-Feb-85 01:55")
                                                             (* Delete a FromLink from card on DatabaseStream.
							     Hook card to orphan if this is the last link.)

          (* * rht 11/15/84: Changed decision as to when to orphanize a card. Now must have deleted its last link 
	  (not just last subbox or filedcard link). Also checks that link doesn't point from card to itself.)



          (* * rht 12/1/84: Now doesn't do any work unless ID is valid, i.e. not DELETED or FREE.)


    (PROG ((ID (fetch (NOTECARDLINK DESTINATIONID) of Link)))
          (COND
	    ((NOT (NC.ValidID ID)))
	    ((NC.ActiveCardP ID)
	      (NC.SetFromLinks ID (DREMOVE (for OldLink in (NC.FetchFromLinks ID)
					      thereis (AND (EQP (fetch (NOTECARDLINK LINKID)
								   of Link)
								(fetch (NOTECARDLINK LINKID)
								   of OldLink))
							   OldLink))
					   (NC.FetchFromLinks ID)))
	      (NC.SetLinksDirtyFlg ID T)
	      (AND (NULL NoOrphanHookFlg)
		   (NOT (FMEMB ID NC.TopLevelCards))
		   (NOT (EQ (fetch (NOTECARDLINK SOURCEID) of Link)
			    ID))
		   (NULL (NC.FetchNewCardFlg ID))
		   (NOT (EQ (fetch (NOTECARDLINK SOURCEID) of Link)
			    NC.OrphanID))
		   (COND
		     ((OR (NULL (NC.FetchFromLinks ID))
			  (for Link in (NC.FetchFromLinks ID) always (EQ (fetch (NOTECARDLINK 
											 SOURCEID)
									    of Link)
									 ID)))
		       (NC.PrintMsg NIL T "You have just removed the last link to " (NC.RetrieveTitle
				      ID)
				    "."
				    (CHARACTER 13)
				    "It is being filed in the Orphan FileBox.")
		       (NC.HookToOrphanCard ID NC.OrphanID DatabaseStream))
		     ((for Link in (NC.FetchFromLinks ID) never (FMEMB (fetch (NOTECARDLINK LINKLABEL)
									  of Link)
								       (QUOTE (SubBox FiledCard))))
		       (NC.PrintMsg NIL T "You have just unfiled " (NC.RetrieveTitle ID)
				    " from its last filebox."
				    (CHARACTER 13)
				    "It is being filed in the Orphan FileBox.")
		       (NC.HookToOrphanCard ID NC.OrphanID DatabaseStream)))))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream "NC.AddFromLink")
			     (NC.GetLinks ID DatabaseStream)
			     (NC.SetFromLinks ID (DREMOVE (for OldLink in (NC.FetchFromLinks ID)
							     thereis
							      (AND (EQ (fetch (NOTECARDLINK LINKID)
									  of Link)
								       (fetch (NOTECARDLINK LINKID)
									  of OldLink))
								   OldLink))
							  (NC.FetchFromLinks ID)))
			     (NC.SetLinksDirtyFlg ID T)
			     (NC.PutLinks ID DatabaseStream)
			     (AND (NULL NoOrphanHookFlg)
				  (NOT (FMEMB ID NC.TopLevelCards))
				  (NOT (EQ (fetch (NOTECARDLINK SOURCEID) of Link)
					   ID))
				  (NULL (NC.FetchNewCardFlg ID))
				  (NOT (EQ (fetch (NOTECARDLINK SOURCEID) of Link)
					   NC.OrphanID))
				  (COND
				    ((OR (NULL (NC.FetchFromLinks ID))
					 (for Link in (NC.FetchFromLinks ID)
					    always (EQ (fetch (NOTECARDLINK SOURCEID) of Link)
						       ID)))
				      (NC.PrintMsg NIL T "You have just removed the last link to "
						   (NC.RetrieveTitle ID)
						   "."
						   (CHARACTER 13)
						   "It is being filed in the Orphan FileBox.")
				      (NC.HookToOrphanCard ID NC.OrphanID DatabaseStream))
				    ((for Link in (NC.FetchFromLinks ID)
					never (FMEMB (fetch (NOTECARDLINK LINKLABEL) of Link)
						     (QUOTE (SubBox FiledCard))))
				      (NC.PrintMsg NIL T "You have just unfiled " (NC.RetrieveTitle
						     ID)
						   " from its last filebox."
						   (CHARACTER 13)
						   "It is being filed in the Orphan FileBox.")
				      (NC.HookToOrphanCard ID NC.OrphanID DatabaseStream)))))
	       (NC.SetFromLinks ID NIL)
	       (NC.SetToLinks ID NIL)))
          (RETURN Link))))

(NC.DelToLink
  (LAMBDA (Link DatabaseStream)                              (* rht: " 2-Apr-85 11:05")

          (* * Delete ToLink spoecified by Link from cards on DatabasseStream)



          (* * rht 12/1/84: Now doesn't do any work unless ID is valid, i.e. not DELETED or FREE.)


    (PROG ((ID (fetch (NOTECARDLINK SOURCEID) of Link)))
          (COND
	    ((NOT (NC.ValidID ID)))
	    ((NC.ActiveCardP ID)
	      (NC.SetToLinks ID (DREMOVE (for OldLink in (NC.FetchToLinks ID)
					    thereis (AND (EQP (fetch (NOTECARDLINK LINKID)
								 of Link)
							      (fetch (NOTECARDLINK LINKID)
								 of OldLink))
							 OldLink))
					 (NC.FetchToLinks ID)))
	      (NC.SetLinksDirtyFlg ID T))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream "NC.AddFromLink")
			     (NC.GetLinks ID DatabaseStream)
			     (NC.SetToLinks ID (DREMOVE (for OldLink in (NC.FetchToLinks ID)
							   thereis (AND (EQP (fetch (NOTECARDLINK
										      LINKID)
										of Link)
									     (fetch (NOTECARDLINK
										      LINKID)
										of OldLink))
									OldLink))
							(NC.FetchToLinks ID)))
			     (NC.SetLinksDirtyFlg ID T)
			     (NC.PutLinks ID DatabaseStream))
	       (NC.SetFromLinks ID NIL)
	       (NC.SetToLinks ID NIL)))
          (RETURN Link))))

(NC.DelReferencesToCard
  (LAMBDA (SourceID LinkOrDestinationID DatabaseStream)      (* rht: " 2-Apr-85 11:20")
                                                             (* The card specified by DestinationID is being 
							     deleted. Remove all references to it from the card 
							     specified by SourceID)
    (PROG (NoteCardType Substance)
          (COND
	    ((NC.ActiveCardP SourceID)
	      (SETQ NoteCardType (NC.FetchType SourceID))
	      (SETQ Substance (NC.FetchSubstance SourceID))
	      (APPLY* (NC.DelReferencesFn NoteCardType)
		      SourceID LinkOrDestinationID))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream "NC.DeleteReferencesToCard")
			     (if (NC.ValidID (NC.GetNoteCard SourceID DatabaseStream))
				 then (SETQ NoteCardType (NC.FetchType SourceID))
				      (SETQ Substance (NC.FetchSubstance SourceID))
				      (APPLY* (NC.DelReferencesFn NoteCardType)
					      SourceID LinkOrDestinationID)
				      (NC.PutNoteCard SourceID DatabaseStream)
				      (NC.DeactivateCard SourceID)))))
          (NC.DelReferencesToCardFromGlobalList SourceID LinkOrDestinationID DatabaseStream))))

(NC.DelReferencesToCardFromGlobalList
  (LAMBDA (SourceID LinkOrDestinationID DatabaseStream)      (* rht: "19-Nov-84 22:53")

          (* The card or link specified by DestinationID is being deleted. Remove all references to it from the global links 
	  list of the card specified by SourceID)



          (* * rht 11/19/84: Fixed a naming typo changing ID to SourceID everywhere. Also fixed DestinationID arg to be 
	  LinkOrDestinationID.)


    (COND
      ((NC.ActiveCardP SourceID)
	(NC.SetGlobalLinks SourceID (for Link in (NC.FetchGlobalLinks SourceID)
				       when (if (NC.IDP LinkOrDestinationID)
						then (NEQ LinkOrDestinationID (fetch (NOTECARDLINK
										       DESTINATIONID)
										 of Link))
					      else (NEQ (fetch (NOTECARDLINK LINKID) of 
									      LinkOrDestinationID)
							(fetch (NOTECARDLINK LINKID) of Link)))
				       collect Link)))
      (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream)
		       (NC.GetLinks SourceID DatabaseStream)
		       (NC.SetGlobalLinks SourceID (for Link in (NC.FetchGlobalLinks SourceID)
						      when (if (NC.IDP LinkOrDestinationID)
							       then (NEQ LinkOrDestinationID
									 (fetch (NOTECARDLINK 
										    DESTINATIONID)
									    of Link))
							     else (NEQ (fetch (NOTECARDLINK LINKID)
									  of LinkOrDestinationID)
								       (fetch (NOTECARDLINK LINKID)
									  of Link)))
						      collect Link))
		       (NC.PutLinks SourceID DatabaseStream))))))

(NC.DelReferencesToCardFromGraph
  (LAMBDA (SourceID LinkOrDestinationID)                     (* rht: "17-Nov-84 18:05")
                                                             (* Delete from the graph specified by Graph all link 
							     icon nodes whose DESTINATIONID is eq to DestinationID)

          (* * rht 11/17/84: Now only redisplays graph if ID is both active *and* has a window.)


    (PROG ((ImageBox (NC.DeletedLinkImageBoxFn NC.DeletedLinkImageObject))
	   LinkIcon
	   (LinkFlg (type? NOTECARDLINK LinkOrDestinationID))
	   LinkID DestinationID Graph)
          (COND
	    (LinkFlg (SETQ LinkID (fetch (NOTECARDLINK LINKID) of LinkOrDestinationID))
		     (OR (NC.IDP SourceID)
			 (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of LinkOrDestinationID))))
	    (T (SETQ DestinationID LinkOrDestinationID)))
          (SETQ Graph (NC.FetchSubstance SourceID))
          (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph)
	     when (AND (NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE NODELABEL)
							       of GraphNode)))
		       (COND
			 (LinkFlg (EQ LinkID (fetch (NOTECARDLINK LINKID) of (NC.FetchLinkFromLinkIcon
									       LinkIcon))))
			 (T (EQ (fetch (NOTECARDLINK DESTINATIONID) of (NC.FetchLinkFromLinkIcon
									 LinkIcon))
				DestinationID))))
	     do (replace (GRAPHNODE NODELABEL) of GraphNode with NC.DeletedLinkImageObject)
		(replace (GRAPHNODE NODEWIDTH) of GraphNode with (fetch (IMAGEBOX XSIZE)
								    of ImageBox))
		(replace (GRAPHNODE NODEHEIGHT) of GraphNode with (fetch (IMAGEBOX YSIZE)
								     of ImageBox)))
          (if (AND (NC.ActiveCardP SourceID)
		   (NC.FetchWindow SourceID))
	      then (REDISPLAYGRAPH (NC.FetchWindow SourceID))))))

(NC.DelReferencesToCardFromSketch
  (LAMBDA (SourceID LinkOrDestinationID)                     (* rht: "20-Aug-85 22:47")

          (* * Remove all Link Icons pointing to Destination ID from the sketch Substance.)



          (* * rht 8/20/85: Rewritten to use Richard's sketch programmer's interface. Eliminates references to sketch records.
	  I'm changing the innards of the affected link icons rather than deleting them and reinserting.
	  That's because deleting the icon would cause a recursive call.)


    (PROG ((LinkFlg (type? NOTECARDLINK LinkOrDestinationID))
	   LinkID DestinationID SketchSubstance)
          (COND
	    (LinkFlg (SETQ LinkID (fetch (NOTECARDLINK LINKID) of LinkOrDestinationID))
		     (OR (NC.IDP SourceID)
			 (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of LinkOrDestinationID))))
	    (T (SETQ DestinationID LinkOrDestinationID)))
          (SETQ SketchSubstance (NC.FetchSubstance SourceID))
          (for SketchElement in (SKETCH.LIST.OF.ELEMENTS SketchSubstance (FUNCTION 
							   NC.LinkIconSketchElementP))
	     bind LinkIcon when (PROGN (SETQ LinkIcon (SKETCH.IMAGEOBJ.OF.ELEMENT SketchElement))
				       (COND
					 (LinkFlg (EQ LinkID (fetch (NOTECARDLINK LINKID)
								of (NC.FetchLinkFromLinkIcon LinkIcon)
								    )))
					 (T (EQ DestinationID (fetch (NOTECARDLINK DESTINATIONID)
								 of (NC.FetchLinkFromLinkIcon 
											 LinkIcon)))))
				       )
	     do (NC.DeleteLinkIconSketchElement SketchElement SourceID)))))

(NC.DelReferencesToCardFromText
  (LAMBDA (SourceID LinkOrDestinationID)                     (* rht: "12-Sep-85 15:27")
                                                             (* Delete all IMAGEOBJECTS in textstream specified by 
							     Substance that are Link Icons whose DESTINATIONID is eq
							     to Destination ID)

          (* * rht 9/12/85: Fixed so restores old selection after putting in deleted link icon.)


    (LET ((LinkFlg (type? NOTECARDLINK LinkOrDestinationID))
       LinkID DestinationID Substance)
      (if LinkFlg
	  then (SETQ LinkID (fetch (NOTECARDLINK LINKID) of LinkOrDestinationID))
	       (OR (NC.IDP SourceID)
		   (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of LinkOrDestinationID)))
	else (SETQ DestinationID LinkOrDestinationID))
      (SETQ Substance (NC.FetchSubstance SourceID))
      (for Link in (TEDIT.LIST.OF.OBJECTS (TEXTOBJ Substance)
					  (FUNCTION NC.LinkIconImageObjP))
	 bind OldSel when (if LinkFlg
			      then (EQ LinkID (fetch (NOTECARDLINK LINKID)
						 of (NC.FetchLinkFromLinkIcon (CAR Link))))
			    else (EQ DestinationID (fetch (NOTECARDLINK DESTINATIONID)
						      of (NC.FetchLinkFromLinkIcon (CAR Link)))))
	 do (replace (IMAGEOBJ IMAGEOBJFNS) of (CAR Link) with NC.NoDeleteImageFns) 
                                                             (* WHENDELETEDFN taken care of earlier in delete cycle)
	    (SETQ OldSel (TEDIT.GETSEL Substance))
	    (TEDIT.DELETE Substance (CADR Link)
			  1)
	    (TEDIT.INSERT.OBJECT NC.DeletedLinkImageObject Substance (CADR Link))
	    (TEDIT.SETSEL Substance OldSel)))))

(NC.DeletedLinkDisplayFn
  (LAMBDA (ImageObj Stream)                                  (* fgh: "14-May-85 13:04")
    (SELECTQ (IMAGESTREAMTYPE Stream)
	     (DISPLAY                                        (* This is being displayed on the screen)
		      (PROG ((ImageBox (NC.DeletedLinkImageBoxFn ImageObj Stream))
			     Bottom XSize YSize Left)
			    (DSPXPOSITION (IPLUS 3 (SETQ Left (DSPXPOSITION NIL Stream)))
					  Stream)
			    (SETQ XSize (fetch (IMAGEBOX XSIZE) of ImageBox))
			    (SETQ YSize (fetch (IMAGEBOX YSIZE) of ImageBox))
			    (SETQ Bottom (IDIFFERENCE (DSPYPOSITION NIL Stream)
						      (fetch (IMAGEBOX YDESC) of ImageBox)))
                                                             (* don't bother to errorset this)
			    (DSPFONT (PROG1 (DSPFONT NC.LinkIconFont Stream)
					    (PRIN1 "Deleted" Stream))
				     Stream)
			    (BITBLT NIL NIL NIL Stream (ADD1 Left)
				    (IPLUS Bottom 2)
				    (IDIFFERENCE XSize 2)
				    (IDIFFERENCE YSize 4)
				    (QUOTE TEXTURE)
				    (COND
				      ((EQ (DSPOPERATION NIL Stream)
					   (QUOTE ERASE))
					(QUOTE ERASE))
				      (T (QUOTE INVERT)))
				    BLACKSHADE)))
	     ((PRESS INTERPRESS)                             (* It's being displayed on a press file)
	       NIL)
	     NIL)))

(NC.DeletedLinkGetFn
  (LAMBDA (InputStream TextStream)                           (* fgh: "26-Feb-84 01:17")
    (BIN InputStream)
    NC.DeletedLinkImageObject))

(NC.DeletedLinkImageBoxFn
  (LAMBDA (ImageObj Stream)                                  (* fgh: " 1-Apr-85 18:07")
    (PROG ((Font NC.DefaultFont))
          (RETURN (create IMAGEBOX
			  XSIZE ←(IPLUS 6 (STRINGWIDTH "Deleted" Font))
			  YSIZE ←(IPLUS 4 (FONTPROP Font (QUOTE HEIGHT)))
			  YDESC ←(IPLUS 2 (FONTPROP Font (QUOTE DESCENT)))
			  XKERN ← 0)))))

(NC.DeletedLinkPutFn
  (LAMBDA (ImageObj OutputStream)                            (* fgh: "26-Feb-84 01:04")
    (BOUT OutputStream 1)))

(NC.DeletedLinkImageObjP
  (LAMBDA (ImageObj)                                         (* rht: "12-Jun-85 10:07")

          (* * Returns non-nil if ImageObj is a deleted link icon.)


    (AND (IMAGEOBJP ImageObj)
	 (EQ (FUNCTION NC.DeletedLinkDisplayFn)
	     (IMAGEOBJPROP ImageObj (QUOTE DISPLAYFN))))))

(NC.CheckForOrphanDelete
  (LAMBDA (SourceID DestinationID SourceWindow)              (* rht: "21-Sep-85 13:27")

          (* Check to make sure we are not deleteing the last reference to a note card from the orphan card.
	  Last references are okay to delete it since they will be put in the orphan card. But deleting last reference from 
	  the orphan card is very, very bad. Warn the user.)


    (PROG ((FilingLinks (LIST NC.SubBoxLinkLabel NC.FiledCardLinkLabel)))
          (RETURN (AND (EQ SourceID NC.OrphanID)
		       (NOT (for Link in (COND
					   ((NC.ActiveCardP DestinationID)
					     (NC.FetchFromLinks DestinationID))
					   (T (NC.GetLinks DestinationID PSA.Database)
					      (NC.FetchFromLinks DestinationID)))
			       thereis (AND (FMEMB (fetch (NOTECARDLINK LINKLABEL) of Link)
						   FilingLinks)
					    (NEQ (fetch (NOTECARDLINK SOURCEID) of Link)
						 NC.OrphanID))))
		       (NC.PrintMsg (NC.FetchWindow SourceID)
				    T
				    (NC.RetrieveTitle DestinationID)
				    (CHARACTER 13)
				    
		      "You have just deleted the last link to this Card/Box from the Orphan Box."
				    (CHARACTER 13)
				    "The Search operation can be used to create a new link."))))))

(NC.HookToOrphanCard
  (LAMBDA (ID OrphanCardID DatabaseStream FromID)            (* rht: "23-May-85 11:29")
                                                             (* The last reference to the card has just been 
							     deleted. Hook this card to the orphan card so it 
							     doesn't get lost forever)
    (COND
      ((NC.ActiveCardP OrphanCardID)
	(NC.MakeAContentsHook OrphanCardID ID (COND
				((EQ (NC.RetrieveType ID DatabaseStream)
				     (QUOTE FileBox))
				  (QUOTE Sub))
				(T NIL))
			      DatabaseStream))
      (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream)
		       (NC.GetNoteCard OrphanCardID DatabaseStream)
		       (NC.MakeAContentsHook OrphanCardID ID (COND
					       ((EQ (NC.RetrieveType ID DatabaseStream)
						    (QUOTE FileBox))
						 (QUOTE Sub))
					       (T NIL))
					     DatabaseStream)
		       (NC.PutNoteCard OrphanCardID DatabaseStream)
		       (NC.PutLinks OrphanCardID DatabaseStream)
		       (NC.DeactivateCard OrphanCardID))))))

(NC.InsertLinkBeforeMarker
  (LAMBDA (SourceID DestinationID LinkLabel DisplayMode Marker# DatabaseStream NoSpacerFlg)
                                                             (* rht: "25-Oct-85 00:28")
                                                             (* Insert a link to DestinationID in SourceID just 
							     before the Marker#'th place marker object)

          (* * rht 12/7/84: Now returns the newly created link.)



          (* * rht 9/13/85: When card is inactive, there won't be a current cursor position. So if no marker# is specified, 
	  then insert at end.)


    (LET (Objects TextStream TextObject (Spacer (CONCAT (CHARACTER 13)))
		  Link)
      (if (NC.ActiveCardP SourceID)
	  then (SETQ TextObject (TEXTOBJ (SETQ TextStream (NC.FetchSubstance SourceID))))
	       (COND
		 ((AND (FIXP Marker#)
		       (SETQ Objects (TEDIT.LIST.OF.OBJECTS TextObject (FUNCTION NC.PlaceMarkerP))))
		   (COND
		     ((EQ Marker# 0)
		       (TEDIT.SETSEL TextStream 1 0 (QUOTE LEFT)))
		     ((IGREATERP Marker# (FLENGTH Objects))
		       (TEDIT.SETSEL TextStream (ADD1 (fetch (TEXTOBJ TEXTLEN) of TextObject))
				     0
				     (QUOTE RIGHT)))
		     (T (TEDIT.SETSEL TextStream (CADAR (FNTH Objects Marker#))
				      0
				      (QUOTE LEFT)))))
		 (NC.MarkersInFileBoxesFlg (TEDIT.SETSEL TextStream (GETEOFPTR TextStream)
							 0
							 (QUOTE RIGHT))))
	       (SETQ Link (NC.InsertLinkInText TextStream LinkLabel DestinationID SourceID 
					       DisplayMode))
	       (if (NULL NoSpacerFlg)
		   then (TEDIT.INSERT TextStream Spacer))
	else (WITH.MONITOR (NC.FetchMonitor DatabaseStream)
			   (COND
			     ((NC.IDP (NC.GetNoteCard SourceID DatabaseStream))
			       (SETQ TextObject (TEXTOBJ (SETQ TextStream (NC.FetchSubstance SourceID)
							   )))
			       (COND
				 ((AND (FIXP Marker#)
				       (SETQ Objects (TEDIT.LIST.OF.OBJECTS TextObject
									    (FUNCTION NC.PlaceMarkerP)
									    )))
				   (COND
				     ((EQ Marker# 0)
				       (TEDIT.SETSEL TextStream 1 0 (QUOTE LEFT)))
				     ((IGREATERP Marker# (FLENGTH Objects))
				       (TEDIT.SETSEL TextStream (ADD1 (fetch (TEXTOBJ TEXTLEN)
									 of TextObject))
						     0
						     (QUOTE RIGHT)))
				     (T (TEDIT.SETSEL TextStream (CADAR (FNTH Objects Marker#))
						      0
						      (QUOTE LEFT)))))
				 (T                          (* Cursor has no position in closed Tedit win, so just 
							     set selection to end.)
				    (TEDIT.SETSEL TextStream (ADD1 (fetch (TEXTOBJ TEXTLEN)
								      of TextObject))
						  0
						  (QUOTE RIGHT))))
			       (SETQ Link (NC.InsertLinkInText TextStream LinkLabel DestinationID 
							       SourceID DisplayMode))
			       (if (NULL NoSpacerFlg)
				   then (TEDIT.INSERT TextStream Spacer))
			       (NC.PutNoteCard SourceID DatabaseStream)
			       (NC.PutLinks SourceID DatabaseStream)
			       (NC.DeactivateCard SourceID)))))
      Link)))

(NC.LinkLabelP
  (LAMBDA (Link ListOfLabels)                                (* rht: " 4-Sep-84 17:21")

          (* * rht 9/4/84: Modified so as to return the linklabel if found or nil.)


    (CAR (FMEMB (fetch (NOTECARDLINK LINKLABEL) of Link)
		(OR (LISTP ListOfLabels)
		    (LIST ListOfLabels))))))

(NC.MakeAContentsHook
  (LAMBDA (ContentsID DestinationID SubOrSuperFlg DatabaseStream)
                                                             (* rht: "25-Oct-85 00:29")

          (* Make a link from a contents card to another card as specified by DestinationID. If card is a regular card, insert
	  link at end of contents card. If card is a supercontents of contents card then insert just before the subcontents 
	  marker (i.e., at end of super contents list). If card is a subcontents card then insert just before note cards 
	  marker (i.e., at end of subcontents list))



          (* * rht 10/25/85: Now checks if card's window is shrunken. If so, shrink it back at the end.)


    (LET ((OrderingFn (LISTGET (NC.RetrievePropList ContentsID DatabaseStream)
			       (QUOTE OrderingFn)))
       (ShrunkenFlg (NC.GetShrunkenWin ContentsID)))
      (PROG1 (COND
	       ((FNTYP OrderingFn)
		 (NC.InsertLinkInOrdering ContentsID DestinationID (COND
					    ((EQ SubOrSuperFlg (QUOTE Sub))
					      NC.SubBoxLinkLabel)
					    (T NC.FiledCardLinkLabel))
					  NIL DatabaseStream NIL OrderingFn))
	       ((EQ SubOrSuperFlg (QUOTE Sub))
		 (NC.InsertLinkBeforeMarker ContentsID DestinationID NC.SubBoxLinkLabel NIL 2 
					    DatabaseStream))
	       (T (NC.InsertLinkBeforeMarker ContentsID DestinationID NC.FiledCardLinkLabel NIL NIL 
					     DatabaseStream)))
	     (if ShrunkenFlg
		 then (SHRINKW (NC.FetchWindow ContentsID)))))))

(NC.InsertLinkInOrdering
  (LAMBDA (SourceID DestinationID LinkLabel DisplayMode DatabaseStream NoSpacerFlg OrderingFn)
                                                             (* rht: "14-Jun-85 12:32")
                                                             (* Insert a link to DestinationID in SourceID.
							     Place to insert is dertermined alphabetically.)

          (* * rht 6/14/85: Fixed the CHLIM uses according to Intermezzo changes. Also took out some SEL setting that was 
	  useless. And changed TEDIT.SETSEL calls. Now uses OrderingFn arg so can do any sorts of orderings user wants.)


    (PROG (Objects TextStream TextObject SEL InsertCharPtr (Spacer (CONCAT (CHARACTER 13)))
		   Link)
          (COND
	    ((NC.ActiveCardP SourceID)
	      (SETQ TextStream (NC.FetchSubstance SourceID))
	      (SETQ TextObject (TEXTOBJ TextStream))
	      (COND
		((SETQ Objects (TEDIT.LIST.OF.OBJECTS TextObject (FUNCTION NC.LinkIconImageObjP)))
		  (for ObjectPair in Objects when (APPLY* OrderingFn DestinationID
							  (fetch (NOTECARDLINK DESTINATIONID)
							     of (NC.FetchLinkFromLinkIcon
								  (CAR ObjectPair))))
		     do (TEDIT.SETSEL TextStream (CADR ObjectPair)
				      0
				      (QUOTE LEFT))
			(RETURN NIL)
		     finally (TEDIT.SETSEL TextStream (GETEOFPTR TextStream)
					   0
					   (QUOTE RIGHT)))))
	      (SETQ SEL (fetch (TEXTOBJ SEL) of TextObject))
	      (SETQ Link (NC.InsertLinkInText TextStream LinkLabel DestinationID SourceID DisplayMode)
		)
	      (COND
		((NULL NoSpacerFlg)
		  (TEDIT.INSERT TextStream Spacer))))
	    (T (WITH.MONITOR (NC.FetchMonitor DatabaseStream)
			     (COND
			       ((NC.IDP (NC.GetNoteCard SourceID DatabaseStream))
				 (SETQ TextStream (NC.FetchSubstance SourceID))
				 (SETQ TextObject (TEXTOBJ TextStream))
				 (COND
				   ((SETQ Objects (TEDIT.LIST.OF.OBJECTS TextObject
									 (FUNCTION 
									   NC.LinkIconImageObjP)))
				     (for ObjectPair in Objects
					when (APPLY* OrderingFn DestinationID
						     (fetch (NOTECARDLINK DESTINATIONID)
							of (NC.FetchLinkFromLinkIcon (CAR ObjectPair))
							    ))
					do (TEDIT.SETSEL TextStream (CADR ObjectPair)
							 0
							 (QUOTE LEFT))
					   (RETURN NIL)
					finally (TEDIT.SETSEL TextStream (GETEOFPTR TextStream)
							      0
							      (QUOTE RIGHT)))))
				 (SETQ SEL (fetch (TEXTOBJ SEL) of TextObject))
				 (SETQ Link (NC.InsertLinkInText TextStream LinkLabel DestinationID 
								 SourceID DisplayMode))
				 (COND
				   ((NULL NoSpacerFlg)
				     (TEDIT.INSERT TextStream Spacer)))
				 (NC.PutNoteCard SourceID DatabaseStream)
				 (NC.PutLinks SourceID DatabaseStream)
				 (NC.DeactivateCard SourceID))))))
          (RETURN Link))))

(NC.IDAlphOrder
  (LAMBDA (ID1 ID2)                                          (* rht: "14-Jun-85 12:28")

          (* * Return T if ID1's title is alphabetically before ID2's.)


    (ALPHORDER (NCP.CardTitle ID1)
	       (NCP.CardTitle ID2))))

(NC.MakeLink
  (LAMBDA (Window LinkLabel DestinationID SourceID DisplayMode AnchorMode Message NoDisplayFlg 
		  LinkToInsertAfter)                         (* kirk: "23-Sep-85 22:56")
                                                             (* Make a link from (OR Window SourceID) to 
							     DestinationID 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)


    (PROG (LinkID Link Type)
          (OR SourceID (SETQ SourceID (NC.IDFromWindow Window)))
          (OR Window (SETQ Window (NC.FetchWindow SourceID)))
          (OR Message (SETQ Message "Please select the Card or Box to be linked to."))
          (OR DestinationID (SETQ DestinationID (NC.SelectNoteCards T
								    (FUNCTION (LAMBDA (CardID)
									(COND
									  ((NEQ CardID SourceID)
									    T)
									  (T (NC.PrintMsg
									       Window T 
							     "A Card/Box cannot link to itself. "
									       (CHARACTER 13)
									       "Selection ignored."
									       (CHARACTER 13))
									     NIL))))
								    NC.SelectingSingleCardMenu 
								    SourceID NIL Message)))
          (COND
	    ((EQ DestinationID '*New% Card*)
	      (SETQ DestinationID (AND (SETQ Type (NC.AskNoteCardType (WINDOWREGION Window)))
				       (NC.CoerceToID (NC.MakeNoteCard Type NIL NoDisplayFlg))))))
          (AND (NULL DestinationID)
	       (RETURN NIL))
          (SETQ LinkID (NC.GetNewLinkID PSA.Database))
          (SETQ Link
	    (create NOTECARDLINK
		    LINKID ← LinkID
		    SOURCEID ← SourceID
		    DESTINATIONID ← DestinationID
		    ANCHORMODE ← AnchorMode
		    LINKLABEL ← LinkLabel
		    DISPLAYMODE ←(OR DisplayMode (NC.DefaultLinkDisplayMode SourceID PSA.Database))))
          (NC.AddToLink Link PSA.Database LinkToInsertAfter)
          (NC.AddFromLink Link PSA.Database)
          (RETURN Link))))

(NC.MakeContentsHooks
  (LAMBDA (ID DatabaseStream)                                (* rht: "19-Aug-85 17:41")
                                                             (* Hooks card specified by ID to all of the current 
							     contents cards by a Contents link)

          (* * rht 8/1/84: Changed the NC.PrintMsg2 call for "No FileBox has been specified." to use NIL as second arg rather 
	  than T. This prevents erasure of previous error messages.)



          (* * rht 12/8/84: Massive rewrite. Now calls NC.MakeChildLink. And always orphanizes if no parent specified.
	  This is because it's currently called only by NC.InsureProperFiling.)



          (* * rht 6/25/85: Now returns NewParents and checks if CANCELLED comes back from NC.SelectNoteCards so can abort the
	  calling operation.)


    (PROG (OneHook (Window (NC.FetchWindow ID))
		   NewParents)
          (SETQ NewParents (NC.SelectNoteCards NIL (QUOTE NC.ContentsCardP)
					       NC.SelectingContentsMenu ID NIL (CONCAT 
						  "Please select the Boxes to file this card in."
										       (CHARACTER
											 13)
										       
				       "'Done' with no selections files it in the ToBeFiled box.")
					       T))
          (if (NOT (OR (EQ NewParents (QUOTE CANCELLED))
		       (AND NewParents (for ParentID in NewParents bind OneHook
					  when (NC.MakeChildLink ID ParentID Window)
					  do (SETQ OneHook T) finally (RETURN OneHook)))))
	      then (NC.PrintMsg Window NIL "No FileBox has been specified." (CHARACTER 13)
				"This card will be filed in the ToBeFiled Box."
				(CHARACTER 13))
		   (NC.HookToOrphanCard ID NC.UnclassifiedID DatabaseStream NIL))
          (COND
	    ((GETPROMPTWINDOW Window NIL NIL T)
	      (SPAWN.MOUSE)
	      (DISMISS 2000)
	      (NC.ClearMsg Window T)))
          (RETURN NewParents))))

(NC.RelabelLink
  (LAMBDA (LinkOrLinkIcon Window NewLinkLabel ForceRedisplayFlg)
                                                             (* rht: " 8-Feb-85 15:49" 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 ID is defined before first use.)


    (PROG (Link LinkIcon LinkID ID DestinationID OldLabel NoteCardType GlobalLinkFlg)
          (COND
	    ((NC.LinkIconImageObjP LinkOrLinkIcon)
	      (SETQ Link (NC.FetchLinkFromLinkIcon LinkOrLinkIcon))
	      (SETQ LinkIcon LinkOrLinkIcon))
	    (T (SETQ Link LinkOrLinkIcon)
	       (COND
		 ((NOT (SETQ GlobalLinkFlg (NC.GlobalLinkP Link)))
		   (SETQ LinkIcon (NC.FetchLinkIconForLink Link))))))
          (SETQ ID (fetch (NOTECARDLINK SOURCEID) of Link))
          (COND
	    ((WINDOWP Window))
	    ((NC.ActiveCardP ID)
	      (SETQ Window (NC.FetchWindow ID))))
          (COND
	    ((NC.SystemLinkLabelP (fetch (NOTECARDLINK LINKLABEL) 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 DestinationID (fetch (NOTECARDLINK DESTINATIONID) of Link))
	      (SETQ LinkID (fetch (NOTECARDLINK LINKID) of Link))
	      (SETQ NoteCardType (NC.FetchType ID))

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


	      (COND
		(GlobalLinkFlg (for GlobalLink in (NC.FetchGlobalLinks ID)
				  when (EQP (fetch (NOTECARDLINK LINKID) of GlobalLink)
					    LinkID)
				  do (replace (NOTECARDLINK LINKLABEL) of GlobalLink with 
										     NewLinkLabel)
				     (NC.SetLinksDirtyFlg ID T)
				     (RETURN)))
		(T (replace (NOTECARDLINK LINKLABEL) of (NC.FetchLinkFromLinkIcon LinkIcon)
		      with NewLinkLabel)
		   (NC.MarkCardDirty ID)))

          (* * Update ToLink list of the SourceID card)


	      (for ToLink in (NC.FetchToLinks ID) when (EQP (fetch (NOTECARDLINK LINKID)
							       of ToLink)
							    LinkID)
		 do (replace (NOTECARDLINK LINKLABEL) of ToLink with NewLinkLabel)
		    (NC.SetLinksDirtyFlg ID T)
		    (RETURN))

          (* * Update FromLink list of DestinationID card)


	      (COND
		((NC.ActiveCardP DestinationID)
		  (for FromLink in (NC.FetchFromLinks DestinationID)
		     when (EQP (fetch (NOTECARDLINK LINKID) of FromLink)
			       LinkID)
		     do (replace (NOTECARDLINK LINKLABEL) of FromLink with NewLinkLabel)
			(NC.SetLinksDirtyFlg DestinationID T)
			(RETURN)))
		(T (WITH.MONITOR (NC.FetchMonitor PSA.Database)
				 (NC.GetLinks DestinationID PSA.Database)
				 (for FromLink in (NC.FetchFromLinks DestinationID)
				    when (EQP (fetch (NOTECARDLINK LINKID) of FromLink)
					      LinkID)
				    do (replace (NOTECARDLINK LINKLABEL) of FromLink with 
										     NewLinkLabel)
				       (NC.SetLinksDirtyFlg DestinationID T)
				       (RETURN))
				 (NC.PutLinks DestinationID PSA.Database)
				 (NC.DeactivateCard DestinationID))))

          (* * Update images in SourceID window)


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

(NC.SystemLinkLabelP
  (LAMBDA (LinkLabel)                                        (* fgh: "23-Apr-84 23:07")
                                                             (* Return T in LinkLabel is a label for a system 
							     maintained link. NIL otherwise.
							     System maintained links determined by hardwire list for
							     now.)
    (FMEMB LinkLabel NC.SystemLinkLabels)))

(NC.ValidLinkP
  (LAMBDA (Link DatabaseStream ZeroLinkOkayFlg)              (* fgh: "29-May-84 16:07")
                                                             (* Check Link to see if it is a valid NOTECARDLINK, 
							     incvluding check that the NoteCard specified by 
							     DESTINATIONID is an active card.)
    (PROG (DestinationID)                                    (* If old format Link, just add on extra field)
          (AND (EQ (LENGTH Link)
		   2)
	       (NCONC1 Link NIL))
          (RETURN (AND (type? NOTECARDLINK Link)
		       (OR (NC.IDP (SETQ DestinationID (fetch (NOTECARDLINK DESTINATIONID)
							  of Link)))
			   (AND ZeroLinkOkayFlg (EQ DestinationID (QUOTE NC00000))))
		       (PROG1 (OR (AND ZeroLinkOkayFlg (EQ DestinationID (QUOTE NC00000)))
				  (EQ (NC.GetNoteCard DestinationID DatabaseStream)
				      DestinationID))
			      (NC.DeactivateCard DestinationID)))))))

(NC.MakeChildLink
  (LAMBDA (ChildID ParentID Window)                          (* rht: " 7-Dec-84 20:09")

          (* * Tries to add ChildID as a child of ParentID using either FiledCard or SubBox link as appropriate.
	  Won't allow if would cause a cycle. Returns new link if successful, else NIL.)


    (COND
      ((for Link in (NC.FetchToLinks ParentID) thereis (AND (NC.ChildLinkP Link)
							    (EQ ChildID (fetch (NOTECARDLINK 
										    DESTINATIONID)
									   of Link))))
	(NC.PrintMsg Window NIL (NC.RetrieveTitle ChildID PSA.Database)
		     " is already a child of "
		     (NC.RetrieveTitle ParentID PSA.Database)
		     (CHARACTER 13))
	NIL)
      ((AND (NEQ ParentID ChildID)
	    (NC.NotDaughterP ChildID ParentID (FUNCTION NC.ChildLinkP)))
	(NC.MakeAContentsHook ParentID ChildID (if (EQ (NC.FetchType ChildID)
						       (QUOTE FileBox))
						   then (QUOTE Sub))
			      PSA.Database))
      (T (NC.PrintMsg Window T (NC.RetrieveTitle ChildID PSA.Database)
		      " is an ancestor of "
		      (NC.RetrieveTitle ParentID PSA.Database)
		      (CHARACTER 13))
	 NIL))))

(NC.SameLinks
  (LAMBDA (LinkList1 LinkList2)                              (* rht: " 6-Feb-85 13:59")

          (* * Returns non-nil if every link in LinkList1 is in LinkList2 and vice versa. Uses LinkID as test of equality.)


    (PROG (LinkIDs1 LinkIDs2)
          (RETURN (OR (EQ (LENGTH LinkList1)
			  (LENGTH LinkList2))
		      (SETQ LinkIDs1 (for Link in LinkList1 collect (fetch (NOTECARDLINK LINKID)
								       of Link)))
		      (SETQ LinkIDs2 (for Link in LinkList2 bind LinkID
					collect (COND
						  ((FMEMB (SETQ LinkID (fetch (NOTECARDLINK LINKID)
									  of Link))
							  LinkIDs1)
						    LinkID)
						  (T (RETURN NIL)))))
		      (LDIFFERENCE LinkIDs2 LinkIDs1))))))

(NC.AddGlobalLinkToCard
  (LAMBDA (WindowOrTextStream)                               (* rht: "15-Feb-85 18:54")

          (* * Called from card's menu to add one global link.)


    (NC.AddGlobalLinksToCard WindowOrTextStream T)))

(NC.AddGlobalLinksToCard
  (LAMBDA (WindowOrTextStream SingleLinkFlg)                 (* rht: "15-Feb-85 19:10")

          (* * Called from card's menu to add some global links.)


    (PROG (Window SourceID DestinationIDs Label)
          (SETQ SourceID (NC.CoerceToID WindowOrTextStream))
          (SETQ Window (NC.FetchWindow SourceID))
          (SETQ Label (NC.AskLinkLabel (NC.FetchWindow (NC.CoerceToID WindowOrTextStream))
				       NIL NIL T T))
          (AND Label (if SingleLinkFlg
			 then (NC.MakeGlobalLink Window Label NIL SourceID)
			      (NC.ClearMsg Window T)
		       else (SETQ DestinationIDs (NC.SelectNoteCards
				NIL
				(FUNCTION (LAMBDA (CardID)
				    (COND
				      ((NEQ CardID SourceID)
					T)
				      (T (NC.PrintMsg (NC.FetchWindow SourceID)
						      T "A Card/Box cannot point to itself. "
						      (CHARACTER 13)
						      "Selection ignored."
						      (CHARACTER 13))
					 NIL))))
				NC.SelectingMultipleCardsMenu SourceID NIL 
				"Please select the Cards or Boxes to be pointed to."))
			    (NC.ClearMsg Window T)
			    (for DestinationID in DestinationIDs do (NC.MakeGlobalLink Window Label 
										    DestinationID 
										       SourceID)))))))

(NC.ChangeCardTitleFromLinkIcon
  (LAMBDA (LinkIcon Window)                                  (* rht: "31-Aug-85 16:19")

          (* * From a link icon sitting in Window, change the title of the link's destination card.)


    (LET (Link ID DestinationID OldTitle NewTitle)
      (if (NC.LinkIconImageObjP LinkIcon)
	  then (SETQ Link (NC.FetchLinkFromLinkIcon LinkIcon))
	       (SETQ ID (fetch (NOTECARDLINK SOURCEID) of Link))
	       (SETQ DestinationID (fetch (NOTECARDLINK DESTINATIONID) of Link))
	       (if (SETQ NewTitle (NC.AskUser (CONCAT "Enter new title for card with title '"
						      (NC.FetchTitle DestinationID)
						      "'"
						      (CHARACTER 13))
					      "-->  "
					      (if (AND (STREQUAL (SETQ OldTitle (NC.RetrieveTitle
								     DestinationID PSA.Database))
								 "Untitled")
						       (NC.FetchNewCardFlg DestinationID))
						  then NIL
						else OldTitle)
					      T Window))
		   then (NC.AssignTitle DestinationID NIL NewTitle)
			(QUOTE CHANGED))))))
)
(* * New Display Mode format)

(DEFINEQ

(NC.CheckDisplayModeFormat
  (LAMBDA (Link)                                             (* rht: "18-Jul-85 16:57")

          (* * If Link's display mode is an atom, then change to the new record format.)



          (* * rht 3/28/85: Now does nothing if link is not in current format. In that case, we should be inside of a 
	  ConvertVersion0ToVersion1 so that a later repair should fix the links.)



          (* * rht 7/17/85: Now turns into a typed record if wasn't already.)


    (LET (DisplayMode)
      (if (NEQ (CAR Link)
	       (QUOTE NOTECARDLINK))
	  then (SETQ Link (CONS (QUOTE NOTECARDLINK)
				Link)))
      (if (type? NOTECARDLINK Link)
	  then (COND
		 ((ATOM (SETQ DisplayMode (fetch (NOTECARDLINK DISPLAYMODE) of Link)))
		   (replace (NOTECARDLINK DISPLAYMODE) of Link with (NC.MakeNewDisplayMode 
										      DisplayMode)))
		 ((NEQ (CAR DisplayMode)
		       (QUOTE LINKDISPLAYMODE))
		   (replace (NOTECARDLINK DISPLAYMODE) of Link with (CONS (QUOTE LINKDISPLAYMODE)
									  DisplayMode)))))
      Link)))

(NC.MakeNewDisplayMode
  (LAMBDA (ModeAtom)                                         (* rht: " 9-Sep-85 22:12")

          (* * Makes a new display mode record structure using info in ModeAtom.)


    (create LINKDISPLAYMODE
	    SHOWTITLEFLG ←(AND (FMEMB ModeAtom (QUOTE (Title Both)))
			       T)
	    SHOWLINKTYPEFLG ←(AND (FMEMB ModeAtom (QUOTE (Label Both)))
				  T)
	    ATTACHBITMAPFLG ←(if (OR (NULL ModeAtom)
				     (EQ ModeAtom (QUOTE Icon)))
				 then T
			       else (QUOTE FLOAT)))))

(NC.DisplayModeFromStylesheetSelections
  (LAMBDA (Selections)                                       (* rht: "18-Jul-85 14:35")

          (* * Return the display mode corresponding to the user's selection from the changeDisplayMode stylesheet.)


    (AND Selections (create LINKDISPLAYMODE
			    SHOWTITLEFLG ←(LISTGET NC.MenuItems/DisplayModeValues (CAR Selections))
			    SHOWLINKTYPEFLG ←(LISTGET NC.MenuItems/DisplayModeValues (CADR Selections)
						      )
			    ATTACHBITMAPFLG ←(LISTGET NC.MenuItems/DisplayModeValues (CADDR 
										       Selections)))))
)

(NC.StylesheetSelectionsFromDisplayMode
  (LAMBDA (DisplayMode)                                      (* rht: "16-Mar-85 16:28")

          (* * Return the list of ChangeDisplayMode stylesheet selections corresponding to the given DisplayMode.)


    (LIST (SELECTQ (fetch (LINKDISPLAYMODE SHOWTITLEFLG) of DisplayMode)
		   (NIL (QUOTE No))
		   (FLOAT (QUOTE Float))
		   (QUOTE Yes))
	  (SELECTQ (fetch (LINKDISPLAYMODE SHOWLINKTYPEFLG) of DisplayMode)
		   (NIL (QUOTE No))
		   (FLOAT (QUOTE Float))
		   (QUOTE Yes))
	  (SELECTQ (fetch (LINKDISPLAYMODE ATTACHBITMAPFLG) of DisplayMode)
		   (NIL (QUOTE No))
		   (FLOAT (QUOTE Float))
		   (QUOTE Yes)))))

(NC.CheckLinkRecordFormat
  (LAMBDA (Links)                                            (* rht: "18-Jul-85 16:18")

          (* * Makes sure links are typedrecords and inserts NOTECARDLINK in car if not. Does it in place to save space)


    (for RestOfLinks on Links when (NEQ (CAAR RestOfLinks)
					(QUOTE NOTECARDLINK))
       do (RPLACA RestOfLinks (CONS (QUOTE NOTECARDLINK)
				    (CAR RestOfLinks))))
    Links))
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.MenuItems/DisplayModeValues)
)

(RPAQQ NC.MenuItems/DisplayModeValues (Yes T No NIL Float FLOAT Yes T No NIL Float FLOAT Yes T No NIL 
					   Float FLOAT))
(* * New fns to support No-Link cards/substances)

(DEFINEQ

(NC.LinksSupportedP
  (LAMBDA (ID AnchorModesList)                               (* fgh: " 8-Feb-85 21:00")

          (* * Are all of the anchor modes supporterd by the card ID)


    (PROG ((SupportedAnchorModes (NC.LinkAnchorModesFromType (NC.FetchType ID))))
          (COND
	    ((EQ SupportedAnchorModes T)
	      (RETURN T))
	    ((NULL SupportedAnchorModes)
	      (RETURN NIL))
	    (T (RETURN (for AnchorMode in AnchorModesList always (FMEMB AnchorMode 
									SupportedAnchorModes))))))))

(NC.LinkAnchorModesFromType
  (LAMBDA (NoteCardType)                                     (* fgh: " 8-Feb-85 18:59")

          (* * Return a list of the link anchor modes supported by cards of type NoteCardType)


    (PROG ((Result (NC.Inherit NC.LinkAnchorModesFromType CardLinkAnchorModesSupported 
			       SubstanceLinkAnchorModesSupported NoteCardType)))
          (COND
	    ((EQ Result T)
	      (RETURN T))
	    (T (RETURN (MKLIST Result)))))))
)
(* * This stuff supports the "push-copy" method of copying links in NC)

(DEFINEQ

(NC.PushCopyLinkIcon
  (LAMBDA (LinkIcon Window)                                  (* fgh: "12-Jul-85 12:41")

          (* * Do a push-copy of LinkIcon from Window)


    (PROG (ID NoteCardType InsertLinkFn TranslatePositionFn NewLinkIcon ScreenPosition NewWindow 
	      WindowPositionX WindowPositionY InsertPos)
          (SETQ ScreenPosition (GETPOSITION))
          (SETQ NewWindow (WHICHW ScreenPosition))
          (SETQ WindowPositionX (LASTMOUSEX NewWindow))
          (SETQ WindowPositionY (LASTMOUSEY NewWindow))
          (COND
	    ((AND (WINDOWP NewWindow)
		  (SETQ ID (NC.IDFromWindow NewWindow))
		  (SETQ NoteCardType (NC.FetchType ID))
		  (SETQ InsertLinkFn (NC.InsertLinkFn NoteCardType))
		  (SETQ TranslatePositionFn (NC.TranslateWindowPositionFn NoteCardType)))
	      (SETQ InsertPos (APPLY* TranslatePositionFn NewWindow WindowPositionX WindowPositionY))
	      (SETQ NewLinkIcon (APPLY* (IMAGEOBJPROP LinkIcon (QUOTE COPYFN))
					LinkIcon))
	      (AND (NEQ (APPLY* (IMAGEOBJPROP LinkIcon (QUOTE WHENCOPIEDFN))
				LinkIcon
				(WINDOWPROP NewWindow (QUOTE DSP))
				(WINDOWPROP Window (QUOTE TEXTSTREAM))
				(WINDOWPROP NewWindow (QUOTE TEXTSTREAM)))
			(QUOTE DON'T))
		   (APPLY* InsertLinkFn NewWindow (NC.FetchLinkFromLinkIcon NewLinkIcon)
			   InsertPos))))
          (RETURN NIL))))
)
(* * Link display icons)

(DEFINEQ

(NC.SetLinkInLinkIcon
  (LAMBDA (LinkIcon Link)                                    (* fgh: "16-Oct-84 23:41")

          (* * Set LinkIcon to be the icon for Link)


    (IMAGEOBJPROP LinkIcon (QUOTE OBJECTDATUM)
		  Link)))

(NC.FetchLinkIconForLink
  (LAMBDA (Link)                                             (* fgh: "23-Oct-84 11:52")

          (* * Find the Link Icon corresponding to Link)


    (PROG ((LinkID (fetch (NOTECARDLINK LINKID) of Link))
	   (SourceID (fetch (NOTECARDLINK SOURCEID) of Link)))
          (RETURN (for LinkIcon in (CAR (APPLY* (NC.CollectReferencesFn (NC.FetchType SourceID))
						SourceID NIL PSA.Database T))
		     thereis (COND
			       ((EQ LinkID (fetch (NOTECARDLINK LINKID) of (NC.FetchLinkFromLinkIcon
									     LinkIcon)))
				 LinkIcon)
			       (T NIL)))))))

(NC.MakeLinkIcon
  (LAMBDA (Link)                                             (* fgh: " 1-Oct-84 20:48")

          (* * Create a Link Icon image object from the lionk info in Link)


    (IMAGEOBJCREATE Link NC.LinkIconImageFns)))

(NC.LinkIconButtonEventInFn
  (LAMBDA (ImageObject WINDOW)                               (* rht: "18-Oct-85 17:16")
                                                             (* If the guy buttons inside a link image object)
    (PROG (ID ClippingRegion HotRegion LeftButtonFlg (Link (NC.FetchLinkFromLinkIcon ImageObject)))
          (SETQ WINDOW (COND
	      ((WINDOWP WINDOW)
		WINDOW)
	      ((DISPLAYSTREAMP WINDOW)
		(WFROMDS WINDOW))
	      ((TEXTSTREAMP WINDOW)
		(WINDOW.FROM.TEDIT.THING WINDOW))
	      (T NIL)))
          (SETQ LeftButtonFlg (MOUSESTATE LEFT))
          (SETQ ClippingRegion (DSPCLIPPINGREGION NIL WINDOW))
          (SETQ HotRegion (CREATEREGION (IPLUS (fetch (REGION LEFT) of ClippingRegion)
					       (FTIMES .25 (fetch (REGION WIDTH) of ClippingRegion)))
					(fetch (REGION BOTTOM) of ClippingRegion)
					(FTIMES .5 (fetch (REGION WIDTH) of ClippingRegion))
					(fetch (REGION HEIGHT) of ClippingRegion)))
          (until (OR (MOUSESTATE UP)
		     (INSIDEP HotRegion (LASTMOUSEX WINDOW)
			      (LASTMOUSEY WINDOW))))
          (AND (MOUSESTATE UP)
	       (RETURN NIL))
          (RESETLST (RESETSAVE (INVERTW WINDOW))
		    (until (OR (MOUSESTATE UP)
			       (NOT (INSIDEP HotRegion (LASTMOUSEX WINDOW)
					     (LASTMOUSEY WINDOW))))))
          (COND
	    ((INSIDEP HotRegion (LASTMOUSEX WINDOW)
		      (LASTMOUSEY WINDOW))
	      (RETURN (COND
			((EQ NC.SelectionInProgress T)       (* A selection is in progress.
							     Don't really want to edit this object, want to select 
							     it. Just add to the selection collection list.)
			  (AND (SETQ ID (fetch (NOTECARDLINK DESTINATIONID) of Link))
			       (NOT (FMEMB ID NC.SelectedCards))
			       (SETQ NC.SelectedCards (CONS ID NC.SelectedCards)))
			  (QUOTE DON'T))
			((AND (KEYDOWNP (QUOTE LSHIFT))
			      (NOT (KEYDOWNP (QUOTE CTRL))))
			  (NC.PushCopyLinkIcon ImageObject WINDOW)
			  (QUOTE DON'T))
			((OR (KEYDOWNP (QUOTE LSHIFT))
			     (KEYDOWNP (QUOTE CTRL)))
			  (QUOTE DON'T))
			((EQ NC.SelectionInProgress (QUOTE Links))
			  (AND (NOT (MEMBER Link NC.SelectedCards))
			       (SETQ NC.SelectedCards (CONS Link NC.SelectedCards)))
			  (QUOTE DON'T))
			(LeftButtonFlg (NC.EditNoteCard (fetch (NOTECARDLINK DESTINATIONID)
							   of Link))
				       (QUOTE DON'T))
			(T (NC.LinkIconMiddleButtonFn ImageObject WINDOW)))))
	    ((INSIDEP ClippingRegion (LASTMOUSEX WINDOW)
		      (LASTMOUSEY WINDOW))
	      (RETURN NIL))))))

(NC.LinkIconDisplayFn
  (LAMBDA (ImageObj ImageStream STREAMTYPE TEXTSTREAM SCALE)
                                                             (* rht: "17-Mar-85 19:19")

          (* * Display a link icon)



          (* * rht 11/13/84: Made width of box lines also scale dependent.)



          (* * rht 12/4/84: Hacked so type-dependent icons come out optionally to left of text.)



          (* * rht 2/9/85: Changed to use new display mode format.)


    (PROG (YSize XSize Left Bottom TitleDisplayMode LinkDisplayMode AttachBitmapFlg DisplayType 
		 Window ID Title Label BoxLeft BoxBottom BoxWidth BoxHeight TextLeft TextBaseLine 
		 ImageBox (Scale (DSPSCALE NIL ImageStream))
		 (Link (NC.FetchLinkFromLinkIcon ImageObj))
		 (Font NC.LinkIconFont)
		 TypeIcon OldBox)

          (* * Determine what type of Display to do)


          (SETQ DisplayType (fetch (NOTECARDLINK DISPLAYMODE) of Link))
          (SETQ ID (fetch (NOTECARDLINK DESTINATIONID) of Link))
          (SETQ TitleDisplayMode (fetch (LINKDISPLAYMODE SHOWTITLEFLG) of DisplayType))
          (SETQ LinkDisplayMode (fetch (LINKDISPLAYMODE SHOWLINKTYPEFLG) of DisplayType))
          (SETQ AttachBitmapFlg (fetch (LINKDISPLAYMODE ATTACHBITMAPFLG) of DisplayType))
          (SETQ Title (SELECTQ TitleDisplayMode
			       (SOURCE (NC.RetrieveTitle (SETQ ID (fetch (NOTECARDLINK SOURCEID)
								     of Link))))
			       (FLOAT (AND NC.LinkIconShowTitleFlg (NC.RetrieveTitle ID PSA.Database))
				      )
			       (NIL NIL)
			       (NC.RetrieveTitle ID PSA.Database)))
          (SETQ Label (AND (if (EQ LinkDisplayMode (QUOTE FLOAT))
			       then NC.LinkIconShowLinkTypeFlg
			     else LinkDisplayMode)
			   (fetch (NOTECARDLINK LINKLABEL) of Link)))
          (SETQ TypeIcon (AND (if (EQ AttachBitmapFlg (QUOTE FLOAT))
				  then NC.LinkIconAttachBitmapFlg
				else AttachBitmapFlg)
			      (NC.GetTypeIcon (NC.FetchType ID))))
                                                             (* If there's nothing to print, then put out a tiny 
							     uninformative icon.)
          (if (AND (NULL Label)
		   (NULL Title)
		   (NULL TypeIcon))
	      then (SETQ TypeIcon NC.TypelessIcon))

          (* * Get the image box info for this icon)


          (SETQ ImageBox (OR (SETQ OldBox (IMAGEOBJPROP ImageObj (QUOTE BOUNDBOX)))
			     (NC.LinkIconImageBoxFn ImageObj ImageStream NIL NIL NIL DisplayType 
						    Title Label)))
          (SETQ XSize (fetch (IMAGEBOX XSIZE) of ImageBox))
          (SETQ YSize (fetch (IMAGEBOX YSIZE) of ImageBox))
          (SETQ Bottom (IDIFFERENCE (DSPYPOSITION NIL ImageStream)
				    (fetch (IMAGEBOX YDESC) of ImageBox)))
          (SETQ Left (DSPXPOSITION NIL ImageStream))

          (* * Put out the icon bitmap for the appropriate type.)


          (COND
	    (TypeIcon (SELECTQ (OR STREAMTYPE (SETQ STREAMTYPE (IMAGESTREAMTYPE ImageStream)))
			       (DISPLAY (BITBLT TypeIcon 0 0 ImageStream (IPLUS Scale Left)
						(IPLUS Scale Bottom)))
			       (PRESS (\WRITEPRESSBITMAP TypeIcon (IPLUS Scale Left)
							 (IPLUS Scale Bottom)
							 NIL NIL ImageStream))
			       (INTERPRESS (MOVETO (IPLUS Scale Left)
						   (IPLUS Scale Bottom)
						   ImageStream)
					   (SHOWBITMAP.IP ImageStream TypeIcon NIL NIL NIL))
			       (NC.ReportError "NC.LinkIconDisplayFn" (CONCAT STREAMTYPE 
					       " is not a stream type that Notecards knows about")))))
                                                             (* Get out if nothing to print but icon.)
          (AND (NULL Title)
	       (NULL Label)
	       (RETURN))

          (* * Draw a box around the border of the link icon)


          (SETQ BoxLeft (IPLUS (COND
				 (TypeIcon (TIMES Scale (BITMAPWIDTH TypeIcon)))
				 (T Scale))
			       Left))
          (SETQ BoxBottom (IPLUS Scale Bottom))
          (SETQ BoxWidth (IDIFFERENCE XSize (TIMES Scale (PLUS 4 (COND
								 (TypeIcon (BITMAPWIDTH TypeIcon))
								 (T 0))))))
          (SETQ BoxHeight (IDIFFERENCE YSize (TIMES Scale 4)))
          (MOVETO BoxLeft BoxBottom ImageStream)
          (RELDRAWTO BoxWidth 0 Scale NIL ImageStream)
          (RELDRAWTO 0 BoxHeight Scale NIL ImageStream)
          (RELDRAWTO (MINUS BoxWidth)
		     0 Scale NIL ImageStream)
          (OR TypeIcon (DRAWTO BoxLeft BoxBottom Scale NIL ImageStream))

          (* * Enter the appropriate text.)


          (SETQ TextLeft (IPLUS BoxLeft (TIMES Scale 5)))
          (SETQ TextBaseLine (IPLUS Bottom (TIMES Scale 3)
				    (FONTPROP Font (QUOTE DESCENT))))
          (DSPXPOSITION TextLeft ImageStream)
          (DSPYPOSITION TextBaseLine ImageStream)
          (DSPFONT (PROG1 (DSPFONT Font ImageStream)
			  (AND Label (PRIN1 (CONCAT "<" Label ">")
					    ImageStream))
			  (AND Label Title (PRIN1 " " ImageStream))
			  (AND Title (PRIN1 Title ImageStream)))
		   ImageStream))))

(NC.LinkIconImageBoxFn
  (LAMBDA (ImageObj ImageStream CurrentX RightMargin DummyArg DisplayType Title Label)
                                                             (* rht: "16-Mar-85 17:22")

          (* * rht 9/20/84: Now scales result before returning by proper amount depending on stream type.
	  e.g. for PRESS and INTERPRESS.)



          (* * rht 11/13/84: In computation of XSIZE, extra width is figured using characters in the font, "nn", rather than 
	  absolute pixel count.)



          (* * rht 2/9/85: Now uses new displaymode format.)


    (PROG ((FONT NC.LinkIconFont)
	   Window ID NoteCardType (Link (NC.FetchLinkFromLinkIcon ImageObj))
	   (Scale (DSPSCALE NIL ImageStream))
	   TypeIcon Label Title AttachBitmapFlg TitleDisplayMode LinkDisplayMode)
          (OR DisplayType (SETQ DisplayType (fetch (NOTECARDLINK DISPLAYMODE) of Link)))
          (SETQ ID (fetch (NOTECARDLINK DESTINATIONID) of Link))
          (SETQ TitleDisplayMode (fetch (LINKDISPLAYMODE SHOWTITLEFLG) of DisplayType))
          (SETQ LinkDisplayMode (fetch (LINKDISPLAYMODE SHOWLINKTYPEFLG) of DisplayType))
          (SETQ AttachBitmapFlg (fetch (LINKDISPLAYMODE ATTACHBITMAPFLG) of DisplayType))
          (SETQ Title (SELECTQ TitleDisplayMode
			       (SOURCE (NC.RetrieveTitle (SETQ ID (fetch (NOTECARDLINK SOURCEID)
								     of Link))))
			       (FLOAT (AND NC.LinkIconShowTitleFlg (NC.RetrieveTitle ID PSA.Database))
				      )
			       (NIL NIL)
			       (NC.RetrieveTitle ID PSA.Database)))
          (SETQ Label (AND (if (EQ LinkDisplayMode (QUOTE FLOAT))
			       then NC.LinkIconShowLinkTypeFlg
			     else LinkDisplayMode)
			   (fetch (NOTECARDLINK LINKLABEL) of Link)))
          (SETQ TypeIcon (AND (if (EQ AttachBitmapFlg (QUOTE FLOAT))
				  then NC.LinkIconAttachBitmapFlg
				else AttachBitmapFlg)
			      (NC.GetTypeIcon (NC.FetchType ID))))
                                                             (* If there's nothing to print, then put out a tiny 
							     uninformative icon.)
          (if (AND (NULL Label)
		   (NULL Title)
		   (NULL TypeIcon))
	      then (SETQ TypeIcon NC.TypelessIcon))
          (RETURN (create IMAGEBOX
			  XSIZE ←(TIMES Scale
					(IPLUS (if TypeIcon
						   then (BITMAPWIDTH TypeIcon)
						 else 0)
					       (if (OR Label Title)
						   then (STRINGWIDTH (CONCAT "nn"
									     (if Label
										 then (CONCAT "<" 
											    Label ">")
									       else "")
									     (if (AND Label Title)
										 then " "
									       else "")
									     (OR Title ""))
								     FONT)
						 else 2)))
			  YSIZE ←(IMAX (if TypeIcon
					   then (TIMES Scale (BITMAPHEIGHT TypeIcon))
					 else 0)
				       (TIMES Scale (PLUS 8 (FONTPROP FONT (QUOTE HEIGHT)))))
			  YDESC ←(COND
			    (RightMargin                     (* This is in a TEdittextstream)
					 (FONTPROP FONT (QUOTE DESCENT)))
			    (T 0))
			  XKERN ← 0)))))

(NC.LinkIconImageObjP
  (LAMBDA (IMAGEOBJ)                                         (* fgh: " 1-Oct-84 20:04")

          (* * Is IMAGEOBJ a Link Icon?)


    (AND (IMAGEOBJP IMAGEOBJ)
	 (EQ (FUNCTION NC.LinkIconGetFn)
	     (IMAGEOBJPROP IMAGEOBJ (QUOTE GETFN))))))

(NC.LinkIconPutFn
  (LAMBDA (ImageObject Stream)                               (* fgh: "30-Oct-84 22:43")

          (* * Writes the Link information in the link icon specified by ImageObject onto the file specified by Stream)


    (PRIN2 (NC.FetchLinkFromLinkIcon ImageObject)
	   Stream)))

(NC.LinkIconGetFn
  (LAMBDA (Stream)                                           (* rht: " 9-Feb-85 23:42")

          (* * Reads the link information from Stream and returns a link icon image object for this link info.
	  If the value on the stream is an atom in the old style, convert to a proper record.)


    (NC.MakeLinkIcon (NC.CheckDisplayModeFormat (READ Stream)))))

(NC.LinkIconMiddleButtonFn
  (LAMBDA (ImageObject Window)                               (* rht: "16-Aug-85 19:58")
                                                             (* Middle button has been pressed in the Notecard 
							     pointer. Bring up menu of choices for manipulating this
							     pointer.)
    (PROG ((ID (fetch (NOTECARDLINK DESTINATIONID) of (NC.FetchLinkFromLinkIcon ImageObject))))
          (COND
	    ((NC.IDP (NC.IDFromWindow Window))
	      (SELECTQ (MENU (COND
			       ((type? MENU NC.LinkIconMiddleButtonMenu)
				 NC.LinkIconMiddleButtonMenu)
			       (T (SETQ NC.LinkIconMiddleButtonMenu
				    (create MENU
					    ITEMS ←(QUOTE ((Bring% Up% Card/Box (QUOTE Edit)
										
					     "Bring up the note card pointed to by this pointer.")
							    (Change% Link% Type (QUOTE Relabel)
										
							      "Change the label of this pointer.")
							    (Change% Card% Title (QUOTE Retitle)
										 
							   "Change the destination card's title.")
							    (Change% Display% Mode (QUOTE Display)
										   
				      "Change the type of information displayed in this pointer.")))
					    CENTERFLG ← T
					    TITLE ← "Link Ops")))))
		       (Edit (NC.EditNoteCard ID))
		       (Display (RETURN (NC.ChangeLinkDisplayMode ImageObject Window)))
		       (Relabel (RETURN (NC.RelabelLink ImageObject Window)))
		       (Retitle (RETURN (NC.ChangeCardTitleFromLinkIcon ImageObject Window)))
		       NIL))
	    (T (NC.EditNoteCard ID))))))

(NC.LinkIconWhenCopiedFn
  (LAMBDA (ImageObject ToWindowStream FromTextStream ToTextStream)
                                                             (* rht: "21-Sep-85 13:18")

          (* * Called when copying a link icon from FromTextStream to ToWindowStream. Sets the necessary link information up 
	  for card corresponding to ToWindowStream.)



          (* * rht 11/18/84: Major hacking. Now checks for all sorts of illegal cases. Either goes ahead with copy, converts 
	  link type to "Unspecified", or deletes the new "invisible" link. The latter will change when imageobj fns can return
	  DON'T.)



          (* * rht 12/12/84: now does RETFROM instead of adding processes to delete imageobj's. This is cleaner, but still 
	  ugly.)



          (* * rht 3/25/85: Fixed to handle copies within a sketch card. That is indicated by nullity of the two textstream 
	  args.)


    (PROG (Label (Link (NC.FetchLinkFromLinkIcon ImageObject))
		 SourceID DestID NewSourceID NewLabel NewDisplayMode OldDisplayMode
		 (ImageObjectCopy (IMAGEOBJPROP ImageObject (QUOTE ImageObjectCopy)))
		 (Window (AND ToWindowStream (WFROMDS ToWindowStream T)))
		 (InTEditCopyFlg (COND
				   ((STKPOS (QUOTE TEDIT.COPY))
				     T)))
		 InsertPos)
          (SETQ Label (fetch (NOTECARDLINK LINKLABEL) of Link))
          (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of Link))
          (SETQ DestID (fetch (NOTECARDLINK DESTINATIONID) of Link))
          (SETQ OldDisplayMode (fetch (NOTECARDLINK DISPLAYMODE) of Link))
          (SETQ NewSourceID (COND
	      ((WINDOWP Window)
		(NC.IDFromWindow Window))
	      ((TEXTSTREAMP ToTextStream)
		(NC.CoerceToID ToTextStream))))
          (COND
	    ((AND (NULL FromTextStream)
		  (NULL ToTextStream))                       (* We must be moving within a sketch.)
	      (SETQ NewSourceID SourceID))
	    ((TEXTSTREAMP ToTextStream)                      (* If it's a text copy, then compute position to insert
							     link at.)
	      (SETQ InsertPos (NC.CharPosFromTextObject (TEXTOBJ ToTextStream)))))
          (COND
	    ((NULL NewSourceID)                              (* Trying to copy to a non NoteCard stream)
	      (NC.PrintMsg Window NIL (CONCAT "Tried to copy a NoteCards link icon" 
					      " to a non-NoteCards stream."
					      (CHARACTER 13)))
	      (NC.CoerceToExternalPutLinkIcon ImageObjectCopy SourceID DestID Label)
	      (RETURN NIL))
	    ((NULL (NC.LinksSupportedP NewSourceID (QUOTE (Local))))
	      (NC.PrintMsg Window NIL (CONCAT "Tried to copy a NoteCards link icon" 
					      " to a NoteCard that"
					      " does not support links!!."
					      (CHARACTER 13)
					      "Tsk. Tsk."
					      (CHARACTER 13)))
	      (COND
		(InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					 NIL T))
		(T (RETURN (QUOTE DON'T)))))
	    ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		  (NEQ (NC.FetchType NewSourceID)
		       (QUOTE FileBox)))                     (* Copy from filebox to non-filebox.)
	      (NC.PrintMsg NIL NIL (CONCAT "Tried to copy filedcard or subbox link to a non-filebox."
					   (CHARACTER 13)
					   "Link type of copy set to 'Unspecified'."
					   (CHARACTER 13)))
	      (SETQ NewLabel NC.UnspecifiedLinkLabel)
	      (SETQ NewDisplayMode (create LINKDISPLAYMODE copying OldDisplayMode SHOWTITLEFLG ← T 
								   SHOWLINKTYPEFLG ← T)))
	    ((AND (NEQ (NC.FetchType SourceID)
		       (QUOTE FileBox))
		  (EQ (NC.FetchType NewSourceID)
		      (QUOTE FileBox)))                      (* Copy from non-filebox to filebox.)
	      (NC.PrintMsg NIL NIL (CONCAT "Can't copy links from non-filebox to filebox."
					   (CHARACTER 13)
					   "Try using 'PutCardsHere'."
					   (CHARACTER 13)))
	      (COND
		(InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					 NIL T))
		(T (RETURN (QUOTE DON'T)))))
	    ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		  (EQ NewSourceID SourceID))                 (* Copy within same filebox.)
	      (NC.PrintMsg NIL NIL (CONCAT "Can't copy links within a FileBox.  Try move instead."
					   (CHARACTER 13)))
	      (COND
		(InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					 NIL T))
		(T (RETURN (QUOTE DON'T)))))
	    ((AND (EQ (NC.FetchType NewSourceID)
		      (QUOTE FileBox))
		  (for Link1 in (NC.FetchToLinks NewSourceID)
		     thereis (AND (NC.ChildLinkP Link1)
				  (EQ DestID (fetch (NOTECARDLINK DESTINATIONID) of Link1)))))
                                                             (* Copy to a filebox already containing this child.)
	      (NC.PrintMsg NIL NIL (CONCAT (NC.RetrieveTitle DestID PSA.Database)
					   " not copied: already appears as a child of "
					   (NC.RetrieveTitle NewSourceID PSA.Database)
					   (CHARACTER 13)))
	      (COND
		(InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					 NIL T))
		(T (RETURN (QUOTE DON'T)))))
	    ((AND (EQ Label (QUOTE SubBox))
		  (OR (EQ NewSourceID DestID)
		      (NOT (NC.NotDaughterP DestID NewSourceID (FUNCTION NC.ChildLinkP)))))
                                                             (* Copy to a filebox causes a cycle.)
	      (NC.PrintMsg NIL NIL (CONCAT "Couldn't copy " Link " because of subbox cycle."
					   (CHARACTER 13)))
	      (COND
		(InTEditCopyFlg (RETFROM (QUOTE TEDIT.COPY)
					 NIL T))
		(T (RETURN (QUOTE DON'T)))))
	    ((AND (FMEMB Label NC.SystemLinkLabels)
		  (NOT (FMEMB Label (QUOTE (FiledCard SubBox))))
		  (NEQ NewSourceID SourceID))                (* Copy of system link outside of own card.)
	      (NC.PrintMsg NIL NIL (CONCAT "Tried to copy system link." (CHARACTER 13)
					   "Link type of copy set to 'Unspecified'."
					   (CHARACTER 13)))
	      (SETQ NewLabel NC.UnspecifiedLinkLabel)
	      (SETQ NewDisplayMode (create LINKDISPLAYMODE copying OldDisplayMode SHOWTITLEFLG ← T 
								   SHOWLINKTYPEFLG ← T))))
          (NC.FillInLinkIcon ImageObjectCopy (OR NewLabel Label)
			     DestID NewSourceID (OR NewDisplayMode OldDisplayMode)
			     (NC.LinkAtCharPos InsertPos ToTextStream)))))

(NC.LinkIconWhenDeletedFn
  (LAMBDA (ImageObject Stream)                               (* rht: "17-Mar-85 18:36")

          (* * When deleting a link icon image object from a card, make sure the link information on the source and 
	  destinmation cards get updated. When deleting a link image object from a prop list editor, just inform the user that
	  this is a useless operation.)



          (* * rht 11/19/84: Now handles the case when a move is in progress. True if the old link is cached on the ImageObj.
	  Also changed so that SourceID is computed from ImageObject rather than from Stream. Similarly for the window.)


    (PROG (Link SourceID DestinationID LinkType Window OldLink)
          (SETQ Link (NC.FetchLinkFromLinkIcon ImageObject))
          (COND
	    ((SETQ OldLink (IMAGEOBJPROP ImageObject (QUOTE LinkBeingMoved)))
	      (NC.DelFromLink OldLink PSA.Database)
	      (NC.DelToLink OldLink PSA.Database)
	      (replace (NOTECARDLINK LINKID) of OldLink with -1)
	      (IMAGEOBJPROP ImageObject (QUOTE LinkBeingMoved)
			    NIL))
	    ((AND (NC.IDP (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of Link)))
		  (NEQ (fetch (NOTECARDLINK ANCHORMODE) of Link)
		       (QUOTE GlobalGlobal))
		  (IMAGEOBJPROP ImageObject (QUOTE InsidePropListEditor)))
	      (SETQ Window (NC.FetchWindow SourceID))
	      (NC.PrintMsg Window T "Note:" (CHARACTER 13)
			   "Deleting a link from this list does NOT"
			   (CHARACTER 13)
			   "delete the link from the card."
			   (CHARACTER 13))
	      (ADD.PROCESS (LIST (QUOTE PROGN)
				 (QUOTE (DISMISS 5000))
				 (LIST (QUOTE AND)
				       (LIST (QUOTE OPENWP)
					     Window)
				       (LIST (QUOTE GETPROMPTWINDOW)
					     Window NIL NIL T)
				       (LIST (QUOTE NC.ClearMsg)
					     Window T)))))
	    (T (SETQ DestinationID (fetch (NOTECARDLINK DESTINATIONID) of Link))
	       (NC.CheckForOrphanDelete SourceID DestinationID)
	       (NC.DelFromLink Link PSA.Database)
	       (NC.DelToLink Link PSA.Database)
	       (replace (NOTECARDLINK LINKID) of Link with -1))))))

(NC.LinkIconWhenInsertedFn
  (LAMBDA (ImageObj WindowStream)                            (* fgh: " 5-Oct-84 12:43")
                                                             (* An Notecard link is being inserted.
							     If this is a deleteundo, then have to re-establish the 
							     link information)
    (PROG ((StackPointer (STKPOS (QUOTE TEDIT.UNDO.DELETION)))
	   SourceID Link)
          (COND
	    ((NULL StackPointer)
	      (RELSTK StackPointer)
	      (RETURN))
	    (T (RELSTK StackPointer)
	       (SETQ SourceID (NC.IDFromWindow WindowStream))
	       (COND
		 ((NC.IDP SourceID)
		   (SETQ Link (NC.FetchLinkFromLinkIcon ImageObj))
		   (NC.AddFromLink Link PSA.Database)
		   (NC.AddToLink Link PSA.Database))))))))

(NC.LinkIconWhenMovedFn
  (LAMBDA (ImageObject ToWindowStream FromTextStream ToTextStream)
                                                             (* rht: "18-Oct-85 11:49")

          (* * Called when moving a link icon from FromTextStream to ToWindowStream. Sets the necessary link information up 
	  for card corresponding to ToWindowStream.)



          (* * rht 11/18/84: Major hacking. Now checks for all sorts of illegal cases. Either goes ahead with move, converts 
	  link type to "Unspecified", or deletes the new "invisible" link. The code is very similar to NC.LinkIconWhenCopiedFn
	  except that within-filebox moves are allowed. Also when aborting a move, we must insert a copy of the link back to 
	  take the place of the deleted original. This will all change when imageobj fns can return DON'T.)



          (* * rht 12/12/84: Now just RETFROM's rather than doing the addprocess stuff. Should be cleaner, but still ugly.)


    (PROG (Label (Link (NC.FetchLinkFromLinkIcon ImageObject))
		 SourceID DestID NewSourceID NewLabel NewDisplayMode OldDisplayMode
		 (Window (AND ToWindowStream (WFROMDS ToWindowStream T)))
		 InsertPos)
          (SETQ Label (fetch (NOTECARDLINK LINKLABEL) of Link))
          (SETQ NewSourceID (COND
	      ((WINDOWP Window)
		(NC.IDFromWindow Window))
	      ((TEXTSTREAMP ToTextStream)
		(NC.CoerceToID ToTextStream))))
          (SETQ SourceID (fetch (NOTECARDLINK SOURCEID) of Link))
          (SETQ DestID (fetch (NOTECARDLINK DESTINATIONID) of Link))
          (SETQ OldDisplayMode (fetch (NOTECARDLINK DISPLAYMODE) of Link))
          (COND
	    ((AND (NULL FromTextStream)
		  (NULL ToTextStream))                       (* We must be moving within a sketch.)
	      (SETQ NewSourceID SourceID))
	    ((TEXTSTREAMP ToTextStream)                      (* If it's a text copy, then compute position to insert
							     link at.)
	      (SETQ InsertPos (NC.CharPosFromTextObject (TEXTOBJ ToTextStream)))))
          (COND
	    ((NULL NewSourceID)                              (* Trying to copy to a non NoteCard stream)
	      (NC.PrintMsg Window NIL (CONCAT "Tried to move a NoteCards link icon" 
					      " to a non-NoteCards stream!!."
					      (CHARACTER 13)
					      "Tsk. Tsk."
					      (CHARACTER 13)))
	      (RETFROM (QUOTE TEDIT.MOVE)
		       NIL T))
	    ((NULL (NC.LinksSupportedP NewSourceID (QUOTE (Local))))
	      (NC.PrintMsg Window NIL (CONCAT "Tried to move a NoteCards link icon" 
					      " to a NoteCard that"
					      " does not support links!!."
					      (CHARACTER 13)
					      "Tsk. Tsk."
					      (CHARACTER 13)))
	      (RETFROM (QUOTE TEDIT.MOVE)
		       NIL T))
	    ((AND (FMEMB Label (QUOTE (FiledCard SubBox)))
		  (NEQ (NC.FetchType NewSourceID)
		       (QUOTE FileBox)))                     (* Move from filebox to non-filebox.)
	      (NC.PrintMsg NIL NIL (CONCAT "Tried to move filedcard or subbox link to a non-filebox."
					   (CHARACTER 13)
					   "Link type of copy set to 'Unspecified'."
					   (CHARACTER 13)))
	      (SETQ NewLabel NC.UnspecifiedLinkLabel)
	      (SETQ NewDisplayMode (create LINKDISPLAYMODE copying OldDisplayMode SHOWTITLEFLG ← T 
								   SHOWLINKTYPEFLG ← T)))
	    ((AND (NEQ (NC.FetchType SourceID)
		       (QUOTE FileBox))
		  (EQ (NC.FetchType NewSourceID)
		      (QUOTE FileBox)))                      (* Move from non-filebox to filebox.)
	      (NC.PrintMsg NIL NIL (CONCAT "Can't move links from non-filebox to filebox."
					   (CHARACTER 13)
					   "Try using PutCardsHere."
					   (CHARACTER 13)))
	      (RETFROM (QUOTE TEDIT.MOVE)
		       NIL T))
	    ((AND (EQ (NC.FetchType NewSourceID)
		      (QUOTE FileBox))
		  (NEQ NewSourceID SourceID)
		  (for Link1 in (NC.FetchToLinks NewSourceID)
		     thereis (AND (NC.ChildLinkP Link1)
				  (EQ DestID (fetch (NOTECARDLINK DESTINATIONID) of Link1)))))
                                                             (* Move to a filebox already containing this child.)
	      (NC.PrintMsg NIL NIL (CONCAT (NC.RetrieveTitle DestID PSA.Database)
					   " not moved: already appears as a child of "
					   (NC.RetrieveTitle NewSourceID PSA.Database)
					   (CHARACTER 13)))
	      (RETFROM (QUOTE TEDIT.MOVE)
		       NIL T))
	    ((AND (EQ Label (QUOTE SubBox))
		  (NEQ NewSourceID SourceID)
		  (OR (EQ NewSourceID DestID)
		      (NOT (NC.NotDaughterP DestID NewSourceID (FUNCTION NC.ChildLinkP)))))
                                                             (* Move to a filebox causes a cycle.)
	      (NC.PrintMsg NIL NIL (CONCAT "Couldn't move " Link " because of subbox cycle."
					   (CHARACTER 13)))
	      (RETFROM (QUOTE TEDIT.MOVE)
		       NIL T))
	    ((AND (FMEMB Label NC.SystemLinkLabels)
		  (NOT (FMEMB Label (QUOTE (FiledCard SubBox))))
		  (NEQ NewSourceID SourceID))                (* Move of system link outside of own card.)
	      (NC.PrintMsg NIL NIL (CONCAT "Tried to copy system link." (CHARACTER 13)
					   "Link type of copy set to 'Unspecified'."
					   (CHARACTER 13)))
	      (SETQ NewLabel NC.UnspecifiedLinkLabel)
	      (SETQ NewDisplayMode (create LINKDISPLAYMODE copying OldDisplayMode SHOWTITLEFLG ← T 
								   SHOWLINKTYPEFLG ← T))))
          (IMAGEOBJPROP ImageObject (QUOTE LinkBeingMoved)
			Link)
          (NC.FillInLinkIcon ImageObject (OR NewLabel Label)
			     DestID NewSourceID (OR NewDisplayMode OldDisplayMode)
			     (NC.LinkAtCharPos InsertPos ToTextStream)))))

(NC.FetchLinkFromLinkIcon
  (LAMBDA (LinkIcon)                                         (* rht: "18-Jul-85 14:54")

          (* * Return the link information from the LinkIcon image object)



          (* * rht 7/18/85: Changed to convert to typed links.)


    (LET ((Link (IMAGEOBJPROP LinkIcon (QUOTE OBJECTDATUM))))
      (NC.CheckDisplayModeFormat (if (EQ (CAR Link)
					 (QUOTE NOTECARDLINK))
				     then Link
				   else (CONS (QUOTE NOTECARDLINK)
					      Link))))))

(NC.ChangeLinkDisplayMode
  (LAMBDA (LinkOrLinkIcon Window NewDisplayMode)             (* rht: "16-Mar-85 16:28")

          (* * Change the display mode of the NOTECARDLINK defined by LinkOrLinkIcon. Have the user choose the new display 
	  mode.)



          (* * NOTE: assumes that the SourceID card of the link is active, i.e., the substance and links are cached for this 
	  card.)



          (* * rht 2/1/85: Now doesn't do all the work if new display mode is same as the old one. Or if user doesn't make a 
	  selection from the menu.)


    (PROG (ID DestinationID Link LinkIcon GlobalLinkFlg OldDisplayMode)
          (COND
	    ((NC.LinkIconImageObjP LinkOrLinkIcon)
	      (SETQ Link (NC.FetchLinkFromLinkIcon LinkOrLinkIcon))
	      (SETQ LinkIcon LinkOrLinkIcon))
	    (T (SETQ Link LinkOrLinkIcon)
	       (COND
		 ((NOT (SETQ GlobalLinkFlg (NC.GlobalLinkP Link)))
		   (SETQ LinkIcon (NC.FetchLinkIconForLink Link))))))
          (SETQ ID (fetch (NOTECARDLINK SOURCEID) of Link))
          (SETQ OldDisplayMode (fetch (NOTECARDLINK DISPLAYMODE) of Link))
          (COND
	    ((WINDOWP Window))
	    ((NC.ActiveCardP ID)
	      (SETQ Window (NC.FetchWindow ID))))

          (* * Get new display mode from user)


          (if (NOT NewDisplayMode)
	      then (SETQ NewDisplayMode
		     (NC.DisplayModeFromStylesheetSelections
		       (STYLESHEET (CREATE.STYLE (QUOTE ITEMS)
						 (LIST (create MENU
							       ITEMS ←(QUOTE (Yes No Float)))
						       (create MENU
							       ITEMS ←(QUOTE (Yes No Float)))
						       (create MENU
							       ITEMS ←(QUOTE (Yes No Float))))
						 (QUOTE ITEM.TITLES)
						 (QUOTE (Title?%  LinkType?%  AttachBitmap?))
						 (QUOTE ITEM.TITLE.FONT)
						 (FONTCOPY MENUFONT (QUOTE WEIGHT)
							   (QUOTE BOLD))
						 (QUOTE SELECTIONS)
						 (NC.StylesheetSelectionsFromDisplayMode 
										   OldDisplayMode)
						 (QUOTE NEED.NOT.FILL.IN)
						 NIL
						 (QUOTE TITLE)
						 (QUOTE Display% Mode?)
						 (QUOTE POSITION)
						 (create POSITION
							 XCOORD ← LASTMOUSEX
							 YCOORD ← LASTMOUSEY))))))

          (* * If new display mode is same as old, then bail out.)


          (COND
	    ((OR (NULL NewDisplayMode)
		 (EQUAL NewDisplayMode OldDisplayMode))
	      (RETURN NIL)))

          (* * Update link in LinkIcon or in global links list)


          (COND
	    (GlobalLinkFlg (for GlobalLink in (NC.FetchGlobalLinks ID)
			      when (EQP (fetch (NOTECARDLINK LINKID) of Link)
					(fetch (NOTECARDLINK LINKID) of GlobalLink))
			      do (replace (NOTECARDLINK DISPLAYMODE) of GlobalLink with 
										   NewDisplayMode))
			   (NC.SetLinksDirtyFlg ID T))
	    (T (replace (NOTECARDLINK DISPLAYMODE) of (NC.FetchLinkFromLinkIcon LinkIcon)
		  with NewDisplayMode)
	       (NC.MarkCardDirty ID)))

          (* * Update link in ToLinks List of Source card)


          (for ToLink in (NC.FetchToLinks ID) when (EQP (fetch (NOTECARDLINK LINKID) of Link)
							(fetch (NOTECARDLINK LINKID) of ToLink))
	     do (replace (NOTECARDLINK DISPLAYMODE) of ToLink with NewDisplayMode))
          (NC.SetLinksDirtyFlg ID T)

          (* * Update Link in FromLinks list of Destination card)


          (SETQ DestinationID (fetch (NOTECARDLINK DESTINATIONID) of Link))
          (COND
	    ((NC.ActiveCardP DestinationID)
	      (for FromLink in (NC.FetchFromLinks DestinationID) when (EQP (fetch (NOTECARDLINK
										    LINKID)
									      of Link)
									   (fetch (NOTECARDLINK
										    LINKID)
									      of FromLink))
		 do (replace (NOTECARDLINK DISPLAYMODE) of FromLink with NewDisplayMode))
	      (NC.SetLinksDirtyFlg DestinationID T))
	    (T (WITH.MONITOR (NC.FetchMonitor PSA.Database)
			     (NC.GetLinks DestinationID PSA.Database)
			     (for FromLink in (NC.FetchFromLinks DestinationID)
				when (EQP (fetch (NOTECARDLINK LINKID) of Link)
					  (fetch (NOTECARDLINK LINKID) of FromLink))
				do (replace (NOTECARDLINK DISPLAYMODE) of FromLink with 
										   NewDisplayMode))
			     (NC.PutLinks DestinationID PSA.Database)
			     (NC.DeactivateCard DestinationID))))

          (* * Update the image in any active window for ID)


          (COND
	    ((AND (WINDOWP Window)
		  (NOT (NC.TEditBasedP (NC.FetchType ID))))
	      (NC.UpdateLinkImages Window (fetch (NOTECARDLINK DESTINATIONID) of Link))))
                                                             (* This causes tedit to redisplay the screen.)
          (RETURN (QUOTE CHANGED)))))

(NC.DefaultLinkDisplayMode
  (LAMBDA (ID DatabaseStream)                                (* rht: "10-Feb-85 16:55")
                                                             (* RETURN the default NoteCard link display mode for 
							     the card -
							     SourceID. Default display mode is determined by the 
							     card type of SourceID.)
    (PROG (NoteCardType DisplayMode CardType)
          (SETQ NoteCardType (NC.RetrieveType ID DatabaseStream))
      Loop(SETQ DisplayMode (fetch (NoteCardType LinkDisplayMode)
			       of (SETQ CardType (for Type in NC.CardTypes
						    when (EQ (fetch (NoteCardType TypeName)
								of Type)
							     NoteCardType)
						    do (RETURN Type) finally (NC.ReportError
									       
								      "NC.DefaultLinkDisplayMode"
									       (CONCAT 
									  " Unknown card type:  "
										       NoteCardType)))
				    )))
          (if DisplayMode
	      then (RETURN (if (ATOM DisplayMode)
			       then (NC.MakeNewDisplayMode DisplayMode)
			     else DisplayMode)))
          (SETQ NoteCardType (fetch (NoteCardType SuperType) of CardType))
          (AND (NEQ NoteCardType (QUOTE NoteCard))
	       (GO Loop))
          (RETURN (QUOTE Icon)))))

(NC.UpdateLinkImages
  (LAMBDA (SourceWindowOrID DestinationID)                   (* rht: " 2-Oct-85 14:49")

          (* * Update the Link Image Objects in SourceCard that point to DestinationID)



          (* * rht 10/2/85: Now checks if card's window was shrunk. If so, unshrink, modify and reshrink.)


    (PROG (SourceWindow SourceCardID NoteCardType ShrunkenWin)
          (COND
	    ((WINDOWP SourceWindowOrID)
	      (SETQ SourceWindow SourceWindowOrID)
	      (SETQ SourceCardID (NC.IDFromWindow SourceWindowOrID)))
	    (T (SETQ SourceWindow (NC.FetchWindow SourceWindowOrID))
	       (SETQ SourceCardID SourceWindowOrID)))
          (if (SETQ ShrunkenWin (NC.GetShrunkenWin SourceWindow))
	      then (EXPANDW ShrunkenWin))
          (SETQ NoteCardType (NC.FetchType SourceCardID))
          (APPLY* (NC.UpdateLinkIconsFn NoteCardType)
		  (OR SourceCardID SourceWindow)
		  DestinationID)
          (if ShrunkenWin
	      then (SHRINKW SourceWindow)))))

(NC.UpdateLinkImagesInGraph
  (LAMBDA (SourceCardID DestinationID)                       (* rht: " 3-Oct-85 20:22")
                                                             (* Update all the NoteCard links that point to 
							     DestinationID from the graph card specified by 
							     SourceCardID)

          (* * rht 2/15/85: Added hack to redraw links into and out of the affected node. This is in case it has changed size.
	  Note the calls to internal grapher functions!)



          (* * rht 10/3/85: Threw away above mentioned code. It was screwing up the link-params info for the affected nodes.)


    (PROG (Window Graph GraphNodes LinkIcon OldAddLinkFn OldDeleteLinkFn)
          (SETQ Window (NC.FetchWindow SourceCardID))
          (SETQ Graph (NC.FetchSubstance SourceCardID))
          (for GraphNode in (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of Graph))
	     when (AND (NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE NODELABEL)
							       of GraphNode)))
		       (EQ DestinationID (fetch (NOTECARDLINK DESTINATIONID) of (
NC.FetchLinkFromLinkIcon LinkIcon))))
	     do                                              (* Update the size of the graph node if doesn't agree 
							     with image box.)
		(NC.GraphNodeLinkIconUpdate Window GraphNode))
          (REDISPLAYW Window))))

(NC.UpdateLinkImagesInSketch
  (LAMBDA (SourceCardID DestinationID)                       (* rht: "20-Aug-85 17:55")
                                                             (* For now do nothing since Link Images in Sketch have 
							     no titles.)

          (* * rht 8/20/85: Rigged this to use Richard's new sketch programmer's interface.)


    (LET ((SketchWin (NC.FetchWindow SourceCardID)))
      (for SketchElement in (SKETCH.LIST.OF.ELEMENTS SketchWin (FUNCTION NC.LinkIconSketchElementP))
	 bind FoundAtLeastOneFlg when (EQ DestinationID (fetch (NOTECARDLINK DESTINATIONID)
							   of (NC.FetchLinkFromLinkIcon (
SKETCH.IMAGEOBJ.OF.ELEMENT SketchElement))))
	 do (SKETCH.ELEMENT.CHANGED SketchWin SketchElement)
	    (SETQ FoundAtLeastOneFlg T)
	 finally (if FoundAtLeastOneFlg
		     then (NC.MarkCardDirty SourceCardID))))))

(NC.UpdateLinkImagesInText
  (LAMBDA (SourceCardIDOrWindow DestinationID)               (* rht: " 8-Feb-85 17:17")

          (* * Update the notecard link image objects that point to DestinationID fromn text card SourceCardIDOrWindow)



          (* * rht 2/8/85: Makes sure not to dirty the card if it wasn't dirty before.)


    (PROG (Window TextObject ListOfNoteCardLinks SourceID WasDirtyFlg)
          (SETQ Window (COND
	      ((WINDOWP SourceCardIDOrWindow)
		SourceCardIDOrWindow)
	      (T (NC.FetchWindow SourceCardIDOrWindow))))
          (SETQ TextObject (WINDOWPROP Window (QUOTE TEXTOBJ)))
          (SETQ ListOfNoteCardLinks (TEDIT.LIST.OF.OBJECTS TextObject (FUNCTION NC.LinkIconImageObjP))
	    )
          (SETQ WasDirtyFlg (NC.CardDirtyP (SETQ SourceID (NC.CoerceToID Window))))
          (for Link in ListOfNoteCardLinks when (EQ (fetch (NOTECARDLINK DESTINATIONID)
						       of (NC.FetchLinkFromLinkIcon (CAR Link)))
						    DestinationID)
	     do (TEDIT.OBJECT.CHANGED TextObject (CAR Link)))
          (NC.MarkCardDirty SourceID (NOT WasDirtyFlg)))))

(NC.LinkIconCopyFn
  (LAMBDA (ImageObject)                                      (* rht: "22-Aug-85 14:56")

          (* * Return a copy of image object. IF it is a system link label, then make its label unspecified.)



          (* * rht 11/18/84: No longer worries about system link labels. All that is handled by WhenCopiedFn and WhenMovedFn.
	  Caches the new copy on the prop list of the original imageobj.)



          (* * rht 8/22/85: Added call to NC.CoerceToExternalPutLinkIcon to make the imageobj look like a external link icon.
	  If we're in a normal imageobj copy then the whencopiedfn will get called and replace the contents of ImageObjectCopy
	  anyway. However, if only the CopyFn gets called, then this will stick.)


    (PROG ((ImageObjectCopy (create IMAGEOBJ copying ImageObject))
	   (Link (NC.FetchLinkFromLinkIcon ImageObject)))
          (NC.CoerceToExternalPutLinkIcon ImageObjectCopy (fetch (NOTECARDLINK SOURCEID)
							     of Link)
					  (fetch (NOTECARDLINK DESTINATIONID) of Link)
					  (fetch (NOTECARDLINK LINKLABEL) of Link))
          (IMAGEOBJPROP ImageObject (QUOTE ImageObjectCopy)
			ImageObjectCopy)
          (RETURN ImageObjectCopy))))

(NC.GetTypeIcon
  (LAMBDA (Type)                                             (* rht: " 1-Oct-85 14:08")

          (* * Return the bitmap icon for the given type.)



          (* * rht 10/1/85: Now checks first if there's a bitmap hung on the Type's prop list.)


    (OR (BITMAPP (GETPROP Type (QUOTE NCTYPEBITMAP)))
	(SELECTQ Type
		 (FileBox NC.FileBoxIcon)
		 (Sketch NC.SketchCardIcon)
		 ((Graph Browser)
		   NC.GraphCardIcon)
		 NC.TextCardIcon))))

(NC.LinkAtCharPos
  (LAMBDA (CharPos TextStream)                               (* rht: "26-Mar-85 15:40")

          (* * Returns the link right before CharPos in TextStream. Return NIL if there is no link icon located before 
	  CharPos.)


    (AND (TEXTSTREAMP TextStream)
	 (for LinkIconPair in (TEDIT.LIST.OF.OBJECTS (TEXTOBJ TextStream)
						     (FUNCTION NC.LinkIconImageObjP))
	    bind OldLinkIconPair while (LESSP (CADR LinkIconPair)
					      CharPos)
	    do (SETQ OldLinkIconPair LinkIconPair) finally (RETURN (AND OldLinkIconPair
									(NC.FetchLinkFromLinkIcon
									  (CAR OldLinkIconPair))))))))

(NC.CharPosFromTextObject
  (LAMBDA (TextObject)                                       (* rht: "27-Jun-85 15:38")

          (* * Return the position # of current selection in TextObject)


    (PROG (Selection)
          (RETURN (AND (fetch (SELECTION SET) of (SETQ Selection (fetch (TEXTOBJ SEL) of TextObject)))
		       (TEDIT.GETPOINT TextObject Selection))))))
)
(DEFINEQ

(NC.FillInLinkIcon
  (LAMBDA (ImageObj Label DestID SourceID DisplayMode LinkToInsertAfter)
                                                             (* rht: "26-Mar-85 14:45")

          (* * Called by WhenCopiedFn and WhenMovedFn to build the new link and stick it in the ImageObj.)


    (IMAGEOBJPROP ImageObj (QUOTE OBJECTDATUM)
		  (NC.MakeLink NIL Label DestID SourceID DisplayMode NIL NIL NIL LinkToInsertAfter))
    (replace (IMAGEOBJ IMAGEOBJFNS) of ImageObj with NC.LinkIconImageFns)))

(NC.InvisibleLinkImageBoxFn
  (LAMBDA (ImageObj Stream)                                  (* rht: "20-Nov-84 10:57")

          (* * Returns a zero-size image box.)


    (create IMAGEBOX
	    XSIZE ← 0
	    YSIZE ← 0
	    YDESC ← 0
	    XKERN ← 0)))

(NC.InvisibleLinkPutFn
  (LAMBDA (ImageObj OutputStream)                            (* fgh: "26-Feb-84 01:04")
    (BOUT OutputStream 1)))

(NC.InvisibleLinkGetFn
  (LAMBDA (InputStream TextStream)                           (* rht: "21-Nov-84 12:10")
    (BIN InputStream)
    NC.InvisibleLinkImageObject))
)
(* * New stuff for allowing put to work from TEdit.)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.ExternalPutLinkIconImageFns)
)

(RPAQ NC.ExternalPutLinkIconImageFns (IMAGEFNSCREATE (FUNCTION NC.ExternalPutLinkIconDisplayFn)
						     (FUNCTION NC.ExternalPutLinkIconImageBoxFn)
						     (FUNCTION NC.ExternalPutLinkIconPutFn)
						     (FUNCTION NC.ExternalPutLinkIconGetFn)
						     NIL
						     (FUNCTION NILL)))
(DEFINEQ

(NC.ExternalPutLinkIconDisplayFn
  (LAMBDA (ImageObj ImageStream STREAMTYPE TEXTSTREAM SCALE)
                                                             (* fgh: "30-May-85 23:09")

          (* * Display a link icon)


    (PROG ((Font (FONTCREATE (QUOTE HELVETICA)
			     10
			     (QUOTE BOLD))))
          (DSPFONT (PROG1 (DSPFONT Font ImageStream)
			  (PRIN1 (IMAGEOBJPROP ImageObj (QUOTE OBJECTDATUM))
				 ImageStream))
		   ImageStream))))

(NC.ExternalPutLinkIconImageBoxFn
  (LAMBDA (ImageObj ImageStream CurrentX RightMargin)        (* fgh: "30-May-85 16:52")
    (PROG ((FONT (FONTCREATE (QUOTE HELVETICA)
			     10
			     (QUOTE BOLD)))
	   (Scale (DSPSCALE NIL ImageStream)))
          (RETURN (create IMAGEBOX
			  XSIZE ←(TIMES Scale (STRINGWIDTH (IMAGEOBJPROP ImageObj (QUOTE OBJECTDATUM))
							   FONT))
			  YSIZE ←(TIMES Scale (FONTPROP FONT (QUOTE HEIGHT)))
			  YDESC ←(COND
			    (RightMargin                     (* This is in a TEdittextstream)
					 (FONTPROP FONT (QUOTE DESCENT)))
			    (T 0))
			  XKERN ← 0)))))

(NC.ExternalPutLinkIconPutFn
  (LAMBDA (ImageObject Stream)                               (* fgh: "30-May-85 23:12")

          (* * Writes the Link information in the link icon specified by ImageObject onto the file specified by Stream)


    (LET (String Link)
      (COND
	((SETQ String (STRINGP (IMAGEOBJPROP ImageObject (QUOTE OBJECTDATUM))))
	  (PRIN2 String Stream))
	(T (SETQ Link (NC.FetchLinkFromLinkIcon ImageObject))
	   (PRIN2 (CONCAT "***[[" (fetch (NOTECARDLINK LINKLABEL) of Link)
			  " link to "
			  (NC.RetrieveTitle (fetch (NOTECARDLINK DESTINATIONID) of Link))
			  "]]***")
		  Stream))))))

(NC.ExternalPutLinkIconGetFn
  (LAMBDA (Stream)                                           (* fgh: "30-May-85 16:43")

          (* * Reads the link information from Stream and returns a link icon image object for this link info.)


    (IMAGEOBJCREATE (READ Stream)
		    NC.ExternalPutLinkIconImageFns)))

(NC.CoerceToExternalPutLinkIcon
  (LAMBDA (ImageObject SourceID DestinationID LinkLabel)     (* rht: "22-Aug-85 21:53")

          (* * Make image object into an external put link icon with the given data)


    (IMAGEOBJPROP ImageObject (QUOTE OBJECTDATUM)
		  (CONCAT "[[" LinkLabel " link to " (NC.RetrieveTitle DestinationID PSA.Database)
			  "]]"))
    (replace (IMAGEOBJ IMAGEOBJFNS) of ImageObject with NC.ExternalPutLinkIconImageFns)))
)
(* * Stuff to register our image object for intermezzo.)

(DEFINEQ

(NC.RegisterPlaceMarkerImageObj
  (LAMBDA NIL                                                (* rht: "31-May-85 11:40")

          (* * Cause the PlaceMarker Image Obj to be registered by creating the make place marker function once)


    (NC.MakePlaceMarker)))
)
(NC.RegisterPlaceMarkerImageObj)
(* * Stuff for handling link icons in sketches.)

(DEFINEQ

(NC.LinkIconSketchElementP
  (LAMBDA (SketchElement)                                    (* rht: "20-Aug-85 16:23")

          (* * Return non-nil if SketchElement is a link icon imageobj.)


    (NC.LinkIconImageObjP (SKETCH.IMAGEOBJ.OF.ELEMENT SketchElement))))

(NC.DeleteLinkIconSketchElement
  (LAMBDA (SketchElement CardID)                             (* rht: "20-Aug-85 23:57")

          (* * This replaces the link icon for SketchElement from SketchWin with deleted link icon.)


    (LET ((Position (SKETCH.POSITION.OF.ELEMENT SketchElement))
       (SketchSubstance (NC.FetchSubstance CardID))
       (LinkIcon (SKETCH.IMAGEOBJ.OF.ELEMENT SketchElement))
       (Window (NC.FetchWindow CardID))
       Scale)
      (SETQ Scale (if Window
		      then (SKETCHW.SCALE Window)
		    else (NC.FetchScale CardID)))
      (create IMAGEOBJ smashing LinkIcon OBJECTDATUM ←(IMAGEOBJPROP NC.DeletedLinkImageObject
								    (QUOTE OBJECTDATUM))
				IMAGEOBJFNS ← NC.DeletedLinkImageFns)
      (AND Window (SKETCH.ELEMENT.CHANGED SketchSubstance SketchElement Window)))))
)
(* * Icons representing notecards types.)


(RPAQ NC.FileBoxIcon (READBITMAP))
(21 18
"OOOOOH@@"
"OOOOOH@@"
"OOOOOH@@"
"H@@@@H@@"
"H@@@@H@@"
"H@B@@H@@"
"H@@@@H@@"
"OOOOOH@@"
"H@@@@H@@"
"H@@@@H@@"
"H@B@@H@@"
"H@@@@H@@"
"OOOOOH@@"
"H@@@@H@@"
"H@@@@H@@"
"H@B@@H@@"
"H@@@@H@@"
"OOOOOH@@")

(RPAQ NC.GraphCardIcon (READBITMAP))
(21 18
"OOOOOH@@"
"H@@@@H@@"
"H@@@@H@@"
"H@N@@H@@"
"H@J@@H@@"
"HAJ@@H@@"
"HBO@@H@@"
"HD@KHH@@"
"KH@FHH@@"
"JH@BHH@@"
"JH@CHH@@"
"KL@@@H@@"
"HBN@@H@@"
"HAJ@@H@@"
"H@J@@H@@"
"H@N@@H@@"
"H@@@@H@@"
"OOOOOH@@")

(RPAQ NC.SketchCardIcon (READBITMAP))
(21 18
"OOOOOH@@"
"H@@@@H@@"
"HGO@@H@@"
"HH@H@H@@"
"H@@G@H@@"
"HC@@HH@@"
"HDH@DH@@"
"HHD@BH@@"
"I@B@@H@@"
"I@B@@H@@"
"HHDONH@@"
"HDHHBH@@"
"HC@HBH@@"
"H@@HBH@@"
"H@@HBH@@"
"H@@ONH@@"
"H@@@@H@@"
"OOOOOH@@")

(RPAQ NC.TextCardIcon (READBITMAP))
(21 18
"OOOOOH@@"
"OOOOOH@@"
"OOOOOH@@"
"OOOOOH@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"H@@@@H@@"
"OOOOOH@@")

(RPAQ NC.TypelessIcon (READBITMAP))
(7 18
"ON@@"
"ON@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"LF@@"
"ON@@")
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.FileBoxIcon NC.GraphCardIcon NC.SketchCardIcon NC.TextCardIcon NC.TypelessIcon)
)
(PUTPROPS NCLINKS COPYRIGHT ("Xerox Corporation" 1984 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (7292 63031 (NC.GlobalLinkP 7302 . 7571) (NC.ChildLinkP 7573 . 7828) (NC.ContentsLinkP 
7830 . 8076) (NC.SubContentsLinkP 8078 . 8324) (NC.ReverseLinkLabelP 8326 . 8949) (NC.GetNewLinkID 
8951 . 9351) (NC.MakeGlobalLink 9353 . 10121) (NC.AddFromLink 10123 . 10947) (NC.AddLinkToGraphCard 
10949 . 11425) (NC.AddLinkToSketchCard 11427 . 12039) (NC.InsertLinkInSketch 12041 . 13133) (
NC.AddLinkToTextCard 13135 . 13603) (NC.AddLinksToTextCard 13605 . 14005) (NC.InsertLinkInText 14007
 . 15728) (NC.InsertLinksInText 15730 . 16793) (NC.AddSourceLink 16795 . 17630) (NC.AddToLink 17632 . 
20628) (NC.DelFromLink 20630 . 24939) (NC.DelToLink 24941 . 26401) (NC.DelReferencesToCard 26403 . 
27652) (NC.DelReferencesToCardFromGlobalList 27654 . 29320) (NC.DelReferencesToCardFromGraph 29322 . 
31300) (NC.DelReferencesToCardFromSketch 31302 . 32943) (NC.DelReferencesToCardFromText 32945 . 34758)
 (NC.DeletedLinkDisplayFn 34760 . 36217) (NC.DeletedLinkGetFn 36219 . 36393) (NC.DeletedLinkImageBoxFn
 36395 . 36807) (NC.DeletedLinkPutFn 36809 . 36957) (NC.DeletedLinkImageObjP 36959 . 37301) (
NC.CheckForOrphanDelete 37303 . 38642) (NC.HookToOrphanCard 38644 . 39741) (NC.InsertLinkBeforeMarker 
39743 . 43063) (NC.LinkLabelP 43065 . 43409) (NC.MakeAContentsHook 43411 . 44969) (
NC.InsertLinkInOrdering 44971 . 48050) (NC.IDAlphOrder 48052 . 48320) (NC.MakeLink 48322 . 50752) (
NC.MakeContentsHooks 50754 . 52753) (NC.RelabelLink 52755 . 56784) (NC.SystemLinkLabelP 56786 . 57207)
 (NC.ValidLinkP 57209 . 58247) (NC.MakeChildLink 58249 . 59485) (NC.SameLinks 59487 . 60298) (
NC.AddGlobalLinkToCard 60300 . 60547) (NC.AddGlobalLinksToCard 60549 . 61894) (
NC.ChangeCardTitleFromLinkIcon 61896 . 63029)) (63068 66690 (NC.CheckDisplayModeFormat 63078 . 64254) 
(NC.MakeNewDisplayMode 64256 . 64828) (NC.DisplayModeFromStylesheetSelections 64830 . 65447) (
NC.StylesheetSelectionsFromDisplayMode 65449 . 66209) (NC.CheckLinkRecordFormat 66211 . 66688)) (66958
 68027 (NC.LinksSupportedP 66968 . 67533) (NC.LinkAnchorModesFromType 67535 . 68025)) (68106 69613 (
NC.PushCopyLinkIcon 68116 . 69611)) (69645 115537 (NC.SetLinkInLinkIcon 69655 . 69899) (
NC.FetchLinkIconForLink 69901 . 70570) (NC.MakeLinkIcon 70572 . 70819) (NC.LinkIconButtonEventInFn 
70821 . 73671) (NC.LinkIconDisplayFn 73673 . 79129) (NC.LinkIconImageBoxFn 79131 . 82457) (
NC.LinkIconImageObjP 82459 . 82760) (NC.LinkIconPutFn 82762 . 83074) (NC.LinkIconGetFn 83076 . 83477) 
(NC.LinkIconMiddleButtonFn 83479 . 85101) (NC.LinkIconWhenCopiedFn 85103 . 91765) (
NC.LinkIconWhenDeletedFn 91767 . 94062) (NC.LinkIconWhenInsertedFn 94064 . 94889) (
NC.LinkIconWhenMovedFn 94891 . 100926) (NC.FetchLinkFromLinkIcon 100928 . 101468) (
NC.ChangeLinkDisplayMode 101470 . 106569) (NC.DefaultLinkDisplayMode 106571 . 107956) (
NC.UpdateLinkImages 107958 . 109031) (NC.UpdateLinkImagesInGraph 109033 . 110488) (
NC.UpdateLinkImagesInSketch 110490 . 111421) (NC.UpdateLinkImagesInText 111423 . 112633) (
NC.LinkIconCopyFn 112635 . 113909) (NC.GetTypeIcon 113911 . 114404) (NC.LinkAtCharPos 114406 . 115115)
 (NC.CharPosFromTextObject 115117 . 115535)) (115538 116684 (NC.FillInLinkIcon 115548 . 116083) (
NC.InvisibleLinkImageBoxFn 116085 . 116350) (NC.InvisibleLinkPutFn 116352 . 116502) (
NC.InvisibleLinkGetFn 116504 . 116682)) (117125 119819 (NC.ExternalPutLinkIconDisplayFn 117135 . 
117638) (NC.ExternalPutLinkIconImageBoxFn 117640 . 118317) (NC.ExternalPutLinkIconPutFn 118319 . 
119004) (NC.ExternalPutLinkIconGetFn 119006 . 119331) (NC.CoerceToExternalPutLinkIcon 119333 . 119817)
) (119883 120173 (NC.RegisterPlaceMarkerImageObj 119893 . 120171)) (120262 121426 (
NC.LinkIconSketchElementP 120272 . 120550) (NC.DeleteLinkIconSketchElement 120552 . 121424)))))
STOP