TextEditor has 49 private instance methods. Fortunately, many of the methods have only a few lines of code. Though you can implement them in any order, begin with getter and setter methods.
Method fileName
fileName "Private - Answers the value of fileName." ^fileName
Method fileName:
fileName: value "Private - Sets the value of fileName." fileName := value.
Method mainWindow
mainWindow "Private - Answers the value for mainWindow." ^mainWindow
Method modified
modified "Private - Answers the value for modified." ^modified
Method popup
popup "Private - Answers the value for popup." ^popup
Method shell
shell "Private - Answers the value for shell." ^shell
Method text
text "Private - Answers the receiver's text widget." ^text
Method workRegion:
workRegion: aWidget "Private - Sets the work region to aWidget." workRegion := aWidget
Method initialize
initialize "Private - Initializes the receiver." modified := false. "Text has not changed since last save."
Method createWindow
createWindow "Private - Creates a window for the text editor." self createMainWindow; createMenuBar; createWorkRegion; createPulldownMenus. self createTopLevelShell. self createPopupMenu. self addPopupMenu.
Method createMainWindow
createMainWindow "Private - Creates a window." mainWindow := CwMainWindow createWidget: 'mainWindow' parent: self shell argBlock: nil
Method createTopLevelShell
createTopLevelShell "Private - Creates a form to hold user interface elements." self shell width: 600; height: 400. self shell addCallback: XmNwindowCloseCallback receiver: self selector: #windowClose:clientData:callData: clientData: nil.
Method createShell
createShell "Private - Create a shell for aWidget." shell := CwTopLevelShell appCreateShell: self class name applicationClass: CwAppContext defaultApplicationClass display: CgDisplay default argBlock: nil.
Method createMenuBar
createMenuBar "Private - Creates a menu bar for the window." menuBar := (mainWindow createMenuBar: 'menuBar' argBlock: nil) manageChild
Method createWorkRegion
createWorkRegion "Private - Creates a work region." (text := self mainWindow createScrolledText: 'text' argBlock: [:w | w editMode: XmMULTILINEEDIT]) manageChild. self workRegion: self text parent. self addValueChangedCallback.
Method createPulldownMenus
createPulldownMenus "Private - Creates pulldown menus." self createFileMenu. self createEditMenuForTextWidget: self text.
Method addPulldownMenu:
addPulldownMenu: label "Private - Adds a pulldown menu to the menu bar." ^self addMenuTo: menuBar label: label
Method addMenuTo:label:
addMenuTo: aParent label: labelString "Private - Adds a menu." | rowColumn labelButton | rowColumn := aParent createPulldownMenu: 'RowColumn',labelString argBlock: nil. labelButton := aParent createCascadeButton: labelString argBlock: nil. labelButton subMenuId: rowColumn; manageChild. ^labelButton
Method addMenuEntryTo:label:selector:
addMenuEntryTo: aParent label: aLabel selector: aSelector "Private - Adds a menu choice to a menu." ^self addMenuEntryTo: aParent label: aLabel selector: aSelector clientData: nil
Method addMenuEntryTo:label:selector:clientData:
addMenuEntryTo: aParent label: aLabel selector: aSelector clientData: clientData "Private - Creates a push button with name aLabel, parent aParent, callback aSelector, and nil as the client data for the callback. Manages the resulting widget." | aButton | aButton := CwPushButton createManagedWidget: aLabel parent: aParent argBlock: nil. aButton addCallback: XmNactivateCallback receiver: self selector: aSelector clientData: clientData; labelString: aLabel. ^aButton
Method createEditMenuForTextWidget:
createEditMenuForTextWidget: aTextWidget "Private - Creates an Edit menu." | aMenu | aMenu := (self addMenuTo: menuBar label: 'Edit') subMenuId. self addMenuEntryTo: aMenu label: 'Copy' selector: #copySelection:clientData:callData: clientData: aTextWidget. self addMenuEntryTo: aMenu label: 'Cut' selector: #cutSelection:clientData:callData: clientData: aTextWidget. self addMenuEntryTo: aMenu label: 'Paste' selector: #pasteSelection:clientData:callData: clientData: aTextWidget. ^aMenu
Method createFileMenu
createFileMenu "Private - Creates a File menu. Answers the pulldown menu." | fileMenu | fileMenu := (self addPulldownMenu: 'File') subMenuId. (self addMenuEntryTo: fileMenu label: 'New Workspace' selector: #newWorkspace:clientData:callData:) accelerator: (CwAccelerator mask: ControlMask keysym: XKn); acceleratorText: 'Ctrl+N'. (self addMenuEntryTo: fileMenu label: 'Open...' selector: #open:clientData:callData:) accelerator: (CwAccelerator mask: ControlMask keysym: XKo); acceleratorText: 'Ctrl+O'.
(fileMenu createSeparator: '-' argBlock: nil) manageChild. (self addMenuEntryTo: fileMenu label: 'Save' selector: #accept:clientData:callData:) accelerator: (CwAccelerator mask: ControlMask keysym: XKs); acceleratorText: 'Ctrl+S'. self addMenuEntryTo: fileMenu label: 'Save As...' selector: #saveAs:clientData:callData:. (self addMenuEntryTo: fileMenu label: 'Undo' selector: #undo:clientData:callData:) accelerator: (CwAccelerator mask: ControlMask keysym: XKr); acceleratorText: 'Ctrl+R'.
(fileMenu createSeparator: '-' argBlock: nil) manageChild. (self addMenuEntryTo: fileMenu label: 'Exit' selector: #windowClose:clientData:callData:) accelerator: (CwAccelerator mask: ControlMask keysym: XKq); acceleratorText: 'Ctrl+Q'. ^fileMenu
Method createPopupMenu
createPopupMenu "Private - Calls methods which define choices in the popup menu." | clientData | popup := self text createPopupMenu: 'popup' argBlock: nil. clientData := Array with: self text with: [self]. self createPopupUndo. self createPopupCopy. self createPopupCut. self createPopupPaste. self createPopupSave.
Method addPopupMenu
addPopupMenu "Private - Creates a popup menu." self text addEventHandler: ButtonMenuMask receiver: self selector: #popup:clientData:callData: clientData: self popup.
Method createPopupCopy
createPopupCopy "Private - Creates a Copy menu choice." | button | button := popup createPushButton: 'Copy' argBlock: nil. button addCallback: XmNactivateCallback receiver: self selector: #copySelection:clientData:callData: clientData: self text; manageChild.
Method createPopupCut
createPopupCut "Private - Creates a Cut menu choice." | button | button := popup createPushButton: 'Cut' argBlock: nil. button addCallback: XmNactivateCallback receiver: self selector: #cutSelection:clientData:callData: clientData: self text; manageChild.
Method createPopupPaste
createPopupPaste "Private - Creates a Paste menu choice." | button | button := popup createPushButton: 'Paste' argBlock: nil. button addCallback: XmNactivateCallback receiver: self selector: #pasteSelection:clientData:callData: clientData: self text; manageChild. (popup createSeparator: '-' argBlock: nil) manageChild.
Method createPopupSave
createPopupSave "Private - Creates a Save menu choice." | button | button := popup createPushButton: 'Save' argBlock: nil. button addCallback: XmNactivateCallback receiver: self selector: #accept:clientData:callData: clientData: self text; manageChild.
Method createPopupUndo
createPopupUndo "Private - Creates an Undo menu choice." | button | button := popup createPushButton: 'Undo' argBlock: nil. button addCallback: XmNactivateCallback receiver: self selector: #undo:clientData:callData: clientData: self text; manageChild. (popup createSeparator: '-' argBlock: nil) manageChild.
Method realizeWindow
realizeWindow "Private - Realizes the receiver's widget hierarchy." shell realizeWidget.
Method accept:clientData:callData:
accept: w clientData: clientData callData: callData "Private - Calls methods that save the text." fileName isNil ifTrue: [self saveAs: w clientData: clientData callData: callData] ifFalse: [ self writeFileName: fileName; removeValueChangedCallback; addValueChangedCallback].
Method addValueChangedCallback
addValueChangedCallback "Private - Adds the valueChangedCallback and clears the modified flag." self text addCallback: XmNvalueChangedCallback receiver: self selector: #valueChanged:clientData:callData: clientData: nil. modified := false.
Method copySelection:clientData:callData:
copySelection: aButton clientData: aTextWidget callData: callData "Private - Marks selected text for copying." ^aTextWidget copySelection
Method cutSelection:clientData:callData:
cutSelection: aButton clientData: aTextWidget callData: callData "Private - Marks selected text for cut operation." ^aTextWidget cutSelection
Method newWorkspace:clientData:callData:
newWorkspace: w clientData: ignore1 callData: ignore2 "Private - Opens a second instance of the text editor." self class new open.
Method open:clientData:callData:
open: w clientData: ignored1 callData: ignored2 "Private - Processes the open callback from the file menu." | name | (name := (CwFileSelectionPrompter for: self shell) title: 'Open File'; prompt) isNil ifTrue: [^self]. self removeValueChangedCallback. self readFileName: name. self addValueChangedCallback. self updateTitle.
Method pasteSelection:clientData:callData:
pasteSelection: aButton clientData: aTextWidget callData: callData "Private - Pastes text in the clipboard." ^aTextWidget paste
Method popup:clientData:callData:
popup: label clientData: aMenu callData: event "Private - Pops up a menu under the cursor." event button = 3 ifFalse: [^self]. aMenu menuPosition: event; manageChild
Method removeValueChangedCallback
removeValueChangedCallback "Private - Removes the valueChangedCallback." self text removeCallback: XmNvalueChangedCallback receiver: self selector: #valueChanged:clientData:callData: clientData: nil.
Method saveAs:clientData:callData:
saveAs: w clientData: clientData callData: callData "Private - Processes the saveAs callback from the file menu." | name | (name := (CwFileSelectionPrompter for: self shell) title: 'Save As'; prompt) isNil ifTrue: [^self].
self writeFileName: name. self removeValueChangedCallback; addValueChangedCallback. self updateTitle.
Method undo:clientData:callData:
undo: widget clientData: clientData callData: callData "Private - Processes the undo callback from the file menu. Re-reads the contents of the last opened or saved file into the workspace." self removeValueChangedCallback. fileName isNil ifTrue: [self text setString: ''] ifFalse: [ self readFileName: fileName]. self addValueChangedCallback.
Method updateTitle
updateTitle "Private - Updates the window title." (fileName isNil or: [fileName = '']) ifTrue: [^self shell title: self class printString]. self shell title: fileName
Method valueChanged:clientData:callData:
valueChanged: w clientData: ignore1 callData: ignore2 "Private - Processes the valueChangedCallback from the text widget. Sets the modified flag to true and removes the callback." modified := true. self removeValueChangedCallback.
Method windowClose:clientData:callData:
windowClose: w clientData: clientData callData: callData "Private - Process the exit callback from the file menu. If the text has changed since the last save, prompt for the Save As dialog." self modified ifTrue: [ ((CwMessagePrompter for: self shell) iconType: XmICONQUESTION; buttonType: XmYESNO; messageString: 'Text has been modified - discard changes?'; prompt) = true ifFalse: [self saveAs: w clientData: clientData callData: callData]. ]. self shell unmapWidget
Method readFileName:
readFileName: name "Private - Reads the contents of the specified file into the workspace." | size file string result | file := CfsFileDescriptor open: name oflag: ORDONLY. file isCfsError ifTrue: [ ^(CwMessagePrompter for: self shell) iconType: XmICONERROR; messageString: file printString; prompt ].
(size := file size) >= self text maxLength ifTrue: [ file close. ^(CwMessagePrompter for: self shell) iconType: XmICONERROR; messageString: 'File size (',size printString,') is greater than Text widget maxLength (', self text maxLength printString,')' ; prompt ]. self showFontCursor: XCWatch in: self shell window while: [ string := String new: file size. result := file read: string startingAt: 1 nbyte: file size. ].
result isCfsError ifTrue: [ file close. ^(CwMessagePrompter for: self shell) iconType: XmICONERROR; messageString: result printString; prompt ]. self showFontCursor: XCWatch in: self shell window while: [ self text setString: string. ]. fileName := name. file close.
Method showCursor:in:while:
showCursor: cursor in: aCgWindow while: aBlock "Private - shows cursor." | result | aCgWindow defineCursor: cursor. result := aBlock value. aCgWindow undefineCursor. ^result
Method showFontCursor:in:while:
showFontCursor: anInteger in: aCgWindow while: aBlock "Private - Shows cursor." | cursor | cursor := self display createFontCursor: anInteger. self showCursor: cursor in: aCgWindow while: aBlock. cursor freeCursor
Method writeFileName:
writeFileName: name "Private - Writes the contents of the workspace to the specified file." | file string result | file := CfsFileDescriptor open: name oflag: OCREAT | OTRUNC | OWRONLY. file isCfsError ifTrue: [ ^(CwMessagePrompter for: self shell) iconType: XmICONERROR; messageString: file printString; prompt ]. self showFontCursor: XCWatch in: self shell window while: [ string := self text getString. result := file write: string startingAt: 1 nbyte: string size. ].
result isCfsError ifTrue: [ file close. ^(CwMessagePrompter for: self shell) iconType: XmICONERROR; messageString: result printString; prompt ]. fileName := name. file close.
Now that you have all of the methods implemented for TextEditor, try opening an instance of the class using DevelopChooser or by evaluating:
TextEditor new open
The finished window resembles the following: