Implementing the private instance methods
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.
Private methods for category Getters & Setters
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.
Private methods for category Initialization & Startup
Method initialize
initialize
"Private - Initializes the receiver."
modified := false. "Text has not changed since last save."
Private methods for category Window Creation
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.
Private methods for category Event Handlers
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.
Private methods for category File Operations
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: