DIRECTORY FS USING [Error, ExpandName, SetKeep], Menus USING [AppendMenuEntry, CreateEntry, Menu, MenuProc], MessageWindow USING [Append, Blink], Rope USING [Cat, Equal, Index, ROPE, Substr], SkiPatrolViewers, ViewerClasses USING [Viewer], ViewerOps USING [AddProp, FetchProp, PaintViewer, SaveViewer], ViewerTools USING [GetSelectionContents] ; SkiPatrolViewersImpl: CEDAR PROGRAM IMPORTS FS, Menus, MessageWindow, Rope, ViewerOps, ViewerTools EXPORTS SkiPatrolViewers = BEGIN YES: BOOLEAN = TRUE; NO: BOOLEAN = FALSE; StoreDocProc: REF Menus.MenuProc _ NEW[Menus.MenuProc _ PrintConfirmMessage]; storePathName: Rope.ROPE; keep: CARDINAL _ 5; -- default keep value for a SkiPatrol viewer AddProps: PUBLIC PROC [viewer: ViewerClasses.Viewer, baseTitle: Rope.ROPE, WDir: Rope.ROPE] ~ { ViewerOps.AddProp[viewer: viewer, prop: $BaseTitle, val: baseTitle]; ViewerOps.AddProp[viewer: viewer, prop: $WorkingDirectory, val: WDir]; }; AddSaveAndStore: PUBLIC PROC [myMenu: Menus.Menu] ~ { Menus.AppendMenuEntry[ menu: myMenu, entry: Menus.CreateEntry[name: "Save", proc: SaveButton] ]; Menus.AppendMenuEntry[ menu: myMenu, entry: Menus.CreateEntry[name: "Store", proc: StoreButton, documentation: StoreDocProc, guarded: YES] ]; }; PrintConfirmMessage: Menus.MenuProc ~ { thisViewer: ViewerClasses.Viewer _ NARROW[parent]; storePathName _ FS.ExpandName[ name: ViewerTools.GetSelectionContents[], wDir: NARROW [ViewerOps.FetchProp[viewer: thisViewer, prop: $WorkingDirectory]] ! FS.Error => IF error.code = $illegalName THEN { MessageWindow.Append[message: error.explanation, clearFirst: YES]; MessageWindow.Blink[]; storePathName _ NIL; GOTO Quit; } ].fullFName; MessageWindow.Append[message: "Please confirm store to file: ", clearFirst: YES]; MessageWindow.Append[message: storePathName]; EXITS Quit => NULL; }; RemoveVersion: PROC [name: Rope.ROPE] RETURNS [Rope.ROPE] ~ { RETURN [Rope.Substr[base: name, len: Rope.Index[s1: name, s2: "!"]]] }; SaveButton: Menus.MenuProc ~ { thisViewer: ViewerClasses.Viewer _ NARROW[parent]; FS.SetKeep[RemoveVersion[thisViewer.file], keep]; ViewerOps.SaveViewer[thisViewer]; thisViewer.name _ Rope.Cat[ NARROW[ViewerOps.FetchProp[viewer: thisViewer, prop: $BaseTitle]], " (", thisViewer.file, ")" ]; ViewerOps.PaintViewer[viewer: thisViewer, hint: caption] }; StoreButton: Menus.MenuProc ~ { thisViewer: ViewerClasses.Viewer _ NARROW[parent]; previousName: Rope.ROPE _ thisViewer.name; -- save in case user selection is bad. previousFile: Rope.ROPE _ thisViewer.file; -- (ditto) file: Rope.ROPE; -- will hold a file name. thisViewer.file _ storePathName; FS.SetKeep[RemoveVersion[thisViewer.file], keep]; ViewerOps.SaveViewer[thisViewer]; file _ Rope.Substr[base: thisViewer.file, len: Rope.Index[s1: thisViewer.file, s2: "!"]]; -- (get rid of the version part of the file name) IF NOT Rope.Equal[thisViewer.name, file] THEN { -- unsuccessful. thisViewer.name _ previousName; thisViewer.file _ previousFile; } ELSE thisViewer.name _ Rope.Cat[ NARROW[ViewerOps.FetchProp[viewer: thisViewer, prop: $BaseTitle]], " (", thisViewer.file, ")" ]; ViewerOps.PaintViewer[viewer: thisViewer, hint: caption] }; END. CHANGE LOG ZSkiPatrolViewersImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last Edited by: Kupfer, August 5, 1984 10:04:01 pm PDT The following procedure REF is used to ask for confirmation for a "store" button. It expands the selected file name and stores it in storePathName. We are betting that the user will be going slow enough that we can ignore race conditions. Add the following properties to "viewer": the baseTitle, which is used with the backing file name as a title (aka caption) for the viewer; the working directory in which the viewer was created. Add buttons for Save and Store to "menu". The Save and Store procs expect a "$BaseTitle" property, which they will use when redrawing the caption. $BaseTitle should just be some generic identifier such as "Alpine Event Log". Also, the Save proc assumes that the viewer already has some backing file associated with it. Convert the user selection to a full path name. If this works, print a message asking the user to confirm a "store" operation, and store the converted path name in storePathName for use by the proc implementing Store. If the conversion doesn't work, print an error message, zap storePathName, and quit. Returns "name", less any version part ("!x"), if any. Save the file and repaint the caption to include the file name. Get the expanded path name (done for us by PrintConfirmMessage). Save the file, and repaint the caption to include the file name. If the Save was unsuccessful (bad file name?), restore the viewer's old caption. Otherwise, set up the caption with the current (perhaps new) file name and display it. Edited on August 5, 1984 10:02:17 pm PDT, by Kupfer Set a "keep" value for all SkiPatrol viewers. A user can change this value (SkiPatrolViewersImpl.keep) via the interpreter, if necessary. changes to: RemoveVersion (created), SaveButton, StoreButton ÊI˜Jšœ™Jšœ Ïmœ1™Kšœ žœ˜(K˜—J˜šœž ˜#Jšžœžœ4˜>Jšžœ˜Jšœž˜J˜Jšžœžœžœ˜Jšžœžœžœ˜J˜Kšœð™ðKšœžœžœ'˜MJšœžœ˜J˜KšœžœÏc,˜AK˜unitš Ïnœžœžœ0žœ žœ˜`šœÁ™ÁK˜DK˜FK˜——š œžœžœ˜5K™Â˜K˜ K•StartOfExpansion’[name: ROPE, proc: Menus.ClickProc, clientData: REF ANY _ NIL, documentation: REF ANY _ NIL, fork: BOOL _ TRUE, guarded: BOOL _ FALSE]˜8K˜—–J[menu: Menus.Menu, entry: Menus.MenuEntry, line: Menus.MenuLine _ 0]˜K˜K–’[name: ROPE, proc: Menus.ClickProc, clientData: REF ANY _ NIL, documentation: REF ANY _ NIL, fork: BOOL _ TRUE, guarded: BOOL _ FALSE]šœbžœ˜fK˜—K˜—š œžœ˜(Kšœ°™°Kšœ#žœ ˜2šœžœ ˜Kšœ)˜)KšœžœC˜O–[]šœžœ žœžœ˜1K–-[message: ROPE, clearFirst: BOOL _ FALSE]šœ=žœ˜BK˜Kšœžœ˜Kšžœ˜ K˜—Kšœ ˜ —K–-[message: ROPE, clearFirst: BOOL _ FALSE]šœLžœ˜QK–-[message: ROPE, clearFirst: BOOL _ FALSE]šœ-˜-K˜Kšž˜Kšœžœ˜ K˜—š   œžœ žœžœžœ˜=Kšœ5™5Kšžœ>˜DK˜—š  œ˜K™?Kšœ#žœ ˜2Kšžœ/˜1K˜!–([base: ROPE _ NIL, rest: ROPE _ NIL]˜K–[]šžœ<˜BK˜K˜K˜K˜—K–w[viewer: ViewerClasses.Viewer, hint: ViewerOps.PaintHint, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL]˜8K˜—š  œ˜K™‚Kšœ#žœ ˜2KšœžœŸ&˜QKšœžœŸ ˜5Kšœ žœŸ˜+K˜Kšœ ˜ Kšžœ/˜1K˜!K˜Kšœ¥Ïrœ™¨K–>[s1: ROPE, pos1: INT _ 0, s2: ROPE, case: BOOL _ TRUE]šœZŸ1˜‹–([base: ROPE _ NIL, rest: ROPE _ NIL]šžœžœ#žœŸ˜@K˜K˜K˜—šž˜˜K–[]šžœ<˜BK˜K˜K˜K˜——K–w[viewer: ViewerClasses.Viewer, hint: ViewerOps.PaintHint, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL]˜8K˜—Lšžœ˜Lšžœž˜ ™3JšœŠ™ŠJšœ ¡œ ¡™<—L™——…— \ÿ