"Initialization code"
 !



!Behavior methods !

addSelector: aSymbol withMethod: aCompiledMethod
		"Add aCompiledMethod to the receiver messageDictionary
         using aSymbol as the key.  If aSymbol is not
         a Symbol report an error."
		"@23.09.94 ch" 
		"@18.09.94 ch: support for the history logging"
	Symbol mustBeSymbol: aSymbol.
	ChApplication historySaveMethod: aSymbol forClass: self.
    self methodDictionary
        at: aSymbol put: aCompiledMethod.
	ChApplication historySaveMethod: aSymbol forClass: self.!
   
removeSelector: aSymbol
		"Remove the method named aSymbol from
         the methods defined in the receiver."
		"@18.09.94 ch: support for the history logging" 
		"@07.11.93 ch: remove the method from all application also"
	aSymbol = #Doit ifFalse: [ 
		ChApplication 
			removeMethod: aSymbol forClass: self;
			historySaveMethod: aSymbol forClass: self.
		].
    self methodDictionary
        removeKey: aSymbol
        ifAbsent: []! !



!Behavior class methods ! !



!Class methods !
   
changeSuperclassTo: aClass
        "Change the superclass of the receiver to aClass."
		"@11.05.94 ch" 
    self superclass removeSubclass: self.
    self superclass class removeSubclass: self class.
    aClass addSubclass: self.
    aClass class addSubclass: self class.
    self compileAll.
    self class compileAll.
    self allSubclasses do: [ :class |
        class compileAll.
        class class compileAll].
    self methodDictionaries:
        (Array with: self methodDictionary), self superclass methodDictionaries.!

removeFromSystem
        "Remove the receiver from Smalltalk.  Report
         an error if there are any subclasses or
         instances of the receiver."
		"@07.11.93 ch: Remove the class from all applications" 
	ChApplication removeClass: self.
    ^self removeFromSystem: true.! !



!Class class methods ! !



!SystemDictionary methods !
   
compressChanges
		"Build a new change log file retaining
         only the latest version of changed
         methods in the current change log.
         Save the image to the image file."
		"@24.09.94 ch" 
		"@23.09.94 ch: clear up the method history"
		"@21.02.94 ch: log class comments too"
	| logDirectory stream tempLogName dialog answer classSource |
    BackupImage ifTrue: [  ( answer := self backupChanges ) ~= 0 ifTrue: [ ^DosDLL OS2Error: answer ] ].
    dialog := DialogBox new fromModule: VPMVM id: 100.
    dialog showWindow.
    logDirectory := (Sources at: 2) file directory.
    stream := logDirectory newFile: 'ChangLog.tmp'.
    stream lineDelimiter: Cr.
    tempLogName := stream pathName.
    self getSourceClasses do: [ :class |
		class dll = 0 ifTrue: [
			"file out the class definition"
			classSource := WriteStream on: (String new: 100).
			class fileOutOn: classSource.
			stream cr; cr; nextPutAll: '"define class"';
				nextChunkPut: classSource contents].
		].
    self getSourceClasses do: [ :class |
        self compressChangesOf: class class into: stream.
        self compressChangesOf: class into: stream].
    self getSourceClasses do: [ :class |
		(ChApplication classCommentOf: class) notEmpty ifTrue: [
			stream cr; cr; nextPutAll: 'ChApplication setClassCommentOf: ',
		        class name, ' to: ', (String with: 10 asCharacter);
				nextChunkPut: (ChApplication classCommentOf: class) printString].
		].
    stream close.
    ( self removeFile: 2 dialog: dialog )
        ifFalse: [ 
            File remove: tempLogName ifAbsent: [ ].
            ^self ].
    File
        rename: tempLogName
        to: (Sources at: 2) pathName.
    Sources
        at: 2
        put: (logDirectory file: (Sources at: 2) file name).
    (Sources at: 2) lineDelimiter: Cr.

	"Clear up the method history."
	ChApplication historyRemove: (ChApplication methodHistory select: [:each |
		(each at: 2) dll = 0 or: [((each at: 2) classField compiledMethodAt: 
			(each at: 2) selector) == (each at: 2)]]).

    Transcript saveImageNoConfirm.
    dialog close!
  
