(FILECREATED "17-Jun-87 18:04:04" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH267.;19 108120 changes to: (FNS NC.OpenCrossFileLinkDestNoteFile NC.GetCrossFileLinkDestCard NC.AskCrossFileLinkMode NC.ComputeCrossFileLinkMode) (VARS RHTPATCH267COMS) previous date: "10-Jun-87 22:42:15" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH267.;18) (* Copyright (c) 1987 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT RHTPATCH267COMS) (RPAQQ RHTPATCH267COMS ((DECLARE: FIRST (P (NC.LoadFileFromDirectories (QUOTE NCBROWSERCARD)) (NC.LoadFileFromDirectories (QUOTE NCSKETCHCARD)))) (* * Fix of bug #578: cross-file link to read-only notefile causes stack overflow. Fixes unreported cross-file links bug whereby deleting an icon for a cross-file link leaves half link. When cross file link is deleted, the other end of the link will be deleted too if its notefile is open.) (* * Change to NCGRAPHCARD) (FNS NC.CollectReferencesInGraph) (* * Change to NCSKETCHCARD) (FNS NC.CollectReferencesInSketch) (* * Change to NCTEXTCARD) (FNS NC.CollectReferencesInText) (* * Changes to NCLINKS) (FNS NC.ValidLinkP NC.MakeLink NC.DeleteFromLink NC.DeleteToLink NC.RelabelLink NC.FileInOrphanBox) (* * Change to NCCARDS) (FNS NC.DeleteNoteCardInternal NC.AssignTitle) (* * Changes to NCCROSSFILELINKS) (FNS NC.OpenCrossFileLinkDestNoteFile NC.CrossFileLinkPutFn NC.CrossFileLinkGetFn NC.CrossFileLinkEditFn NC.GetCrossFileLinkDestCard) (RECORDS CrossFileLinkSubstance) (* * New stuff for NCCROSSFILELINKS) (GLOBALVARS NC.NewCrossFileLinksMode) (INITVARS (NC.NewCrossFileLinksMode (QUOTE ASK))) (FNS NC.AskCrossFileLinkMode NC.DeleteCrossFileLinkCard NC.FetchRemoteCrossFileLinkCard NC.CheckCrossFileLinkCardTitle NC.CheckCrossFileLinkType NC.MakeCrossFileLinkIconStandIn NC.ComputeCrossFileLinkMode) (* * PLEASE remove the globalvar NC.NewCrossFileLinksTwoWayFlg from NCCROSSFILELINKS coms) (* * Changes to NCBROWSERCARD) (FNS NC.GrowLinkLattice NC.MakeBrowserCard NC.UpdateBrowserCard NC.ExpandBrowserNode NC.ConnectNodesInBrowser NC.DelBrowserContentsLink) (FNS NC.GetBrowserHashArray NC.GetBrowserNodeID NC.RemoveBrowserNodeHashArrayEntry))) (DECLARE: FIRST (NC.LoadFileFromDirectories (QUOTE NCBROWSERCARD)) (NC.LoadFileFromDirectories (QUOTE NCSKETCHCARD)) ) (* * Fix of bug #578: cross-file link to read-only notefile causes stack overflow. Fixes unreported cross-file links bug whereby deleting an icon for a cross-file link leaves half link. When cross file link is deleted, the other end of the link will be deleted too if its notefile is open.) (* * Change to NCGRAPHCARD) (DEFINEQ (NC.CollectReferencesInGraph (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg) (* rht: " 1-Jun-87 22:11") (* * Return a list of all links or link icons in graph substance Substance. If CheckAndDeleteFlg, then delete any links found that are not valid links.) (* * fgh 11/14/85 Updated to handle Card object.) (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of ActualLink is a valid card.) (DECLARE (GLOBALVARS NC.DeletedLinkImageObject)) (LET ((Substance (NC.FetchSubstance Card)) ActualLink DirtyFlg Links LinkIcon CollectItem) (SETQ Links (for GraphNode in (fetch (GRAPH GRAPHNODES) of Substance) when (COND ((NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE NODELABEL) of GraphNode))) (SETQ ActualLink (NC.FetchLinkFromLinkIcon LinkIcon)) (COND ((NULL CheckAndDeleteFlg)) ((AND (LISTP CheckAndDeleteFlg) (FMEMB (fetch (Link DestinationCard) of ActualLink) CheckAndDeleteFlg))) ((AND (NC.ValidLinkP ActualLink) (NC.ValidCardP (fetch (Link DestinationCard) of ActualLink)))) (T (replace (GRAPHNODE NODELABEL) of GraphNode with NC.DeletedLinkImageObject) (SETQ DirtyFlg T) NIL))) (T NIL)) collect (PROGN (SETQ CollectItem (COND (ReturnLinkIconsFlg LinkIcon) (T ActualLink))) (COND ((NULL ReturnLocationsFlg) CollectItem) (T (CONS CollectItem (fetch (GRAPHNODE NODELABEL) of GraphNode))))))) (CONS Links DirtyFlg)))) ) (* * Change to NCSKETCHCARD) (DEFINEQ (NC.CollectReferencesInSketch (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg) (* rht: "26-May-87 11:55") (* * Return a list of all links in sketch substance Substance. If CheckAndDeleteFlg, then delete any links found that are not valid links.) (* * rht 8/20/85: Rewritten to use Richard's sketch programmer's interface. Eliminates references to sketch records.) (* * fgh 11/14/85 Updated to handle Card object.) (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of ActualLink is a valid card.) (LET ((SketchSubstance (NC.FetchSubstance Card)) DirtyFlg) (CONS (for SketchElt in (SKETCH.LIST.OF.ELEMENTS SketchSubstance (FUNCTION NC.LinkIconSketchElementP)) bind LinkIcon CollectItem ActualLink when (PROGN (SETQ ActualLink (NC.FetchLinkFromLinkIcon (SETQ LinkIcon ( SKETCH.IMAGEOBJ.OF.ELEMENT SketchElt)))) (COND ((NULL CheckAndDeleteFlg) (* No checking required) T) ((AND (LISTP CheckAndDeleteFlg) (FMEMB (fetch (Link DestinationCard) of ActualLink) CheckAndDeleteFlg)) (* Already checked since ID cached on CheckAndDeleteFlg list) T) ((AND (NC.ValidLinkP ActualLink) (NC.ValidCardP (fetch (Link DestinationCard) of ActualLink))) (* Link is valid) T) (T (* Link is bad. Replace it with the DeletedLink image object.) (NC.DeleteLinkIconSketchElement SketchElt Card) (SETQ DirtyFlg T) NIL))) collect (SETQ CollectItem (COND (ReturnLinkIconsFlg LinkIcon) (T ActualLink))) (COND (ReturnLocationsFlg (CONS CollectItem (SKETCH.POSITION.OF.ELEMENT SketchElt))) (T CollectItem))) DirtyFlg)))) ) (* * Change to NCTEXTCARD) (DEFINEQ (NC.CollectReferencesInText (LAMBDA (Card CheckAndDeleteFlg ReturnLinkIconsFlg ReturnLocationsFlg) (* rht: " 1-Jun-87 22:11") (* * Return a list of all links or link icons in text substance Substance. If CheckAndDeleteFlg, then delete any links found that are not valid links.) (* * fgh 11/13/85 Updated to handle Card object. Eliminated DatabaseStream argument.) (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now have to check that destination of ActualLink is a valid card.) (DECLARE (GLOBALVARS NC.DeletedLinkImageObject)) (PROG (ActualLink DirtyFlg Links (Substance (NC.FetchSubstance Card))) (SETQ Links (for ImageObjectDecriptor in (TEDIT.LIST.OF.OBJECTS (TEXTOBJ Substance) (FUNCTION NC.LinkIconImageObjP)) when (PROGN (SETQ ActualLink (NC.FetchLinkFromLinkIcon (CAR ImageObjectDecriptor))) (COND ((NULL CheckAndDeleteFlg) (* No checking required) T) ((AND (LISTP CheckAndDeleteFlg) (FMEMB (fetch (Link DestinationCard) of ActualLink) CheckAndDeleteFlg)) (* Already checked since ID cached on CheckAndDeleteFlg list) T) ((AND (NC.ValidLinkP ActualLink) (NC.ValidCardP (fetch (Link DestinationCard) of ActualLink))) (* Link is valid) T) (T (* Link is bad. Replace it with the DeletedLink image object.) (create IMAGEOBJ smashing (CAR ImageObjectDecriptor) OBJECTDATUM ←(fetch (IMAGEOBJ OBJECTDATUM) of NC.DeletedLinkImageObject) IMAGEOBJPLIST ←(fetch (IMAGEOBJ IMAGEOBJPLIST) of NC.DeletedLinkImageObject) IMAGEOBJFNS ←(fetch (IMAGEOBJ IMAGEOBJFNS) of NC.DeletedLinkImageObject)) (SETQ DirtyFlg T) NIL))) collect (COND ((AND ReturnLinkIconsFlg (NOT ReturnLocationsFlg)) (CAR ImageObjectDecriptor)) ((AND ReturnLinkIconsFlg ReturnLocationsFlg) (CONS (CAR ImageObjectDecriptor) (CADR ImageObjectDecriptor))) ((AND (NOT ReturnLinkIconsFlg) ReturnLocationsFlg) (CONS ActualLink (CADR ImageObjectDecriptor))) (T ActualLink)))) (RETURN (CONS Links DirtyFlg))))) ) (* * Changes to NCLINKS) (DEFINEQ (NC.ValidLinkP (LAMBDA (Link) (* rht: "27-May-87 12:13") (* Check Link to see if it is a valid NOTECARDLINK, incvluding check that the NoteCard specified by DESTINATIONID is an active card.) (* * kirk 15Nov85: deleted use of DatabaseStream) (* * rht 7/18/86: Was actually reading in the destination card from notefile! No more.) (* * rht 5/27/87: Took out checks for valid source and destination cards.) (LET (DestinationCard) (AND (type? Link Link) (NEQ (fetch (Link UID) of Link) -1))))) (NC.MakeLink (LAMBDA (Window LinkLabel DestinationCard SourceCard DisplayMode AnchorMode Message NoDisplayFlg LinkToInsertAfter CrossFileLinksMode) (* rht: "28-May-87 13:39") (* * Make a link from (OR Window SourceCard) to DestinationCard with linklabel of LinkLabel) (* * rht 1/12/85: If need to create a new card, then now shows card type menu near window of SourceID.) (* * rht 1/13/85: Added extra args Message and NoDisplayFlg.) (* * rht 3/26/85: Added LinkToInsertAfter arg which should be NIL or a link to insert the new To link after. If NIL, then insert at front of ToLinks.) (* * kirk 9/23/85: took out GETPROMPTWINDOW call for asknotecardtype) (* * kirk: 14Nov85: changed NC.CoerceToID to to NC.CoerceToCard) (* * fgh 11/16/85 Changed from PROG to LET and used COND to contyrol returnmed value.) (* * fgh 2/5/86 Changed call DefaultLinkDisplayMode to FetchLinkDisplayMode) (* * fgh 6/5/86 Now calls AskLinkLabel if LinkLabel arg is NIL) (* * rht 7/4/86: Added check for readonly card.) (* * kef 7/17/86: Added calls to grab the write permission on the appropriate card parts.) (* * kef 7/22/86: Saves the links on the Destination Card now right away, while still holding onto the FROMLINKS write lock.) (* * fgh 8/30/86 Adpated to use NC.IfCardPartNotBusy.) (* * rht 9/29/86: Tossed Ken's call to NC.PutFromLinks; It was the cause of too many nasty breaks. Also made syntactic fixes.) (* * rht 10/4/86: Now handles cross file links. New arg CrossFileLinksMode determines whether cross-file link will be two-way, i.e. will destination card know it's being linked to.) (* * rht 11/10/86: Now creates new crossfile link if Destination card is a CrossFileLink card that we didn't just create.) (* * rht 11/14/86: Now checks if non-nil DestinationCard before trying to do cross-filelink stuff.) (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.) (* * rht 12/9/86: Throws out JustCreatedFlg marker stuff.) (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.) (* * rht 12/16/86: Fixed bug whereby electing not to open notefile containing crossfilelink dest card caused break.) (* * rht 12/16/86: Now passes Window down to NC.GetCrossFileLinkDestCard.) (* * rg 3/18/87 added NCP.WithLockedCards wrapper) (* * rht 5/25/87: No longer tries to make two way cross-file links when dest notefile is open read-only. Also assumes that CrossFileLinksMode is one of TWOWAY, ONEWAY or ASK. Now fills in the new RemoteCrossFileLinkCardUID field of cross file link cards.) (DECLARE (GLOBALVARS NC.SelectingSingleCardMenu NC.NewCrossFileLinksMode)) (OR SourceCard (SETQ SourceCard (NC.CoerceToCard Window))) (AND (NC.CheckForNotReadOnly SourceCard Window "Can't make links in ") (NCP.WithLockedCards (LET (Link Type) (OR Window (SETQ Window (NC.FetchWindow SourceCard))) (OR Message (SETQ Message "Please shift-select the Card or Box to be linked to.")) (OR LinkLabel (SETQ LinkLabel (NC.AskLinkLabel Window NIL NIL T NIL))) (OR DestinationCard (SETQ DestinationCard (NC.SelectNoteCards T (FUNCTION (LAMBDA (Card) (COND ((NOT (NC.SameCardP Card SourceCard)) T) (T (NC.PrintMsg Window T "A Card/Box cannot link to itself. " (CHARACTER 13) "Selection ignored." (CHARACTER 13)) NIL)))) NC.SelectingSingleCardMenu SourceCard Message))) (if (EQ DestinationCard (QUOTE *New% Card*)) then (SETQ DestinationCard (AND (SETQ Type (NC.AskNoteCardType (WINDOWREGION Window))) (NC.CoerceToCard (NC.MakeNoteCard Type (fetch (Card NoteFile) of SourceCard) NIL NoDisplayFlg))))) (* * If we're trying to link to a CrossFileLink card, then check whether card was just created. If so, then it's the first link, otherwise we make a new CrossFileLink.) (AND DestinationCard (NC.CrossFileLinkCardP DestinationCard) (SETQ DestinationCard (NC.GetCrossFileLinkDestCard DestinationCard Window)) (NC.SetUserDataProp DestinationCard (QUOTE JustCreatedFlg) NIL)) (if DestinationCard then (NC.IfCardPartNotBusy DestinationCard (QUOTE FROMLINKS) (NC.IfCardPartNotBusy SourceCard (QUOTE TOLINKS) (* * If have cross-file link, then make two new crossfilelink cards, one per notefile. Make global link over there from crossfilelink card to DestinationCard and local link here from SourceCard to crossfilelink card.) (if (NOT (NC.SameNoteFileP (fetch (Card NoteFile) of SourceCard) (fetch (Card NoteFile) of DestinationCard)) ) then (LET ((CrossFileLinksTwoWayFlg (OR (EQ CrossFileLinksMode (QUOTE TWOWAY)) (AND (NULL CrossFileLinksMode) (EQ NC.NewCrossFileLinksMode (QUOTE TWOWAY)) ) (AND (OR (EQ CrossFileLinksMode (QUOTE ASK)) (AND (NULL CrossFileLinksMode) (EQ NC.NewCrossFileLinksMode (QUOTE ASK)))) (NC.AskCrossFileLinkMode DestinationCard Window)))) RemoteSourceCard) (if CrossFileLinksTwoWayFlg then (AND (SETQ RemoteSourceCard (NC.CreateCrossFileLinkCard DestinationCard SourceCard T)) (NC.MakeGlobalLink Window LinkLabel DestinationCard RemoteSourceCard DisplayMode))) (SETQ DestinationCard (NC.CreateCrossFileLinkCard SourceCard DestinationCard CrossFileLinksTwoWayFlg)) (if RemoteSourceCard then (* Make the two crossfile link cards know about each other's UIDs.) (replace (CrossFileLinkSubstance RemoteCrossFileLinkCardUID) of (NC.FetchSubstance RemoteSourceCard) with (fetch (Card UID) of DestinationCard)) (replace (CrossFileLinkSubstance RemoteCrossFileLinkCardUID) of (NC.FetchSubstance DestinationCard) with (fetch (Card UID) of RemoteSourceCard)) ))) (SETQ Link (create Link UID ←(NC.MakeUID) SourceCard ← SourceCard DestinationCard ← DestinationCard AnchorMode ← AnchorMode Label ← LinkLabel DisplayMode ←(OR DisplayMode (NC.FetchLinkDisplayMode SourceCard)))) (NC.AddToLink Link LinkToInsertAfter) (NC.AddFromLink Link) Link)) else NIL)))))) (NC.DeleteFromLink (LAMBDA (Link NoOrphanHookFlg) (* rht: "27-May-87 14:40") (* * This is part of what used to be the innards of NC.DeleteLink.) (* * rht 3/26/87: Changed to call NC.DeleteNoteCardInternal with QuietFlg on.) (* * rht 5/26/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that DestinationCard is a valid card. Now calls NC.DeleteCrossFileLinkCard which tries to delete other end of cross-file link if that notefile is open.) (AND (NC.ValidLinkP Link) (LET ((DestinationCard (fetch (Link DestinationCard) of Link))) (AND (NC.ValidCardP DestinationCard) (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of DestinationCard) ) (NC.DelFromLink Link NoOrphanHookFlg) (NC.DelReferencesToCardFromShowLinks DestinationCard Link) (* * Delete cross file link cards when their links are deleted.) (if (NC.CrossFileLinkCardP DestinationCard) then (NC.DeleteCrossFileLinkCard DestinationCard)))))))) (NC.DeleteToLink (LAMBDA (Link Don'tDelLinkIconFlg) (* rht: "27-May-87 14:40") (* * This is part of what used to be the innards of NC.DeleteLink.) (* * rht 3/26/87: Changed to call NC.DeleteNoteCardInternal with QuietFlg on.) (* * rht 5/27/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that SourceCard is valid card. Now calls NC.DeleteCrossFileLinkCard which tries to delete other end of cross-file link if that notefile is open.) (AND (NC.ValidLinkP Link) (LET ((SourceCard (fetch (Link SourceCard) of Link))) (AND (NC.ValidCardP SourceCard) (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of SourceCard)) (OR Don'tDelLinkIconFlg (NC.DelReferencesToCard SourceCard Link)) (NC.DelToLink Link) (NC.DelReferencesToCardFromShowLinks SourceCard Link) (* * Delete cross file link cards when their links are deleted.) (if (NC.CrossFileLinkCardP SourceCard) then (NC.DeleteCrossFileLinkCard SourceCard)))))))) (NC.RelabelLink (LAMBDA (LinkOrLinkIcon Window NewLinkLabel ForceRedisplayFlg) (* rht: "27-May-87 22:35" pp pp) (* Relabel a NoteCard link. Ask user for new label. Update all the proper references to this link.) (* * rht 11/19/84: Fixed so that Card is defined before first use.) (* * kirk 14Nov85: deleted use of and LinkID) (* * kef 8/8/86: Added obtaining write lock and NC.PutFromLinks.) (* * fgh 8/30/86 Adapted to NC.IfCardPartNotBusy) (* * rht 9/29/86: Changed Ken's call to NC.CardBeingEditedP to NC.ActiveCardP and other minor mod's.) (* * rg 5/15/87 now calls NC.LinksCachedP instead of NC.ActiveCardP) (* * rht 5/27/87: Now passes new label through cross file link if its dest notefile is open.) (LET (Link LinkIcon Card DestinationCard OldLabel NoteCardType GlobalLinkFlg) (if (NC.LinkIconImageObjP LinkOrLinkIcon) then (SETQ Link (NC.FetchLinkFromLinkIcon LinkOrLinkIcon)) (SETQ LinkIcon LinkOrLinkIcon) else (SETQ Link LinkOrLinkIcon) (OR (SETQ GlobalLinkFlg (NC.GlobalLinkP Link)) (SETQ LinkIcon (NC.FetchLinkIconForLink Link)))) (SETQ Card (fetch (Link SourceCard) of Link)) (COND ((WINDOWP Window)) ((NC.ActiveCardP Card) (SETQ Window (NC.FetchWindow Card)))) (SETQ DestinationCard (fetch (Link DestinationCard) of Link)) (NC.IfCardPartNotBusy DestinationCard (QUOTE FROMLINKS) (COND ((NC.SystemLinkLabelP (fetch (Link Label) of Link)) (NC.PrintMsg Window T "This is a system maintained pointer." (CHARACTER 13) "You cannot change its label." (CHARACTER 13)) (SPAWN.MOUSE) (DISMISS 1500) (NC.ClearMsg Window T)) ((SETQ NewLinkLabel (OR NewLinkLabel (NC.AskLinkLabel Window NIL NIL T T))) (SETQ NoteCardType (NC.RetrieveType Card)) (* * Put new label in Link Icon or global links list) (if GlobalLinkFlg then (for GlobalLink in (NC.FetchGlobalLinks Card) when (NC.SameLinkP GlobalLink Link) do (replace (Link Label) of GlobalLink with NewLinkLabel) (NC.SetLinksDirtyFlg Card T) (RETURN)) else (replace (Link Label) of (NC.FetchLinkFromLinkIcon LinkIcon) with NewLinkLabel) (NC.MarkCardDirty Card)) (* * Update ToLink list of the SourceCard card) (for ToLink in (NC.FetchToLinks Card) when (NC.SameLinkP ToLink Link) do (replace (Link Label) of ToLink with NewLinkLabel) (NC.SetLinksDirtyFlg Card T) (RETURN)) (* * Update FromLink list of DestinationCard card) (if (NC.LinksCachedP DestinationCard) then (for FromLink in (NC.FetchFromLinks DestinationCard) when (NC.SameLinkP FromLink Link) do (replace (Link Label) of FromLink with NewLinkLabel) (NC.SetLinksDirtyFlg DestinationCard T) (RETURN)) else (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of DestinationCard)) (NC.GetLinks DestinationCard) (for FromLink in (NC.FetchFromLinks DestinationCard) when (NC.SameLinkP FromLink Link) do (replace (Link Label) of FromLink with NewLinkLabel) (NC.SetLinksDirtyFlg DestinationCard T) (RETURN)) (NC.PutFromLinks DestinationCard) (NC.UncacheLinks DestinationCard))) (* * Pass change through cross-file link to other notefile if open.) (if (NC.CrossFileLinkCardP Card) then (LET ((RemoteCrossFileLinkCard ( NC.FetchRemoteCrossFileLinkCard Card))) (AND RemoteCrossFileLinkCard (NC.CheckCrossFileLinkType RemoteCrossFileLinkCard Card Link)))) (if (NC.CrossFileLinkCardP DestinationCard) then (LET ((RemoteCrossFileLinkCard ( NC.FetchRemoteCrossFileLinkCard DestinationCard))) (AND RemoteCrossFileLinkCard (NC.CheckCrossFileLinkType RemoteCrossFileLinkCard DestinationCard Link)))) (* * Update images in SourceCard window) (COND ((AND (NULL ForceRedisplayFlg) (NC.TEditBasedP NoteCardType)) (QUOTE CHANGED)) ((WINDOWP Window) (NC.UpdateLinkImages Window (fetch (Link DestinationCard) of Link)) NIL) (T NIL)))))))) (NC.FileInOrphanBox (LAMBDA (Link DestinationCard) (* rht: "29-May-87 01:00") (* * Hook card to orphan if this is the last link.) (* * rht 7/4/86: Changed to call NC.FetchSpecialCards so that RegistryCard, etc. won't have to be filed somewhere.) (* * rg 11/18/86 Added globalvars declaration) (* * rht 4/20/87: Changed to work on new cards unless they're displayed on screen. Also removed reference to long-demised NC.OrphansID.) (* * rht 5/28/87: Now calls NC.CardNeedsFilingP, i.e. card should need filing before we gripe.) (LET ((SourceCard (fetch (Link SourceCard) of Link))) (AND (NC.CardNeedsFilingP DestinationCard) (NOT (NC.SameCardP SourceCard DestinationCard)) (NOT (AND (NC.FetchNewCardFlg DestinationCard) (NC.FetchWindow DestinationCard))) (NOT (NC.SameCardP SourceCard (fetch (NoteFile OrphansCard) of (fetch (Card NoteFile) of SourceCard)))) (COND ((OR (NULL (NC.FetchFromLinks DestinationCard)) (for FromLink in (NC.FetchFromLinks DestinationCard) always (NC.SameCardP (fetch (Link SourceCard) of FromLink) DestinationCard))) (NC.PrintMsg NIL T "You have just removed the last link to " (NC.RetrieveTitle DestinationCard) "." (CHARACTER 13) "It is being filed in the Orphan FileBox.") (NC.HookToOrphanCard DestinationCard)) ((for FromLink in (NC.FetchFromLinks DestinationCard) never (FMEMB (fetch (Link Label) of FromLink) (QUOTE (SubBox FiledCard)))) (NC.PrintMsg NIL T "You have just unfiled " (NC.RetrieveTitle DestinationCard) " from its last filebox." (CHARACTER 13) "It is being filed in the Orphan FileBox.") (NC.HookToOrphanCard DestinationCard)))) Link))) ) (* * Change to NCCARDS) (DEFINEQ (NC.DeleteNoteCardInternal (LAMBDA (Card QuietFlg InterestedWindow IgnoreLinksFlg) (* rht: " 8-Jun-87 23:47") (* * Delete a single note card from a NoteFile) (* * rht 8/11/86 Now calls NC.DeleteReferencesToCardFromShowLinks to smash any link icons in show links menus pointing to this card.) (* * kef 7/28/86: Added code to obtain all of the write locks deemed necessary.) (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding whether or not to setup the release of the write lock afterwards.) (* * kef 7/31/86: Added the nesting of the obtaining writelocks with deactivating the card.) (* * fgh 8/30/86 Translated APPLY* to NC.ApplyFn. Made cosmetic changes in FOR loop concewrning WriteLocks.) (* * rht 1/16/87: Moved call to MarkCardDeletedFn after call to NC.QuitCard.) (* * rg 3/11/87 renamed) (* * rht 3/13/87: Added QuietFlg, InterestedWindow, and IgnoreLinksFlg args. The latter non-nil causes card deletion but no link cutting.) (* * rht 3/25/87: Now calls NC.CoerceToInterestedWindow.) (* * rht 5/27/87: Changed to match reduced functionality of NC.ValidLinkP, now checks that DestinationCard and SourceCard are valid cards.) (* * pmi 6/8/87: Moved call to NC.GreyCard to beginning of this function.) (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR)) (RESETSAVE NIL (BQUOTE (NC.SetBeingDeletedFlg , Card NIL))) (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card)) (OR (OPENWP InterestedWindow) (SETQ InterestedWindow (NC.CoerceToInterestedWindow Card))) (LET ((WriteLocks (for CardPart in (QUOTE (SUBSTANCE TITLE TOLINKS FROMLINKS GLOBALTOLINKS PROPLIST)) collect (CONS Card CardPart))) ToLinks FromLinks Window BusyPart) (NC.SetBeingDeletedFlg Card T) (* * First grey the card being deleted.) (NC.GreyCard Card) (if (NOT IgnoreLinksFlg) then (SETQ ToLinks (NC.RetrieveToLinks Card)) (SETQ FromLinks (NC.RetrieveFromLinks Card)) (for ToLink in ToLinks do (NCONC WriteLocks (for CardPart in (QUOTE (TOLINKS FROMLINKS GLOBALTOLINKS)) collect (CONS (fetch (Link DestinationCard) of ToLink) CardPart)))) (for FromLink in FromLinks do (NCONC WriteLocks (for CardPart in (QUOTE (SUBSTANCE TOLINKS FROMLINKS GLOBALTOLINKS)) collect (CONS (fetch (Link SourceCard) of FromLink) CardPart))))) (* * The for... loop that follows is the condition that we can obtain all of the write locks on all of the card parts collected in WriteLocks. If we obtain a writelock, setup a RESETSAVE to release it upon exit. Then finally, if we do obtain a write lock, return T so that the for loop's "always" condition is satisfied. If we don't obtain a write lock for a given card part, save that one as a variable so we can report it to the user. Then return NIL, so that the for loop's "always" condition is not satisfied, and we bump out of the for loop.) (OR QuietFlg (NC.PrintMsg InterestedWindow T "Collecting write locks...")) (COND ((for WriteLock in WriteLocks bind WLCard WLCardPart when (NC.ValidCardP (SETQ WLCard (CAR WriteLock))) always (SETQ WLCardPart (CDR WriteLock)) (COND ((NC.ApplyFn ObtainWritePermissionFn WLCard WLCardPart) (RESETSAVE NIL (BQUOTE (APPLY* , (fetch (Card ReleaseWritePermissionFn) of WLCard) , WLCard , WLCardPart)) ) T) (T (SETQ BusyPart WriteLock) NIL))) (* * Call off to the MarkCardDeletedFn specific to the NoteFile.) (RESETSAVE (for CardPart in (QUOTE (SUBSTANCE TOLINKS GLOBALTOLINKS PROPLIST)) do (NC.ApplyFn ObtainWritePermissionFn Card CardPart)) (BQUOTE (NC.DeactivateCard , Card T))) (NC.ApplyFn MarkCardDeletedFn Card) (NC.SetToLinks Card NIL) (NC.SetFromLinks Card NIL) (if (NOT IgnoreLinksFlg) then (OR QuietFlg (NC.PrintMsg InterestedWindow NIL "Removing links to and from other cards...")) (for ToLink in ToLinks bind DestCard when (AND (NC.ValidLinkP ToLink) (NC.ValidCardP (SETQ DestCard (fetch (Link DestinationCard) of ToLink)))) do (NC.DelFromLink ToLink) (NC.DelReferencesToCardFromShowLinks DestCard ToLink)) (for FromLink in FromLinks bind SourceCard when (AND (NC.ValidLinkP FromLink) (NC.ValidCardP (SETQ SourceCard (fetch (Link SourceCard) of FromLink)))) do (NC.DelToLink FromLink) (NC.DelReferencesToCard SourceCard Card) (NC.DelReferencesToCardFromShowLinks SourceCard FromLink)) (OR QuietFlg (NC.PrintMsg InterestedWindow NIL "..done."))) (if (NC.ActiveCardP Card) then (NC.TurnOffDirtyFlgs Card) (NC.CloseAllPropListEditors Card) (NC.QuitCard Card T T)) (NC.ApplyFn MarkCardDeletedFn Card) (NC.SetNewCardFlg Card NIL)) (T (NC.CardPartBusy (CAR BusyPart) (CDR BusyPart) InterestedWindow)))))))) (NC.AssignTitle (LAMBDA (CardIdentifier NoClearMsgFlg NewTitle InterestedWindow) (* rht: "29-May-87 15:49") (* * Change the title of the card specified by the WindowOrTextStreamOrID) (* * rht 2/1/85: Changed from NC.PutTitle to NC.SetTitleDirtyFlg, unless card is not active. We shouldn't be writing to the notefile until save time.) (* * fgh 11/11/85: Added support for CardID, CardInfo and noteFile objects. Also entered call to Nc.StoreTitle.) (* * fgh 6/9/86 Added code to check to make sure that another operation is not in progress on this card when this fn is called.) (* * fgh 6/13/86 Now spawns mouse in case called under MOUSE process.) (* * fgh 6/27/86 returns T if completed okay.) (* * rht 7/4/86: Added check for readonly card.) (* * kef 7/16/86: Added obtain write permission.) (* * kef 7/24/86: Doesn't release the write lock if this is a new card.) (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding whether or not to setup the release of the write lock afterwards.) (* * fgh 8/30/86 Converted to use NC.IfCardPartNotBusy.) (* * rg 3/3/87 Enlarged scope of NC.ProtectedCardOperation) (* * rht 3/23/87: Now takes InterestedWindow arg.) (* * rht 3/24/87: Now calls NC.CoerceToInterestedWindow) (* * rht 5/27/87: Now passes title through cross-file link card if dest notefile is open.) (* * rht 5/29/87: Now uncaches links if they weren't cached when we came in.) (ALLOW.BUTTON.EVENTS) (LET ((Card (NC.CoerceToCard CardIdentifier)) OldTitle Window) (NC.ProtectedCardOperation Card "Assign Title" NIL (NC.IfCardPartNotBusy Card (QUOTE TITLE) (OR InterestedWindow (SETQ InterestedWindow ( NC.CoerceToInterestedWindow Card))) (if (NC.CheckForNotReadOnly Card InterestedWindow "Can't change titles for cards in ") then (COND ((SETQ NewTitle (OR (STRINGP NewTitle) (AND NewTitle (OR (LITATOM NewTitle) (NUMBERP NewTitle)) (MKSTRING NewTitle)) (NC.AskUser (CONCAT "Enter the title for this card" (CHARACTER 13)) "--> " (COND ((AND (STREQUAL (SETQ OldTitle ( NC.RetrieveTitle Card)) "Untitled") (NC.FetchNewCardFlg Card)) NIL) (T OldTitle)) (NULL NoClearMsgFlg) InterestedWindow))) (NC.SetTitle Card NewTitle) (* * Now do a PutTitle so that anyone else coming along will pick up on the new title. The only exception is if this card hasn't been written to the NoteFile yet, which is true when the NewCardFlg is T. In that case, we can't put the title down yet, so just mark it dirty.) (COND ((fetch (Card NewCardFlg) of Card) (NC.SetTitleDirtyFlg Card T)) (T (NC.PutTitle Card) (NC.SetTitleDirtyFlg Card NIL))) (AND (WINDOWP (SETQ Window (NC.FetchWindow Card))) (WINDOWPROP Window (QUOTE TITLE) NewTitle)) (LET ((LinksWereCachedFlg (NC.LinksCachedP Card))) (if (NOT LinksWereCachedFlg) then (NC.GetLinks Card)) (for FromLink in (NC.FetchFromLinks Card) do (LET ((ContainingCard (fetch (Link SourceCard) of FromLink)) RemoteCrossFileLinkCard) (if (AND (NC.CrossFileLinkCardP ContainingCard) (SETQ RemoteCrossFileLinkCard ( NC.FetchRemoteCrossFileLinkCard ContainingCard))) then ( NC.CheckCrossFileLinkCardTitle RemoteCrossFileLinkCard Card) else (AND (NC.ActiveCardP ContainingCard) (WINDOWP ( NC.FetchWindow ContainingCard)) (NC.UpdateLinkImages ContainingCard Card))))) (if (NOT LinksWereCachedFlg) then (NC.UncacheLinks Card))) T)) else NIL)))))) ) (* * Changes to NCCROSSFILELINKS) (DEFINEQ (NC.OpenCrossFileLinkDestNoteFile (LAMBDA (DestNoteFile DestFileName InterestedWindow CrossFileLinkCard) (* rht: " 8-Jun-87 11:39") (* * If DestNoteFile is an open notefile, then fine. Otherwise get file names from user and keep trying to open until she gives up.) (* * rht 5/25/87: Minor change: no longer passes InterestedWindow to NC.OpenNoteFile.) (* * rht 6/3/87: Now calls new function NC.AskUserWithMenu. Added CrossFileLinkCard argument whose title is used to construct Message.) (* * rht 6/8/87: Now computes WasOpenPromptWindowFlg) (OR InterestedWindow (NC.CoerceToInterestedWindow CrossFileLinkCard)) (LET ((WasOpenPromptWindowFlg (NC.PromptWindowOpenP InterestedWindow))) (if (NCP.OpenNoteFileP DestNoteFile) then DestNoteFile else (LET ((MenuItems (QUOTE (Read/Write Read-Only Don't% Open)))) (for while (OR DestFileName (SETQ DestFileName (NC.AskUser "File name to try opening: " NIL NIL T InterestedWindow WasOpenPromptWindowFlg))) do (LET ((Message (if (NC.ValidCardP CrossFileLinkCard) then (CONCAT "Open " DestFileName " to look for '" (NC.RetrieveTitle CrossFileLinkCard) "'?") else (CONCAT "OPEN " DestFileName "?"))) ReadOnlyOpenFlg) (if (AND (SELECTQ (NC.AskUserWithMenu MenuItems Message InterestedWindow WasOpenPromptWindowFlg T) (Read/Write (SETQ ReadOnlyOpenFlg NIL) T) (Read-Only (SETQ ReadOnlyOpenFlg T)) (Don't% Open (RETURN NIL)) (RETURN NIL)) (NCP.OpenNoteFileP (SETQ DestNoteFile (NC.OpenNoteFile (OR DestNoteFile DestFileName) NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL ReadOnlyOpenFlg)))) then (RETURN DestNoteFile) else (NC.PrintMsg InterestedWindow T "Couldn't open " DestFileName "." (CHARACTER 13)) (SETQ DestFileName (SETQ DestNoteFile NIL)) (if (NOT (NC.AskYesOrNo "Want to try opening a different notefile? " " -- " "Yes" NIL InterestedWindow WasOpenPromptWindowFlg)) then (RETURN NIL)))))))))) (NC.CrossFileLinkPutFn (LAMBDA (Card Stream) (* rht: "27-May-87 15:07") (* * Put crossfilelink substance) (* * rht 11/1/86: Now uses our readtable when printing.) (* * rht 5/27/87: Changed to write down new fields RemoteCrossFileLinkCardUID and CrossFileLinkTwoWayFlg of CrossFileLinkSubstance record.) (DECLARE (GLOBALVARS NC.OrigReadTable)) (LET ((Substance (NC.FetchSubstance Card))) (NC.WriteUID Stream (fetch (CrossFileLinkSubstance CrossFileLinkDestCardUID) of Substance)) (NC.WriteUID Stream (fetch (CrossFileLinkSubstance CrossFileLinkDestNoteFileUID) of Substance)) (NC.WriteUID Stream (fetch (CrossFileLinkSubstance RemoteCrossFileLinkCardUID) of Substance)) (PRINT (fetch (CrossFileLinkSubstance CrossFileLinkDestFileHint) of Substance) Stream NC.OrigReadTable) (PRINT (fetch (CrossFileLinkSubstance CrossFileLinkTwoWayFlg) of Substance) Stream NC.OrigReadTable)) 1)) (NC.CrossFileLinkGetFn (LAMBDA (Card Length Stream VersionNum) (* rht: "27-May-87 15:06") (* * Get the crossfilelink substance from the disk) (* * rht 11/1/86: Now uses our readtable when reading.) (* * rht 5/27/87: Now reads in new format of CrossFileLinkSubstance record with two new fields.) (DECLARE (GLOBALVARS NC.OrigReadTable)) (if (LEQ VersionNum 0) then (create CrossFileLinkSubstance CrossFileLinkDestCardUID ←(NC.ReadUID Stream) CrossFileLinkDestNoteFileUID ←(NC.ReadUID Stream) CrossFileLinkDestFileHint ←(READ Stream NC.OrigReadTable)) else (create CrossFileLinkSubstance CrossFileLinkDestCardUID ←(NC.ReadUID Stream) CrossFileLinkDestNoteFileUID ←(NC.ReadUID Stream) RemoteCrossFileLinkCardUID ←(NC.ReadUID Stream) CrossFileLinkDestFileHint ←(READ Stream NC.OrigReadTable) CrossFileLinkTwoWayFlg ←(READ Stream NC.OrigReadTable))))) (NC.CrossFileLinkEditFn (LAMBDA (Card Substance RegionOrPosition TypeSpecificArgs) (* rht: "27-May-87 18:34") (* * Given a CrossFileLink Substance, try to find the corresponding destination card in the destination notefile and bring it up.) (* * rht 11/13/86: Now updates title of crossfile link card to be the same as destination card if necessary.) (* * rht 5/27/87: Now calls NC.CheckCrossFileLinkCardTitle.) (LET ((DestinationCard (NC.GetCrossFileLinkDestCard Card)) DestinationCardTitle) (if DestinationCard then (NC.CheckCrossFileLinkCardTitle Card DestinationCard) (NC.EditNoteCard DestinationCard RegionOrPosition TypeSpecificArgs))))) (NC.GetCrossFileLinkDestCard (LAMBDA (CrossFileLinkCard InterestedWindow Don'tOpenDestNoteFileFlg) (* rht: " 8-Jun-87 11:39") (* * Find the notefile corresponding to this crossfilelink and try to open it if not already open. Then look for the card in there having the given UID. Return NIL if failed for any reason.) (* * rht 11/10/86: Make sure CrossFileLinkCard is cached before fetching substance.) (* * rht 11/19/86: Now rips off version number from destination notefile hint.) (* * rht 12/11/86: Now checks that destination card is not deleted.) (* * rht 12/16/86: Now takes InterestedWindow argument.) (* * rht 3/25/87: Now calls NC.CoerceToInterestedWindow.) (* * rht 3/27/87: Now calls NC.OpenCrossFileLinkDestNoteFile.) (* * rht 5/27/87: New arg Don'tOpenDestNoteFileFlg. If non-nil, then destination notefile has to be already open.) (* * rht 6/4/87: Now passes CrossFileLinkCard to NC.OpenCrossFileLinkDestNoteFile.) (* * rht 6/8/87: Now computes WasOpenPromptWindowFlg) (LET ((Title (NC.FetchTitle CrossFileLinkCard)) (SourceNoteFile (fetch (Card NoteFile) of CrossFileLinkCard)) Substance DestNoteFileUID DestFileHint DestCardUID DestNoteFile DestFileName Card WasOpenPromptWindowFlg) (OR InterestedWindow (SETQ InterestedWindow (NC.CoerceToInterestedWindow SourceNoteFile))) (SETQ WasOpenPromptWindowFlg (NC.PromptWindowOpenP InterestedWindow)) (if (NOT (NC.ActiveCardP CrossFileLinkCard)) then (NC.GetNoteCard CrossFileLinkCard)) (SETQ Substance (NC.FetchSubstance CrossFileLinkCard)) (SETQ DestCardUID (fetch (CrossFileLinkSubstance CrossFileLinkDestCardUID) of Substance)) (SETQ DestNoteFileUID (fetch (CrossFileLinkSubstance CrossFileLinkDestNoteFileUID) of Substance)) (SETQ DestFileHint (fetch (CrossFileLinkSubstance CrossFileLinkDestFileHint) of Substance)) (SETQ DestNoteFile (NC.NoteFileFromNoteFileUID DestNoteFileUID)) (SETQ DestFileName (OR (AND (type? NoteFile DestNoteFile) (fetch (NoteFile FullFileName) of DestNoteFile)) DestFileHint)) (for while (if Don'tOpenDestNoteFileFlg then (NCP.OpenNoteFileP DestNoteFile) else (SETQ DestNoteFile (NC.OpenCrossFileLinkDestNoteFile DestNoteFile DestFileName InterestedWindow CrossFileLinkCard))) bind NewFileName do (if (NC.ValidCardP (SETQ Card (NC.CardFromUID DestCardUID DestNoteFile))) then (if (NOT (EQUAL (SETQ NewFileName (fetch (NoteFile FullFileName) of DestNoteFile)) (FULLNAME (fetch (CrossFileLinkSubstance CrossFileLinkDestFileHint) of Substance)))) then (replace (CrossFileLinkSubstance CrossFileLinkDestFileHint) of Substance with (PACKFILENAME (QUOTE VERSION) NIL (QUOTE BODY) NewFileName)) (NC.MarkCardDirty CrossFileLinkCard)) (RETURN Card) else (if Don'tOpenDestNoteFileFlg then (RETURN NIL) else (NC.PrintMsg InterestedWindow T "Couldn't find destination card in " DestFileName "." (CHARACTER 13)) (if (NOT (NC.AskYesOrNo "Want to try opening a different notefile? " " -- " "Yes" NIL InterestedWindow WasOpenPromptWindowFlg)) then (RETURN NIL) else (SETQ DestNoteFile (SETQ DestFileName NIL))))))))) ) [DECLARE: EVAL@COMPILE (DATATYPE CrossFileLinkSubstance (CrossFileLinkDestCardUID CrossFileLinkDestNoteFileUID CrossFileLinkDestFileHint ( CrossFileLinkTwoWayFlg FLAG) RemoteCrossFileLinkCardUID)) ] (/DECLAREDATATYPE (QUOTE CrossFileLinkSubstance) (QUOTE (POINTER POINTER POINTER FLAG POINTER)) (QUOTE ((CrossFileLinkSubstance 0 POINTER) (CrossFileLinkSubstance 2 POINTER) (CrossFileLinkSubstance 4 POINTER) (CrossFileLinkSubstance 4 (FLAGBITS . 0)) (CrossFileLinkSubstance 6 POINTER))) (QUOTE 8)) (* * New stuff for NCCROSSFILELINKS) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS NC.NewCrossFileLinksMode) ) (RPAQ? NC.NewCrossFileLinksMode (QUOTE ASK)) (DEFINEQ (NC.AskCrossFileLinkMode (LAMBDA (DestCard InterestedWindow) (* rht: "28-May-87 13:54") (* * Ask the user whether to make the link be twoway or oneway. Return T if user says two-way. If dest notefile is open read-only, then only choice is one-way so don't ask.) (LET* ((NoteFile (fetch (Card NoteFile) of DestCard)) (FullFileName (fetch (NoteFile FullFileName) of NoteFile))) (if (NC.ReadOnlyNoteFileP NoteFile) then NIL else (NC.AskYesOrNo (CONCAT "Okay to make cross-file link to '" (NC.RetrieveTitle DestCard) "' in '" (FILENAMEFIELD FullFileName (QUOTE NAME)) ";" (FILENAMEFIELD FullFileName (QUOTE VERSION)) "' be TWOWAY?" (CHARACTER 13) "(otherwise leaves no record of link in destination notefile) ") NIL "Yes" T InterestedWindow))))) (NC.DeleteCrossFileLinkCard (LAMBDA (CrossFileLinkCard) (* rht: "27-May-87 21:54") (* * Delete the crossfile link card. If it's a twoway crossfile link, and its "twin" is in an open notefile, then delete the cross file link over there.) (LET ((DestCard (NC.FetchRemoteCrossFileLinkCard CrossFileLinkCard))) (if DestCard then (NC.DeleteNoteCardInternal DestCard T)) (NC.DeleteNoteCardInternal CrossFileLinkCard T)))) (NC.FetchRemoteCrossFileLinkCard (LAMBDA (CrossFileLinkCard) (* rht: "27-May-87 21:54") (* * Return the remote "twin" of CrossFileLinkCard if its notefile is open.) (LET ((CrossFileLinkSubstance (NCP.CardSubstance CrossFileLinkCard)) DestCard RemoteCrossFileLinkCardUID NoteFileUID NoteFile) (if (AND (fetch (CrossFileLinkSubstance CrossFileLinkTwoWayFlg) of CrossFileLinkSubstance) (SETQ RemoteCrossFileLinkCardUID (fetch (CrossFileLinkSubstance RemoteCrossFileLinkCardUID) of CrossFileLinkSubstance)) (type? UID (SETQ NoteFileUID (fetch (CrossFileLinkSubstance CrossFileLinkDestNoteFileUID) of CrossFileLinkSubstance))) (NCP.OpenNoteFileP (SETQ NoteFile (NC.NoteFileFromNoteFileUID NoteFileUID) )) (NC.ValidCardP (SETQ DestCard (NC.CardFromUID RemoteCrossFileLinkCardUID NoteFile)))) then DestCard else NIL)))) (NC.CheckCrossFileLinkCardTitle (LAMBDA (CrossFileLinkCard DestinationCard) (* rht: "27-May-87 21:47") (* * If titles don't agree, change crossfilelink card title to match.) (LET ((DestinationCardTitle (NC.RetrieveTitle DestinationCard))) (if (NOT (STREQUAL DestinationCardTitle (NC.RetrieveTitle CrossFileLinkCard))) then (NC.AssignTitle CrossFileLinkCard NIL DestinationCardTitle))))) (NC.CheckCrossFileLinkType (LAMBDA (RemoteCrossFileLinkCard LocalCrossFileLinkCard Link) (* rht: "27-May-87 22:33") (* * If link types don't agree, change remote crossfilelink type to match.) (LET ((RemoteDestCard (NC.GetCrossFileLinkDestCard LocalCrossFileLinkCard NIL T)) (LinkLabel (fetch (Link Label) of Link)) RemoteLink NoteFile) (if RemoteDestCard then (SETQ RemoteLink (OR (for FromLink in (NC.RetrieveFromLinks RemoteCrossFileLinkCard) when (NC.SameCardP (fetch (Link SourceCard) of FromLink) RemoteDestCard) do (RETURN FromLink)) (for ToLink in (NC.RetrieveToLinks RemoteCrossFileLinkCard) when (NC.SameCardP (fetch (Link DestinationCard) of ToLink) RemoteDestCard) do (RETURN ToLink)))) (if (NOT (EQ (fetch (Link Label) of RemoteLink) LinkLabel)) then (if (NOT (NCP.ValidLinkTypeP LinkLabel (SETQ NoteFile (fetch (Card NoteFile) of RemoteCrossFileLinkCard))) ) then (NCP.CreateLinkType LinkLabel NoteFile)) (NC.RelabelLink RemoteLink NIL LinkLabel)))))) (NC.MakeCrossFileLinkIconStandIn (LAMBDA (CrossFileLinkCard) (* rht: "27-May-87 23:39") (* * Return an imageobj to act as a standin for a cross file link.) (DECLARE (GLOBALVARS NC.ExternalPutLinkIconImageFns)) (IMAGEOBJCREATE (CONCAT "[[ Cross-file link to '" (NC.RetrieveTitle CrossFileLinkCard) "' ]]") NC.ExternalPutLinkIconImageFns))) (NC.ComputeCrossFileLinkMode (LAMBDA (RemoteCard CrossFileLinkModePropList InterestedWindow) (* rht: " 6-Jun-87 16:19") (* * If we've already made cross file links to RemoteCard's notefile, then it'll be registered on CrossFileLinkModePropList. Otherwise, consult global var, possibly ask user, and register her answer on CrossFileLinkModePropList.) (* * rht 6/6/87: Changed so that check of globalvar happens before check of CrossFileLinkModePropList.) (DECLARE (GLOBALVARS NC.NewCrossFileLinksMode)) (LET ((NoteFile (fetch (Card NoteFile) of RemoteCard)) Mode) (COND ((FMEMB NC.NewCrossFileLinksMode (QUOTE (TWOWAY ONEWAY))) NC.NewCrossFileLinksMode) ((FMEMB NoteFile CrossFileLinkModePropList) (LISTGET CrossFileLinkModePropList NoteFile)) (T (SETQ Mode (if (NC.AskCrossFileLinkMode RemoteCard InterestedWindow) then (QUOTE TWOWAY) else (QUOTE ONEWAY))) (LISTPUT CrossFileLinkModePropList NoteFile Mode) Mode))))) ) (* * PLEASE remove the globalvar NC.NewCrossFileLinksTwoWayFlg from NCCROSSFILELINKS coms) (* * Changes to NCBROWSERCARD) (DEFINEQ (NC.GrowLinkLattice (LAMBDA (RootCardsList CurrentGraph ListOfLinkLabels GraphCard RemainingSearchDepth) (* rht: "29-May-87 01:46") (* Grow a lattice by following the links from RootID card among ListOfLinkLabels. Lattice will be fed to LAYOUTGRAPH, so for each note card encountered by following the links just fill in the ID, LABEL and daughter IDs) (* * rht 8/3/84: Changed so as to also follow from links if they are present (prefixed by "←") on ListOfLinkLabels.) (* * rht 10/4/84: Now stores the link label on the prop list of the NODEID of the graph under the property name of the destination ID. This is so that links can be drawn with dashing depending on the link's label.) (* * rht 3/8/85: Added RemainingSearchDepth arg to limit the lattice growth to given depth.) (* * rht 8/9/85: Changed so that backward links are no longer stored as a separate link type. Rather they're told apart from forward links by being stored on the destination node's prop list.) (* * rht 4/4/85: Now first arg can be either a root Card or an existing graphnode. If the latter, then we're expanding an existing graph below that node. If the former than we're starting a new lattice.) (* * rht 10/17/85: Changed from a recursive depth-first algorithm to a loop-driven breadth-first alg.) (* * rht 11/17/85: Handles new card and notefile objects.) (* * rht 5/26/87: Now tries to follow cross-file links.) (LET (CardsAndDepthsQueue) (* Make the queue contain pairs of root Card and depth remaining to search.) (SETQ CardsAndDepthsQueue (for Card in RootCardsList collect (CONS Card RemainingSearchDepth))) (* Make it a TCONC list for fast appending to the end.) (SETQ CardsAndDepthsQueue (CONS CardsAndDepthsQueue (LAST CardsAndDepthsQueue))) (* * Do breadth-first search using the queue IDsAndDepthsQueue.) (for bind CardAndDepth Card RemainingSearchDepth ToLinks FromLinks DestinationIDs GraphNodeID GraphNode eachtime (BLOCK) (* Grab and take apart 1st pair on queue.) (SETQ CardAndDepth (CAAR CardsAndDepthsQueue)) (SETQ Card (CAR CardAndDepth)) (SETQ RemainingSearchDepth (CDR CardAndDepth)) (* Remove the front pair from the queue.) (RPLACA CardsAndDepthsQueue (CDAR CardsAndDepthsQueue)) (* If that was the last pair, then start queue over fresh.) (if (NULL (CAR CardsAndDepthsQueue)) then (SETQ CardsAndDepthsQueue NIL)) while Card unless (NC.SameCardP Card GraphCard) do (SETQ GraphNodeID (NC.GetBrowserNodeID GraphCard Card)) (* Go grab this ID's links.) (if (NC.ActiveCardP Card) then (SETQ ToLinks (NC.FetchToLinks Card)) (SETQ FromLinks (NC.FetchFromLinks Card)) else (NC.GetLinks Card) (SETQ ToLinks (NC.FetchToLinks Card)) (SETQ FromLinks (NC.FetchFromLinks Card))) (if (IGREATERP RemainingSearchDepth 0) then (* Crush the ID's proplist.) (if (NOT (NC.GraphNodeIDGetProp GraphNodeID (QUOTE TouchedFlg))) then (NC.SmashGraphNodeIDProps GraphNodeID) (NC.GraphNodeIDPutProp GraphNodeID (QUOTE TouchedFlg) T)) (SETQ DestinationIDs (NCONC (for Link in ToLinks bind DestID DestVisitedFlg DestTouchedFlg ThisWayLinkFlg OtherWayLinkFlg eachtime (BLOCK) (if (SETQ ThisWayLinkFlg (NC.LinkLabelP Link ListOfLinkLabels)) then (SETQ DestID (NC.GetBrowserNodeID GraphCard (LET ((DestCard (fetch (Link DestinationCard) of Link))) (if (NC.CrossFileLinkCardP DestCard) then (OR ( NC.GetCrossFileLinkDestCard DestCard) DestCard) else DestCard)))) (SETQ DestVisitedFlg (NC.GraphNodeIDGetProp DestID (QUOTE VisitedFlg))) (SETQ DestTouchedFlg (NC.GraphNodeIDGetProp DestID (QUOTE TouchedFlg))) (SETQ OtherWayLinkFlg (NC.ReverseLinkLabelP Link ListOfLinkLabels))) when ThisWayLinkFlg unless (AND DestVisitedFlg OtherWayLinkFlg) collect (* Record presence of this link.) (NC.UIDAddProp GraphNodeID DestID (fetch (Link Label) of Link) T) DestID) (for Link in FromLinks bind DestID DestTouchedFlg DestVisitedFlg ThisWayLinkFlg OtherWayLinkFlg SourceCard eachtime (BLOCK) (if (AND (SETQ ThisWayLinkFlg (NC.ReverseLinkLabelP Link ListOfLinkLabels)) (NOT (NC.SameCardP GraphCard (SETQ SourceCard (LET ((SrcCard (fetch (Link SourceCard) of Link))) (if (NC.CrossFileLinkCardP SrcCard) then (OR ( NC.GetCrossFileLinkDestCard SrcCard) SrcCard) else SrcCard)))))) then (SETQ DestID (NC.GetBrowserNodeID GraphCard SourceCard)) (SETQ DestVisitedFlg (NC.GraphNodeIDGetProp DestID (QUOTE VisitedFlg))) (SETQ DestTouchedFlg (NC.GraphNodeIDGetProp DestID (QUOTE TouchedFlg))) (SETQ OtherWayLinkFlg (NC.LinkLabelP Link ListOfLinkLabels))) when ThisWayLinkFlg unless (AND DestVisitedFlg OtherWayLinkFlg) collect (* Crush the dest node's prop list if it's never been touched. But if dest node is a fringe node for this search, don't have to clear the whole proplist.) (if (NOT DestTouchedFlg) then (if (EQ 1 RemainingSearchDepth) then (NC.GraphNodeIDRemProp DestID GraphNodeID) else (NC.SmashGraphNodeIDProps DestID) (NC.GraphNodeIDPutProp DestID (QUOTE TouchedFlg) T))) (* Record presence of this link.) (NC.UIDAddProp DestID GraphNodeID (fetch (Link Label) of Link) T) DestID))) (SETQ DestinationIDs (DREMOVE (NC.GetBrowserNodeID GraphCard GraphCard) (INTERSECTION DestinationIDs DestinationIDs))) else (SETQ DestinationIDs NIL)) (NC.GraphNodeIDPutProp GraphNodeID (QUOTE VisitedFlg) T) (* * Create new node and add to graph unless we're working on a node already in the graph.) (if (SETQ GraphNode (FASSOC GraphNodeID CurrentGraph)) then (* If node is in graph, but we won't expand further, then leave it's destination IDs alone.) (AND (GREATERP RemainingSearchDepth 0) (replace (GRAPHNODE TONODES) of GraphNode with DestinationIDs)) else (SETQ CurrentGraph (NCONC CurrentGraph (LIST (create GRAPHNODE NODEID ← GraphNodeID TONODES ← DestinationIDs NODELABEL ← Card))))) (* * Attach new IDs to end of queue.) (for DestinationID in DestinationIDs bind DestCard eachtime (BLOCK) (SETQ DestCard (NC.CardFromBrowserNodeID DestinationID)) unless (OR (NC.GraphNodeIDGetProp DestinationID (QUOTE VisitedFlg)) (for CardAndDepth in (CAR CardsAndDepthsQueue) eachtime (BLOCK) thereis (NC.SameCardP DestCard (CAR CardAndDepth)))) do (SETQ CardsAndDepthsQueue (TCONC CardsAndDepthsQueue (CONS DestCard (SUB1 RemainingSearchDepth))))) ) CurrentGraph))) (NC.MakeBrowserCard (LAMBDA (Card Title NoDisplayFlg ParamList) (* rht: " 4-Jun-87 11:49") (* Make a browser card with id Card using root at RootID and the link following predictae specified by Predicate. IF Root and/or ListOfLinkLabels not specified, ask the user.) (* * rht 8/3/84: Changed to call NC.AskLinkLabel with its ReverseLinkLabel parameter set to T.) (* * fgh 10/2/84 Changed Link Icons to be image objects in NodeLabel of Graph Npodes rather than annotations on graph nodes.) (* * rht 10/19/84: Fixed setting up of browser card's prop list in case NoDisplayFlg is T so we have no Window. Now NC.MakeLinksLegend returns the label pairs.) (* * rht 11/27/84: Removed the WINDOWADDPROP call to put NC.GraphCardCloseFn on the CLOSEFN of the window. This causes trouble. NC.QuitCard will get put on by NC.MakeNoteCard and that's enough.) (* * rht 1/3/85: Now puts a dummy region of the right size if the NoDisplayFlg is on.) (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.) (* * rht 2/14/85: Added VerticalFlg and made BrowserSpecs get put on browser's proplist in all cases.) (* * rht 4/1/85: Now calls NC.AskBrowserSpecs with additional Don'tAskFlg in case of call from Programmer's interface.) (* * rht 11/17/85: Updated to handle new card and notefile objects.) (* * rht 2/7/86: Now gets browser format, etc. via fetch/set fns.) (* * rht 5/6/86: Took out call to NC.SetupTitleBarMenu.) (* * rht 5/8/86: Added calls to rig title bar properly.) (* * rht 7/10/86: Now passes ListOfLinkLabels to NC.AskBrowserSpecs.) (* * rht 9/19/86: Mod to above fix. Now calls NC.MakeNewCardWindow a new fn that creates window and hangs Card off windowprop.) (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection. Also added GLOBALVARS statement.) (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.) (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a standin for a cross file link icon.) (* * rg 3/18/87 added NC.CardSelectionOperation wrapper) (* * rht 3/20/87: Removed needless call to NC.ActivateCard.) (* * rg 4/2/87 changed wrapper to NCP.WithLockedCards and added NC.IfAllCardsFree wrapper) (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when GrowLinkLattice wasn't able to follow into the remote notefile.) (DECLARE (GLOBALVARS NC.SubBoxLinkLabel NC.BrowserContentsLinkLabel NC.SpecialBrowserSpecsFlg NC.*Graph*BrowserFormat NC.SelectingBrowserSourceMenu)) (NCP.WithLockedCards (PROG ((RootCards (MKLIST (LISTGET ParamList (QUOTE ROOTCARDS)))) (ListOfLinkLabels (LISTGET ParamList (QUOTE LINKTYPES))) (BrowserFormat (LISTGET ParamList (QUOTE FORMAT))) (Depth (LISTGET ParamList (QUOTE DEPTH))) (CardType (NC.RetrieveType Card)) Lattice RootNodes Window Graph SpecialBrowserSpecs BrowserSpecs DropVirtualNodesFlg) (NC.IfAllCardsFree (NC.LockListOfCards RootCards "Make Browser Card") (COND ((NULL NoDisplayFlg) (SETQ Window (NC.MakeNewCardWindow Card (OR Title "Untitled"))) (WINDOWADDPROP Window (QUOTE SHRINKFN) (FUNCTION NC.GraphCardShrinkFn)))) (if (NULL RootCards) then (SETQ RootCards (if NoDisplayFlg then (LIST NIL) else (NC.SelectNoteCards NIL NIL NC.SelectingBrowserSourceMenu Window "Please shift-select the Cards and/or Boxes the browser should start from." T)))) (COND ((EQ RootCards (QUOTE DON'T)) (NC.DeactivateCard Card) (CLOSEW Window) (RETURN))) (NC.HoldTTYProcess) (SETQ BrowserSpecs (NC.AskBrowserSpecs Window Card ListOfLinkLabels Depth BrowserFormat T (if (OR ParamList NoDisplayFlg) then (QUOTE DONTASK)))) (COND ((NULL BrowserSpecs) (NC.DeactivateCard Card) (CLOSEW Window) (RETURN))) (SETQ ListOfLinkLabels (CAR BrowserSpecs)) (SETQ Depth (CADR BrowserSpecs)) (SETQ BrowserFormat (CADDR BrowserSpecs)) (* If user wants *GRAPH* format, i.e. virtual nodes eliminated, then set the flag) (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat) then (SETQ DropVirtualNodesFlg T)) (SETQ SpecialBrowserSpecs (COND (NC.SpecialBrowserSpecsFlg (NC.AskSpecialBrowserSpecs Window)) (T (create SPECIALBROWSERSPECS)))) (OR NoDisplayFlg (NC.PrintMsg Window T (CHARACTER 13) "Computing browser graph. Please wait. ...")) (* Create new browser hash array) (NC.GetBrowserHashArray Card) (* Compute lattice breakdth-first starting from roots.) (SETQ Lattice (NC.GrowLinkLattice RootCards NIL ListOfLinkLabels Card Depth)) (SETQ RootNodes (for RootCard in RootCards collect (NC.GetBrowserNodeID Card RootCard))) (OR NoDisplayFlg (WINDOWPROP Window (QUOTE NoteCardObject) Card)) (* * Link destination id information stored in NodeLabel field into a LinkIcon for display) (for Node in Lattice bind NodeID (CrossFileLinkModePropList ←(LIST (fetch (Card NoteFile) of Card) NIL)) eachtime (BLOCK) do (replace (GRAPHNODE NODELABEL) of Node with (LET (NewLink) (if (AND (NOT (NC.CrossFileLinkCardP (fetch (GRAPHNODE NODELABEL) of Node))) (SETQ NewLink (NC.MakeLink Window NC.BrowserContentsLinkLabel (fetch (GRAPHNODE NODELABEL) of Node) Card NIL NIL NIL NIL NIL (NC.ComputeCrossFileLinkMode (fetch (GRAPHNODE NODELABEL) of Node) CrossFileLinkModePropList Window)))) then (NC.MakeLinkIcon NewLink) else (NC.MakeCrossFileLinkIconStandIn (fetch (GRAPHNODE NODELABEL) of Node))))) (* Untouch each graph node so that next Recompute will put fresh values on proplist.) (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node)) (NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID) (QUOTE TouchedFlg)) (NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID) (QUOTE VisitedFlg))) (SETQ Graph (if (AND Lattice RootNodes) then (LAYOUTGRAPH Lattice RootNodes (SUBST (QUOTE LATTICE) NC.*Graph*BrowserFormat BrowserFormat) (fetch (SPECIALBROWSERSPECS Font) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS MotherD) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS PersonalD) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS FamilyD) of SpecialBrowserSpecs)) else (create GRAPH))) (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window DropVirtualNodesFlg)) (OR NoDisplayFlg (NC.PrintMsg Window NIL "Done!")) (NC.SetSubstance Card Graph) (NC.SetBrowserLinkLabels Card (OR ListOfLinkLabels (LIST NC.SubBoxLinkLabel))) (NC.SetBrowserRoots Card RootCards) (NC.SetBrowserFormat Card BrowserFormat) (NC.SetBrowserDepth Card Depth) (NC.SetSpecialBrowserSpecs Card SpecialBrowserSpecs) (COND (NoDisplayFlg (RETURN Card))) (WINDOWPROP Window (QUOTE GRAPH) Graph) (NC.InstallTitleBarLeftMenu Window CardType) (NC.InstallTitleBarMiddleMenu Window CardType) (NC.RelayoutBrowserCard Window) (RETURN Window)))))) (NC.UpdateBrowserCard (LAMBDA (Window) (* rht: " 4-Jun-87 11:50") (* * rht 10/14/84: Added call to DETACHALLWINDOWS to close any existing links legend window and prompt window. Also added call to NC.MakeLinksLegend to make a new attached legend menu.) (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.) (* * rht 2/14/85: Added ability to respecify roots and link labels before recomputing graph.) (* * rht 3/8/85: Modified to use new browser props stored on card's proplist as of release 1.2.) (* * rht 3/17/85: Now takes OnlyLayoutFlg argument. If set, then don't recompute lattice or ask about root nodes.) (* * rht 11/17/85: updated to handle new card and notefile objects.) (* * kirk 23Jan86 Changed to use NC.AskYesOrNo) (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.) (* * rht 3/7/86: Now only closes the Links legend menu attached window.) (* * rht 6/10/86: Moved code to delete links legend menu and code to make new browser hash array to after questioning user about respecifying roots.) (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.) (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.) (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.) (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a standin for a cross file link icon.) (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg) (* * rg 3/18/87 added NC.CardSelectionOperation wrapper) (* * rht 3/19/87: Fixed the part that calls NC.MakeLink so it really only rebuilds links if they've changed.) (* * rg 4/1/87 changed CANCELLED to DON'T) (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when GrowLinkLattice wasn't able to follow into the remote notefile.) (LET ((Card (NC.CoerceToCard Window))) (NC.ProtectedCardOperation Card "Recompute Browser Card" NIL (NCP.WithLockedCards (PROG (LinkLabels RootCards RootNodes Lattice LinkIcon Graph GraphNodes NodeLabel BrowserSpecs BrowserFormat DropVirtualNodesFlg Depth SpecialBrowserSpecs OldLabelNodes OldRootCards) (SETQ RootCards (NC.FetchBrowserRoots Card)) (NC.IfAllCardsFree (NC.LockListOfCards RootCards "Update Browser Card") (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card)) (SETQ BrowserFormat (OR (NC.FetchBrowserFormat Card) (QUOTE (LATTICE)))) (* If user wants *GRAPH* format, i.e. virtual nodes eliminated, then set the flag) (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat) then (SETQ DropVirtualNodesFlg T)) (SETQ Depth (OR (NC.FetchBrowserDepth Card) 999999)) (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card) (create SPECIALBROWSERSPECS))) (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph (WINDOWPROP Window (QUOTE GRAPH))))) (* Get new roots.) (if (OR (NULL RootCards) (NC.AskYesOrNo "Want to respecify roots? " "--" "No" T Window T NIL)) then (NC.BrowserFlipRoots Window Card GraphNodes (SETQ OldRootCards RootCards)) (SETQ RootCards (NC.SelectNoteCards NIL NIL NC.SelectingBrowserSourceMenu Window (CONCAT "Please shift-select the Cards and/or Boxes the browser should start from." (CHARACTER 13) "(Current roots are highlighted.)") T)) (NC.BrowserFlipRoots Window Card GraphNodes OldRootCards) (COND ((EQ RootCards (QUOTE DON'T)) (RETURN)))) (* Get rid of the links legend menu attached window.) (for Win in (ATTACHEDWINDOWS Window) when (WINDOWPROP Win (QUOTE LINKSLEGENDWINP)) do (DETACHWINDOW Win) (CLOSEW Win)) (* Smash the current hash array, putting a fresh one in its place.) (NC.GetBrowserHashArray Card) (NC.PrintMsg Window T (CHARACTER 13) "Computing browser graph. Please wait. ...") (* Compute lattice breadth-first from the roots.) (SETQ Lattice (NC.GrowLinkLattice RootCards NIL LinkLabels Card Depth)) (SETQ RootNodes (for RootCard in RootCards collect ( NC.GetBrowserNodeID Card RootCard))) (NC.SetPropListDirtyFlg Card T) (* Remove all links that are in the old browser graph but not in the new one) (for Node in GraphNodes eachtime (BLOCK) unless (for LatticeNode in Lattice bind (CardForNode ←( NC.CardFromBrowserNodeID ( NC.CoerceToGraphNodeID Node))) thereis (NC.SameCardP CardForNode ( NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID LatticeNode)))) do (LET ((NodeLabel (fetch (GRAPHNODE NODELABEL) of Node))) (COND ((NC.LinkIconImageObjP NodeLabel) (NC.DeleteLink (NC.FetchLinkFromLinkIcon NodeLabel) T T)) ((STRINGP NodeLabel) (* Collect the label nodes from the old browser.) (SETQ OldLabelNodes (CONS Node OldLabelNodes)))))) (* Create Links for all nodes in the new browser graph but not in the old one.) (for Node in Lattice eachtime (BLOCK) bind (CrossFileLinkModePropList ←(LIST (fetch (Card NoteFile) of Card) NIL)) do (LET ((NodeID (fetch (GRAPHNODE NODEID) of Node)) (OldNode (for GraphNode in GraphNodes bind (CardForNode ←(NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID Node))) when (NC.SameCardP CardForNode ( NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID GraphNode))) do (RETURN GraphNode)))) (if OldNode then (replace (GRAPHNODE NODELABEL) of Node with (fetch (GRAPHNODE NODELABEL) of OldNode)) else (replace (GRAPHNODE NODELABEL) of Node with (LET (NewLink) (if (AND (NOT (NC.CrossFileLinkCardP (fetch (GRAPHNODE NODELABEL) of Node))) (SETQ NewLink (NC.MakeLink Window NC.BrowserContentsLinkLabel (fetch (GRAPHNODE NODELABEL) of Node) Card NIL NIL NIL NIL NIL ( NC.ComputeCrossFileLinkMode (fetch (GRAPHNODE NODELABEL) of Node) CrossFileLinkModePropList Window)))) then (NC.MakeLinkIcon NewLink) else (NC.MakeCrossFileLinkIconStandIn (fetch (GRAPHNODE NODELABEL) of Node)))))) (* Untouch each graph node so that next Recompute will put fresh values on proplist.) (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg)) (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg)))) (* Throw in the label nodes from the old browser.) (SETQ Lattice (NCONC Lattice OldLabelNodes)) (* For each old label node, take away nonexistent fromnodes and save the label nodes that no longer have any from nodes.) (for OldLabelNode in OldLabelNodes eachtime (BLOCK) do (replace (GRAPHNODE FROMNODES) of OldLabelNode with (for FromNodeID in (fetch (GRAPHNODE FROMNODES) of OldLabelNode) bind FromNode eachtime (BLOCK) when (SETQ FromNode (FASSOC FromNodeID Lattice)) collect (* If the From node isn't a label node, then add to its Tonode list.) (if (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of FromNode)) then (replace (GRAPHNODE TONODES) of FromNode with (CONS (fetch (GRAPHNODE NODEID) of OldLabelNode) (fetch (GRAPHNODE TONODES) of FromNode)))) FromNodeID)) (* For the old label node's ToNodes, just need to remove any for ToNodes that no longer exist.) (replace (GRAPHNODE TONODES) of OldLabelNode with (for ToNodeID in (fetch (GRAPHNODE TONODES) of OldLabelNode) bind ToNode eachtime (BLOCK) when (SETQ ToNode (FASSOC ToNodeID Lattice)) collect (* If the To node isn't a label node, then add to its FromNode list.) (if (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of ToNode)) then (replace (GRAPHNODE FROMNODES) of ToNode with (CONS (fetch (GRAPHNODE NODEID) of OldLabelNode) (fetch (GRAPHNODE FROMNODES) of ToNode)))) ToNodeID))) (* Layout graph, including as roots any non-virtual nodes with no from nodes to avoid disconnected graphs.) (SETQ Graph (if (AND Lattice RootNodes) then (LAYOUTGRAPH Lattice (for Node in Lattice bind NodeID eachtime (BLOCK) (SETQ NodeID (OR (NC.CoerceToGraphNodeID Node) (fetch (GRAPHNODE NODEID) of Node))) when (OR (FMEMB NodeID RootNodes) (NULL (fetch (GRAPHNODE FROMNODES) of Node))) collect NodeID) (SUBST (QUOTE LATTICE) NC.*Graph*BrowserFormat BrowserFormat) (fetch (SPECIALBROWSERSPECS Font) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS MotherD) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS PersonalD) of SpecialBrowserSpecs) (fetch (SPECIALBROWSERSPECS FamilyD) of SpecialBrowserSpecs)) else (create GRAPH))) (* Build links legend and fix up TONODES in the graph.) (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window DropVirtualNodesFlg)) (NC.SetBrowserRoots Card RootCards) (NC.SetBrowserDepth Card Depth) (WINDOWPROP Window (QUOTE GRAPH) Graph) (NC.RelayoutBrowserCard Window)))))))) (NC.ExpandBrowserNode (LAMBDA (Window) (* rht: " 4-Jun-87 11:50") (* * Ask user to choose a node in the browser and recompute the part of the lattice under that node to the given depth. And relayout the graph. The code is just a modification of the NC.UpdateBrowserCard code.) (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.) (* * rht 6/10/86: No longer does relayout after expand. Uses NC.LayoutNewBrowserNodes to compute proper locations of new nodes. Also calls NC.ShowBrowserGraph.) (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.) (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg) (* * rht 5/26/87: Now handles cross-file links properly, i.e. uses cross-file link standin in cases when GrowLinkLattice wasn't able to follow into the remote notefile.) (LET ((Card (NC.CoerceToCard Window))) (NC.ProtectedCardOperation Card "Expand Node of Browser Card" NIL (PROG (NodeToExpand LinkLabels RootCards RootNodes Lattice LinkIcon OldToNodePairs Graph GraphNodes NodeLabel OldNode Link BrowserSpecs BrowserFormat DropVirtualNodesFlg Depth SpecialBrowserSpecs SavedLabelNodes NewNodes) (SETQ RootCards (NC.FetchBrowserRoots Card)) (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card)) (SETQ BrowserFormat (NC.FetchBrowserFormat Card)) (* If user wants *GRAPH* format, i.e. virtual nodes eliminated, then set the flag) (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat) then (SETQ DropVirtualNodesFlg T)) (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card) (create SPECIALBROWSERSPECS))) (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph (WINDOWPROP Window (QUOTE GRAPH))))) (* If there aren't any nodes in graph, then get out pronto.) (if (NULL GraphNodes) then (NC.PrintMsg Window T "No nodes to expand.") (DISMISS 1000) (NC.ClearMsg Window T) (RETURN NIL)) (* Create hash array if haven't already.) (NC.GetBrowserHashArray Card Graph) (NC.PrintMsg Window T "Pick node to expand." (CHARACTER 13)) (* Note call to the grapher function READ/NODE to select a graph node.) (SETQ NodeToExpand (READ/NODE GraphNodes Window)) (* Can't expand a label node.) (if (NOT (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of NodeToExpand))) then (NC.PrintMsg NIL T "Sorry, can't expand a label node.") (FLASHW PROMPTWINDOW) (NC.ClearMsg Window T) (RETURN)) (SETQ Depth (MKATOM (NC.AskUser "Depth to expand (type integer or INF): " "--" 1 T Window NIL NIL T))) (COND ((EQ Depth (QUOTE INF)) (SETQ Depth MAX.FIXP)) ((NOT (AND (FIXP Depth) (GREATERP Depth 0))) (NC.PrintMsg Window T "Depth must be an integer greater than 0 or INF.") (RETURN))) (NC.PrintMsg Window T (CHARACTER 13) "Augmenting browser graph. Please wait. ...") (* Save the nodes pointed to by the chosen node that are label nodes. GrowLinkLattice will trash those, so we restore afterwards.) (SETQ SavedLabelNodes (for ToNode in (fetch (GRAPHNODE TONODES) of NodeToExpand) eachtime (BLOCK) when (AND (NOT (EQ (CAR ToNode) LINKPARAMS)) (NOT (NC.LinkIconImageObjP ToNode))) collect ToNode)) (* Increase link lattice from chosen node to given depth.) (SETQ Lattice (NC.GrowLinkLattice (LIST (NC.CardFromBrowserNodeID (fetch (GRAPHNODE NODEID) of NodeToExpand))) (APPEND GraphNodes) LinkLabels Card Depth)) (AND SavedLabelNodes (replace (GRAPHNODE TONODES) of NodeToExpand with (APPEND SavedLabelNodes (fetch (GRAPHNODE TONODES) of NodeToExpand)))) (SETQ RootNodes (for RootCard in RootCards collect (NC.GetBrowserNodeID Card RootCard))) (NC.SetPropListDirtyFlg Card T) (* Create Links for all nodes in the new browser graph but not in the old one.) (for Node in Lattice bind NodeID (CrossFileLinkModePropList ←(LIST (fetch (Card NoteFile) of Card) NIL)) do (COND ((SETQ OldNode (FASSOC (SETQ NodeID (OR (NC.CoerceToGraphNodeID Node) (fetch (GRAPHNODE NODEID) of Node))) GraphNodes)) (replace (GRAPHNODE NODELABEL) of Node with (fetch (GRAPHNODE NODELABEL) of OldNode))) (T (replace (GRAPHNODE NODELABEL) of Node with (LET (NewLink) (if (AND (NOT (NC.CrossFileLinkCardP (fetch (GRAPHNODE NODELABEL) of Node))) (SETQ NewLink (NC.MakeLink Window NC.BrowserContentsLinkLabel (fetch (GRAPHNODE NODELABEL) of Node) Card NIL NIL NIL NIL NIL (NC.ComputeCrossFileLinkMode (fetch (GRAPHNODE NODELABEL) of Node) CrossFileLinkModePropList Window)))) then (NC.MakeLinkIcon NewLink) else (NC.MakeCrossFileLinkIconStandIn (fetch (GRAPHNODE NODELABEL) of Node))))) (* Make a list of all new nodes.) (push NewNodes Node))) (* Throw away virtual node info.) (AND NodeID (replace (GRAPHNODE NODEID) of Node with NodeID)) (* Untouch each graph node so that next Recompute will put fresh values on proplist.) (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg)) (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg)) (* Smash all the unnecessary junk off existing nodes, letting LAYOUTGRAPH and NC.MakeLinksLegend recompute.) (replace (GRAPHNODE TONODES) of Node with (for ToNode in (fetch (GRAPHNODE TONODES) of Node) bind ToNodeID eachtime (BLOCK) collect (if (SETQ ToNodeID (NC.CoerceToGraphNodeID ToNode)) then (* Throw away link parameterlist info.) (* Throw away link dashing info.) (NC.GraphNodeIDPutProp NodeID ToNodeID (for LabelPair in (NC.GraphNodeIDGetProp NodeID ToNodeID) collect (OR (CAR LabelPair) LabelPair))) (NC.GraphNodeIDPutProp ToNodeID NodeID (for LabelPair in (NC.GraphNodeIDGetProp ToNodeID NodeID) collect (OR (CAR LabelPair) LabelPair))) ToNodeID else ToNode)))) (* LAYOUTGRAPH doesn't like duplicate nodes. These get created when virtual nodes are turned into regular nodes.) (SETQ Lattice (NC.RemoveDuplicateNodesFromGraph Lattice)) (NC.RebuildFromNodesInGraph Lattice) (AND NewNodes (NC.LayoutNewBrowserNodes NodeToExpand NewNodes BrowserFormat SpecialBrowserSpecs)) (replace (GRAPH GRAPHNODES) of Graph with Lattice) (* Build links legend and fix up TONODES in the graph.) (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window DropVirtualNodesFlg)) (WINDOWPROP Window (QUOTE GRAPH) Graph) (* Display the graph.) (NC.ShowBrowserGraph Graph Window) (NC.SetSubstance Card Graph) (NC.MarkCardDirty Card) (NC.ClearMsg Window T)))))) (NC.ConnectNodesInBrowser (LAMBDA (Window) (* rht: "29-May-87 00:13") (* * Draw any links, from the current link set, between any pairs of nodes currently being shown in the browser.) (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns. Also fixed one last old call to GETPROPLIST on a NodeID.) (* * rht 3/2/86: Added WINDOWPROP for SCROLLFN and RESHAPEFN.) (* * fgh 5/21/86 Updated reinstallation of title bar menus after SHOWGRAPH to use new title bar menu mechanism.) (* * rht 6/10/86: Now calls NC.ShowBrowserGraph.) (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.) (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg) (* * rht 5/28/87: Modified to handle cross-file links.) (LET ((Card (NC.CoerceToCard Window))) (NC.ProtectedCardOperation Card "Reconnect Browser Card" NIL (PROG (LinkLabels Graph GraphNodes BrowserFormat DropVirtualNodesFlg NodeIDs) (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card)) (SETQ BrowserFormat (NC.FetchBrowserFormat Card)) (* If user wants *GRAPH* format, i.e. virtual nodes eliminated, then set the flag) (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat) then (SETQ DropVirtualNodesFlg T)) (SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph (WINDOWPROP Window (QUOTE GRAPH))))) (* Create hash array if haven't already.) (NC.GetBrowserHashArray Card Graph) (* check graph node size against image box size.) (NC.GraphLinkIconUpdateCheck Card Window Graph NIL) (* These are the workhorse loops that rebuild the TONODES of each nonvirtual node.) (* First smash all the nodeID's proplists and accumulate nodeIDs.) (SETQ NodeIDs (for Node in GraphNodes bind NodeID eachtime (BLOCK) when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of Node)) collect (NC.SmashGraphNodeIDProps (SETQ NodeID ( NC.CoerceToGraphNodeID Node))) NodeID)) (* Throw away duplicates obtained from virtual nodes.) (SETQ NodeIDs (INTERSECTION NodeIDs NodeIDs)) (* Next accumulate all linktypes on the from node's proplist using the To node's graphnodeID as prop name. We do the analogous thing for backward links, but notice that we ignore backward linktypes that also appear in the list in their forward version.) (for NodeID in NodeIDs bind RealCard do (for Link in (NC.RetrieveToLinks (SETQ RealCard ( NC.CardFromBrowserNodeID NodeID))) bind DestNodeID eachtime (BLOCK) when (NC.LinkLabelP Link LinkLabels) when (LET ((DestCard (fetch (Link DestinationCard) of Link))) (SETQ DestNodeID (NC.GetBrowserNodeID Card (if (NC.CrossFileLinkCardP DestCard) then (OR (NC.GetCrossFileLinkDestCard DestCard Window) DestCard) else DestCard))) (SETQ DestNodeID (for ID in NodeIDs when (NC.SameUIDP DestNodeID ID) do (RETURN ID)))) do (NC.UIDAddProp NodeID DestNodeID (fetch (Link Label) of Link) T)) (for Link in (NC.RetrieveFromLinks RealCard) bind SourceNodeID eachtime (BLOCK) when (AND (NC.ReverseLinkLabelP Link LinkLabels) (NOT (NC.LinkLabelP Link LinkLabels))) when (LET ((SourceCard (fetch (Link SourceCard) of Link))) (SETQ SourceNodeID (NC.GetBrowserNodeID Card (if (NC.CrossFileLinkCardP SourceCard) then (OR (NC.GetCrossFileLinkDestCard SourceCard Window) SourceCard) else SourceCard))) (SETQ SourceNodeID (for ID in NodeIDs when (NC.SameUIDP SourceNodeID ID) do (RETURN ID)))) do (NC.UIDAddProp SourceNodeID NodeID (fetch (Link Label) of Link) T))) (for Node in GraphNodes bind NodeID OldToNodeIDs eachtime (BLOCK) unless (LISTP (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node))) when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of Node)) do (* Accumulate the old NodeIDs, possibly virtual, from the TONODES list.) (SETQ OldToNodeIDs (for ToNode in (fetch (GRAPHNODE TONODES) of Node) collect (if (EQ (CAR ToNode) LINKPARAMS) then (CADR ToNode) else ToNode))) (* The trick here is to use a virtual node for this ToNode if one was used before, otherwise just the ToNodeID. Also throw in the label nodes that were in the TONODES list before.) (replace (GRAPHNODE TONODES) of Node with (NCONC (for ToNodeID on ( NC.ComputeBrowserSavedLinkingInfoForNode NodeID) by (CDDR ToNodeID) eachtime (BLOCK) collect (OR (for OldToNodeID in OldToNodeIDs thereis (AND (LISTP OldToNodeID) (EQ (CAR ToNodeID) (CAR OldToNodeID)) OldToNodeID)) (CAR ToNodeID))) (for ToNodeID in OldToNodeIDs eachtime (BLOCK) unless (NC.SameCardP Card ( NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID ToNodeID))) collect ToNodeID)))) (NC.RebuildFromNodesInGraph GraphNodes) (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window DropVirtualNodesFlg)) (* Display the graph.) (NC.ShowBrowserGraph Graph Window) (NC.SetSubstance Card (WINDOWPROP Window (QUOTE GRAPH))) (NC.MarkCardDirty Card) (NC.ClearMsg Window T)))))) (NC.DelBrowserContentsLink (LAMBDA (GraphCard DestCard) (* rht: "26-May-87 01:52") (* * Delete the browsercontents link connecting GraphCard and DestID.) (* * rht 11/17/85: updated to handle new card and notefile formats.) (* * rht 4/30/86: Now checks to make sure there's a link to delete.) (* * rht 5/26/87: Now handles cross-file browsercontents links.) (LET ((Links (NCP.GetLinks GraphCard DestCard NC.BrowserContentsLinkLabel))) (if (CDR Links) then (NC.ReportError "NC.DelBrowserContentsLink" (CONCAT "Multiple browser contents links between " (NC.FetchTitle GraphCard) " and " (NC.FetchTitle DestCard) )) NIL) (if Links then (NC.DeleteLink (CAR Links) NIL T) else (* Could be that it's a cross file browsercontents link.) (for Link in (NCP.GetLinks GraphCard NIL NC.BrowserContentsLinkLabel) bind CrossFileLinkCard (DestCardUID ←(fetch (Card UID) of DestCard)) when (AND (NC.CrossFileLinkCardP (SETQ CrossFileLinkCard (fetch (Link DestinationCard) of Link))) (NC.SameUIDP DestCardUID (fetch (CrossFileLinkSubstance CrossFileLinkDestCardUID) of (NCP.CardSubstance CrossFileLinkCard)))) do (RETURN (NC.DeleteLink Link T T))))))) ) (DEFINEQ (NC.GetBrowserHashArray (LAMBDA (BrowserCard Graph) (* rht: "10-Jun-87 22:41") (* * Build and install a hash array mapping cards to browsernode UIDs, unless one's already there. If Graph argument is nil, then make a new hash array smashing any existin one.) (* * rht 4/30/86: Now makes sure we're not working with a label node instead of a card node.) (* * rht 6/1/87: Changed hash array to map from card UIDs to graph node ids rather than from card objects to graph node ids.) (* * rht 6/10/87: Now checks that CardObject on GraphNodeID is valid card before stashing in hash array.) (DECLARE (GLOBALVARS NC.BrowserHashArraySize)) (if (AND Graph (NC.HashArrayFromBrowserCard BrowserCard)) else (LET ((HashArray (NC.CreateUIDHashArray NC.BrowserHashArraySize))) (NC.SetUserDataProp BrowserCard (QUOTE BrowserHashArray) HashArray) (AND Graph (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph) bind GraphNodeID eachtime (BLOCK) when (SETQ GraphNodeID ( NC.CoerceToGraphNodeID GraphNode)) do (LET ((CardObject (NC.GraphNodeIDGetProp GraphNodeID (QUOTE CardObject) ))) (if (NC.ValidCardP CardObject) then (PUTHASH (fetch (Card UID) of CardObject) GraphNodeID HashArray))))))))) (NC.GetBrowserNodeID (LAMBDA (BrowserCard NodeCard) (* rht: " 1-Jun-87 21:42") (* * Create a browser node atom from a new UID. Hang the card object off as a property for those who need it.) (* * rht 11/18/85: Now checks to see if NodeCard already appears in graph before creating a new GraphNodeID. Use the browser hash array to do the lookup.) (* * rht 6/1/87: Changed hash array to map from card UIDs to graph node ids rather than from card objects to graph node ids.) (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard)) (NodeCardUID (fetch (Card UID) of NodeCard)) NewUID) (if (GETHASH NodeCardUID HashArray) else (NC.GraphNodeIDPutProp (SETQ NewUID (NC.MakeBrowserNodeUID)) (QUOTE CardObject) NodeCard) (PUTHASH NodeCardUID NewUID HashArray) NewUID)))) (NC.RemoveBrowserNodeHashArrayEntry (LAMBDA (BrowserCard NodeCard) (* rht: " 1-Jun-87 21:40") (* * Remove the entry for given card from given browser's hash array.) (* * rht 6/1/87: Now expects hash array to map from card UIDs to graph node ids rather than from card objects to graph node ids.) (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard))) (if HashArray then (PUTHASH (fetch (Card UID) of NodeCard) NIL HashArray))))) ) (PUTPROPS RHTPATCH267 COPYRIGHT ("Xerox Corporation" 1987)) (DECLARE: DONTCOPY (FILEMAP (NIL (2857 4863 (NC.CollectReferencesInGraph 2867 . 4861)) (4899 7324 ( NC.CollectReferencesInSketch 4909 . 7322)) (7358 10299 (NC.CollectReferencesInText 7368 . 10297)) ( 10331 28389 (NC.ValidLinkP 10341 . 11078) (NC.MakeLink 11080 . 18594) (NC.DeleteFromLink 18596 . 19772 ) (NC.DeleteToLink 19774 . 20976) (NC.RelabelLink 20978 . 26331) (NC.FileInOrphanBox 26333 . 28387)) ( 28420 39545 (NC.DeleteNoteCardInternal 28430 . 34803) (NC.AssignTitle 34805 . 39543)) (39586 49191 ( NC.OpenCrossFileLinkDestNoteFile 39596 . 42161) (NC.CrossFileLinkPutFn 42163 . 43302) ( NC.CrossFileLinkGetFn 43304 . 44365) (NC.CrossFileLinkEditFn 44367 . 45188) ( NC.GetCrossFileLinkDestCard 45190 . 49189)) (49935 56083 (NC.AskCrossFileLinkMode 49945 . 50935) ( NC.DeleteCrossFileLinkCard 50937 . 51466) (NC.FetchRemoteCrossFileLinkCard 51468 . 52561) ( NC.CheckCrossFileLinkCardTitle 52563 . 53038) (NC.CheckCrossFileLinkType 53040 . 54460) ( NC.MakeCrossFileLinkIconStandIn 54462 . 54898) (NC.ComputeCrossFileLinkMode 54900 . 56081)) (56218 104935 (NC.GrowLinkLattice 56228 . 65138) (NC.MakeBrowserCard 65140 . 73905) (NC.UpdateBrowserCard 73907 . 86506) (NC.ExpandBrowserNode 86508 . 96075) (NC.ConnectNodesInBrowser 96077 . 103282) ( NC.DelBrowserContentsLink 103284 . 104933)) (104936 108038 (NC.GetBrowserHashArray 104946 . 106507) ( NC.GetBrowserNodeID 106509 . 107468) (NC.RemoveBrowserNodeHashArrayEntry 107470 . 108036))))) STOP