'From etoys2.2 of 1 October 2007 [latest update: #1753] on 5 November 2007 at 5:02:54 pm'! "Change Set: newBookRevert-yo Date: 5 November 2007 Author: Yoshiki Ohshima Provides better revert for book pages. In the previous implementation, the revert data was saved along with the book. However, in the typical use, you almost always want to go back to the last saved state; this means that you only save one good version and defer the creation of revert data after the project is loaded."! !Morph methodsFor: 'submorphs-accessing' stamp: 'yo 11/5/2007 16:10'! allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy (put in primarily for bookmorphs)" ^ #()! ! !BookMorph methodsFor: 'accessing' stamp: 'yo 9/13/2007 14:57'! currentPage (submorphs includes: currentPage) ifFalse: [self currentPage: nil]. ^ currentPage! ! !BookMorph methodsFor: 'accessing' stamp: 'yo 11/5/2007 15:37'! currentPage: aPage currentPage _ aPage. (currentPage notNil and: [ (aPage hasProperty: #revertMarked) and: [ (self revertablePageForPage: aPage) isNil]]) ifTrue: [ self markForRevert: aPage ]. ^ aPage. ! ! !BookMorph methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:55'! fromRemoteStream: strm "Make a book from an index and a bunch of pages on a server. NOT showing any page!! Index and pages must live in the same directory. If the book has moved, save the current correct urls for each of the pages. Self must already have a url stored in property #url." | remote dict bookUrl oldStem stem oldUrl endPart | remote := strm fileInObjectAndCode. bookUrl := (SqueakPage new) url: (self valueOfProperty: #url); url. "expand a relative url" oldStem := SqueakPage stemUrl: (remote second) url. oldStem := oldStem copyUpToLast: $/. stem := SqueakPage stemUrl: bookUrl. stem := stem copyUpToLast: $/. oldStem = stem ifFalse: ["Book is in new directory, fix page urls" 2 to: remote size do: [:ii | oldUrl := (remote at: ii) url. endPart := oldUrl copyFrom: oldStem size + 1 to: oldUrl size. (remote at: ii) url: stem , endPart]]. self initialize. pages := OrderedCollection new. 2 to: remote size do: [:ii | pages add: (remote at: ii)]. currentPage fullReleaseCachedState; delete. "the blank one" self currentPage: remote second. dict := remote first. self setProperty: #modTime toValue: (dict at: #modTime). dict at: #allText ifPresent: [:val | self setProperty: #allText toValue: val]. dict at: #allTextUrls ifPresent: [:val | self setProperty: #allTextUrls toValue: val]. #(#color #borderWidth #borderColor #pageSize) with: #(#color: #borderWidth: #borderColor: #pageSize:) do: [:key :sel | dict at: key ifPresent: [:val | self perform: sel with: val]]. ^self! ! !BookMorph methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:55'! removeEverything self currentPage: nil. pages _ OrderedCollection new. self removeAllMorphs. self removeProperty: #pagesForRevert. "forget saved pages"! ! !BookMorph methodsFor: 'insert and delete' stamp: 'yo 9/13/2007 14:57'! deletePageBasic | thisPage | thisPage _ self pageNumberOf: currentPage. pages remove: currentPage. currentPage delete. self currentPage: nil. pages isEmpty ifTrue: [^ self insertPage]. self goToPage: (thisPage min: pages size) ! ! !BookMorph methodsFor: 'insert and delete' stamp: 'yo 9/13/2007 14:57'! insertPageColored: aColor "Insert a new page for the receiver, using the given color as its background color" | sz newPage bw bc | bc := currentPage isNil ifTrue: [sz := pageSize. bw := 0. Color blue muchLighter] ifFalse: [sz := currentPage extent. bw := currentPage borderWidth. currentPage borderColor]. newPagePrototype ifNil: [newPage := (PasteUpMorph new) extent: sz; color: aColor; wantsMouseOverHalos: false. newPage borderWidth: bw; borderColor: bc. newPage setProperty: #automaticPhraseExpansion toValue: true] ifNotNil: [Cursor wait showWhile: [newPage := newPagePrototype veryDeepCopy]]. newPage setNameTo: self defaultNameStemForNewPages. newPage vResizeToFit: false. pages isEmpty ifTrue: [pages add: (self currentPage: newPage)] ifFalse: [pages add: newPage after: currentPage]. self nextPage! ! !BookMorph methodsFor: 'insert and delete' stamp: 'yo 9/13/2007 14:55'! insertPageSilentlyAtEnd "Create a new page at the end of the book. Do not turn to it." | sz newPage bw bc cc | cc := currentPage isNil ifTrue: [sz := pageSize. bw := 0. bc := Color blue muchLighter. color] ifFalse: [sz := currentPage extent. bw := currentPage borderWidth. bc := currentPage borderColor. currentPage color]. newPagePrototype ifNil: [newPage := (PasteUpMorph new) extent: sz; color: cc. newPage borderWidth: bw; borderColor: bc] ifNotNil: [Cursor wait showWhile: [newPage := newPagePrototype veryDeepCopy]]. newPage setNameTo: self defaultNameStemForNewPages. newPage vResizeToFit: false. pages isEmpty ifTrue: [pages add: (self currentPage: newPage) "had been none"] ifFalse: [pages add: newPage after: pages last]. ^newPage! ! !BookMorph methodsFor: 'menu' stamp: 'yo 11/5/2007 17:01'! addBookMenuItemsTo: aMenu hand: aHandMorph "For the 'control menu' -- add book-menu items to it." | controlsShowing subMenu | subMenu _ MenuMorph new defaultTarget: self. subMenu add: 'previous page' translated action: #previousPage. subMenu add: 'next page' translated action: #nextPage. subMenu add: 'goto page' translated action: #goToPage. subMenu add: 'insert a page' translated action: #insertPage. subMenu add: 'delete this page' translated action: #deletePage. self canRevertThisPage ifTrue: [ subMenu add: 'revert this page' translated action: #revertPage]. controlsShowing _ self hasSubmorphWithProperty: #pageControl. controlsShowing ifTrue: [subMenu add: 'hide page controls' translated action: #hidePageControls. subMenu add: 'fewer page controls' translated action: #fewerPageControls] ifFalse: [subMenu add: 'show page controls' translated action: #showPageControls]. self isInFullScreenMode ifTrue: [ subMenu add: 'exit full screen' translated action: #exitFullScreen. ] ifFalse: [ subMenu add: 'show full screen' translated action: #goFullScreen. ]. subMenu addLine. subMenu add: 'sound effect for all pages' translated action: #menuPageSoundForAll:. subMenu add: 'sound effect this page only' translated action: #menuPageSoundForThisPage:. subMenu add: 'visual effect for all pages' translated action: #menuPageVisualForAll:. subMenu add: 'visual effect this page only' translated action: #menuPageVisualForThisPage:. subMenu addLine. subMenu add: 'sort pages' translated action: #sortPages:. subMenu add: 'uncache page sorter' translated action: #uncachePageSorter. (self hasProperty: #dontWrapAtEnd) ifTrue: [subMenu add: 'wrap after last page' translated selector: #setWrapPages: argument: true] ifFalse: [subMenu add: 'stop at last page' translated selector: #setWrapPages: argument: false]. subMenu addLine. subMenu add: 'search for text' translated action: #textSearch. (aHandMorph pasteBuffer class isKindOf: PasteUpMorph class) ifTrue: [subMenu add: 'paste book page' translated action: #pasteBookPage]. subMenu add: 'send all pages to server' translated action: #savePagesOnURL. subMenu add: 'send this page to server' translated action: #saveOneOnURL. subMenu add: 'reload all from server' translated action: #reload. subMenu add: 'copy page url to clipboard' translated action: #copyUrl. subMenu add: 'keep in one file' translated action: #keepTogether. subMenu add: 'save as new-page prototype' translated action: #setNewPagePrototype. newPagePrototype ifNotNil: [subMenu add: 'clear new-page prototype' translated action: #clearNewPagePrototype]. subMenu add: 'mark this page to be revertable' translated action: #markForRevert. subMenu add: 'mark entire book to be revertable' translated action: #markBookForRevert. subMenu add: 'unmark this page to be revertable' translated action: #unmarkForRevert. subMenu add: 'unmark entire book to be revertable' translated action: #unmarkBookForRevert. " subMenu add: 'revert this page' translated action: #revertPage. subMenu add: 'revert all pages' translated action: #revertAllPages." aMenu add: 'book...' translated subMenu: subMenu ! ! !BookMorph methodsFor: 'menu' stamp: 'yo 9/13/2007 13:40'! addSaveAndRevertItemsTo: aMenu "Add items relating to use of revertable page-prototypes " | subMenu | subMenu := MenuMorph new defaultTarget: self. subMenu add: 'mark this page to be revertable' translated action: #markForRevert.. subMenu add: 'mark entire book to be revertable' translated action: #markBookForRevert. aMenu add: 'save for later revert...' translated subMenu: subMenu! ! !BookMorph methodsFor: 'navigation' stamp: 'yo 9/13/2007 14:56'! insertPageMorphInCorrectSpot: aPageMorph "The user is going to a new page; the old one is gone; add the new one at the appropriate place." self pageControlsAtTop ifTrue: [self addMorphBack: (self currentPage: aPageMorph)] ifFalse: [self addMorphFront: (self currentPage: aPageMorph)] ! ! !BookMorph methodsFor: 'submorphs-accessing' stamp: 'yo 11/5/2007 16:11'! allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy. Especially the non-showing pages in BookMorphs. (As needed, make a variant of this that brings in all pages that are not in memory.)" | coll | coll _ OrderedCollection new. pages do: [:pg | pg isInMemory ifTrue: [ pg == currentPage ifFalse: [coll add: pg]]]. "(self valueOfProperty: #pagesForRevert ifAbsent: [#()]) do: [:mm | coll add: mm value]." ^ coll! ! !BookMorph methodsFor: 'fileIn/out' stamp: 'yo 11/5/2007 13:38'! prepareToBeSaved super prepareToBeSaved. self removeProperty: #pagesForRevert. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 13:48'! deletePageAlongWithPlayers: page | set | set _ Set new. page allMorphsDo: [:e | e player notNil ifTrue: [set add: e player]. e delete]. (set select: [:p | p class isSystemDefined not]) do: [:p | p class removeFromSystemUnlogged]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 9/13/2007 15:43'! markBookForRevert pages do: [:pg | self markForRevert: pg]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 9/13/2007 15:42'! markForRevert self markForRevert: currentPage. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 14:44'! markForRevert: page "Save the current page for future revert." | key revertPage revertDict | page setProperty: #revertMarked toValue: true. revertDict _ self pagesForRevert. key _ page valueOfProperty: #revertKey ifAbsent: [0]. revertPage := revertDict at: key ifAbsent: [nil]. (key = 0 or: [revertPage isNil]) ifTrue: [key := revertDict ifEmpty: [1] ifNotEmpty: [revertDict keys max + 1]. page setProperty: #revertKey toValue: key. revertDict at: key put: page copy] ifFalse: [ self deletePageAlongWithPlayers: revertPage. revertDict at: key put: page copy]! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 15:57'! pagesForRevert "A normal book has its pages in the pages inst var, and cannot revert a page. If a book has the property pagesForRevert, then any (or all) pages can have a backup copy. The user can ask to revert after messing up a page. Good for tutorials. Only authors are expected to preserve pages using saveForRevert. This method creates and returns the pagesForRevert collection. It is a journal and is not in the same order as pages." | revColl | revColl _ self valueOfProperty: #pagesForRevert ifAbsent: [nil]. (revColl notNil and: [(revColl isKindOf: Dictionary) not]) ifTrue: [ revColl do: [:p | self deletePageAlongWithPlayers: p value ]. revColl _ nil. ]. revColl ifNil: [ revColl _ Dictionary new. self setProperty: #pagesForRevert toValue: revColl. ]. ^ revColl.! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 14:21'! revertAllPages "Go back to saved copies of all pages." pages do: [:e | self revertPageInner: e]. self goToPage: 1! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 13:28'! revertablePageForKey: anInteger "If I have a saved page with the given revertKey, an Integer, answer it, else answer nil." | forRevert | (forRevert := self pagesForRevert) isEmptyOrNil ifTrue: [^ nil]. ^ forRevert at: anInteger ifAbsent: [nil]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 14:16'! revertablePageForPage: aPage "If I have a saved page for the page, answer it, else answer nil." | forRevert key | (forRevert := self pagesForRevert) isEmptyOrNil ifTrue: [^ nil]. key := aPage valueOfProperty: #revertKey ifAbsent: [0]. ^ forRevert at: key ifAbsent: [nil]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 13:07'! revertPage (self revertPageInner: currentPage) ifFalse: [ ^ self inform: 'sorry, nothing was saved for this page.' translated]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 15:32'! revertPageInner: aPage | replacement index newReplacement | replacement _ self revertablePageForPage: aPage. replacement ifNil: [^ false]. index := pages indexOf: aPage. newReplacement _ replacement veryDeepCopy. newReplacement setNameTo: 'page'. pages at: index put: newReplacement. (pages at: index) position: aPage position. aPage == currentPage ifTrue: [aPage owner ifNotNil: [aPage owner addMorph: newReplacement inFrontOf: aPage]]. self deletePageAlongWithPlayers: aPage. aPage removeViewersOnSubsIn: self presenter. aPage == currentPage ifTrue: [self currentPage: newReplacement]. ^ true. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 9/13/2007 15:40'! unmarkBookForRevert pages do: [:p | self unmarkForRevert: p]. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 9/13/2007 15:40'! unmarkForRevert ^ self unmarkForRevert: currentPage. ! ! !BookMorph methodsFor: 'new reverting' stamp: 'yo 11/5/2007 14:41'! unmarkForRevert: page "Forget the data around reverting for this page." | key revertPage | revertPage _ self revertablePageForPage: page. revertPage ifNotNil: [ key _ page valueOfProperty: #revertKey. page removeProperty: #revertKey. page removeProperty: #revertMarked. self deletePageAlongWithPlayers: revertPage. self pagesForRevert removeKey: key]. ! ! !GeeBookMorph methodsFor: 'as yet unclassified' stamp: 'yo 9/13/2007 14:59'! rebuildPages pages _ self geePageRectangles collect: [ :each | GeeBookPageMorph new disableDragNDrop; geeMail: geeMail geeMailRectangle: each. ]. currentPage delete. self currentPage: nil. pages isEmpty ifTrue: [^ self insertPage]. self goToPage: 1. ! ! !MoviePlayerMorph methodsFor: 'private' stamp: 'yo 9/13/2007 14:59'! makeMyPage currentPage ifNotNil: [(currentPage isMemberOf: ImageMorph) ifTrue: ["currentPage is already an ImageMorph." (currentPage image extent = frameSize and: [currentPage image depth = frameDepth]) ifTrue: [^ self "page is already properly dimensioned."]. ^ currentPage image: (Form extent: frameSize depth: frameDepth)] ifFalse: [currentPage releaseCachedState; delete]]. self currentPage: (ImageMorph new image: (Form extent: frameSize depth: frameDepth)). currentPage lock. pages _ OrderedCollection with: currentPage. self addMorphFront: currentPage! ! !StackMorph methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:59'! initializeWith: aCardMorph "Install the card inside a new stack. Make no border or controls, so I the card's look is unchanged. Card already has a CardPlayer." | wld | wld _ aCardMorph world. self initialize. self pageSize: aCardMorph extent. self borderWidth: 0; layoutInset: 0; color: Color transparent. pages _ Array with: aCardMorph. self currentPage: aCardMorph. self privateCards: (OrderedCollection with: currentPage currentDataInstance). currentPage beAStackBackground. self position: aCardMorph position. submorphs last delete. self addMorph: currentPage. self showPageControls: self fullControlSpecs. wld addMorph: self. ! ! !StoryboardBookMorph methodsFor: 'navigation' stamp: 'yo 9/13/2007 14:59'! insertPageMorphInCorrectSpot: aPageMorph "Insert the page morph at the correct spot" | place | place _ submorphs size > 1 ifTrue: [submorphs second] ifFalse: [submorphs first]. "Old architecture had a tiny spacer morph as the second morph; now architecture does not" self addMorph: (self currentPage: aPageMorph) behind: place. self changeTiltFactor: self getTiltFactor. self changeZoomFactor: self getZoomFactor. zoomController target: currentPage. ! ! !TabbedPalette methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:58'! addTabFor: aReferent font: aFont | aTab | aTab _ tabsMorph addTabFor: aReferent font: aFont. pages add: aReferent. currentPage ifNil: [self currentPage: aReferent]. ^ aTab! ! !TabbedPalette methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:58'! addTabForBook: aBook | aTab | aTab _ tabsMorph addTabForBook: aBook. pages add: aBook. currentPage ifNil: [self currentPage: aBook]. ^ aTab! ! !TabbedPalette methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:58'! addTabForBook: aBook withBalloonText: text | aTab | aTab _ tabsMorph addTabForBook: aBook. pages add: aBook. currentPage ifNil: [self currentPage: aBook]. text ifNotNil: [aTab setBalloonText: text]. ^ aTab! ! !TabbedPalette methodsFor: 'initialization' stamp: 'yo 9/13/2007 14:59'! newTabs: tabsList "Reconstitute the palette based on info in the tabs list" | itsBook color1 color2 color3 | pages _ pages species new. tabsMorph ifNotNil: [color1 _ tabsMorph highlightColor. color2 _ tabsMorph regularColor. color3 _ tabsMorph color. tabsMorph delete]. tabsMorph _ IndexTabs new. self addMorphFront: tabsMorph. color1 ifNotNil: [tabsMorph highlightColor: color1 regularColor: color2; color: color3]. currentPage ifNotNil: [currentPage delete. self currentPage: nil]. tabsList do: [:aTab | tabsMorph addTab: aTab. aTab unHighlight. (itsBook _ aTab morphToInstall) ifNotNil: [pages add: itsBook. currentPage ifNil: [self currentPage: itsBook]]]. tabsMorph position: self position + self borderWidth! ! !TabbedPalette methodsFor: 'misc menu items' stamp: 'yo 9/13/2007 14:58'! showNoPaletteAndHighlightTab: aTab | oldTab morphToInstall aSketchEditor | oldTab _ tabsMorph highlightedTab. (oldTab notNil and: [(morphToInstall _ oldTab morphToInstall) isKindOf: PaintBoxMorph]) ifTrue: [(aSketchEditor _ self world submorphOfClass: SketchEditorMorph) ifNotNil: [aSketchEditor cancelOutOfPainting]. morphToInstall delete]. currentPage ifNotNil: [currentPage delete]. self currentPage: nil. submorphs size > 1 ifTrue: "spurious submorphs, yecch" [(submorphs copyFrom: 2 to: submorphs size) do: [:m | m delete]]. tabsMorph highlightTab: aTab! ! !TabbedPalette methodsFor: 'submorphs-add/remove' stamp: 'yo 9/13/2007 14:57'! replaceSubmorph: oldMorph by: newMorph super replaceSubmorph: oldMorph by: newMorph. oldMorph == currentPage ifTrue: [self currentPage: newMorph]! ! !TabbedPalette methodsFor: 'viewer tab' stamp: 'yo 9/13/2007 14:58'! viewMorph: aMorph "The receiver is expected to have a viewer tab; select it, and target it to aMorph" | aPlayer aViewer oldOwner | ((currentPage isKindOf: Viewer) and: [currentPage scriptedPlayer == aMorph player]) ifTrue: [^ self]. oldOwner _ owner. self delete. self visible: false. aPlayer _ aMorph assuredPlayer. self showNoPalette. aViewer _ StandardViewer new initializeFor: aPlayer barHeight: 0. aViewer enforceTileColorPolicy. self showNoPalette. currentPage ifNotNil: [currentPage delete]. self addMorphBack: (self currentPage: aViewer beSticky). self snapToEdgeIfAppropriate. tabsMorph highlightTab: nil. self visible: true. oldOwner addMorphFront: self. self world startSteppingSubmorphsOf: aViewer. self layoutChanged! ! BookMorph removeSelector: #deleteSavedPageForRevert:! !BookMorph reorganize! ('accessing' cardsOrPages currentPage currentPage: pageNamed: pageNumberOf: pages pages: setAllPagesColor: userString) ('caching' releaseCachedState) ('classification' defersHaloToInterior) ('copying' updateReferencesUsing:) ('dropping/grabbing' allowSubmorphExtraction wantsDroppedMorph:event:) ('e-toy support' canRevertThisPage configureForKids deleteAlongWithPlayers encouragesHaloTransferToEnclosedPasteUpMorph succeededInRevealing:) ('halos and balloon help' defersHaloOnClickTo:) ('initialization' defaultColor fromRemoteStream: fromURL: initialize newPages: newPages:currentIndex: removeEverything setInitialState) ('insert and delete' defaultNameStemForNewPages deletePage deletePageBasic insertPageColored: insertPageLabel:morphs: insertPageSilentlyAtEnd insertPage:pageSize: insertPage:pageSize:atIndex:) ('layout' acceptDroppingMorph:event:) ('menu' addAdvancedItemsTo: addAllPagesItemsTo: addBookMenuItemsTo:hand: addBookToggleItemsTo: addSaveAndRevertItemsTo: addTransitionItemsTo: bookMenu bookmarkForThisPage buildThreadOfProjects copyUrl duplicatePage findText: findText:inStrings:startAt:container:pageNum: forgetURLs getAllText getStemUrl goToPage highlightText:at:in: invokeBookMenu invokeShortBookMenu keepTogether loadImagesIntoBook makeUniformPageSize menuPageSoundForAll: menuPageSoundForThisPage: menuPageSoundFor:event: menuPageVisualForAll: menuPageVisualForThisPage: menuPageVisualFor:event: pageControlsVisible pasteBookPage reload reserveUrls reserveUrlsIfNeeded saveAsNumberedURLs saveIndexOfOnly: saveIndexOnURL saveOneOnURL saveOnUrlPage: savePagesOnURL setNewPagePrototype setPageColor textSearch textSearchAgain textSearch: thumbnailForThisPage toggleFullScreen toggleShowingOfPageControls uncachePageSorter) ('menu commands' saveForRevert sortPages) ('navigation' buildFloatingPageControls goToPageMorph: goToPageMorph:fromBookmark: goToPageMorph:runTransitionScripts: goToPageMorph:transitionSpec: goToPageMorph:transitionSpec:runTransitionScripts: goToPageUrl: goToPage: goToPage:transitionSpec: goToPage:transitionSpec:runTransitionScripts: goto: insertPageMorphInCorrectSpot: lastPage nextPage pageNumber previousPage setWrapPages: showMoreControls toggleWrapPages transitionSpecFor:) ('other' adjustCurrentPageForFullScreen exitFullScreen goFullScreen isInFullScreenMode makeMinimalControlsWithColor:title: resizePagesTo: setExtentFromHalo:) ('parts bin' initializeToStandAlone) ('printing' pagesHandledAutomatically) ('scripting' chooseAndRevertToVersion installRollBackButtons methodHolders methodHolderVersions revertToCheckpoint:) ('sorting' acceptSortedContentsFrom: morphsForPageSorter sortPages:) ('submorphs-accessing' allNonSubmorphMorphs) ('submorphs-add/remove' abandon) ('*morphic-Postscript Canvases' asPostscript fullDrawPostscriptOn:) ('uniform page size' keepingUniformPageSizeString maintainsUniformPageSize maintainsUniformPageSize: pageControlsAtTop pageControlsAtTop: pageControlsShort pageControlsShort: toggleMaintainUniformPageSize togglePageControlsAtTop togglePageControlsShort toggleUsingPrivatePresenter uniformPageSize usesPrivatePresenter usingPrivatePresenterString wrappingAtEndString) ('menus' printPSToFile) ('*connectors-attachments-nk' isConnectable) ('master pages' saveBookForRevert) ('page controls' fullControlSpecs pageNumberReport shortControlSpecs) ('fileIn/out' pagesAndColorInSISSFormat prepareToBeSaved storeAsDataStream storeAsDataStreamNamed:) ('new reverting' deletePageAlongWithPlayers: markBookForRevert markForRevert markForRevert: pagesForRevert revertAllPages revertablePageForKey: revertablePageForPage: revertPage revertPageInner: unmarkBookForRevert unmarkForRevert unmarkForRevert:) !