| package | package := Package name: 'Pst-Ui-Dolphin'. package paxVersion: 0; basicComment: 'Pocket Smalltalk 1.6 Copyright (c) 1998-2001 www.PocketSmalltalk.com GEOS changes and enhancements: Copyright (c) 1999, 2000 by Petr Novak Toolbar enhancements: Copyright (c) 2000 by Joey Gibson (joeyGibson@mindspring.com) This product is Open Source - see LICENSE.TXT for more information. Home page: http://www.pocketsmalltalk.com GEOS version home page: http://www.i.cz/PeN/pst9110.html SE version: http://www.joeygibson.com/st After filing in this package, evaluate the following to open a launcher (you can replace initSystem with initGeosSystem or initPalmOSSystem): PstSystem resetAll. PstLauncher show. There are a couple of things that make sure this package loads the Palm OS and GEOS parts of Pocket Smalltalk. One is the postinstall and preuninstall scripts, which directly force the packages related to these parts to be loaded. Another is PstImageStripper>>requiredPackageNames method which references these packages directly as well.'. package basicPackageVersion: ''. "Image stripper bytes" package imageStripperBytes: #[33 83 84 66 32 48 32 70 15 16 0 3 0 0 0 80 115 116 73 109 97 103 101 83 116 114 105 112 112 101 114 0 0 0 0 0 0 0 0 54 0 6 0 83 116 114 105 110 103 14 0 0 0 80 115 116 45 85 105 45 68 111 108 112 104 105 110 114 0 0 0 12 0 0 0 80 111 99 107 101 116 83 116 46 101 120 101 78 2 13 0 1 0 0 0 83 84 66 67 108 97 115 115 80 114 111 120 121 0 0 0 0 114 0 0 0 14 0 0 0 80 115 116 45 85 105 45 68 111 108 112 104 105 110 114 0 0 0 24 0 0 0 80 115 116 82 117 110 116 105 109 101 83 101 115 115 105 111 110 77 97 110 97 103 101 114 239 191 5 0 114 0 0 0 19 0 0 0 80 115 116 83 121 115 116 101 109 32 114 101 115 101 116 65 108 108 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]. "Add the package scripts" package basicScriptAt: #postinstall put: 'PstImageStripper installPstRequiredPackageNames. PstDolphinInterface initialize.'. package basicScriptAt: #preinstall put: ' "If the deployement kit does not exist, then make sure we can still install our PstImageStripper" (Smalltalk includesKey: #ImageStripper) ifFalse: [ Object subclass: #ImageStripper instanceVariableNames: '''' classVariableNames: '''' poolDictionaries: '''' classInstanceVariableNames: ''''].'. package basicScriptAt: #preuninstall put: 'PstImageStripper uninstallPstRequiredPackageNames.'. "Add the class names, loose method names, global names, resource names" package classNames add: #PstAboutShell; add: #PstClassBrowser; add: #PstConstantsBrowser; add: #PstDebugger; add: #PstImageStripper; add: #PstInspector; add: #PstLauncher; add: #PstMethodListBrowser; add: #PstPackageBrowser; add: #PstRuntimeSessionManager; add: #PstShell; add: #PstSourceCodePresenter; add: #PstSplash; add: #PstToolbar; add: #PstToolbarHelper; add: #PstWorkspace; yourself. package methodNames add: #PstBehavior -> #methodTree; add: #PstClassLibrary -> #classTree; add: #PstDolphinInterface -> #closeAllWindows; add: #PstMethod -> #richTextSource; add: #PstPocketSmalltalkGEOS -> #defaultCodeFile; add: #PstPocketSmalltalkPalmOS -> #defaultCodeFile; add: #PstSystem -> #chooseFont; add: #PstSystem -> #setDefaultFont:size:; add: #TextEdit -> #onKeyTyped:; add: 'PstPackage class' -> #chooseSelecting:; add: 'PstResourceDatabase class' -> #fromUser; add: 'PstStatistics class' -> #display:caption:; yourself. package globalNames yourself. package resourceNames yourself. "Binary Global Names" package binaryGlobalNames: (Set new yourself). "Resource Names" package allResourceNames: (Set new add: #PstAboutShell -> 'Default view'; add: #PstClassBrowser -> 'Default view'; add: #PstConstantsBrowser -> 'Default view'; add: #PstDebugger -> 'Default view'; add: #PstInspector -> 'Default view'; add: #PstLauncher -> 'Default view'; add: #PstMethodListBrowser -> 'Default view'; add: #PstPackageBrowser -> 'Default view'; add: #PstSourceCodePresenter -> 'Workspace view'; add: #PstToolbar -> 'PstDebugger Toolbar'; add: #PstToolbar -> 'PstEditTools Toolbar'; add: #PstToolbar -> 'PstFileTools Toolbar'; add: #PstToolbar -> 'PstImage Toolbar'; add: #PstToolbar -> 'PstTools Toolbar'; add: #PstToolbar -> 'PstWorkspaceTools Toolbar'; add: #PstWorkspace -> 'Default view'; yourself). "Add the prerequisite names" package setPrerequisites: (IdentitySet new add: 'Application Deployment Kit'; add: 'Dolphin'; add: 'Pst-Base'; add: 'Pst-Base-Dolphin'; add: 'Pst-GEOS-Base'; add: 'Pst-PalmOS-Base'; yourself). package! "Class Definitions"! Object subclass: #PstToolbarHelper instanceVariableNames: 'launcher containingTool' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! ImageStripper subclass: #PstImageStripper instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! Shell subclass: #PstAboutShell instanceVariableNames: 'imagePresenter' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! Shell subclass: #PstShell instanceVariableNames: 'toolbarHelper' classVariableNames: 'PstShellIcon' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstClassBrowser instanceVariableNames: 'classTree methodTree sourceCode modeList sideList kludge statusModel' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstConstantsBrowser instanceVariableNames: 'categoryList constantsList sourceCode statusModel' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstDebugger instanceVariableNames: 'interpreter contextList sourceCode localFieldList localFieldSource sourceMode disassemblyMap' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstInspector instanceVariableNames: 'fieldList sourceCode historyStack' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstLauncher instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstMethodListBrowser instanceVariableNames: 'methodList sourceCode updateBlock' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstPackageBrowser instanceVariableNames: 'packageList classList methodList constantList statusModel' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! PstShell subclass: #PstWorkspace instanceVariableNames: 'sourceCode' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! RichTextPresenter subclass: #PstSourceCodePresenter instanceVariableNames: 'expressionOffset autoindent' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! RuntimeSessionManager subclass: #PstRuntimeSessionManager instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! Splash subclass: #PstSplash instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! Toolbar subclass: #PstToolbar instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! "Loose Methods"! !PstBehavior methodsFor! methodTree | tree all | tree := TreeModel new. all := '(all)'. tree add: all asChildOf: nil. self sortedMethods do: [:method | tree add: (PstQuasiMethod for: method) asChildOf: all]. self sortedCategories do: [:category | tree add: category asChildOf: nil. (self class sortMethods: (categories at: category)) do: [:each | tree add: each asChildOf: category]]. ^tree.! ! !PstBehavior categoriesFor: #methodTree!categories!public! ! !PstClassLibrary methodsFor! classTree "Answer a TreeModel for the current class hierarchy." | tree | tree := TreeModel new. self roots do: [:each | each buildTree: tree]. ^tree.! ! !PstClassLibrary categoriesFor: #classTree!accessing!public! ! !PstDolphinInterface methodsFor! closeAllWindows " Close everything except the launcher." (Smalltalk at: #PstShell) allSubinstances do: [:each | (each isMemberOf: PstLauncher) ifFalse: [each exit]].! ! !PstDolphinInterface categoriesFor: #closeAllWindows!public!ui! ! !PstMethod methodsFor! richTextSource | converter | converter := RichText rtfConverter. converter font: PstSystem current defaultFont. converter text: self sourceCode. keywordMap isNil ifFalse: [ keywordMap do: [:interval | converter selectionRange: interval; beBold]]. commentMap isNil ifFalse: [ commentMap do: [:interval | converter selectionRange: interval; beItalic]]. " argumentMap isNil ifFalse: [ argumentMap do: [:interval | converter selectionRange: interval; beItalic]]." ^converter richText.! ! !PstMethod categoriesFor: #richTextSource!printing!public! ! !PstPackage class methodsFor! chooseSelecting: selecting "PstPackage choose." | packages default | packages := PstPackageLibrary current packages reject: [:each | each isUncommitted]. default := selecting. default isNil ifTrue: [ self default isUncommitted ifFalse: [ default := self default]]. (packages includes: default) ifFalse: [ default := nil]. ^default isNil ifTrue: [ ChoicePrompter choices: packages caption: 'Choose a Package'] ifFalse: [ ChoicePrompter on: default choices: packages caption: 'Choose a Package'].! ! !PstPackage class categoriesFor: #chooseSelecting:!accessing!public! ! !PstPocketSmalltalkGEOS methodsFor! defaultCodeFile ^FileSaveDialog new fileTypes: (Array with: #('GEOS VM files (*.vm)' '*.vm') with: FileDialog allFilesType); defaultExtension: 'vm'; yourself.! ! !PstPocketSmalltalkGEOS categoriesFor: #defaultCodeFile!*-unclassified!public! ! !PstPocketSmalltalkPalmOS methodsFor! defaultCodeFile ^FileSaveDialog new fileTypes: (Array with: #('PRC files (*.prc)' '*.prc') with: FileDialog allFilesType); defaultExtension: 'prc'; yourself.! ! !PstPocketSmalltalkPalmOS categoriesFor: #defaultCodeFile!*-unclassified!public! ! !PstResourceDatabase class methodsFor! fromUser | filename dialog | dialog := FileOpenDialog new. dialog fileTypes: #(('Resource Databases (*.prc)' '*.prc') ('All Files (*.*)' '*.*')); caption: 'Select a .PRC file'. filename := dialog showModal. filename isNil ifTrue: [^nil]. (File exists: filename) ifFalse: [ MessageBox notify: 'That file does not exist.'. ^nil]. ^self fromFile: filename.! ! !PstResourceDatabase class categoriesFor: #fromUser!instance creation!public! ! !PstStatistics class methodsFor! display: statisticsSelector caption: captionString | presenter | presenter := RichTextPresenter showOn: (self new perform: statisticsSelector). presenter view topShell caption: captionString. ^presenter view topShell.! ! !PstStatistics class categoriesFor: #display:caption:!public!utility! ! !PstSystem methodsFor! chooseFont defaultFont := Font choose.! setDefaultFont: fontName size: size | font | font := fontName copyFrom: 2 to: (fontName size - 1). defaultFont := Font name: font size: size.! ! !PstSystem categoriesFor: #chooseFont!public!user interface! ! !PstSystem categoriesFor: #setDefaultFont:size:!project management!public! ! !TextEdit methodsFor! onKeyTyped: aKeyEvent "Handle aKeyEvent. If the receiver is in updatePerChar mode, then we update the model immediately after processing the character. Implementation Note: Sadly the edit control does not insert tabs if used in conjunction with IsDialogMessage(), even though it says it wants to receive them. We therefore fix this bug overridding WM_GETDLGCODE and never allowing it to reach the control. This prevents the control from getting the notion that it is in a dialog, and retains the saner behaviour. An alternative workaround to implementing WM_GETDLGCODE would be to recode this method thus: ... | answer | answer := aKeyEvent code == VK_TAB ifTrue: [self replaceSelection: String tab. 0] ifFalse: [super onChar: aKeyEvent]. ... However the WM_GETDLGCODE override is preferred, because it prevents other nasties too." | answer | answer := super onKeyTyped: aKeyEvent. self updatePerChar ifTrue: [self apply]. self presenter trigger: #afterKeyTyped: with: aKeyEvent. ^answer! ! !TextEdit categoriesFor: #onKeyTyped:!event handling!public! ! "End of package definition"! PstToolbarHelper comment: ''! PstToolbarHelper guid: (GUID fromString: '{E1A2CE6D-E7EC-47BB-967C-E4779B9596B2}')! !PstToolbarHelper categoriesForClass!Unclassified! ! !PstToolbarHelper methodsFor! containingTool "Answer the value of the receiver's ''containingTool'' instance variable." ^containingTool! containingTool: anObject "Set the value of the receiver's ''containingTool'' instance variable to the argument, anObject." containingTool := anObject! launcher "Answer the value of the receiver's ''launcher'' instance variable." ^launcher! launcher: anObject "Set the value of the receiver's ''launcher'' instance variable to the argument, anObject, or the first instance of it we can find." anObject isNil ifTrue: [launcher := (PstLauncher allInstances) at: 1] ifFalse: [launcher := anObject]. ! newProject launcher newProject.! openClassBrowser "Open a PstClassbrowser." launcher openClassBrowser.! openClassBrowserOnClass: aClass "Open a PstClassbrowser." launcher openClassBrowserOnClass: aClass.! openClassBrowserOnMethod: aMethod "Open a PstClassbrowser." launcher openClassBrowserOnMethod: aMethod.! openConstantsBrowser launcher openConstantsBrowser.! openConstantsBrowserOnConstant: aConstant launcher openConstantsBrowserOnConstant: aConstant.! openPackageBrowser launcher openPackageBrowser.! openProject launcher openProject.! openWorkspace launcher openWorkspace.! saveProject launcher saveProject.! ! !PstToolbarHelper categoriesFor: #containingTool!accessing!public! ! !PstToolbarHelper categoriesFor: #containingTool:!accessing!public! ! !PstToolbarHelper categoriesFor: #launcher!accessing!public! ! !PstToolbarHelper categoriesFor: #launcher:!accessing!public! ! !PstToolbarHelper categoriesFor: #newProject!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openClassBrowser!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openClassBrowserOnClass:!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openClassBrowserOnMethod:!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openConstantsBrowser!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openConstantsBrowserOnConstant:!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openPackageBrowser!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openProject!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #openWorkspace!*-unclassified!public! ! !PstToolbarHelper categoriesFor: #saveProject!actions-system!public! ! !PstToolbarHelper class methodsFor! new ^super new initialize launcher: nil.! with: aLauncher "Answer a new instance of the class, with aLauncher setup as the launcher." ^super new initialize launcher: aLauncher.! ! !PstToolbarHelper class categoriesFor: #new!*-unclassified!public! ! !PstToolbarHelper class categoriesFor: #with:!instance creation!public! ! PstImageStripper comment: ''! PstImageStripper guid: (GUID fromString: '{9EA465A6-0816-4B1C-868A-FEAC39AF4AC3}')! !PstImageStripper categoriesForClass!Unclassified! ! !PstImageStripper methodsFor! developmentMethodCategoryNames "Answer a of the names of s containing only development methods which must therefore be stripped from the image when it is deployed." | names | names := super developmentMethodCategoryNames. names remove: 'categories' ifAbsent: []. ^names! initialize "Private - Initialize the receiver" super initialize. self executableName: 'PocketSt.exe'; runtimeSessionManagerClass: PstRuntimeSessionManager; rootPackage: (Package manager packageNamed: 'Pst-Ui-Dolphin'); preStripScript: 'PstSystem resetAll.'. ! requiredPackageNames "Answers a of the names of the packages required by application. These should already have been loaded into the image." ^(super requiredPackageNames) addAll: self class pstRequiredPackageNames; yourself.! ! !PstImageStripper categoriesFor: #developmentMethodCategoryNames!constants!public! ! !PstImageStripper categoriesFor: #initialize!constants!public! ! !PstImageStripper categoriesFor: #requiredPackageNames!constants!public! ! !PstImageStripper class methodsFor! installPstRequiredPackageNames " ^ void Install the packages needed to make me a complete product. See pstRequiredPackageNames." ^self pstRequiredPackageNames do: [:each | Package manager install: (File composePath: self owningPackage path stem: each extension: Package packageExtension)].! pstRequiredPackageNames " ^ > Return the names of the packages needed to make me a complete product." ^OrderedCollection new add: 'Pst-PalmOS-Dolphin'; add: 'Pst-GEOS-Dolphin'; yourself.! uninstallPstRequiredPackageNames " ^ void Remove/uninstall the packages needed to make me a complete product. See pstRequiredPackageNames." | package | self pstRequiredPackageNames do: [:each | package := Package manager packageNamed: each ifNone: [nil]. package isNil ifFalse: [ package uninstall]]. ! ! !PstImageStripper class categoriesFor: #installPstRequiredPackageNames!*-unclassified!public! ! !PstImageStripper class categoriesFor: #pstRequiredPackageNames!*-unclassified!public! ! !PstImageStripper class categoriesFor: #uninstallPstRequiredPackageNames!*-unclassified!public! ! PstAboutShell comment: ''! PstAboutShell guid: (GUID fromString: '{EC8B4F53-AEED-4619-A91D-4D4BF366050E}')! !PstAboutShell categoriesForClass!Unclassified! ! !PstAboutShell methodsFor! createComponents "Private - Create the presenters contained by the receiver." super createComponents. imagePresenter := self add: ImagePresenter new name: 'imagePresenter'. imagePresenter value: (Bitmap fromFile: (File composePath: SessionManager current installationDirectory subPath: 'PstSplash.bmp') usingLocator: FileLocator absolute).! ok self view close.! ! !PstAboutShell categoriesFor: #createComponents!*-unclassified!private! ! !PstAboutShell categoriesFor: #ok!*-unclassified!public! ! !PstAboutShell class methodsFor! icon ^PstShell icon! ! !PstAboutShell class categoriesFor: #icon!*-unclassified!public! ! PstShell comment: ''! PstShell guid: (GUID fromString: '{F0B9A87B-59AB-4F93-B618-9911450935FC}')! !PstShell categoriesForClass!No category! ! !PstShell methodsFor! doIt self sourceCodePart doItFor: self receiverForEvaluations.! findClassMatching: match | classes | PstSystem lastArgumentFor: #findClass put: match. classes := (self classLibrary classesMatching: match) asSortedCollection: [:left :right | left name <= right name]. classes isEmpty ifTrue: [ MessageBox notify: 'There is no class matching ', match printString, '.'. ^nil]. ^classes size = 1 ifTrue: [classes first] ifFalse: [ ChoicePrompter choices: classes caption: 'Which one did you mean?']! inspectIt self sourceCode inspectItFor: self receiverForEvaluations.! printIt self sourceCodePart printItFor: self receiverForEvaluations.! receiverForEvaluations ^PstBasicObject forNil.! sourceCodeBrowseImplementors " ^ void Take the selection in the source code view and find all methods whose selector matches it." self sourceCodePart isNil ifTrue: [ ^self]. self sourceCodePart selectedExpression isNil ifTrue: [ ^self]. PstMethodListBrowser showImplementorsOf: self sourceCodePart selectedExpression ! sourceCodeBrowseIt " ^ void Take the selection in the source code view and find all classes that match." | class | self sourceCodePart isNil ifTrue: [ ^self]. self sourceCodePart selectedExpression isNil ifTrue: [ ^self]. class := self findClassMatching: self sourceCodePart selectedExpression. class isNil ifTrue: [ ^self]. PstClassBrowser browseClass: class! sourceCodeBrowseSenders " ^ void Take the selection in the source code view and find all methods who send a selector matching it." | match choices choice | self sourceCodePart isNil ifTrue: [ ^self]. match := self sourceCodePart selectedExpression. match isNil ifTrue: [ ^self]. choices := PstClassLibrary current methodsWithSelector: match. choices isEmpty ifTrue: [ MessageBox notify: 'No classes implement #', match, '.'. ^self]. choices := (choices collect: [:each | each selector]) asSet asSortedCollection. choice := choices size = 1 ifTrue: [choices first] ifFalse: [ChoicePrompter choices: choices caption: 'Senders of ?']. choice isNil ifTrue: [ ^self]. PstMethodListBrowser showSendersOf: choice! sourceCodePart self subclassResponsibility! toolbarFileNew toolbarHelper newProject.! toolbarFileOpen toolbarHelper openProject.! toolbarFileSave toolbarHelper saveProject.! toolbarHelper: aToolbarHelper "Assigns a PstToolbarHelper to a tool." toolbarHelper := aToolbarHelper. toolbarHelper containingTool: self.! toolbarOpenClassBrowser "Open a class browser." toolbarHelper openClassBrowser.! toolbarOpenConstantsBrowser toolbarHelper openConstantsBrowser.! toolbarOpenPackageBrowser toolbarHelper openPackageBrowser.! toolbarOpenWorkspace toolbarHelper openWorkspace.! toolbarSaveProject toolbarHelper saveProject.! ! !PstShell categoriesFor: #doIt!*-unclassified!public! ! !PstShell categoriesFor: #findClassMatching:!*-unclassified!public! ! !PstShell categoriesFor: #inspectIt!*-unclassified!public! ! !PstShell categoriesFor: #printIt!*-unclassified!public! ! !PstShell categoriesFor: #receiverForEvaluations!*-unclassified!public! ! !PstShell categoriesFor: #sourceCodeBrowseImplementors!*-unclassified!public! ! !PstShell categoriesFor: #sourceCodeBrowseIt!*-unclassified!public! ! !PstShell categoriesFor: #sourceCodeBrowseSenders!*-unclassified!public! ! !PstShell categoriesFor: #sourceCodePart!*-subclass responsibility!*-unclassified!public! ! !PstShell categoriesFor: #toolbarFileNew!*-unclassified!public! ! !PstShell categoriesFor: #toolbarFileOpen!*-unclassified!public! ! !PstShell categoriesFor: #toolbarFileSave!*-unclassified!public! ! !PstShell categoriesFor: #toolbarHelper:!*-unclassified!public! ! !PstShell categoriesFor: #toolbarOpenClassBrowser!*-unclassified!public! ! !PstShell categoriesFor: #toolbarOpenConstantsBrowser!*-unclassified!public! ! !PstShell categoriesFor: #toolbarOpenPackageBrowser!*-unclassified!public! ! !PstShell categoriesFor: #toolbarOpenWorkspace!*-unclassified!public! ! !PstShell categoriesFor: #toolbarSaveProject!*-unclassified!public! ! !PstShell class methodsFor! icon PstShellIcon isNil ifTrue: [ PstShellIcon := Icon fromFile: 'pocketst.ico']. ^PstShellIcon.! ! !PstShell class categoriesFor: #icon!*-unclassified!public! ! PstClassBrowser comment: ''! PstClassBrowser guid: (GUID fromString: '{C70501FC-8548-47DF-AAEC-E4E7C21E02A6}')! !PstClassBrowser categoriesForClass!No category! ! !PstClassBrowser methodsFor! accept "Answer whether compilation succeeded." | mode | mode := self mode. sourceCode view isModified: false. "hmm..." mode == #source ifTrue: [^self acceptSource]. mode == #class ifTrue: [^self acceptClass]. mode == #comment ifTrue: [^self acceptComment].! acceptClass PstCrossPlatformInterface do: [PstClassDefiner new redefine: self selectedClass as: self sourceString] onCompilerErrorDo: [:exception | sourceCode handleError: exception message from: exception start to: exception stop. ^false] onCompilerWarningDo: [:exception | sourceCode handleWarning: exception message from: exception start to: exception stop. exception resume]. self updateSourcePane. ^true. "hrm"! acceptComment self selectedClass isNil ifTrue: [^self]. self selectedClass comment: self sourceString. self updateSourcePane. ^true.! acceptSource | cls method category | cls := self classForMethods. cls isNil ifTrue: [^false]. method := PstSystem current qcompilerClass compile: self sourceString in: cls notifying: sourceCode. method isNil ifTrue: [^false]. category := (cls includesSelector: method selector) ifTrue: [cls categoryOfMethod: (cls methodAt: method selector)] ifFalse: [self selectedCategory]. category isNil ifTrue: [category := cls preferredCategoryOf: method selector]. category isNil ifTrue: [category := 'uncategorized']. kludge := method. cls installMethod: method classified: category. self selectMethodNamed: method selector. self statusMessage: 'Accepted ', method fullDisplayString. ^true.! addSubclass | subclassName | subclassName := Prompter prompt: 'Enter a new class name:' caption: 'Add subclass'. (subclassName isNil or: [subclassName isEmpty]) ifTrue: [^self]. (PstParser isValidIdentifier: subclassName) ifFalse: [^MessageBox notify: subclassName printString, ' is not a valid class name.']. (self classLibrary hasClassNamed: subclassName) ifTrue: [^MessageBox notify: 'There is already a class named ', subclassName, '.']. PstClassDefiner new define: (self selectedClass definitionForNewSubclass: subclassName). self selectClassNamed: subclassName.! blankRichText ^self richTextFor: String new.! browseImplementors PstMethodListBrowser showImplementorsOf: self selectedMethod selector.! browseReferencesToClass PstMethodListBrowser showMethodsReferringTo: self selectedClass.! browseReferencesToClassVariable | cls varNames varName | cls := self selectedClass. varNames := cls visibleClassVariableNames. varNames isEmpty ifTrue: [^MessageBox notify: 'No class variables are visible from ', cls name, '.']. varName := ChoicePrompter choices: varNames caption: 'Select an class variable'. varName isNil ifTrue: [^self]. PstMethodListBrowser showMethodsReferringToSharedVariable: varName.! browseReferencesToInstanceVariable | cls instVarName | cls := self selectedClass. cls allInstVarNames isEmpty ifTrue: [^MessageBox notify: cls name, ' defines no instance variables.']. instVarName := ChoicePrompter choices: cls allInstVarNames caption: 'Select an instance variable'. instVarName isNil ifTrue: [^self]. PstMethodListBrowser showMethodsOf: cls referringToInstanceVariable: instVarName.! browseSenders PstMethodListBrowser showSendersOf: self selectedMethod selector.! canBrowseMetaclasses ^true.! categorize | category | (self selectedMethod isNil and: [self selectedCategory notNil]) ifTrue: [^self renameCategory]. category := PstSystem lastArgumentFor: #categorize. category := Prompter on: category prompt: 'Which category?' caption: 'Categorize'. (category isNil or: [category isEmpty]) ifTrue: [^self]. category := self filterCategory: category. category isEmpty ifTrue: [^self]. PstSystem lastArgumentFor: #categorize put: category. self classForMethods reclassify: self selectedMethod as: category.! changeClassPackage | package | package := PstPackage chooseSelecting: self selectedClass package. package isNil ifTrue: [^self]. self selectedClass package: package. self updateMethodTree.! changeMethodPackage | package | package := PstPackage chooseSelecting: self selectedMethod actualPackage. package isNil ifTrue: [^self]. self selectedMethod package: package. self updateMethodTree.! checkClassRefsForDelete: cls | methods stream | methods := PstClassLibrary current methodsReferencingClassNamed: cls name. methods isEmpty ifTrue: [ MessageBox notify: 'No methods referenced ', cls name, ', so deleting it will not cause problems.'. ^true]. stream := String new writeStream. stream print: methods size; nextPutAll: ' method'; nextPutAll: (methods size = 1 ifTrue: [''] ifFalse: ['s']); nextPutAll: ' referenced '; nextPutAll: cls name; nextPut: $.; cr; nextPutAll: 'Do you want to browse '; nextPutAll: (methods size = 1 ifTrue: ['that method'] ifFalse: ['those methods']); nextPutAll: ' now?'. ^(MessageBox confirm: stream contents) ifTrue: [ PstMethodListBrowser showMethodsReferencingClassNamed: cls name. true] ifFalse: [ (MessageBox confirm: 'Do you want to cancel the deletion of ', cls name, '?') not].! classForMethods "Answer the class that methods are to be taken from (or added to). This is just the selected class, or the selected class's metaclass, depending on the 'side' we are looking at." "This may answer nil, like #selectedClass." | class | class := self selectedClass. class isNil ifTrue: [^nil]. ^self side == #instance ifTrue: [class] ifFalse: [class qclass].! classLibrary ^PstClassLibrary current.! classSide sideList selectionByIndex: 2.! clearStatus statusModel value: ''.! completeSelector Transcript show: 'completing...'; cr.! createComponents super createComponents. classTree := self add: TreePresenter new name: 'classTree'. methodTree := self add: TreePresenter new name: 'methodTree'. sourceCode := self add: PstSourceCodePresenter new name: 'sourceCode'. modeList := self add: ListPresenter new name: 'modeList'. self canBrowseMetaclasses ifTrue: [ sideList := self add: ListPresenter new name: 'classSide'].! createSchematicWiring | statusItem | super createSchematicWiring. self when: #closeRequested: send: #onCloseRequested: to: self. self hookupToModel. modeList list: self modeListChoices. self canBrowseMetaclasses ifTrue: [ sideList list: self sideListChoices. sideList when: #selectionChanged send: #onSideChanged to: self. sideList when: #selectionChanging: send: #promptToSaveChanges: to: self]. self updateClassTree. modeList when: #selectionChanged send: #onModeChanged to: self. modeList when: #selectionChanging: send: #promptToSaveChanges: to: self. classTree when: #selectionChanged send: #onSelectedClassChanged to: self. classTree when: #selectionChanging: send: #promptToSaveChanges: to: self. methodTree when: #selectionChanged send: #onSelectedMethodChanged to: self. methodTree when: #selectionChanging: send: #promptToSaveChanges: to: self. methodTree when: #actionPerformed send: #onMethodDoubleClicked to: self. sourceCode when: #completeSelector send: #completeSelector to: self. statusModel := ValueHolder with: String new. statusItem := (self view viewNamed: 'status') addItem: StatusItem new. statusItem model: statusModel. statusItem getImageBlock: [:blah | nil]. "statusItem imageManager: nil." self updateFonts.! currentClassString "Always display the class definition even when looking at the metaclass." ^self richTextFor: self selectedClass definition.! currentCommentString ^self richTextFor: (self selectedClass comment isNil ifTrue: [String new] ifFalse: [self selectedClass comment]).! currentDisassemblyString ^self richTextFor: (self selectedMethod isNil ifTrue: ['[No method selected]'] ifFalse: [self selectedMethod disassembly]).! currentSourceString ^self selectedMethod isNil ifTrue: [self blankRichText] ifFalse: [self selectedMethod richTextSource].! delete | category | self selectedMethod isNil ifTrue: [^self deleteCategory]. (MessageBox confirm: 'Really delete #', self selectedMethod selector, '?') ifFalse: [^self]. category := self selectedMethod category. self selectedMethod package: nil. self classForMethods removeSelector: self selectedMethod selector. (methodTree model includes: category) ifTrue: [ methodTree selection: category; expand: category]. ! deleteCategory | category | category := self selectedCategory. category isNil ifTrue: [ (MessageBox confirm: 'Really delete all the methods in this class?') ifFalse: [^self]. ^self classForMethods removeAllCategories]. (MessageBox confirm: 'Really delete all the methods in category ', category printString, '?') ifFalse: [^self]. self classForMethods removeCategory: category.! deleteClass | cls | cls := self selectedClass. (MessageBox confirm: 'Really delete ', cls name, '?') ifFalse: [^self]. (self checkClassRefsForDelete: cls) ifFalse: [^self]. self classLibrary removeClass: cls ifFail: [:reason | ^MessageBox notify: cls name, ' cannot be removed because ', reason, '.'].! detachFromModel PstClassLibrary current removeEventsTriggeredFor: self.! dirty "^self textHasBeenChanged." ^sourceCode view isModified.! disableSourcePane sourceCode view isReadOnly: true.! enableSourcePane sourceCode view isReadOnly: false.! filterCategory: category ^category reject: [:each | each == $( or: [each == $) or: [each == $']]].! findClass | string classes class | string := Prompter on: (PstSystem lastArgumentFor: #findClass) prompt: 'Find which class?' caption: 'Find Class'. (string isNil or: [string isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #findClass put: string. classes := (self classLibrary classesMatching: string) asSortedCollection: [:left :right | left name <= right name]. classes isEmpty ifTrue: [ ^MessageBox notify: 'There is no class matching ', string printString, '.']. class := classes size = 1 ifTrue: [classes first] ifFalse: [ ChoicePrompter choices: classes caption: 'Which one did you mean?']. class isNil ifTrue: [^self]. (classTree model includes: class) ifTrue: [classTree selection: class].! hookupToModel | library | library := PstClassLibrary current. library when: #addedMethod:to: send: #onAddedMethod:to: to: self. library when: #removedMethod:from: send: #onRemovedMethod:from: to: self. library when: #reclassifiedMethod:of: send: #onReclassifiedMethod:of: to: self. library when: #changedShape: send: #onChangedShape: to: self. library when: #addedClass: send: #onAddedClass: to: self. library when: #removedClass: send: #onRemovedClass: to: self. library when: #changedSuperclassOf: send: #onChangedSuperclassOf: to: self. library when: #changedNameOf: send: #onChangedNameOf: to: self. library when: #recompiledBehavior: send: #onRecompiledBehavior: to: self.! instanceSide sideList selectionByIndex: 1.! mode ^self modeSymbols at: (self modeListChoices indexOf: modeList selectionOrNil).! modeListChoices ^#('Source' 'Class' 'Disassembly' 'Comment').! modeSymbols ^#(source class disassembly comment).! newMethod modeList selection: self modeListChoices first. sourceCode value: String new. sourceCode setFocus.! onAddedClass: qclass self updateClassTree.! onAddedMethod: method to: class class == self classForMethods ifTrue: [self updateMethodTree].! onChangedNameOf: cls classTree model refresh: cls.! onChangedShape: cls cls == self selectedClass ifTrue: [self updateSourcePane].! onChangedSuperclassOf: class self updateClassTree.! onCloseRequested: valueHolder self detachFromModel.! onMethodDoubleClicked self selectedMethod isNil ifFalse: [ self selectMethodNamed: self selectedMethod selector].! onModeChanged self updateSourcePane.! onReclassifiedMethod: method of: class class == self classForMethods ifTrue: [self updateMethodTree].! onRecompiledBehavior: behavior behavior == self classForMethods ifTrue: [self updateMethodTree].! onRemovedClass: qclass classTree model remove: qclass.! onRemovedMethod: method from: class class == self classForMethods ifTrue: [self updateMethodTree].! onSelectedClassChanged "Automatically select the 'class' pane." modeList selection = 'Comment' ifFalse: [ modeList selection: (self modeListChoices detect: [:each | each = 'Class'])]. self clearStatus. self updateSourcePane. self updateMethodTree.! onSelectedMethodChanged "Make sure the 'source' pane is selected." self clearStatus. kludge := self selectedMethod. self selectedMethod isNil ifFalse: [ modeList selection: (self modeListChoices detect: [:each | each = 'Source'])]. self updateSourcePane.! onSideChanged self clearStatus. self updateMethodTree.! promptToSaveChanges "Answer false if it's OK to change panes." | discard | self dirty ifFalse: [ ^false]. "why is this hack necessary?" discard := (MessageBox confirm: 'Discard changes?'). sourceCode view isModified: discard not. ^discard not! promptToSaveChanges: valueHolder valueHolder value: self promptToSaveChanges not. ^valueHolder value.! queryCommand: commandQuery | sym | super queryCommand: commandQuery. sym := commandQuery command. sym == #accept ifTrue: [commandQuery enabled: (self selectedClass notNil and: [#(source class comment) includes: self mode])]. (#(deleteMethod browseSenders browseImplementors changeMethodPackage) includes: sym) ifTrue: [commandQuery enabled: self selectedMethod notNil]. (sym == #quickCategorize or: [sym == #categorize]) ifTrue: [commandQuery enabled: (self selectedMethod notNil or: [self selectedCategory notNil])]. (#(addSubclass fileOut fileOutHierarchy deleteClass recompileClass recompileHierarchy browseReferencesToClass browseReferencesToInstanceVariable changeClassPackage) includes: sym) ifTrue: [commandQuery enabled: self selectedClass notNil].! quickCategorize | category categories | self selectedMethod isNil ifTrue: [ ^(MessageBox confirm: 'Recategorize all methods in category ', self selectedCategory printString, '?') ifTrue: [self quickCategorizeCategory] ifFalse: [self]]. category := self classForMethods preferredCategoryOf: self selectedMethod selector. categories := self class commonCategories. category isNil ifFalse: [ categories := (Array with: category), categories]. category := ChoicePrompter choices: categories caption: 'Categorize'. (category isNil or: [category isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #categorize put: category. self classForMethods reclassify: self selectedMethod as: category.! quickCategorizeCategory | classForMethods category | classForMethods := self classForMethods. (classForMethods methodsInCategory: self selectedCategory) copy do: [:method | category := classForMethods preferredCategoryOf: method selector. category isNil ifFalse: [ self classForMethods reclassify: method as: category]].! receiverForEvaluations ^self selectedClass isNil ifTrue: [PstBasicObject forNil] ifFalse: [self classForMethods].! recompileClass Cursor wait showWhile: [ self selectedClass safelyRecompile].! recompileHierarchy Cursor wait showWhile: [ self selectedClass safelyRecompileHierarchy].! renameCategory | category | category := Prompter on: self selectedCategory prompt: 'New name for category?' caption: 'Rename Category'. (category isNil or: [category isEmpty]) ifTrue: [^self]. category = self selectedCategory ifTrue: [^self]. self classForMethods renameCategory: self selectedCategory to: category.! richTextFor: string | converter | converter := RichText rtfConverter. converter font: PstSystem current defaultFont. converter text: string. ^converter richText.! selectClassNamed: className (self classLibrary hasClassNamed: className) ifTrue: [classTree selection: (self classLibrary classNamed: className)].! selectedCategory | selection tree category | selection := methodTree selectionOrNil. selection isNil ifTrue: [^nil]. tree := methodTree model. category := tree parentOf: selection. category isNil ifTrue: [ category := selection]. ^category = '(all)' ifTrue: [nil] ifFalse: [category].! selectedClass ^classTree selectionOrNil.! selectedMethod | sel | sel := methodTree selectionOrNil. sel isNil ifTrue: [^nil]. ^sel class == String "category?" ifTrue: [nil] ifFalse: [sel actualMethod].! selectMethodNamed: selector | tree | tree := methodTree model. tree do: [:each | (each class ~~ String and: [each isQuasi not and: [each selector = selector]]) ifTrue: [^methodTree selection: each]].! side "Answer whether we are looking at the #instance or #class side." | selection | selection := sideList selection. ^selection == self sideListChoices first ifTrue: [#instance] ifFalse: [#class].! sideListChoices ^#('Instance' 'Class').! sourceCodePart ^sourceCode! sourceString ^sourceCode view plainText.! statusMessage: string statusModel value: string.! system ^PstSystem current.! textHasBeenChanged "Answer whether the source text has been changed from the original." "This is used rather than #isModified because #isModified is not reliable." | mode text | mode := self mode. text := sourceCode view plainText. text isEmpty ifTrue: [^false]. "special case" mode == #source ifTrue: [ ^kludge isNil ifTrue: [text notEmpty] ifFalse: [kludge sourceCode ~= text]]. mode == #class ifTrue: [ ^self selectedClass isNil ifTrue: [text notEmpty] ifFalse: [self selectedClass definition ~= text]]. mode == #comment ifTrue: [ ^self selectedClass isNil ifTrue: [text notEmpty] ifFalse: [(self selectedClass comment isNil ifTrue: [String new] ifFalse: [self selectedClass comment]) ~= text]]. ^false.! updateClassTree | oldSelection | oldSelection := self selectedClass isNil ifTrue: [nil] ifFalse: [self selectedClass name]. classTree model: PstClassLibrary current classTree. PstClassLibrary current roots do: [:each | classTree expand: each]. self selectClassNamed: oldSelection.! updateFonts | b | b := [:presenter | presenter isNil ifFalse: [ presenter view font: self system defaultFont]]. b value: sourceCode; value: classTree; value: methodTree; value: modeList; value: sideList.! updateMethodTree | tree selector | selector := self selectedMethod isNil ifTrue: [nil] ifFalse: [self selectedMethod selector]. tree := self classForMethods isNil ifTrue: [TreeModel new] ifFalse: [self classForMethods methodTree]. methodTree model: tree. selector isNil ifFalse: [self selectMethodNamed: selector].! updateSourcePane | mode string | self selectedClass isNil ifTrue: [ self disableSourcePane. ^sourceCode value: String new]. mode := self mode. (#(source class comment) includes: mode) ifTrue: [self enableSourcePane] ifFalse: [self disableSourcePane]. mode == #source ifTrue: [string := self currentSourceString]. mode == #class ifTrue: [string := self currentClassString]. mode == #disassembly ifTrue: [string := self currentDisassemblyString]. mode == #comment ifTrue: [string := self currentCommentString]. sourceCode setValue: string. sourceCode view refreshContents.! ! !PstClassBrowser categoriesFor: #accept!actions!public! ! !PstClassBrowser categoriesFor: #acceptClass!actions!public! ! !PstClassBrowser categoriesFor: #acceptComment!actions!public! ! !PstClassBrowser categoriesFor: #acceptSource!actions!public! ! !PstClassBrowser categoriesFor: #addSubclass!actions!public! ! !PstClassBrowser categoriesFor: #blankRichText!public!utility! ! !PstClassBrowser categoriesFor: #browseImplementors!actions!public! ! !PstClassBrowser categoriesFor: #browseReferencesToClass!actions!public! ! !PstClassBrowser categoriesFor: #browseReferencesToClassVariable!actions!public! ! !PstClassBrowser categoriesFor: #browseReferencesToInstanceVariable!actions!public! ! !PstClassBrowser categoriesFor: #browseSenders!actions!public! ! !PstClassBrowser categoriesFor: #canBrowseMetaclasses!predicates!public! ! !PstClassBrowser categoriesFor: #categorize!actions!public! ! !PstClassBrowser categoriesFor: #changeClassPackage!actions!public! ! !PstClassBrowser categoriesFor: #changeMethodPackage!actions!public! ! !PstClassBrowser categoriesFor: #checkClassRefsForDelete:!actions!public! ! !PstClassBrowser categoriesFor: #classForMethods!accessing!public! ! !PstClassBrowser categoriesFor: #classLibrary!accessing!public! ! !PstClassBrowser categoriesFor: #classSide!actions!public! ! !PstClassBrowser categoriesFor: #clearStatus!public!utility! ! !PstClassBrowser categoriesFor: #completeSelector!public!utility! ! !PstClassBrowser categoriesFor: #createComponents!initialization!public! ! !PstClassBrowser categoriesFor: #createSchematicWiring!initialization!public! ! !PstClassBrowser categoriesFor: #currentClassString!public!updating! ! !PstClassBrowser categoriesFor: #currentCommentString!public!updating! ! !PstClassBrowser categoriesFor: #currentDisassemblyString!public!updating! ! !PstClassBrowser categoriesFor: #currentSourceString!public!updating! ! !PstClassBrowser categoriesFor: #delete!actions!public! ! !PstClassBrowser categoriesFor: #deleteCategory!actions!public! ! !PstClassBrowser categoriesFor: #deleteClass!actions!public! ! !PstClassBrowser categoriesFor: #detachFromModel!initialization!public! ! !PstClassBrowser categoriesFor: #dirty!accessing!public! ! !PstClassBrowser categoriesFor: #disableSourcePane!public!updating! ! !PstClassBrowser categoriesFor: #enableSourcePane!public!updating! ! !PstClassBrowser categoriesFor: #filterCategory:!public!utility! ! !PstClassBrowser categoriesFor: #findClass!actions!public! ! !PstClassBrowser categoriesFor: #hookupToModel!initialization!public! ! !PstClassBrowser categoriesFor: #instanceSide!actions!public! ! !PstClassBrowser categoriesFor: #mode!accessing!public! ! !PstClassBrowser categoriesFor: #modeListChoices!accessing!public! ! !PstClassBrowser categoriesFor: #modeSymbols!accessing!public! ! !PstClassBrowser categoriesFor: #newMethod!actions!public! ! !PstClassBrowser categoriesFor: #onAddedClass:!event handling!public! ! !PstClassBrowser categoriesFor: #onAddedMethod:to:!event handling!public! ! !PstClassBrowser categoriesFor: #onChangedNameOf:!event handling!public! ! !PstClassBrowser categoriesFor: #onChangedShape:!event handling!public! ! !PstClassBrowser categoriesFor: #onChangedSuperclassOf:!event handling!public! ! !PstClassBrowser categoriesFor: #onCloseRequested:!event handling!public! ! !PstClassBrowser categoriesFor: #onMethodDoubleClicked!event handling!public! ! !PstClassBrowser categoriesFor: #onModeChanged!event handling!public! ! !PstClassBrowser categoriesFor: #onReclassifiedMethod:of:!event handling!public! ! !PstClassBrowser categoriesFor: #onRecompiledBehavior:!event handling!public! ! !PstClassBrowser categoriesFor: #onRemovedClass:!event handling!public! ! !PstClassBrowser categoriesFor: #onRemovedMethod:from:!event handling!public! ! !PstClassBrowser categoriesFor: #onSelectedClassChanged!event handling!public! ! !PstClassBrowser categoriesFor: #onSelectedMethodChanged!event handling!public! ! !PstClassBrowser categoriesFor: #onSideChanged!event handling!public! ! !PstClassBrowser categoriesFor: #promptToSaveChanges!event handling!public! ! !PstClassBrowser categoriesFor: #promptToSaveChanges:!event handling!public! ! !PstClassBrowser categoriesFor: #queryCommand:!actions!public!updating! ! !PstClassBrowser categoriesFor: #quickCategorize!actions!public! ! !PstClassBrowser categoriesFor: #quickCategorizeCategory!actions!public! ! !PstClassBrowser categoriesFor: #receiverForEvaluations!evaluating!public! ! !PstClassBrowser categoriesFor: #recompileClass!actions!public! ! !PstClassBrowser categoriesFor: #recompileHierarchy!actions!public! ! !PstClassBrowser categoriesFor: #renameCategory!actions!public! ! !PstClassBrowser categoriesFor: #richTextFor:!public!utility! ! !PstClassBrowser categoriesFor: #selectClassNamed:!public!utility! ! !PstClassBrowser categoriesFor: #selectedCategory!accessing!public! ! !PstClassBrowser categoriesFor: #selectedClass!accessing!public! ! !PstClassBrowser categoriesFor: #selectedMethod!accessing!public! ! !PstClassBrowser categoriesFor: #selectMethodNamed:!public!utility! ! !PstClassBrowser categoriesFor: #side!accessing!public! ! !PstClassBrowser categoriesFor: #sideListChoices!accessing!public! ! !PstClassBrowser categoriesFor: #sourceCodePart!public!utility! ! !PstClassBrowser categoriesFor: #sourceString!accessing!public! ! !PstClassBrowser categoriesFor: #statusMessage:!public!utility! ! !PstClassBrowser categoriesFor: #system!accessing!public! ! !PstClassBrowser categoriesFor: #textHasBeenChanged!public!utility! ! !PstClassBrowser categoriesFor: #updateClassTree!public!updating! ! !PstClassBrowser categoriesFor: #updateFonts!public!updating! ! !PstClassBrowser categoriesFor: #updateMethodTree!public!updating! ! !PstClassBrowser categoriesFor: #updateSourcePane!public!updating! ! !PstClassBrowser class methodsFor! browse: method | shell | shell := self show. shell selectClassNamed: method ownerClass name. shell selectMethodNamed: method selector.! browseClass: class | shell | shell := self show. class isMeta ifTrue: [ shell classSide. shell selectClassNamed: class uniqueInstance name] ifFalse: [ shell instanceSide. shell selectClassNamed: class name]. ^shell.! browseMethod: method | shell | shell := self browseClass: method ownerClass. shell selectMethodNamed: method selector. ^shell.! commonCategories ^#('accessing' 'comparing' 'converting' 'initialization' 'instance creation' 'predicates' 'printing' 'private' 'utility').! defaultView ^'Default view'.! ! !PstClassBrowser class categoriesFor: #browse:!public!utility! ! !PstClassBrowser class categoriesFor: #browseClass:!public!utility! ! !PstClassBrowser class categoriesFor: #browseMethod:!public!utility! ! !PstClassBrowser class categoriesFor: #commonCategories!accessing!public! ! !PstClassBrowser class categoriesFor: #defaultView!defaults!public! ! PstConstantsBrowser comment: ''! PstConstantsBrowser guid: (GUID fromString: '{812CFB02-B11E-4A02-8CA8-A2BEB862E61F}')! !PstConstantsBrowser categoriesForClass!No category! ! !PstConstantsBrowser methodsFor! accept | object | object := PstSmalltalkParser parseSimpleLiteral: self sourceString. object isNil ifTrue: [ ^MessageBox notify: 'Constants can only have simple literal values.']. self selectedConstant value: object.! addCategory | string | string := Prompter prompt: 'Name for new category?' caption: 'Add Category'. (string isNil or: [string isEmpty]) ifTrue: [^self]. (self model hasCategoryNamed: string) ifTrue: [^MessageBox notify: 'There is already a category with that name.']. self model addCategoryNamed: string. self selectCategoryNamed: string.! browseReferencesToConstant PstMethodListBrowser showMethodsReferringToConstant: self selectedConstant.! categorizeConstant | category constant | constant := self selectedConstant. category := ChoicePrompter on: constant category choices: self model categoryNames caption: 'Select a Category'. category isNil ifTrue: [^self]. self model reclassify: constant name as: category. self selectConstant: constant.! changePackage | package constant | constant := self selectedConstant. package := PstPackage chooseSelecting: constant package. package isNil ifTrue: [^self]. constant package: package.! checkConstantRefs: constant for: reason | methods stream | methods := PstClassLibrary current methodsReferringToConstant: constant. methods isEmpty ifTrue: [ MessageBox notify: 'No methods referenced ', constant displayString, ', so ', reason, ' it will not cause problems.'. ^true]. stream := String new writeStream. stream print: methods size; nextPutAll: ' method'; nextPutAll: (methods size = 1 ifTrue: [''] ifFalse: ['s']); nextPutAll: ' referenced '; nextPutAll: constant displayString; nextPut: $.; cr; nextPutAll: 'Do you want to browse '; nextPutAll: (methods size = 1 ifTrue: ['that method'] ifFalse: ['those methods']); nextPutAll: ' now?'. ^(MessageBox confirm: stream contents) ifTrue: [ PstMethodListBrowser showMethodsReferringToConstant: constant. true] ifFalse: [ (MessageBox confirm: 'Do you want to cancel the ', reason, ' of constant ', constant displayString, '?') not].! createComponents super createComponents. categoryList := self add: ListPresenter new name: 'categories'. constantsList := self add: ListPresenter new name: 'constants'. sourceCode := self add: PstSourceCodePresenter new name: 'source'.! createSchematicWiring | statusItem | super createSchematicWiring. self when: #closeRequested: send: #onCloseRequested: to: self. categoryList when: #selectionChanged send: #updateConstantsList to: self. constantsList when: #selectionChanged send: #onSelectedConstantChanged to: self. self hookupToModel. statusModel := ValueHolder with: String new. statusItem := (self view viewNamed: 'status') addItem: StatusItem new. statusItem model: statusModel. statusItem getImageBlock: [:blah | nil]. sourceCode view font: PstSystem current defaultFont. self updateCategories.! deleteCategory | category constants | category := self selectedCategory. constants := (self model categoryNamed: category) copy. constants isEmpty ifFalse: [ (MessageBox confirm: 'Really delete the ', (constants size = 1 ifTrue: ['constant'] ifFalse: [constants size printString, ' constants']), ' in this category?') ifFalse: [^self]]. constants do: [:constant | (self checkConstantRefs: constant for: 'deleting') ifFalse: [^self]. self model removeConstantNamed: constant name]. (self model categoryNamed: category) isEmpty ifTrue: [self model removeCategory: category].! deleteConstant | constant | constant := self selectedConstant. (MessageBox confirm: 'Really delete ', constant displayString, '?') ifFalse: [^self]. (self checkConstantRefs: constant for: 'deleting') ifFalse: [^self]. self model removeConstantNamed: constant name.! detachFromModel self model removeEventsTriggeredFor: self.! findConstant | name constant | name := Prompter prompt: 'Name of constant to find?' caption: 'Find Constant'. (name isNil or: [name isEmpty]) ifTrue: [^self]. name := self fixConstantName: name. constant := self model findConstant: name, '*'. constant isNil ifTrue: [MessageBox notify: 'There is no constant with that name.'] ifFalse: [self selectConstant: constant].! fixConstantName: string ^string reject: [:each | each == $#].! hookupToModel self model when: #organizationChanged send: #updateCategories to: self. self model when: #categoryChanged: send: #onCategoryChanged: to: self. self model when: #constantChanged: send: #onConstantChanged: to: self.! newConstant | string | string := Prompter prompt: 'Name for new constant?' caption: 'New Constant'. (string isNil or: [string isEmpty]) ifTrue: [^self]. string := self fixConstantName: string. (PstConstant isValidConstantName: string) ifFalse: [^MessageBox notify: string printString, ' is not a valid name for a constant.']. (self model hasConstantNamed: string) ifTrue: [^MessageBox notify: 'There is already a constant with that name.']. self model define: string as: PstBasicObject forNil classified: self selectedCategory. self selectConstant: (self model constantNamed: string).! onCategoryChanged: categoryName (self selectedCategory notNil and: [self selectedCategory = categoryName]) ifTrue: [self updateConstantsList].! onCloseRequested: valueHolder self detachFromModel.! onConstantChanged: constant constant == self selectedConstant ifTrue: [ self updateSourceCode. self updateConstantPackage].! onSelectedConstantChanged self updateSourceCode. self updateConstantPackage.! queryCommand: commandQuery super queryCommand: commandQuery. (#(newConstant deleteCategory renameCategory) includes: commandQuery command) ifTrue: [commandQuery enabled: self selectedCategory notNil]. (#(accept deleteConstant browseReferencesToConstant categorizeConstant changePackage) includes: commandQuery command) ifTrue: [commandQuery enabled: self selectedConstant notNil].! renameCategory | category newName | category := self selectedCategory. newName := Prompter on: category prompt: 'New name for category?' caption: 'Rename Category'. (newName isNil or: [newName isEmpty]) ifTrue: [^self]. (self model hasCategoryNamed: newName) ifTrue: [^MessageBox notify: 'There is already a category named ', newName printString, '.']. self model renameCategory: category to: newName. self selectCategoryNamed: newName.! selectCategoryNamed: categoryName categoryList selection: (categoryList list detect: [:each | each = categoryName] ifNone: [^self]). ! selectConstant: constant self selectCategoryNamed: constant category. constantsList selection: constant.! selectedCategory ^categoryList selectionOrNil.! selectedConstant ^constantsList selectionOrNil.! sourceCodePart ^sourceCode! sourceString ^sourceCode view plainText.! updateCategories categoryList list: self model categoryNames.! updateConstantPackage | constant | constant := self selectedConstant. constant isNil ifTrue: [^statusModel value: '']. statusModel value: (constant package isUncommitted ifTrue: [constant displayString, ' in no package'] ifFalse: [constant displayString, ' in package ', constant package displayString]). ! updateConstantsList constantsList list: (self selectedCategory isNil ifTrue: [#()] ifFalse: [self model categoryNamed: self selectedCategory]) copy "defeat Dolphin 'optimization'".! updateSourceCode | string | string := self selectedConstant isNil ifTrue: [String new] ifFalse: [self selectedConstant value displayString]. sourceCode value: string.! ! !PstConstantsBrowser categoriesFor: #accept!actions!public! ! !PstConstantsBrowser categoriesFor: #addCategory!actions!public! ! !PstConstantsBrowser categoriesFor: #browseReferencesToConstant!actions!public! ! !PstConstantsBrowser categoriesFor: #categorizeConstant!actions!public! ! !PstConstantsBrowser categoriesFor: #changePackage!actions!public! ! !PstConstantsBrowser categoriesFor: #checkConstantRefs:for:!public!utility! ! !PstConstantsBrowser categoriesFor: #createComponents!initialization!public! ! !PstConstantsBrowser categoriesFor: #createSchematicWiring!initialization!public! ! !PstConstantsBrowser categoriesFor: #deleteCategory!actions!public! ! !PstConstantsBrowser categoriesFor: #deleteConstant!actions!public! ! !PstConstantsBrowser categoriesFor: #detachFromModel!initialization!public! ! !PstConstantsBrowser categoriesFor: #findConstant!actions!public! ! !PstConstantsBrowser categoriesFor: #fixConstantName:!public!utility! ! !PstConstantsBrowser categoriesFor: #hookupToModel!initialization!public! ! !PstConstantsBrowser categoriesFor: #newConstant!actions!public! ! !PstConstantsBrowser categoriesFor: #onCategoryChanged:!event handling!public! ! !PstConstantsBrowser categoriesFor: #onCloseRequested:!event handling!public! ! !PstConstantsBrowser categoriesFor: #onConstantChanged:!event handling!public! ! !PstConstantsBrowser categoriesFor: #onSelectedConstantChanged!event handling!public! ! !PstConstantsBrowser categoriesFor: #queryCommand:!actions!public! ! !PstConstantsBrowser categoriesFor: #renameCategory!actions!public! ! !PstConstantsBrowser categoriesFor: #selectCategoryNamed:!public!utility! ! !PstConstantsBrowser categoriesFor: #selectConstant:!public!utility! ! !PstConstantsBrowser categoriesFor: #selectedCategory!accessing!public! ! !PstConstantsBrowser categoriesFor: #selectedConstant!accessing!public! ! !PstConstantsBrowser categoriesFor: #sourceCodePart!actions!public! ! !PstConstantsBrowser categoriesFor: #sourceString!accessing!public! ! !PstConstantsBrowser categoriesFor: #updateCategories!public!updating! ! !PstConstantsBrowser categoriesFor: #updateConstantPackage!public!utility! ! !PstConstantsBrowser categoriesFor: #updateConstantsList!public!updating! ! !PstConstantsBrowser categoriesFor: #updateSourceCode!public!updating! ! !PstConstantsBrowser class methodsFor! browse: constant | shell | shell := self show. shell selectConstant: constant. ^shell.! defaultModel ^PstConstantsLibrary current.! defaultView ^'Default view'.! ! !PstConstantsBrowser class categoriesFor: #browse:!public!utility! ! !PstConstantsBrowser class categoriesFor: #defaultModel!defaults!public! ! !PstConstantsBrowser class categoriesFor: #defaultView!defaults!public! ! PstDebugger comment: ''! PstDebugger guid: (GUID fromString: '{72DABC87-8ECC-47CC-B896-E6E21F728E1C}')! !PstDebugger categoriesForClass!No category! ! !PstDebugger methodsFor! checkIfFinished interpreter hasMoreInstructions ifFalse: [ (MessageBox confirm: 'Process finished - close debugger?') ifTrue: [self exit]].! contexts ^contextList list.! createComponents super createComponents. contextList := self add: ListPresenter new name: 'contextList'. localFieldList := self add: ListPresenter new name: 'localFieldList'. localFieldSource := self add: PstSourceCodePresenter new name: 'localFieldSource'. sourceCode := self add: PstSourceCodePresenter new name: 'sourceCode'.! createSchematicWiring super createSchematicWiring. contextList when: #selectionChanged send: #onSelectedContextChanged to: self. localFieldList when: #selectionChanged send: #onSelectedFieldChanged to: self. localFieldList when: #actionPerformed send: #onInspectField to: self. interpreter := model. self updateContexts.! currentDisassemblySourceRange | context ip start stop | (context := self selectedContext) isNil ifTrue: [^nil]. ip := context instructionPtr. ip isNil ifTrue: [^nil]. ^(ip between: 1 and: disassemblyMap size) ifTrue: [disassemblyMap at: ip] ifFalse: [nil].! currentMethodSourceRange | context instruction | (context := self selectedContext) isNil ifTrue: [^nil]. context instructionPtr isNil ifTrue: [^nil]. context instructionPtr > context method instructions size ifTrue: [^nil]. instruction := context method instructions at: context instructionPtr. ^instruction sourcePosition.! dropToSelectedContext | context count | self selectedContext isNil ifTrue: [^self]. interpreter dropToFrame: self selectedContext. self updateContexts. self selectedContextIndex: self contexts size - interpreter callStack size + 1.! fieldValue | context index | (context := self selectedContext) isNil ifTrue: [^self]. index := self selectedFieldIndex. index < 1 ifTrue: [^self]. ^interpreter dataStackAt: (context localVarBase + index -1) ! fieldValue: text localFieldSource setValue: text. localFieldSource view refreshContents.! getLocalSourceCode: index | object string | object := interpreter dataStackAt: self selectedContext localVarBase + index - 1. string := PstSystem current qcompilerClass evaluate: 'self printString' for: object notifying: self localSourceCodePart. string isNil ifTrue: [^'[error during printing]']. ^string qclass name = 'String' ifTrue: [string convertToString] ifFalse: ['[did not print as a string]'].! highlightSourceRange | interval | interval := self sourceMode == #source ifTrue: [self currentMethodSourceRange] ifFalse: [self currentDisassemblySourceRange]. (interval isNil or: [interval isEmpty]) ifTrue: [^self]. sourceCode view selectionRange: interval.! instructionPtrForCursorPosition: position ^3.! interpreter: newInterpreter interpreter := newInterpreter. interpreter debugger: self. self updateContexts.! localFieldNames | method stream context | stream := Array new writeStream. (context := self selectedContext) isNil ifTrue: [^stream contents]. method := context method. 1 to: method argumentCount do: [:n | stream nextPut: 'arg_', n printString]. 1 to: method temporaryCount do: [:n | stream nextPut: 'temp_', n printString]. 1 to: context dataStackPtr - context localVarBase - method localVariableCount do: [:n | stream nextPut: 'stack_', n printString]. ^stream contents.! localFieldValue | context index | (context := self selectedContext) isNil ifTrue: [^'']. index := self selectedFieldIndex. index < 1 ifTrue: [^'']. ^self stringForValue: (interpreter dataStackAt: (context localVarBase + index -1))! onInspectField PstInspector showOn: self fieldValue.! onSelectedContextChanged self updateSourceCode. self updateLocalFields.! onSelectedFieldChanged self updateLocalFieldValue. ! receiverForMethods ^self selectedContext isNil ifTrue: [PstBasicObject forNil] ifFalse: [self selectedContext receiver].! selectContextIndex: index contextList selectionByIndex: index.! selectedContext ^contextList selectionOrNil.! selectedContextIndex ^contextList selectionByIndex.! selectedField ^localFieldList selectionOrNil.! selectedFieldIndex ^localFieldList selectionByIndex.! selectedMethod ^self selectedContext isNil ifTrue: [nil] ifFalse: [self selectedContext method].! singleStep | context destSP destIP | self selectedContext isNil ifTrue: [^self]. destSP := self contexts size - self selectedContextIndex. destIP := self selectedContext instructionPtr. "Restore the top stack frame for interpretation." interpreter restoreCallStackFrame. interpreter interpretWhile: [ (interpreter callStack size > destSP or: [interpreter callStack size == destSP and: [interpreter instructionPtr = destIP]]) and: [interpreter hasMoreInstructions]]. self sourceMode == #source ifTrue: [self skipBoringInstructions]. interpreter saveCallStackFrame. self updateContexts. self selectContextIndex: self contexts size - interpreter callStack size + 1. self checkIfFinished. ! skipBoringInstructions interpreter interpretWhile: [ interpreter hasMoreInstructions and: [interpreter peekInstruction hasVisibleEffect not]].! sourceCode: text sourceCode setValue: text. sourceCode view refreshContents.! sourceCodePart ^sourceCode! sourceMode ^#source.! stepInto | context count | self selectedContext isNil ifTrue: [^self]. "Restore the top stack frame for interpretation." interpreter restoreCallStackFrame. count := 0. interpreter interpretWhile: [ interpreter hasMoreInstructions and: [(count := count + 1) <= 1]]. self sourceMode == #source ifTrue: [self skipBoringInstructions]. interpreter saveCallStackFrame. self updateContexts. self selectContextIndex: self contexts size - interpreter callStack size + 1. self checkIfFinished.! stringForValue: value | string | string := localFieldSource evaluate: 'self printString' for: value. string isNil ifTrue: [^'[error during printing]']. ^string qclass name = 'String' ifTrue: [string convertToString] ifFalse: ['[did not print as a string]'].! updateContexts contextList list: interpreter callStack reverse.! updateDisassemblySourceCode | string assoc | self selectedMethod isNil ifTrue: [ string := ''. disassemblyMap := nil] ifFalse: [ assoc := self selectedMethod disassemblyWithMap. string := assoc key. disassemblyMap := assoc value]. self sourceCode: string.! updateLocalFields localFieldList list: self localFieldNames. self updateLocalFieldValue. ! updateLocalFieldValue self fieldValue: self localFieldValue.! updateMethodSourceCode | string | string := self selectedMethod isNil ifTrue: [''] ifFalse: [self selectedMethod richTextSource]. self sourceCode: string.! updateSourceCode self sourceMode == #source ifTrue: [self updateMethodSourceCode] ifFalse: [self updateDisassemblySourceCode]. self highlightSourceRange.! ! !PstDebugger categoriesFor: #checkIfFinished!actions!public! ! !PstDebugger categoriesFor: #contexts!accessing!public! ! !PstDebugger categoriesFor: #createComponents!initialization!public! ! !PstDebugger categoriesFor: #createSchematicWiring!initialization!public! ! !PstDebugger categoriesFor: #currentDisassemblySourceRange!public!utility! ! !PstDebugger categoriesFor: #currentMethodSourceRange!public!utility! ! !PstDebugger categoriesFor: #dropToSelectedContext!actions!public! ! !PstDebugger categoriesFor: #fieldValue!public!updating! ! !PstDebugger categoriesFor: #fieldValue:!accessing!public! ! !PstDebugger categoriesFor: #getLocalSourceCode:!public!updating! ! !PstDebugger categoriesFor: #highlightSourceRange!public!utility! ! !PstDebugger categoriesFor: #instructionPtrForCursorPosition:!accessing!public! ! !PstDebugger categoriesFor: #interpreter:!initialization!public! ! !PstDebugger categoriesFor: #localFieldNames!public!updating! ! !PstDebugger categoriesFor: #localFieldValue!public!updating! ! !PstDebugger categoriesFor: #onInspectField!event handling!public! ! !PstDebugger categoriesFor: #onSelectedContextChanged!event handling!public! ! !PstDebugger categoriesFor: #onSelectedFieldChanged!event handling!public! ! !PstDebugger categoriesFor: #receiverForMethods!accessing!public! ! !PstDebugger categoriesFor: #selectContextIndex:!actions!public! ! !PstDebugger categoriesFor: #selectedContext!accessing!public! ! !PstDebugger categoriesFor: #selectedContextIndex!accessing!public! ! !PstDebugger categoriesFor: #selectedField!accessing!public! ! !PstDebugger categoriesFor: #selectedFieldIndex!accessing!public! ! !PstDebugger categoriesFor: #selectedMethod!accessing!public! ! !PstDebugger categoriesFor: #singleStep!actions!public! ! !PstDebugger categoriesFor: #skipBoringInstructions!public!utility! ! !PstDebugger categoriesFor: #sourceCode:!accessing!public! ! !PstDebugger categoriesFor: #sourceCodePart!public!updating! ! !PstDebugger categoriesFor: #sourceMode!accessing!public! ! !PstDebugger categoriesFor: #stepInto!actions!public! ! !PstDebugger categoriesFor: #stringForValue:!public!utility! ! !PstDebugger categoriesFor: #updateContexts!public!updating! ! !PstDebugger categoriesFor: #updateDisassemblySourceCode!public!updating! ! !PstDebugger categoriesFor: #updateLocalFields!public!updating! ! !PstDebugger categoriesFor: #updateLocalFieldValue!public!updating! ! !PstDebugger categoriesFor: #updateMethodSourceCode!public!updating! ! !PstDebugger categoriesFor: #updateSourceCode!public!updating! ! !PstDebugger class methodsFor! debugFor: interpreter ^self showOn: interpreter.! defaultModel ^self shouldNotImplement.! defaultView ^'Default view'.! ! !PstDebugger class categoriesFor: #debugFor:!public!utility! ! !PstDebugger class categoriesFor: #defaultModel!*-should not implement!defaults!public! ! !PstDebugger class categoriesFor: #defaultView!defaults!public! ! PstInspector comment: ''! PstInspector guid: (GUID fromString: '{9965B347-330E-4440-98E2-13AA7966345F}')! !PstInspector categoriesForClass!No category! ! !PstInspector methodsFor! accept self halt.! createComponents super createComponents. historyStack := OrderedCollection new. fieldList := self add: ListPresenter new name: 'fieldList'. sourceCode := self add: PstSourceCodePresenter new name: 'sourceCode'.! createSchematicWiring fieldList list: self fieldNames. fieldList when: #selectionChanged send: #onSelectedFieldChanged to: self. fieldList when: #actionPerformed send: #nestedInspect to: self. sourceCode view font: PstSystem current defaultFont.! curtail historyStack := OrderedCollection new.! fieldNames | stream | stream := Array new writeStream. stream nextPut: 'self'; nextPut: 'self class'; nextPutAll: self model slotNames; nextPutAll: ((1 to: self model indexedSlotCount) collect: [:each | each printString]). ^stream contents.! fieldValue | field value | field := self selectedField. field isNil ifTrue: [^nil]. field = 'self' ifTrue: [^self model]. field = 'self class' ifTrue: [^self model qclass]. field first isDigit ifTrue: [^self indexedField: field]. ^self namedField: field.! fieldValueString | value | value := self fieldValue. ^value isNil ifTrue: [''] ifFalse: [self stringForValue: value]. ! indexedField: indexString | index | index := Integer fromString: indexString. ^(self model hasIndexedSlotAt: index) ifTrue: [self model indexedSlotAt: index] ifFalse: [nil].! namedField: indexString | index | index := self model slotNames indexOf: indexString. ^(self model hasNamedSlotAt: index) ifTrue: [self model namedSlotAt: index] ifFalse: [nil].! nestedInspect self push. self model: self fieldValue. self updateAll.! onSelectedFieldChanged self updateSourceCode.! pop self model: historyStack removeLast.! popInspect self pop. self updateAll.! push historyStack addLast: self model.! queryCommand: commandQuery super queryCommand: commandQuery. (#(spawnInspector nestedInspect) identityIncludes: commandQuery command) ifTrue: [ ^commandQuery enabled: self selectedField notNil]. (#(popInspect toTopLevel curtail) identityIncludes: commandQuery command) ifTrue: [^commandQuery enabled: historyStack notEmpty].! receiverForEvaluations ^self model.! selectedField ^fieldList selectionOrNil.! sourceCodePart ^sourceCode! spawnInspector self class showOn: self fieldValue.! stringForValue: value | string | string := sourceCode evaluate: 'self printString' for: value. string isNil ifTrue: [^'[error during printing]']. ^string qclass name = 'String' ifTrue: [string convertToString] ifFalse: ['[did not print as a string]'].! toTopLevel [historyStack isEmpty] whileFalse: [self pop]. self updateAll.! updateAll self updateCaption; updateFieldList; updateSourceCode.! updateCaption self caption: 'Inspecting: ', self model displayString.! updateFieldList fieldList list: self fieldNames. ! updateSourceCode sourceCode value: self fieldValueString.! ! !PstInspector categoriesFor: #accept!evaluating!public! ! !PstInspector categoriesFor: #createComponents!initialization!public! ! !PstInspector categoriesFor: #createSchematicWiring!initialization!public! ! !PstInspector categoriesFor: #curtail!actions!public! ! !PstInspector categoriesFor: #fieldNames!accessing!public! ! !PstInspector categoriesFor: #fieldValue!accessing!public! ! !PstInspector categoriesFor: #fieldValueString!accessing!public! ! !PstInspector categoriesFor: #indexedField:!accessing!public! ! !PstInspector categoriesFor: #namedField:!accessing!public! ! !PstInspector categoriesFor: #nestedInspect!actions!public! ! !PstInspector categoriesFor: #onSelectedFieldChanged!public!updating! ! !PstInspector categoriesFor: #pop!actions!public! ! !PstInspector categoriesFor: #popInspect!actions!public! ! !PstInspector categoriesFor: #push!actions!public! ! !PstInspector categoriesFor: #queryCommand:!actions!public! ! !PstInspector categoriesFor: #receiverForEvaluations!evaluating!public! ! !PstInspector categoriesFor: #selectedField!accessing!public! ! !PstInspector categoriesFor: #sourceCodePart!actions!public! ! !PstInspector categoriesFor: #spawnInspector!actions!public! ! !PstInspector categoriesFor: #stringForValue:!accessing!public! ! !PstInspector categoriesFor: #toTopLevel!actions!public! ! !PstInspector categoriesFor: #updateAll!public!updating! ! !PstInspector categoriesFor: #updateCaption!public!updating! ! !PstInspector categoriesFor: #updateFieldList!public!updating! ! !PstInspector categoriesFor: #updateSourceCode!public!updating! ! !PstInspector class methodsFor! defaultModel ^PstBasicObject forNil.! defaultView ^'Default view'.! ! !PstInspector class categoriesFor: #defaultModel!defaults!public! ! !PstInspector class categoriesFor: #defaultView!defaults!public! ! PstLauncher comment: ''! PstLauncher guid: (GUID fromString: '{1C785371-AEEB-404D-8AA6-2907AD6693E8}')! !PstLauncher categoriesForClass!No category! ! !PstLauncher methodsFor! chooseFont self system chooseFont.! clearGlobals (MessageBox confirm: 'Really clear all shared variables?') ifFalse: [^self]. self system globals clearAllGlobals.! createSchematicWiring super createSchematicWiring. self when: #closeRequested: send: #onCloseRequested: to: self.! exit super exit. PstCrossPlatformInterface closeAllWindows.! exitSmalltalk self exit.! filenameFromUserUsing: fileDialogClass reason: reason | filename | filename := PstSystem lastArgumentFor: reason. filename := (fileDialogClass on: filename asValue) showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^nil]. PstSystem lastArgumentFor: reason put: filename. ^filename.! findImplementors | string | string := Prompter on: (PstSystem lastArgumentFor: #implementors) prompt: 'Implementors of which selector:' caption: 'Find Implementors'. (string isNil or: [string isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #implementors put: string. PstMethodListBrowser showImplementorsOf: string.! findMethodsContainingString | string | string := Prompter on: (PstSystem lastArgumentFor: #methodsContainingString) prompt: 'Enter text to search for:' caption: 'Find Methods Containing String'. (string isNil or: [string isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #methodsContainingString put: string. PstMethodListBrowser showMethodsContainingString: string.! findMethodsReferringTo | string value | string := Prompter on: (PstSystem lastArgumentFor: #methodsReferringTo) prompt: 'Enter a value to search for:' caption: 'Find Methods Referring To'. (string isNil or: [string isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #methodsReferringTo put: string. value := PstSystem current qcompilerClass parserClass parseSimpleLiteral: string. value isNil ifTrue: [^MessageBox notify: 'That is not a valid literal value.']. PstMethodListBrowser showMethodsReferringTo: value.! findSenders | string | string := Prompter on: (PstSystem lastArgumentFor: #senders) prompt: 'Senders of which selector:' caption: 'Find Senders'. (string isNil or: [string isEmpty]) ifTrue: [^self]. PstSystem lastArgumentFor: #senders put: string. PstMethodListBrowser showSendersOf: string.! generateCode | filename | (filename := PstSystem lastArgumentFor: #generatedCode) isEmpty ifTrue: [^self generateCodeAs]. self generateCode: filename.! generateCode: filename | stream optimized | PstSystem current checkIfCanGenerateCode: [:message | ^MessageBox notify: 'Cannot generate code because ', message]. PstSystem lastArgumentFor: #generatedCode put: filename. optimized := PstSystem current booleanProperty: 'optimization' ifAbsent: [false]. filename isNil ifTrue: [^self]. stream := FileStream write: filename text: false. [Cursor wait showWhile: [ PstSystem current codeGeneratorClass generateCodeForSystem: self system optimized: optimized on: stream]] ensure: [stream close].! generateCodeAs | filename | filename := PstSystem current defaultCodeFile caption: 'Generate Code'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. "If file exists, prompt to overwrite." (File exists: filename) ifTrue: [(MessageBox confirm: 'Overwrite generated binary file?' caption: 'Overwrite?') ifFalse: [^self]]. self generateCode: filename.! initialize super initialize. self toolbarHelper: (PstToolbarHelper with: self).! newProjectOfType: type " type ^ void Set the system up to build a project of type type." "If there is no current project, no sense warning eh ?" PstSystem current isNil ifFalse: [ (MessageBox confirm: 'Starting a new project will erase any unsaved changes. Proceed anyway?') ifFalse: [^self]]. PstSystem resetAs: type. self updateCaption.! onCloseRequested: valueHolder (MessageBox confirm: 'Really exit Pocket Smalltalk?') ifFalse: [ valueHolder value: false. ^false]. "Only exit automatically if this is not a development image." (SessionManager current isKindOf: PstRuntimeSessionManager) ifTrue: [ SessionManager current exit]. PstCrossPlatformInterface closeAllWindows. ^valueHolder value.! openClassBrowser "PstSystem current classBrowserClass show." (PstClassBrowser show) toolbarHelper: (PstToolbarHelper with: self).! openClassBrowserOnClass: aClass "PstSystem current classBrowserClass show." |cb| cb := PstClassBrowser browseClass: aClass. cb toolbarHelper: (PstToolbarHelper with: self). ! openClassBrowserOnMethod: aMethod |cb| cb := PstClassBrowser browseMethod: aMethod. cb toolbarHelper: (PstToolbarHelper with: self). ! openConstantsBrowser (PstConstantsBrowser show) toolbarHelper: (PstToolbarHelper with: self).! openConstantsBrowserOnConstant: aConstant |cb| cb := PstConstantsBrowser browse: aConstant. cb toolbarHelper: (PstToolbarHelper with: self). ! openPackageBrowser (PstPackageBrowser show) toolbarHelper: (PstToolbarHelper with: self).! openProject | filename system | filename := FileOpenDialog new fileTypes: (Array with: #('Smalltalk Projects (*.pst)' '*.pst') with: #('Old Smalltalk Projects (*.prj)' '*.prj') with: FileDialog allFilesType); defaultExtension: 'prj'; caption: 'Open Project'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. (PstSystem current notNil and: [PstPackageLibrary current packages size > 1]) ifTrue: [ (MessageBox confirm: 'Opening a project will erase any unsaved changes. Proceed anyway?') ifFalse: [^self]]. system := PstSystem current. system isNil ifTrue: [ system := PstSmalltalkSystem basicNew]. ((File splitExtensionFrom: filename) = 'prj') ifTrue: [system loadOldProject: filename] ifFalse: [system loadProject: filename]. self updateCaption.! openWorkspace (PstWorkspace show) toolbarHelper: (PstToolbarHelper with: self).! queryCommand: commandQuery super queryCommand: commandQuery. commandQuery command == #emitDebugInfo ifTrue: [commandQuery checked: (self system propertyAt: #debug)]. (commandQuery command == #openProject or: [commandQuery command notNil and: [commandQuery command startsWith: 'newProject']]) ifTrue: [ commandQuery enabled: true. ^self]. PstSystem current isNil ifTrue: [ commandQuery enabled: false. ^self].! saveProject self system projectFilename isNil ifTrue: [ ^self saveProjectAs]. self system confirmUncommitted ifFalse: [ ^self]. self system saveProjectAs: self system projectFilename.! saveProjectAs | filename | self system confirmUncommitted ifFalse: [ ^self]. filename := FileSaveDialog new fileTypes: (Array with: #('Smalltalk Projects (*.pst)' '*.pst') with: #('Smalltalk Old Projects (*.prj)' '*.prj') with: FileDialog allFilesType); defaultExtension: 'pst'; caption: 'Save Project'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. "If file exists, prompt user to overwrite or not." (File exists: filename) ifTrue: [(MessageBox confirm: 'Overwrite existing project file? This can''t be undone.' caption: 'Overwrite?') ifFalse: [^self]]. self system saveProjectAs: filename. self updateCaption.! showAbout PstAboutShell show.! showInstructionStatistics PstStatistics display: #instructionStatistics caption: 'Instruction Statistics'.! showMethodStatistics PstStatistics display: #methodStatistics caption: 'Method Statistics'.! showSelectorsImplementedButNotSent | selectors choice | selectors := PstClassLibrary current selectorsImplementedButNotSent asSortedCollection. choice := ChoicePrompter choices: selectors caption: 'Implemented but not Sent'. choice isNil ifFalse: [ PstMethodListBrowser showImplementorsOf: choice].! showSelectorsSentButNotImplemented | selectors choice | selectors := PstClassLibrary current selectorsSentButNotImplemented asSortedCollection. choice := ChoicePrompter choices: selectors caption: 'Sent but not Implemented'. choice isNil ifFalse: [ PstMethodListBrowser showSendersOf: choice].! system ^PstSystem current.! updateCaption | projectName systemName | projectName := nil. systemName := 'no project'. PstSystem current isNil ifFalse: [ projectName := PstSystem current projectFilename. systemName := PstSystem current class displayName]. self caption: 'Pocket Smalltalk: ', (projectName isNil ifTrue: [systemName] ifFalse: [systemName, ' - ', projectName]).! ! !PstLauncher categoriesFor: #chooseFont!actions!actions-options!public! ! !PstLauncher categoriesFor: #clearGlobals!actions!actions-options!public! ! !PstLauncher categoriesFor: #createSchematicWiring!initialization!public! ! !PstLauncher categoriesFor: #exit!actions!actions-system!public! ! !PstLauncher categoriesFor: #exitSmalltalk!actions!actions-system!public! ! !PstLauncher categoriesFor: #filenameFromUserUsing:reason:!public!utility! ! !PstLauncher categoriesFor: #findImplementors!actions!actions-search!public! ! !PstLauncher categoriesFor: #findMethodsContainingString!actions!actions-search!public! ! !PstLauncher categoriesFor: #findMethodsReferringTo!actions!actions-search!public! ! !PstLauncher categoriesFor: #findSenders!actions!actions-search!public! ! !PstLauncher categoriesFor: #generateCode!actions!actions-system!public! ! !PstLauncher categoriesFor: #generateCode:!actions!actions-system!public! ! !PstLauncher categoriesFor: #generateCodeAs!actions-system!public! ! !PstLauncher categoriesFor: #initialize!initialization!public! ! !PstLauncher categoriesFor: #newProjectOfType:!actions-system!public! ! !PstLauncher categoriesFor: #onCloseRequested:!event handling!public! ! !PstLauncher categoriesFor: #openClassBrowser!actions!actions-tools!public! ! !PstLauncher categoriesFor: #openClassBrowserOnClass:!actions!actions-tools!public! ! !PstLauncher categoriesFor: #openClassBrowserOnMethod:!actions!actions-tools!public! ! !PstLauncher categoriesFor: #openConstantsBrowser!actions!actions-tools!public! ! !PstLauncher categoriesFor: #openConstantsBrowserOnConstant:!actions!actions-tools!public! ! !PstLauncher categoriesFor: #openPackageBrowser!actions-tools!public! ! !PstLauncher categoriesFor: #openProject!actions!actions-system!public! ! !PstLauncher categoriesFor: #openWorkspace!actions!actions-tools!public! ! !PstLauncher categoriesFor: #queryCommand:!actions!public! ! !PstLauncher categoriesFor: #saveProject!actions-system!public! ! !PstLauncher categoriesFor: #saveProjectAs!actions!actions-system!public! ! !PstLauncher categoriesFor: #showAbout!*-unclassified!public! ! !PstLauncher categoriesFor: #showInstructionStatistics!actions-statistics!public! ! !PstLauncher categoriesFor: #showMethodStatistics!actions-statistics!public! ! !PstLauncher categoriesFor: #showSelectorsImplementedButNotSent!actions!actions-search!public! ! !PstLauncher categoriesFor: #showSelectorsSentButNotImplemented!actions!actions-search!public! ! !PstLauncher categoriesFor: #system!accessing!public! ! !PstLauncher categoriesFor: #updateCaption!public!utility! ! !PstLauncher class methodsFor! defaultView ^'Default view'.! description ^'Pocket Smalltalk'! initialize "Private - Initialize the receiver. Register the tools folder icon with SmalltalkSystem" PstSystem resetAll. Smalltalk developmentSystem addSamplesFolderIconFor: self description: self description! uninitialize "Private - Uninitialize the receiver as it is about to be removed from the system. Un-register the system tools folder icon for the receiver." Smalltalk developmentSystem removeSystemFolderIconNamed: self description! ! !PstLauncher class categoriesFor: #defaultView!defaults!public! ! !PstLauncher class categoriesFor: #description!defaults!public! ! !PstLauncher class categoriesFor: #initialize!defaults!public! ! !PstLauncher class categoriesFor: #uninitialize!defaults!public! ! PstMethodListBrowser comment: ''! PstMethodListBrowser guid: (GUID fromString: '{275558E3-6EF7-47E6-B358-217F8EABEA4C}')! !PstMethodListBrowser categoriesForClass!No category! ! !PstMethodListBrowser methodsFor! accept "Answer true or false depending on whether compilation succeeded." | oldMethod method cls category | (oldMethod := self selectedMethod) isNil ifTrue: [^MessageBox notify: '(No method is selected)']. category := oldMethod category. cls := self selectedMethod ownerClass. method := PstSystem current qcompilerClass compile: self sourceString in: cls notifying: sourceCode. method isNil ifTrue: [^false]. cls installMethod: method classified: category. self selectMethodNamed: oldMethod selector ownerClass: cls. ^true.! browseImplementors self class showImplementorsOf: self selectedMethod selector.! browseSelection methodList selectionOrNil isNil ifTrue: [^self]. PstClassBrowser browseMethod: methodList selectionOrNil.! browseSenders self class showSendersOf: self selectedMethod selector.! createComponents super createComponents. methodList := self add: ListPresenter new name: 'methodList'. sourceCode := self add: PstSourceCodePresenter new name: 'sourceCode'.! createSchematicWiring super createSchematicWiring. self model when: #addedMethod:to: send: #onAddedMethod:to: to: self. self model when: #removedMethod:from: send: #onRemovedMethod:from: to: self. self model when: #recompiledBehavior: send: #onRecompiledBehavior: to: self. methodList when: #selectionChanged send: #onSelectedMethodChanged to: self. methodList when: #actionPerformed send: #browseSelection to: self. methodList view getTextBlock: [:method | method fullDisplayString]. self updateFonts.! deleteMethod (MessageBox confirm: 'Really delete #', self selectedMethod selector, '?') ifFalse: [^self]. self selectedClass removeSelector: self selectedMethod selector.! onAddedMethod: method to: class self updateMethodList.! onRecompiledBehavior: behavior (methodList list anySatisfy: [:method | method ownerClass == behavior]) ifTrue: [self updateMethodList].! onRemovedMethod: method from: class self updateMethodList.! onSelectedMethodChanged self updateSourceCode.! queryCommand: commandQuery super queryCommand: commandQuery. (#(accept browseSelection browseSenders browseImplementors deleteMethod) includes: commandQuery command) ifTrue: [commandQuery enabled: self selectedMethod notNil].! receiverForEvaluations ^self selectedClass isNil ifTrue: [PstBasicObject forNil] ifFalse: [self selectedClass].! selectedClass ^self selectedMethod isNil ifTrue: [nil] ifFalse: [self selectedMethod ownerClass].! selectedMethod ^methodList selectionOrNil.! selectMethodNamed: selector ownerClass: ownerClass | method | method := methodList list detect: [:each | each selector = selector and: [each ownerClass == ownerClass]] ifNone: [nil]. method isNil ifFalse: [methodList selection: method].! sourceCodePart ^sourceCode! sourceString ^sourceCode view plainText.! updateBlock: block updateBlock := block.! updateFonts | b | b := [:presenter | presenter view font: PstSystem current defaultFont]. b value: methodList; value: sourceCode.! updateMethodList self updateMethodListWith: (updateBlock value: self model).! updateMethodListWith: collection | m | m := self selectedMethod. methodList list: (self model sortMethods: collection). (m notNil and: [collection includes: m]) ifTrue: [methodList selection: m]. self updateSourceCode. methodList list isEmpty ifFalse: [methodList selectionByIndex: 1].! updateSourceCode | string | string := self selectedMethod isNil ifTrue: [String new] ifFalse: [self selectedMethod richTextSource]. sourceCode value: string.! ! !PstMethodListBrowser categoriesFor: #accept!actions!public! ! !PstMethodListBrowser categoriesFor: #browseImplementors!actions!public! ! !PstMethodListBrowser categoriesFor: #browseSelection!actions!public! ! !PstMethodListBrowser categoriesFor: #browseSenders!actions!public! ! !PstMethodListBrowser categoriesFor: #createComponents!initialization!public! ! !PstMethodListBrowser categoriesFor: #createSchematicWiring!initialization!public! ! !PstMethodListBrowser categoriesFor: #deleteMethod!actions!public! ! !PstMethodListBrowser categoriesFor: #onAddedMethod:to:!event handling!public! ! !PstMethodListBrowser categoriesFor: #onRecompiledBehavior:!event handling!public! ! !PstMethodListBrowser categoriesFor: #onRemovedMethod:from:!event handling!public! ! !PstMethodListBrowser categoriesFor: #onSelectedMethodChanged!event handling!public! ! !PstMethodListBrowser categoriesFor: #queryCommand:!actions!public! ! !PstMethodListBrowser categoriesFor: #receiverForEvaluations!evaluating!public! ! !PstMethodListBrowser categoriesFor: #selectedClass!accessing!public! ! !PstMethodListBrowser categoriesFor: #selectedMethod!accessing!public! ! !PstMethodListBrowser categoriesFor: #selectMethodNamed:ownerClass:!actions!public! ! !PstMethodListBrowser categoriesFor: #sourceCodePart!event handling!public! ! !PstMethodListBrowser categoriesFor: #sourceString!accessing!public! ! !PstMethodListBrowser categoriesFor: #updateBlock:!initialization!public! ! !PstMethodListBrowser categoriesFor: #updateFonts!public!updating! ! !PstMethodListBrowser categoriesFor: #updateMethodList!public!updating! ! !PstMethodListBrowser categoriesFor: #updateMethodListWith:!public!updating! ! !PstMethodListBrowser categoriesFor: #updateSourceCode!public!updating! ! !PstMethodListBrowser class methodsFor! defaultModel ^PstSystem current classLibrary.! defaultView ^'Default view'.! showImplementorsOf: selector ^self showUsing: [:classLibrary | classLibrary methodsWithSelector: selector] ifNone: [MessageBox notify: 'No classes implement #', selector, '.'] caption: 'Implementors of #', selector.! showMethodsContainingString: string ^self showUsing: [:classLibrary | classLibrary methodsContainingString: string] ifNone: [MessageBox notify: 'No methods contain that string.'] caption: 'Methods containing ', string printString.! showMethodsOf: qclass referringToInstanceVariable: instVarName ^self showUsing: [:classLibrary | qclass methodsReferringToInstanceVariable: instVarName] ifNone: [MessageBox notify: 'No methods reference ', instVarName] caption: 'Methods referencing ', qclass name, '.', instVarName.! showMethodsReferencingClassNamed: className ^self showUsing: [:classLibrary | classLibrary methodsReferencingClassNamed: className] ifNone: [MessageBox notify: 'No methods refer to ', className displayString] caption: 'Methods referring to ', className displayString.! showMethodsReferringTo: value ^self showUsing: [:classLibrary | classLibrary methodsReferringTo: value] ifNone: [MessageBox notify: 'No methods refer to ', value displayString] caption: 'Methods referring to ', value displayString.! showMethodsReferringToConstant: constant ^self showUsing: [:classLibrary | classLibrary methodsReferringToConstant: constant] ifNone: [MessageBox notify: 'No methods refer to ', constant displayString] caption: 'Methods referring to ', constant displayString.! showMethodsReferringToSharedVariable: variableName ^self showUsing: [:classLibrary | classLibrary methodsReferringToSharedVariable: variableName] ifNone: [MessageBox notify: 'No methods refer to ', variableName displayString] caption: 'Methods referring to ', variableName displayString.! showSendersOf: selector ^self showUsing: [:classLibrary | classLibrary methodsSending: selector] ifNone: [MessageBox notify: 'No methods send #', selector, '.'] caption: 'Senders of #', selector.! showUsing: updateBlock ifNone: noneBlock caption: caption "Show (and answer) a new instance of the receiver, but only if updateBlock gives a non-empty result. If it gives an empty result, answer the result of evaluating noneBlock instead." | results newModel shell | newModel := self defaultModel. results := updateBlock value: newModel. results isEmpty ifTrue: [^noneBlock value]. shell := self showOn: newModel. shell caption: caption. shell updateBlock: updateBlock. shell updateMethodListWith: results. ^shell.! ! !PstMethodListBrowser class categoriesFor: #defaultModel!defaults!public! ! !PstMethodListBrowser class categoriesFor: #defaultView!defaults!public! ! !PstMethodListBrowser class categoriesFor: #showImplementorsOf:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsContainingString:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsOf:referringToInstanceVariable:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsReferencingClassNamed:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsReferringTo:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsReferringToConstant:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showMethodsReferringToSharedVariable:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showSendersOf:!public!utility! ! !PstMethodListBrowser class categoriesFor: #showUsing:ifNone:caption:!public!utility! ! PstPackageBrowser comment: ''! PstPackageBrowser guid: (GUID fromString: '{B6B89C9E-F738-4722-A78E-A0C8C9A17423}')! !PstPackageBrowser categoriesForClass!No category! ! !PstPackageBrowser methodsFor! addUncommittedClass | class | class := self chooseUncommittedClass. class isNil ifTrue: [^self]. class package: self selectedPackage.! browseImplementors PstMethodListBrowser showImplementorsOf: self selectedMethod selector.! browseReferencesToConstant PstMethodListBrowser showMethodsReferringToConstant: self selectedConstant. ! browseSelectedClass "PstClassBrowser browseClass: self selectedClass." toolbarHelper openClassBrowserOnClass: self selectedClass. ! browseSelectedConstant "PstConstantsBrowser browse: self selectedConstant." toolbarHelper openConstantsBrowserOnConstant: self selectedConstant.! browseSelectedMethod "PstClassBrowser browseMethod: self selectedMethod." toolbarHelper openClassBrowserOnMethod: self selectedMethod. ! browseSenders PstMethodListBrowser showSendersOf: self selectedMethod selector.! chooseUncommittedClass | classes | classes := PstClassLibrary current uncommittedClasses. classes isEmpty ifTrue: [ MessageBox notify: 'All classes are already assigned to packages.'. ^nil]. ^ChoicePrompter choices: classes caption: 'Select a Class'.! createComponents super createComponents. packageList := self add: ListPresenter new name: 'packageList'. classList := self add: ListPresenter new name: 'classList'. methodList := self add: ListPresenter new name: 'methodList'. constantList := self add: ListPresenter new name: 'constantList'.! createSchematicWiring | statusItem | super createSchematicWiring. self model when: #changed send: #updatePackageList to: self. self model when: #classesChangedFor: send: #updateClassesFor: to: self. self model when: #methodsChangedFor: send: #updateMethodsFor: to: self. self model when: #constantsChangedFor: send: #updateConstantsFor: to: self. packageList when: #selectionChanged send: #onSelectedPackageChanged to: self. packageList when: #actionPerformed send: #showSelectedPackage to: self. classList when: #actionPerformed send: #browseSelectedClass to: self. methodList when: #actionPerformed send: #browseSelectedMethod to: self. constantList when: #actionPerformed send: #browseSelectedConstant to: self. methodList view getTextBlock: [:method | method fullDisplayString]. statusModel := ValueHolder with: String new. statusItem := (self view viewNamed: 'status') addItem: StatusItem new. statusItem model: statusModel. statusItem getImageBlock: [:blah | nil]. self updatePackageList.! dontSavePackageWithProject self selectedPackage dontSave: self selectedPackage dontSave not.! generateDocumentation | filename directory indexName | (MessageBox confirm: 'Automatically generate HTML documentation for this package?') ifFalse: [^self]. filename := FileSaveDialog new value: (PstDocumentationGenerator defaultFilenameForPackage: self selectedPackage); fileTypes: (Array with: #('HTML Files (*.html)' '*.html') with: FileSaveDialog allFilesType); defaultExtension: 'html'; caption: 'Name Index HTML File'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. directory := File splitPathFrom: filename. indexName := File splitStemFrom: filename. Cursor wait showWhile: [ PstDocumentationGenerator writePackageDocumentation: self selectedPackage toDirectory: directory indexFileNamed: indexName]. MessageBox notify: 'Documentation generated.'.! installPackage | filename | filename := FileOpenDialog new caption: 'Install Package'; fileTypes: #(('Smalltalk Source Files (*.st)' '*.st') ('All Files (*.*)' '*.*')); defaultExtension: 'st'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. (self model hasPackageNamed: filename) ifTrue: [(MessageBox confirm: 'Reload this package?') ifFalse: [^self]]. self model deferUpdatesDuring: [self model installPackageNamed: filename].! moveSelectedClass | package | package := PstPackage chooseSelecting: self selectedClass package. package isNil ifTrue: [^self]. self selectedClass package: package.! moveSelectedConstant | package | package := PstPackage chooseSelecting: self selectedConstant package. package isNil ifTrue: [^self]. self selectedConstant package: package.! moveSelectedPackageToFront | package | package := self selectedPackage. self model movePackageToFront: package. packageList selection: package.! newPackage | filename | filename := FileSaveDialog new caption: 'New Package'; fileTypes: #(('Smalltalk Source Files (*.st)' '*.st') ('All Files (*.*)' '*.*')); defaultExtension: 'st'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [^self]. (self model hasPackageNamed: filename) ifTrue: [(MessageBox confirm: 'Replace the loaded package?') ifFalse: [^self]]. self model createPackageNamed: filename.! onSelectedPackageChanged self updateClassList; updateMethodList; updateConstantList.! queryCommand: query | symbol | super queryCommand: query. symbol := query command. (#(browseSelectedClass removeSelectedClass moveSelectedClass) identityIncludes: symbol) ifTrue: [query enabled: self selectedClass notNil]. (#(addUncommittedClass savePackage savePackageAs moveSelectedPackageToFront dontSavePackageWithProject generateDocumentation) identityIncludes: symbol) ifTrue: [query enabled: (self selectedPackage notNil and: [self selectedPackage isUncommitted not])]. self selectedPackage notNil ifTrue: [ symbol == #dontSavePackageWithProject ifTrue: [ query enabled: self selectedPackage name notNil]. symbol == #dontSavePackageWithProject ifTrue: [ query isEnabled ifTrue: [ query checked: self selectedPackage dontSave]]]. symbol == #savePackage ifTrue: [ query enabled: self selectedPackage name notNil]. (#(removeSelectedMethod browseSelectedMethod browseImplementors browseSenders) identityIncludes: symbol) ifTrue: [query enabled: self selectedMethod notNil]. (#(moveSelectedConstant browseSelectedConstant browseReferencesToConstant removeSelectedConstant) identityIncludes: symbol) ifTrue: [query enabled: self selectedConstant notNil].! removePackage self selectedPackage isNil ifTrue: [^self]. "shouldn't happen" (MessageBox confirm: 'Really remove ', (self selectedPackage baseFilename), ' from project?') ifFalse: [^self]. PstPackageLibrary current removePackage: self selectedPackage.! removeSelectedClass (MessageBox confirm: 'Remove ', self selectedClass displayString, ' from this package?') ifFalse: [^self]. self selectedClass package: PstPackage uncommitted.! removeSelectedConstant | constant | constant := self selectedConstant. (MessageBox confirm: 'Remove ', constant displayString, ' from this package?') ifFalse: [^self]. constant package:PstPackage uncommitted.! removeSelectedMethod | method | method := self selectedMethod. (MessageBox confirm: 'Remove ', method fullDisplayString, ' from this package?') ifFalse: [^self]. method package isNil ifTrue: [ method package: PstPackage uncommitted] ifFalse: [ method package: nil].! savePackage self selectedPackage save.! savePackageAs | dialog filename package | package := self selectedPackage. dialog := FileSaveDialog on: package filename asValue. filename := dialog fileTypes: (Array with: #('Smalltalk Source Files' '*.st') with: dialog allFilesType); caption: 'Save Package'; defaultExtension: 'st'; showModal. (filename isNil or: [filename isEmpty]) ifTrue: [ ^self]. (self model hasPackageNamed: filename) ifTrue: [ (MessageBox confirm: 'Replace the loaded package with the same name ', filename printString, ' ?') ifFalse: [^self]]. package saveAs: filename.! selectedClass ^classList selectionOrNil.! selectedConstant ^constantList selectionOrNil.! selectedMethod ^methodList selectionOrNil.! selectedPackage ^packageList selectionOrNil.! setSelectedPackageAsDefault self selectedPackage isNil ifTrue: [^self]. "shouldn't happen" PstPackageLibrary current defaultPackage: self selectedPackage. self updatePackageList.! showSelectedPackage | package string | (package := self selectedPackage) isNil ifTrue: [^self]. string := package isUncommitted ifTrue: ['Uncommitted package'] ifFalse: [package filename]. ^MessageBox notify: string.! statusMessage: string statusModel value: string.! updateClassesFor: package package == self selectedPackage ifTrue: [self updateClassList].! updateClassList classList list: (self selectedPackage isNil ifTrue: [#()] ifFalse: [self selectedPackage classes copy]).! updateConstantList constantList list: (self selectedPackage isNil ifTrue: [#()] ifFalse: [self selectedPackage constants copy]).! updateConstantsFor: package package == self selectedPackage ifTrue: [self updateConstantList].! updateMethodList methodList list: (self selectedPackage isNil ifTrue: [#()] ifFalse: [self selectedPackage methods copy]).! updateMethodsFor: package package == self selectedPackage ifTrue: [self updateMethodList].! updatePackageList packageList list: self model packages copy.! ! !PstPackageBrowser categoriesFor: #addUncommittedClass!actions!public! ! !PstPackageBrowser categoriesFor: #browseImplementors!actions!public! ! !PstPackageBrowser categoriesFor: #browseReferencesToConstant!actions!public! ! !PstPackageBrowser categoriesFor: #browseSelectedClass!actions!public! ! !PstPackageBrowser categoriesFor: #browseSelectedConstant!actions!public! ! !PstPackageBrowser categoriesFor: #browseSelectedMethod!actions!public! ! !PstPackageBrowser categoriesFor: #browseSenders!actions!public! ! !PstPackageBrowser categoriesFor: #chooseUncommittedClass!public!utility! ! !PstPackageBrowser categoriesFor: #createComponents!initialization!public! ! !PstPackageBrowser categoriesFor: #createSchematicWiring!initialization!public! ! !PstPackageBrowser categoriesFor: #dontSavePackageWithProject!actions!public! ! !PstPackageBrowser categoriesFor: #generateDocumentation!actions!public! ! !PstPackageBrowser categoriesFor: #installPackage!actions!public! ! !PstPackageBrowser categoriesFor: #moveSelectedClass!actions!public! ! !PstPackageBrowser categoriesFor: #moveSelectedConstant!actions!public! ! !PstPackageBrowser categoriesFor: #moveSelectedPackageToFront!actions!public! ! !PstPackageBrowser categoriesFor: #newPackage!actions!public! ! !PstPackageBrowser categoriesFor: #onSelectedPackageChanged!event handling!public! ! !PstPackageBrowser categoriesFor: #queryCommand:!actions!public! ! !PstPackageBrowser categoriesFor: #removePackage!actions!public! ! !PstPackageBrowser categoriesFor: #removeSelectedClass!actions!public! ! !PstPackageBrowser categoriesFor: #removeSelectedConstant!actions!public! ! !PstPackageBrowser categoriesFor: #removeSelectedMethod!actions!public! ! !PstPackageBrowser categoriesFor: #savePackage!actions!public! ! !PstPackageBrowser categoriesFor: #savePackageAs!actions!public! ! !PstPackageBrowser categoriesFor: #selectedClass!accessing!public! ! !PstPackageBrowser categoriesFor: #selectedConstant!accessing!public! ! !PstPackageBrowser categoriesFor: #selectedMethod!accessing!public! ! !PstPackageBrowser categoriesFor: #selectedPackage!accessing!public! ! !PstPackageBrowser categoriesFor: #setSelectedPackageAsDefault!actions!public! ! !PstPackageBrowser categoriesFor: #showSelectedPackage!actions!public! ! !PstPackageBrowser categoriesFor: #statusMessage:!public!utility! ! !PstPackageBrowser categoriesFor: #updateClassesFor:!public!updating! ! !PstPackageBrowser categoriesFor: #updateClassList!public!updating! ! !PstPackageBrowser categoriesFor: #updateConstantList!public!updating! ! !PstPackageBrowser categoriesFor: #updateConstantsFor:!public!updating! ! !PstPackageBrowser categoriesFor: #updateMethodList!public!updating! ! !PstPackageBrowser categoriesFor: #updateMethodsFor:!public!updating! ! !PstPackageBrowser categoriesFor: #updatePackageList!public!updating! ! !PstPackageBrowser class methodsFor! defaultModel ^PstPackageLibrary current.! defaultView ^'Default view'.! ! !PstPackageBrowser class categoriesFor: #defaultModel!defaults!public! ! !PstPackageBrowser class categoriesFor: #defaultView!defaults!public! ! PstWorkspace comment: ''! PstWorkspace guid: (GUID fromString: '{630D0381-52ED-4857-A86F-D06C65ACC36C}')! !PstWorkspace categoriesForClass!No category! ! !PstWorkspace methodsFor! createComponents super createComponents. sourceCode := self add: PstSourceCodePresenter new name: 'sourceCode'.! createSchematicWiring super createSchematicWiring. sourceCode view font: PstSystem current defaultFont.! source: aString sourceCode value: aString! sourceCodePart ^sourceCode! ! !PstWorkspace categoriesFor: #createComponents!initialization!public! ! !PstWorkspace categoriesFor: #createSchematicWiring!initialization!public! ! !PstWorkspace categoriesFor: #source:!evaluating!public! ! !PstWorkspace categoriesFor: #sourceCodePart!evaluating!public! ! !PstWorkspace class methodsFor! defaultView ^'Default view'.! ! !PstWorkspace class categoriesFor: #defaultView!defaults!public! ! PstSourceCodePresenter comment: ''! PstSourceCodePresenter guid: (GUID fromString: '{229241B7-DEC8-4EBA-A695-F7942D2A23FD}')! !PstSourceCodePresenter categoriesForClass!No category! ! !PstSourceCodePresenter methodsFor! afterKeyTyped: keyEvent (keyEvent code == 13 and: [autoindent]) ifTrue: [self performAutoIndent].! createSchematicWiring self when: #afterKeyTyped: send: #afterKeyTyped: to: self.! doItFor: receiver | expression | expression := self selectedExpression. expression isNil ifTrue: [^self]. self evaluate: expression for: receiver.! evaluate: expression for: receiver | result | Cursor wait showWhile: [ result := PstSystem current qcompilerClass evaluate: expression for: receiver notifying: self]. ^result.! handleError: message from: start to: stop self highlightErrorFrom: start to: stop. MessageBox notify: 'Error: ', message, '.'.! handleWarning: message from: start to: stop self highlightErrorFrom: start to: stop. MessageBox notify: 'Warning: ', message, '.'.! highlightErrorFrom: start to: stop (start isNil or: [stop isNil]) ifTrue: [^self]. self view selectionStart: start + expressionOffset end: stop + expressionOffset.! initialize super initialize. autoindent := true. self resetExpressionOffset.! initialWhitespaceOf: string | readStream writeStream | readStream := string readStream. writeStream := String new writeStream. [readStream atEnd not and: [readStream peek isSeparator]] whileTrue: [writeStream nextPut: readStream next]. ^writeStream contents. ! inspectItFor: receiver | expression result printString | expression := self selectedExpression. result := expression isNil ifTrue: [PstBasicObject forNil] ifFalse: [self evaluate: expression for: receiver]. result isNil ifTrue: [^self]. PstInspector showOn: result.! performAutoIndent | thisLine start end string | thisLine := self view currentLine. "line 1 is the top" thisLine == 1 ifTrue: [^self]. "no previous indentation" start := self view positionAtLine: thisLine - 1. end := start + (self view lineLength: thisLine - 1) - 1. string := self view plainText copyFrom: start to: end. self replaceSelection: (self initialWhitespaceOf: string).! printItFor: receiver | expression result printString position | expression := self selectedExpression. result := expression isNil ifTrue: [PstBasicObject forNil] ifFalse: [self evaluate: expression for: receiver]. result isNil ifTrue: [^self]. result := self evaluate: 'self printString' for: result. result isNil ifTrue: [^self]. printString := result qclass name = 'String' ifTrue: [result convertToString] ifFalse: ['[unprintable]']. position := self view selectionRange stop + 1. self view caretPosition: position; replaceSelection: printString; selectionRange: (position to: position + printString size - 1).! resetExpressionOffset expressionOffset := 0.! selectedExpression "Answer the currently selected area of text (for do-it, etc.), or nil if no area is selected." | range | range := self view selectionRange. range isEmpty ifTrue: [^nil]. expressionOffset := range first - 1. ^self view plainText copyFrom: range first to: range last.! ! !PstSourceCodePresenter categoriesFor: #afterKeyTyped:!event handling!public! ! !PstSourceCodePresenter categoriesFor: #createSchematicWiring!initialization!public! ! !PstSourceCodePresenter categoriesFor: #doItFor:!evaluating!public! ! !PstSourceCodePresenter categoriesFor: #evaluate:for:!evaluating!public! ! !PstSourceCodePresenter categoriesFor: #handleError:from:to:!error handling!public! ! !PstSourceCodePresenter categoriesFor: #handleWarning:from:to:!error handling!public! ! !PstSourceCodePresenter categoriesFor: #highlightErrorFrom:to:!error handling!public! ! !PstSourceCodePresenter categoriesFor: #initialize!initialization!public! ! !PstSourceCodePresenter categoriesFor: #initialWhitespaceOf:!public!utility! ! !PstSourceCodePresenter categoriesFor: #inspectItFor:!evaluating!public! ! !PstSourceCodePresenter categoriesFor: #performAutoIndent!public!utility! ! !PstSourceCodePresenter categoriesFor: #printItFor:!evaluating!public! ! !PstSourceCodePresenter categoriesFor: #resetExpressionOffset!public!utility! ! !PstSourceCodePresenter categoriesFor: #selectedExpression!evaluating!public! ! PstRuntimeSessionManager comment: ''! PstRuntimeSessionManager guid: (GUID fromString: '{CB619F62-A716-4562-B64D-962FBDB6EA0D}')! !PstRuntimeSessionManager categoriesForClass!Unclassified! ! !PstRuntimeSessionManager methodsFor! main PstDolphinInterface initialize. PstLauncher show.! showSplash "Show a splash screen for this session. Can be overidden in subclasses to bring up an appropriate splash." PstSplash new showTimed.! ! !PstRuntimeSessionManager categoriesFor: #main!*-unclassified!public! ! !PstRuntimeSessionManager categoriesFor: #showSplash!*-unclassified!public! ! PstSplash comment: ''! PstSplash guid: (GUID fromString: '{30366DFF-82C0-4D12-91D6-C480073D4EA3}')! !PstSplash categoriesForClass!Unclassified! ! !PstSplash methodsFor! defaultWindowStyle "Private - Answer the default basic window creation style" ^WS_POPUP | WS_DLGFRAME! ! !PstSplash categoriesFor: #defaultWindowStyle!*-unclassified!private! ! !PstSplash class methodsFor! new "Try to get the splash bitmap." | bitmap | bitmap := (Bitmap fromFile: (File composePath: SessionManager current installationDirectory subPath: 'PstSplash.bmp') usingLocator: FileLocator absolute). "bitmap := Bitmap fromFile: 'c:\pst\PstSplash.bmp'." ^self bitmap: bitmap. ! ! !PstSplash class categoriesFor: #new!*-unclassified!public! ! PstToolbar comment: ''! PstToolbar guid: (GUID fromString: '{87573EB5-F2CF-41E6-9B71-A025BE5FCFAA}')! !PstToolbar categoriesForClass!Unclassified! ! !PstToolbar class methodsFor! referencedViews "The purpose of this method is to prevent the toolbars loaded as ReferenceViews from being stripped (the reference chasing in D4.0 does not detect the names of reference views in referencing view resources at present)." 'PstEditTools Toolbar'. 'PstDebugger Toolbar'. 'PstTools Toolbar'. 'PstFileTools Toolbar'. 'PstWorkspaceTools Toolbar'. 'PstImage Toolbar'. ! ! !PstToolbar class categoriesFor: #referencedViews!constants!must not strip!public! ! "Binary Globals"! "Resources"! (ResourceIdentifier class: PstAboutShell name: 'Default view') assign: (Object fromBinaryStoreBytes: #[33 83 84 66 32 48 32 70 2 12 0 1 0 0 0 86 105 101 119 82 101 115 111 117 114 99 101 0 0 0 0 14 1 36 0 83 84 66 82 101 115 111 117 114 99 101 83 84 66 66 121 116 101 65 114 114 97 121 65 99 99 101 115 115 111 114 80 114 111 120 121 0 0 0 0 54 0 9 0 66 121 116 101 65 114 114 97 121 110 10 0 0 33 83 84 66 32 48 32 78 8 12 0 10 0 0 0 83 84 66 86 105 101 119 80 114 111 120 121 0 0 0 0 78 2 13 0 1 0 0 0 83 84 66 67 108 97 115 115 80 114 111 120 121 0 0 0 0 54 0 6 0 83 116 114 105 110 103 7 0 0 0 68 111 108 112 104 105 110 146 0 0 0 9 0 0 0 83 104 101 108 108 86 105 101 119 38 0 5 0 65 114 114 97 121 24 0 0 0 0 0 0 0 0 0 0 0 194 0 0 0 2 0 0 0 1 0 158 1 1 0 2 0 96 0 0 0 0 0 0 0 6 3 3 0 82 71 66 0 0 0 0 255 1 0 0 255 1 0 0 255 1 0 0 6 2 5 0 80 111 105 110 116 0 0 0 0 67 4 0 0 215 1 0 0 135 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 2 26 0 83 84 66 73 100 101 110 116 105 116 121 68 105 99 116 105 111 110 97 114 121 80 114 111 120 121 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 18 0 0 0 73 100 101 110 116 105 116 121 68 105 99 116 105 111 110 97 114 121 194 0 0 0 2 0 0 0 90 0 0 0 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 12 0 0 0 83 116 97 116 105 99 66 105 116 109 97 112 194 0 0 0 17 0 0 0 0 0 0 0 96 0 0 0 194 0 0 0 2 0 0 0 54 0 12 0 76 97 114 103 101 73 110 116 101 103 101 114 4 0 0 0 14 1 0 68 1 0 0 0 128 1 0 0 70 4 11 0 2 0 0 0 86 97 108 117 101 72 111 108 100 101 114 0 0 0 0 0 0 0 0 32 0 0 0 6 1 16 0 67 111 109 112 97 114 105 115 111 110 80 111 108 105 99 121 0 0 0 0 6 2 7 0 77 101 115 115 97 103 101 0 0 0 0 14 1 14 0 83 84 66 83 121 109 98 111 108 80 114 111 120 121 0 0 0 0 146 0 0 0 2 0 0 0 61 61 194 0 0 0 0 0 0 0 70 10 10 0 3 0 0 0 68 73 66 83 101 99 116 105 111 110 0 0 0 0 1 0 0 0 16 0 0 0 14 2 17 0 83 84 66 83 105 110 103 108 101 116 111 110 80 114 111 120 121 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 24 0 0 0 73 109 97 103 101 82 101 108 97 116 105 118 101 70 105 108 101 76 111 99 97 116 111 114 90 2 0 0 0 0 0 0 146 0 0 0 7 0 0 0 99 117 114 114 101 110 116 146 0 0 0 13 0 0 0 80 115 116 83 112 108 97 115 104 46 98 109 112 14 2 31 0 83 84 66 69 120 116 101 114 110 97 108 82 101 115 111 117 114 99 101 76 105 98 114 97 114 121 80 114 111 120 121 0 0 0 0 146 0 0 0 16 0 0 0 100 111 108 112 104 105 110 100 114 48 48 52 46 100 108 108 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 210 1 0 0 4 0 0 0 227 147 225 119 6 2 13 0 78 117 108 108 67 111 110 118 101 114 116 101 114 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 0 160 2 0 0 6 1 15 0 77 101 115 115 97 103 101 83 101 113 117 101 110 99 101 0 0 0 0 14 2 18 0 83 84 66 67 111 108 108 101 99 116 105 111 110 80 114 111 120 121 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 17 0 0 0 79 114 100 101 114 101 100 67 111 108 108 101 99 116 105 111 110 194 0 0 0 1 0 0 0 6 3 11 0 77 101 115 115 97 103 101 83 101 110 100 0 0 0 0 90 2 0 0 0 0 0 0 146 0 0 0 16 0 0 0 99 114 101 97 116 101 65 116 58 101 120 116 101 110 116 58 194 0 0 0 2 0 0 0 18 1 0 0 0 0 0 0 1 0 0 0 31 0 0 0 18 1 0 0 0 0 0 0 209 1 0 0 11 1 0 0 128 1 0 0 6 1 15 0 87 73 78 68 79 87 80 76 65 67 69 77 69 78 84 0 0 0 0 54 0 9 0 66 121 116 101 65 114 114 97 121 44 0 0 0 44 0 0 0 0 0 0 0 1 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 15 0 0 0 232 0 0 0 148 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 194 0 0 0 0 0 0 0 18 1 0 0 0 0 0 0 193 0 0 0 193 0 0 0 0 0 0 0 19 0 0 0 146 0 0 0 14 0 0 0 105 109 97 103 101 80 114 101 115 101 110 116 101 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 191 34 0 0 0 0 0 0 70 5 4 0 3 0 0 0 73 99 111 110 0 0 0 0 0 0 0 0 16 0 0 0 192 2 0 0 146 0 0 0 28 0 0 0 46 46 92 46 46 92 46 46 92 46 46 92 80 83 84 92 112 111 99 107 101 116 115 116 46 105 99 111 48 3 0 0 18 1 0 0 0 0 0 0 67 4 0 0 215 1 0 0 18 1 0 0 0 0 0 0 67 4 0 0 215 1 0 0 130 3 0 0 0 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 194 0 0 0 3 0 0 0 242 3 0 0 0 0 0 0 16 4 0 0 194 0 0 0 2 0 0 0 18 1 0 0 0 0 0 0 11 0 0 0 11 0 0 0 18 1 0 0 0 0 0 0 67 4 0 0 215 1 0 0 96 0 0 0 242 3 0 0 0 0 0 0 90 2 0 0 0 0 0 0 146 0 0 0 5 0 0 0 116 101 120 116 58 194 0 0 0 1 0 0 0 146 0 0 0 25 0 0 0 65 98 111 117 116 32 80 111 99 107 101 116 32 83 109 97 108 108 116 97 108 107 46 46 46 96 0 0 0 242 3 0 0 0 0 0 0 90 2 0 0 0 0 0 0 146 0 0 0 8 0 0 0 109 101 110 117 66 97 114 58 194 0 0 0 1 0 0 0 0 0 0 0 96 0 0 0 98 4 0 0 0 0 0 0 130 4 0 0 44 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 5 0 0 0 5 0 0 0 38 2 0 0 240 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 194 0 0 0 3 0 0 0 128 1 0 0 90 0 0 0 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 10 0 0 0 83 116 97 116 105 99 84 101 120 116 194 0 0 0 16 0 0 0 0 0 0 0 96 0 0 0 194 0 0 0 2 0 0 0 210 1 0 0 4 0 0 0 0 1 0 68 1 0 0 0 112 6 0 0 0 0 0 0 242 0 0 0 0 0 0 0 255 1 0 0 255 1 0 0 255 1 0 0 0 0 0 0 7 0 0 0 0 0 0 0 6 4 4 0 70 111 110 116 0 0 0 0 0 0 0 0 16 0 0 0 6 1 7 0 76 79 71 70 79 78 84 0 0 0 0 130 4 0 0 60 0 0 0 243 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 144 1 0 0 0 0 0 0 3 2 1 34 86 101 114 100 97 110 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 1 0 0 0 0 0 0 193 0 0 0 193 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 210 1 0 0 4 0 0 0 227 147 225 119 98 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 130 3 0 0 0 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 194 0 0 0 2 0 0 0 242 3 0 0 0 0 0 0 16 4 0 0 194 0 0 0 2 0 0 0 18 1 0 0 0 0 0 0 19 2 0 0 21 0 0 0 18 1 0 0 0 0 0 0 19 2 0 0 35 1 0 0 112 6 0 0 242 3 0 0 0 0 0 0 176 5 0 0 194 0 0 0 1 0 0 0 146 0 0 0 150 0 0 0 80 111 99 107 101 116 32 83 109 97 108 108 116 97 108 107 32 49 46 54 13 10 13 10 67 111 112 121 114 105 103 104 116 32 40 67 41 32 49 57 57 56 45 50 48 48 49 32 80 111 99 107 101 116 83 109 97 108 108 116 97 108 107 46 99 111 109 13 10 13 10 80 111 114 116 105 111 110 115 58 13 10 67 111 112 121 114 105 103 104 116 32 40 67 41 32 50 48 48 48 32 80 101 116 114 32 78 111 118 97 107 13 10 67 111 112 121 114 105 103 104 116 32 40 67 41 32 50 48 48 48 32 45 32 50 48 48 49 32 74 111 101 121 32 71 105 98 115 111 110 112 6 0 0 98 4 0 0 0 0 0 0 130 4 0 0 44 0 0 0 44 0 0 0 0 0 0 0 1 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 9 1 0 0 10 0 0 0 18 2 0 0 155 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 176 4 0 0 192 4 0 0 0 0 0 0 19 0 0 0 90 0 0 0 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 10 0 0 0 80 117 115 104 66 117 116 116 111 110 194 0 0 0 17 0 0 0 0 0 0 0 96 0 0 0 194 0 0 0 2 0 0 0 210 1 0 0 4 0 0 0 0 32 1 68 1 0 0 0 48 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 210 1 0 0 4 0 0 0 46 162 226 119 70 4 18 0 2 0 0 0 67 111 109 109 97 110 100 68 101 115 99 114 105 112 116 105 111 110 0 0 0 0 90 2 0 0 0 0 0 0 146 0 0 0 2 0 0 0 111 107 146 0 0 0 3 0 0 0 38 79 75 1 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 130 3 0 0 0 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 194 0 0 0 3 0 0 0 242 3 0 0 0 0 0 0 16 4 0 0 194 0 0 0 2 0 0 0 18 1 0 0 0 0 0 0 185 1 0 0 85 1 0 0 18 1 0 0 0 0 0 0 171 0 0 0 61 0 0 0 48 8 0 0 242 3 0 0 0 0 0 0 90 2 0 0 0 0 0 0 146 0 0 0 10 0 0 0 105 115 69 110 97 98 108 101 100 58 194 0 0 0 1 0 0 0 32 0 0 0 48 8 0 0 242 3 0 0 0 0 0 0 176 5 0 0 194 0 0 0 1 0 0 0 146 0 0 0 3 0 0 0 38 79 75 48 8 0 0 98 4 0 0 0 0 0 0 130 4 0 0 44 0 0 0 44 0 0 0 0 0 0 0 1 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 220 0 0 0 170 0 0 0 49 1 0 0 200 0 0 0 170 3 0 0 0 0 0 0 192 3 0 0 176 4 0 0 192 4 0 0 0 0 0 0 19 0 0 0 192 4 0 0 0 0 0 0 19 0 0 0 70 5 4 0 3 0 0 0 73 99 111 110 0 0 0 0 0 0 0 0 16 0 0 0 14 2 17 0 83 84 66 83 105 110 103 108 101 116 111 110 80 114 111 120 121 0 0 0 0 78 2 13 0 1 0 0 0 83 84 66 67 108 97 115 115 80 114 111 120 121 0 0 0 0 54 0 6 0 83 116 114 105 110 103 7 0 0 0 68 111 108 112 104 105 110 18 1 0 0 24 0 0 0 73 109 97 103 101 82 101 108 97 116 105 118 101 70 105 108 101 76 111 99 97 116 111 114 14 1 14 0 83 84 66 83 121 109 98 111 108 80 114 111 120 121 0 0 0 0 18 1 0 0 7 0 0 0 99 117 114 114 101 110 116 18 1 0 0 13 0 0 0 83 104 101 108 108 86 105 101 119 46 105 99 111 14 2 31 0 83 84 66 69 120 116 101 114 110 97 108 82 101 115 111 117 114 99 101 76 105 98 114 97 114 121 80 114 111 120 121 0 0 0 0 18 1 0 0 16 0 0 0 100 111 108 112 104 105 110 100 114 48 48 52 46 100 108 108 0 0 0 0])! (ResourceIdentifier class: PstClassBrowser name: 'Default view') assign: (Object fromBinaryStoreBytes: #[33 83 84 66 32 48 32 70 2 12 0 1 0 0 0 86 105 101 119 82 101 115 111 117 114 99 101 0 0 0 0 14 1 36 0 83 84 66 82 101 115 111 117 114 99 101 83 84 66 66 121 116 101 65 114 114 97 121 65 99 99 101 115 115 111 114 80 114 111 120 121 0 0 0 0 54 0 9 0 66 121 116 101 65 114 114 97 121 22 47 0 0 33 83 84 66 32 48 32 78 8 12 0 10 0 0 0 83 84 66 86 105 101 119 80 114 111 120 121 0 0 0 0 78 2 13 0 1 0 0 0 83 84 66 67 108 97 115 115 80 114 111 120 121 0 0 0 0 54 0 6 0 83 116 114 105 110 103 7 0 0 0 68 111 108 112 104 105 110 146 0 0 0 9 0 0 0 83 104 101 108 108 86 105 101 119 38 0 5 0 65 114 114 97 121 24 0 0 0 0 0 0 0 0 0 0 0 194 0 0 0 2 0 0 0 1 0 158 1 1 0 2 0 96 0 0 0 0 0 0 0 0 0 0 0 6 2 5 0 80 111 105 110 116 0 0 0 0 1 5 0 0 193 3 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 7 12 0 66 111 114 100 101 114 76 97 121 111 117 116 0 0 0 0 1 0 0 0 1 0 0 0 90 0 0 0 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 13 0 0 0 67 111 110 116 97 105 110 101 114 86 105 101 119 194 0 0 0 15 0 0 0 0 0 0 0 96 0 0 0 194 0 0 0 2 0 0 0 54 0 12 0 76 97 114 103 101 73 110 116 101 103 101 114 4 0 0 0 0 0 0 68 1 0 2 0 48 1 0 0 0 0 0 0 6 1 11 0 83 121 115 116 101 109 67 111 108 111 114 0 0 0 0 31 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 3 10 0 70 108 111 119 76 97 121 111 117 116 0 0 0 0 1 0 0 0 1 0 0 0 14 1 14 0 83 84 66 83 121 109 98 111 108 80 114 111 120 121 0 0 0 0 146 0 0 0 4 0 0 0 108 101 102 116 14 2 26 0 83 84 66 73 100 101 110 116 105 116 121 68 105 99 116 105 111 110 97 114 121 80 114 111 120 121 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 18 0 0 0 73 100 101 110 116 105 116 121 68 105 99 116 105 111 110 97 114 121 194 0 0 0 0 0 0 0 0 0 0 0 6 1 15 0 77 101 115 115 97 103 101 83 101 113 117 101 110 99 101 0 0 0 0 14 2 18 0 83 84 66 67 111 108 108 101 99 116 105 111 110 80 114 111 120 121 0 0 0 0 122 0 0 0 0 0 0 0 160 0 0 0 146 0 0 0 17 0 0 0 79 114 100 101 114 101 100 67 111 108 108 101 99 116 105 111 110 194 0 0 0 1 0 0 0 6 3 11 0 77 101 115 115 97 103 101 83 101 110 100 0 0 0 0 234 1 0 0 0 0 0 0 146 0 0 0 16 0 0 0 99 114 101 97 116 101 65 116 58 101 120 116 101 110 116 58 194 0 0 0 2 0 0 0 242 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 242 0 0 0 0 0 0 0 241 4 0 0 51 0 0 0 48 1 0 0 6 1 15 0 87 73 78 68 79 87 80 76 65 67 69 77 69 78 84 0 0 0 0 54 0 9 0 66 121 116 101 65 114 114 97 121 44 0 0 0 44 0 0 0 0 0 0 0 1 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0