--- a/TextView.st Sat Jan 16 10:40:59 2016 +0000
+++ b/TextView.st Tue Jan 19 07:05:36 2016 +0000
@@ -30,7 +30,8 @@
WordSelectCatchesBlanks LastSearchPatterns
NumRememberedSearchPatterns LastSearchIgnoredCase
LastSearchWasMatch DefaultParenthesisSpecification
- LastSearchWasMatchWithRegex LastSearchWasWrapAtEndOfText'
+ LastSearchWasMatchWithRegex LastSearchWasWrapAtEndOfText
+ LastSearchWasReplace LastSearchReplacedString'
poolDictionaries:''
category:'Views-Text'
!
@@ -355,6 +356,17 @@
#selectLines
'If checked, lines containing the matched string are selected.'
+#replacePreserveCase
+'Preserve the case of replaced text'
+
+#replaceAll
+'Search and replace all occurrences of the searched string'
+
+#searchWithWrap
+'Wrap around at the end of the text, an continue the search from the top'
+
+#matchWithRegex
+'Use regex pattern for search (as opposed to glob pattern)'
)
! !
@@ -382,7 +394,7 @@
name: 'String search'
min: (Point 10 10)
max: (Point 1280 1024)
- bounds: (Rectangle 0 0 420 323)
+ bounds: (Rectangle 0 0 429 349)
)
component:
(SpecCollection
@@ -426,7 +438,7 @@
tabable: true
model: caseSensitive
translateLabel: true
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
(ViewSpec
name: 'MatchBox'
@@ -447,15 +459,15 @@
label: 'Regex Match'
name: 'CheckBox6'
layout: (LayoutFrame -151 1 0 0 0 1 22 0)
- visibilityChannel: matchWithRegexVisible
- enableChannel: match
+ activeHelpKey: matchWithRegex
+ enableChannel: matchWithRegexVisible
model: matchWithRegex
translateLabel: true
)
)
)
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
(CheckBoxSpec
label: 'Search Full Words'
@@ -466,7 +478,7 @@
tabable: true
model: searchFullWord
translateLabel: true
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
(CheckBoxSpec
label: 'At Begin of Line Only'
@@ -476,7 +488,7 @@
tabable: true
model: searchAtBeginOfLineOnly
translateLabel: true
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
(CheckBoxSpec
label: 'Variable Only'
@@ -489,7 +501,7 @@
model: searchVariable
translateLabel: true
labelChannel: stringWithVariableUnderCursorHolder
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
(CheckBoxSpec
label: 'Select Lines'
@@ -505,32 +517,36 @@
(CheckBoxSpec
label: 'Wrap at End of Text (forward only)'
name: 'CheckBox7'
- activeHelpKey: searchAtBeginOfLineOnly
+ activeHelpKey: searchWithWrap
level: 0
tabable: true
model: wrapAtEndOfTextHolder
translateLabel: true
- extent: (Point 420 24)
+ extent: (Point 429 24)
)
- (ViewSpec
- name: 'ReplaceBox'
+ (HorizontalPanelViewSpec
+ name: 'HorizontalPanel1'
+ horizontalLayout: leftFit
+ verticalLayout: fit
+ ignoreInvisibleComponents: false
+ elementsChangeSize: true
component:
(SpecCollection
collection: (
(CheckBoxSpec
- label: 'Global Replace With:'
+ label: 'Replace By:'
name: 'CheckBox4'
- layout: (LayoutFrame 0 0 0 0 180 0 23 0)
activeHelpKey: replaceText
level: 0
enableChannel: replaceEnabled
tabable: true
model: replaceBoolean
translateLabel: true
+ resizeForLabel: true
+ useDefaultExtent: true
)
(InputFieldSpec
name: 'ReplaceEntryField'
- layout: (LayoutFrame 180 0 0 0 -2 1 22 0)
activeHelpKey: replaceText
visibilityChannel: replaceBoolean
enableChannel: replaceBoolean
@@ -538,11 +554,34 @@
acceptOnReturn: true
acceptOnTab: true
acceptOnPointerLeave: true
+ extent: (Point 299 24)
)
)
)
- extent: (Point 420 24)
+ extent: (Point 429 24)
+ )
+ (CheckBoxSpec
+ label: ' Replace All (to End of Text)'
+ name: 'CheckBox8'
+ activeHelpKey: replaceAll
+ level: 0
+ enableChannel: replaceBoolean
+ tabable: true
+ model: replaceAllBoolean
+ translateLabel: true
+ extent: (Point 429 24)
+ )
+ (CheckBoxSpec
+ label: ' Preserve Case'
+ name: 'CheckBox9'
+ activeHelpKey: replacePreserveCase
+ level: 0
+ enableChannel: replaceBoolean
+ tabable: true
+ model: replacePreserveCaseBoolean
+ translateLabel: true
+ extent: (Point 429 24)
)
)
@@ -2211,7 +2250,8 @@
fwd ign match initialString
bindings bldr doSearch modal searchVariableHolder selectedVariable searchFullWordHolder
replaceBooleanEnabledHolder replaceBooleanHolder replaceTextHolder
- searchAtBeginOfLineOnlyHolder|
+ replaceAllBooleanHolder replacePreserveCaseBooleanHolder
+ searchAtBeginOfLineOnlyHolder updateReturnKeyBehavior|
searchBarActionBlock notNil ifTrue:[
self resetVariablesBeforeNewSearch.
@@ -2231,8 +2271,10 @@
searchVariableHolder := (lastSearchWasVariableSearch ? false) asValue.
searchFullWordHolder := false asValue.
searchAtBeginOfLineOnlyHolder := false asValue.
- replaceBooleanHolder := false asValue.
- replaceTextHolder := '' asValue.
+ replaceBooleanHolder := ("LastSearchWasReplace ?" false) asValue.
+ replaceAllBooleanHolder := false asValue.
+ replacePreserveCaseBooleanHolder := false asValue.
+ replaceTextHolder := (LastSearchReplacedString ? '') asValue.
replaceBooleanEnabledHolder := self isReadOnly not asValue.
patternHolder := '' asValue.
@@ -2268,34 +2310,42 @@
and:[selectedVariable notNil]].
isVariableSearch ifTrue:[
- searchAction := [self searchVariableWithSyntaxElement:selectedVariable forward:fwd].
+ searchAction :=
+ [
+ self searchVariableWithSyntaxElement:selectedVariable forward:fwd
+ ].
] ifFalse:[
lastSearchWasVariableSearch := false.
LastSearchIgnoredCase := lastSearchIgnoredCase := (caseHolder value not).
LastSearchWasMatch := lastSearchWasMatch := matchHolder value.
LastSearchWasMatchWithRegex := matchWithRegexHolder value.
LastSearchWasWrapAtEndOfText := wrapAtEndHolder value.
+ LastSearchWasReplace :=replaceBooleanHolder value.
+ LastSearchReplacedString := replaceTextHolder value.
+
pattern := patternHolder value.
pattern notEmptyOrNil ifTrue:[
- searchAction := [
- self searchUsingSpec:(
- ListView::SearchSpec new
- pattern:pattern
- ignoreCase:lastSearchIgnoredCase
- match: lastSearchWasMatch
- regexMatch:matchWithRegexHolder value
- variable: searchVariableHolder value
- fullWord: searchFullWordHolder value
- forward:fwd
- atBeginOfLineOnly:searchAtBeginOfLineOnlyHolder value
- wrapAtEnd:wrapAtEndHolder value).
- ]
+ searchAction :=
+ [
+ self searchUsingSpec:(
+ ListView::SearchSpec new
+ pattern:pattern
+ ignoreCase:lastSearchIgnoredCase
+ match: lastSearchWasMatch
+ regexMatch:matchWithRegexHolder value
+ variable: searchVariableHolder value
+ fullWord: searchFullWordHolder value
+ forward:fwd
+ atBeginOfLineOnly:searchAtBeginOfLineOnlyHolder value
+ wrapAtEnd:wrapAtEndHolder value).
+ ]
]
].
replaceBooleanHolder value ifTrue:[
- |selStart|
-
+ |selStart replacement replaceAction|
+
+ replacement := replaceTextHolder value.
isVariableSearch ifTrue:[
"/ must replace from the end towards beginning,
"/ because syntax-elements do not update their position, when
@@ -2303,23 +2353,39 @@
selectedVariable := selectedVariable lastElementInChain.
self selectFromCharacterPosition:selectedVariable start to:selectedVariable stop.
- searchAction := [selectedVariable := selectedVariable previousElement.
- selectedVariable notNil ifTrue:[
- self selectFromCharacterPosition:selectedVariable start to:selectedVariable stop.
- ].
- "/ self searchVariableWithSyntaxElement:selectedVariable forward:false
- ].
+ searchAction :=
+ [
+ selectedVariable := selectedVariable previousElement.
+ selectedVariable notNil ifTrue:[
+ self selectFromCharacterPosition:selectedVariable start to:selectedVariable stop.
+ ].
+ "/ self searchVariableWithSyntaxElement:selectedVariable forward:false
+ ].
].
+ replaceAction := [ self replace:replacement ].
+ replacePreserveCaseBooleanHolder value ifTrue:[
+ replaceAction := [
+ self selectionAsString isUppercaseFirst ifTrue:[
+ self replace:replacement asUppercaseFirst
+ ] ifFalse:[
+ self replace:replacement asLowercaseFirst
+ ]
+ ].
+ ].
+
selStart := self characterPositionOfSelection.
- self replace:(replaceTextHolder value).
-
+
+ replaceAction value.
searchAction value.
- [self characterPositionOfSelection ~= selStart] whileTrue:[
- selStart := self characterPositionOfSelection.
- self replace:(replaceTextHolder value).
- searchAction value.
- ]
+
+ replaceAllBooleanHolder value ifTrue:[
+ [self characterPositionOfSelection ~= selStart] whileTrue:[
+ selStart := self characterPositionOfSelection.
+ replaceAction value.
+ searchAction value.
+ ]
+ ]
] ifFalse:[
searchAction value.
].
@@ -2328,11 +2394,23 @@
bindings := IdentityDictionary new.
bindings at:#searchPattern put:patternHolder.
modal ifTrue:[
- bindings at:#nextAction put:[searchBox doAccept.].
- bindings at:#prevAction put:[fwd := false. searchBox doAccept.].
+ bindings at:#nextAction put:[
+ replaceAllBooleanHolder value ifTrue:[
+ searchBox doAccept.
+ ] ifFalse:[
+ doSearch value:true
+ ]
+ ].
+ bindings at:#prevAction put:[
+ replaceAllBooleanHolder value ifTrue:[
+ fwd := false. searchBox doAccept.
+ ] ifFalse:[
+ doSearch value:false
+ ]
+ ].
] ifFalse:[
- bindings at:#nextAction put:[doSearch value:true. "searchBox doAccept."].
- bindings at:#prevAction put:[doSearch value:false. "fwd := false. searchBox doAccept."].
+ bindings at:#nextAction put:[doSearch value:true.].
+ bindings at:#prevAction put:[doSearch value:false.].
].
bindings at:#caseSensitive put:caseHolder.
bindings at:#match put:matchHolder.
@@ -2370,7 +2448,28 @@
bindings at:#replaceEnabled put:replaceBooleanEnabledHolder.
bindings at:#replaceBoolean put:replaceBooleanHolder.
+ bindings at:#replaceAllBoolean put:replaceAllBooleanHolder.
+ bindings at:#replacePreserveCaseBoolean put:replacePreserveCaseBooleanHolder.
bindings at:#replaceTextHolder put:replaceTextHolder.
+
+ bindings at:#flyByHelpSpec put:self class flyByHelpSpec.
+
+ updateReturnKeyBehavior :=
+ [
+ |lbl returnAction|
+
+ "/ when replacing, do not close box on return
+ replaceBooleanHolder value ifTrue:[
+ lbl := 'Close'.
+ returnAction := searchAction.
+ ] ifFalse:[
+ lbl := 'Cancel'.
+ returnAction := nil.
+ ].
+ (bldr componentAt:#cancelButton) label:(resources string:lbl).
+ searchBox window keyboardProcessor returnAction:returnAction.
+ ].
+
replaceBooleanHolder onChangeEvaluate:
[
replaceBooleanHolder value ifTrue:[
@@ -2378,7 +2477,9 @@
] ifFalse:[
(bldr componentAt:#patternComboBox) requestFocus
].
+ updateReturnKeyBehavior value.
].
+
modal ifTrue:[
searchBox := SimpleDialog new.
] ifFalse:[
@@ -2397,7 +2498,8 @@
(bldr componentAt:#cancelButton) cursor:(Cursor thumbsDown).
modal ifTrue:[
- searchBox openDialog.
+ updateReturnKeyBehavior value.
+ searchBox openDialogAtPointer.
searchBox accepted ifTrue:[ doSearch value:fwd ].
] ifFalse:[
(bldr componentAt:#nextButton) isReturnButton:false.