implementorsOf: aSymbol in: aClass
		"Open a MethodBrowser on all methods
         named aSymbol in aClass and its subclasses."
		"@06.07.94 ch: ChChangeBrowser renamed to ChSourceBrowser" 
		"@22.06.94 ch: use ChChangeBrowser instead of MethodBrowser"
	| methods |
    methods := OrderedCollection new.
    CursorManager execute change.
    aClass isCollection
        ifTrue: [
            aClass do: [:class |
                methods := methods, (class implementorsOf: aSymbol)]]
        ifFalse: [
            methods := aClass implementorsOf: aSymbol].
    CursorManager normal change.
	ChSourceBrowser new
		extraTitle: 'Implementors of ', aSymbol printString;
		openOnCompiledMethods: methods!
   
sendersOf: aSymbol in: aClass
		"Open a MethodBrowser on all methods in aClass
         and its subclasses that reference aSymbol."
		"@06.07.94 ch: ChChangeBrowser renamed to ChSourceBrowser" 
		"@22.06.94 ch: use ChChangeBrowser instead of MethodBrowser"
	| methods |
    methods := OrderedCollection new.
    CursorManager execute change.
    aClass isCollection
        ifTrue: [
            aClass do: [:class |
                methods := methods, (class sendersOf: aSymbol)]]
        ifFalse: [
            methods := aClass sendersOf: aSymbol].
    CursorManager normal change.
    ChSourceBrowser new
		extraTitle: 'Senders of ', aSymbol printString;
		highlightLiterals: aSymbol;
		openOnCompiledMethods: methods! !



!SystemDictionary class methods ! !



!NotificationManager methods !
 
startUp
		"Private - Start a Smalltalk/V session."
		"@11.09.94 ch: added support for the startvpm.st file" 
	| font previousScreenSize |
    Font initialize.
    font := PM memPS currentFont.
    Font setSysFont: font.
    CursorManager initialize.
    Bitmap initialize.
    previousScreenSize := Display extent.
    Screen initialize.
    FileDialog initialize.
    DosLibrary setMaxFH: 100.
    VPMVM closeStartupDialog.
    Smalltalk isRunTime
        ifTrue: [self startUpApplication]
        ifFalse: [
            ((previousScreenSize ~= Display extent) or: [windows isEmpty])
                ifTrue: [
                    self initialize.
                    TextFont := ListFont := font.
                    TranscriptWindow initializeTranscript]
                ifFalse: [self resume].
            SmalltalkEmulatorInst := SmalltalkEmulator newServer.
			(File exists: 'startvpm.st' in: Disk) ifTrue: [
				(Disk file: 'startvpm.st') fileIn; close]
			].! !



!NotificationManager class methods ! !



!DictionaryInspector methods !
  
inspectMenu: pane
        "Private - Set the dictionary
         inspector list pane menu."
		"@11.05.94 ch: added #sendersOfSelection" 
    | menu |
    menu := (Menu 
        labels: '~Inspect\~Add\~Senders\~Remove' withCrs
        lines: Array new
        selectors: #(inspectSelection add sendersOfSelection remove))
            title: '~Dictionary';
            owner: self;
            yourself.
    menu disableItem: #inspectSelection.
    pane setMenu: menu!
 
sendersOfSelection
        "Private - Open a method browser on the senders
        of the selected association."
		"@11.05.94 ch" 
    instIndex isNil
        ifTrue: [^self].
    Smalltalk sendersOf: (object associationAt: (instList at: instIndex) key)! !



!DictionaryInspector class methods ! !



!ApplicationWindow methods !

openChApplicationBrowser
		"Private - The user selected Browse Applications from the 
		File menu."
		"@06.07.94 ch: Cursor to execute state" 
		"@06.11.93 ch"
	CursorManager execute changeFor: [ 
	    ChApplicationBrowser new open]!
 
openIPFBrowser
		"Private - The user selected 'Edit IPF Files' from the File 
		menu."
		"@06.07.94 ch: Cursor to execute state" 
		"@12.02.94 ch: Creation"
	CursorManager execute changeFor: [ 
	    ChIPFBrowser new open].!
   
openLibraryBuilder
		"Private - The user selected Build Libraries from the File 
		menu."
		"@06.07.94 ch: Cursor to execute state" 
		"@12.02.94 ch: Creation"
	CursorManager execute changeFor: [ 
	    ChLibraryBuilder new open].!

openSourceBrowser
		"Private - The user selected Browser Changes from the 
		File menu."
		"@06.07.94 ch: ChChangeBrowser renamed to ChSourceBrowser" 
		"@06.07.94 ch: Cursor to execute state"
		"@07.05.94 ch: use ChSourceBrowser>>open"
		"@25.02.94 ch: use ChFileDialog"
		"@05.02.94 ch"
	CursorManager execute changeFor: [ 
		ChSourceBrowser new open]!
 
saveImageFile
		"Private - Save the current image and
         log the event on the change log."
		"@02.09.94 ch: bug fix: lastSavedImagePosition must be set prior to image 
		save" 
		"@09.08.94 ch: Save the last SavedImage position"
	| int handles iconHandles answer |
    Bitmap allInstancesPrim do: [:b| b aboutToSaveImage].
    (Sources at: 2) close.
    CursorManager execute change.
    Disk makeCurrent.
    int := Process enableInterrupts: false.
    DynamicLinkLibrary withAllSubclasses do: [:class |
        class clearCachedAddresses].
    handles := IdentityDictionary new.
    File allInstancesPrim do: [:each |
        handles at: each put: each fileId.
        each fileId: nil].
    iconHandles := IdentityDictionary new.
    Icon allInstancesPrim do: [:each |
        iconHandles at: each put: each handle.
        each handle: nil].
	ChSourceBrowser lastSavedImagePosition: (Sources at: 2) size.
    answer := Smalltalk save.
    handles associationsDo: [:a |
        a key fileId: a value].
    iconHandles associationsDo: [:a |
        a key handle: a value].
    Process enableInterrupts: int.
    Smalltalk openChangeLogIn: (Sources at: 2) file directory.
    answer ~= 0 ifTrue: [
        MessageBox
            notify: 'IMPORTANT WARNING!!'
            withText: 'An error has occurred during image save.  Your image file is probably corrupted.  DO NOT EXIT Smalltalk!!  You should determine the cause of the problem (such as "out of disk space"), fix it, and save your image again.'.
        ^DosDLL OS2Error: answer ].
    Smalltalk logEvaluate:
        '"*** saved image on: '
        , Date today printString, ' '
        , Time now printString, ' ***"'.
    (Sources at: 2) flush! !



!ApplicationWindow class methods !
   
fileMenu
		"Private - Answer the File menu."
		"@06.07.94 ch: ChChangeBrowser renamed to ChSourceBrowser" 
		"@25.02.94 ch"
		"@12.02.94 ch: added openLibraryBuilder"
		"@16.08.93 ch : Added ChangeBrowser"
	^Menu new
        appendItem: '~New Workspace	Alt+N' selector: #openWorkspace accelKey: $n accelBits: AfAlt | AfChar ;
        appendItem: '~Open...	Alt+O' selector: #openFile accelKey: $o accelBits: AfAlt | AfChar ;
        appendItem: '~Install...	Alt+I' selector: #installFile accelKey: $i accelBits: AfAlt | AfChar ;
        appendItem: '~Save	Alt+S' selector: #accept accelKey: $s accelBits: AfAlt | AfChar ;
        appendItem: 'Save ~As...	Alt+A' selector: #saveAs accelKey: $a accelBits: AfAlt | AfChar ;
        appendItem: '~Browse Classes	Alt+B' selector: #openClassBrowser accelKey: $b accelBits: AfAlt | AfChar ;
		appendSeparator;
		appendItem: 'Browse App~lications' selector: #openChApplicationBrowser;
		appendItem: 'Browse ~Source Files' selector: #openSourceBrowser;
		appendItem: 'Build ~Libraries' selector: #openLibraryBuilder;
		appendItem: 'Edit IPF Files' selector: #openIPFBrowser;
		appendSeparator;
        appendItem: 'Browse ~Disk	Alt+D' selector: #openDiskBrowser accelKey: $d accelBits: AfAlt | AfChar ;
        appendItem: '~Print	Alt+P' selector: #print accelKey: $p accelBits: AfAlt | AfChar ;
        appendItem: '~Restore	Alt+R' selector: #restore accelKey: $r accelBits: AfAlt | AfChar ;
        appendSeparator ;
        appendItem: 'Save Image...' selector: #saveImage ;
        title: '~File'! !



!TextPane methods !
  
formatComment
		"Format the comment of the method in the text pane."
		"@30.07.94 ch: use config variable 'CommentWidth'" 
		"@06.11.93 ch"
	| start end |  
	self disableRefresh.
	self selectBefore: 1 @ 1.
    (self searchPM: MlfsearchSelectmatch  for: '"') ifFalse: [^self].
    self getPMSelection. start := selStart.
	(self searchPM: MlfsearchSelectmatch  for: '"') ifFalse: [^self].
	self getPMSelection. end := selEnd.
	self selectFrom: ((self pointFromIndex: start) x: 1) to: 
		(self pointFromIndex: end).
	self insert: (self selectedItem 
		formatLeftString: (String with: Tab with: Tab) width: 
			(ChApplication configVariables at: 'CommentWidth')).
	self enableRefresh!

implementorsOfSelection
		"Open a message browser on the implementors of the the selected 
		string. If the selection is empty prompt the user for a string."
		"@06.11.93 ch"  
	| aString | 
	(aString := self selectedItem) isEmpty ifTrue: [
		aString := Prompter prompt: 'Please enter a selector name.'
			default: ''].
	aString isNil ifTrue: [^self].
	aString := aString trim: #isSelectorCharacter.
	Smalltalk implementorsOf: aString asSymbol!
  
sendersOfSelection
		"Open a message browser on the senders of the the selected 
		string. If the selection is empty prompt the user for a string."
		"@08.05.94 ch: use Smalltalk>>extendedSendersOfSelection:" 
		"@06.03.94 ch: look into Pooldictionaries also" 
		"@06.11.93 ch"  
	| aString | 
	(aString := self selectedItem) isEmpty ifTrue: [
		aString := Prompter 
			prompt: 'Please enter a selector or global or pool variable name.'
			default: ''].
	aString isNil ifTrue: [^self].
	Smalltalk extendedSendersOf: aString.! !



!TextPane class methods !

editMenu
        "Answer the Edit menu."
		"@06.11.93 ch"  
    | ctrlBits |
    ctrlBits := AfChar | AfControl.
    ^Menu new
        appendItem: '~Undo	Alt+BckSp' selector: #undo accelKey: VkBackspace accelBits: AfAlt | AfVirtualkey;
        appendItem: 'Cu~t	Shift+Del' selector: #cutSelection accelKey: VkDelete accelBits: AfShift | AfVirtualkey ;
        appendItem: '~Copy	Ctrl+Ins' selector: #copySelection accelKey: VkInsert accelBits: ctrlBits | AfVirtualkey ;
        appendItem: '~Paste	Shift+Ins' selector: #pasteSelection accelKey: VkInsert accelBits: AfShift | AfVirtualkey ;
        appendItem: 'C~lear	Del' selector: #deleteSelection ;
        appendItem: 'Select ~All	Ctrl+A' selector: #selectAll accelKey: $a accelBits: ctrlBits;
        appendItem: 'Print ~Selection	Ctrl+P' selector: #printSelection accelKey: $p accelBits: ctrlBits;
        appendItem: '~Word Wrap	Ctrl+W' selector: #toggleWrap acceleratorString: 'Ctrl+W';
        appendSubMenu: (self bracketsMenu owner: self) ;
		appendItem: '~Format Comment	Ctrl-O' selector: #formatComment accelKey: $o accelBits: ctrlBits;
        appendSeparator ;
        appendItem: '~Find/Replace...	Ctrl+F' selector: #findReplace accelKey: $f accelBits: ctrlBits;
        appendItem: 'Find A~gain	Ctrl+G' selector: #again accelKey: $g accelBits: ctrlBits;
        accelKey: $c accelBits: ctrlBits  for: #copySelection;
        accelKey: $x accelBits: ctrlBits  for: #cutSelection;
        accelKey: $v accelBits: ctrlBits  for: #pasteSelection;
        title: '~Edit'!
 
smalltalkMenu
        "Answer the Smalltalk menu."
		"@06.11.93 ch"
    ^Menu new
        appendItem: '~Show It	Ctrl+S' selector: #printIt accelKey: $s accelBits: AfChar | AfControl ;
        appendItem: '~Do It	Ctrl+D' selector: #doIt accelKey: $d accelBits: AfChar | AfControl ;
        appendItem: '~Inspect It	Ctrl+I' selector: #inspectIt accelKey: $i accelBits: AfChar | AfControl ;
        appendItem: 'File It I~n	Ctrl+N' selector: #fileItIn accelKey: $n accelBits: AfChar | AfControl ;
        appendItem: 'Senders' selector: #sendersOfSelection;
        appendItem: 'Implementors' selector: #implementorsOfSelection;
        title: '~Smalltalk'! !
"Finalization code"
 
"Set Class Comment for the ClassReader class which is
used as a sample for the class documentation report."   
(Smalltalk includesKey: #ChApplication) ifTrue: [
(Smalltalk at: #ChApplication) setClassCommentOf: 'ClassReader' to: 
'A ClassReader supports Smalltalk source code reading and installation (compilation) from a stream, and writing to a stream. The source code is in ''chunk format''. A ClassReader is used for writing the entire source code of a class to a file, for reading a file to define a class, and for reading portions of a file to selectively recover methods (for example, from the change.log).

@

.class : Contains the class to be worked on by the ClassReader.']!

  
Transcript cr; nextPutAll: 'ChapMan Integration installed.'!
