/
GTSpotterPragmaBasedProcessor.class.st
199 lines (162 loc) · 5.5 KB
/
GTSpotterPragmaBasedProcessor.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
"
This is the abstract class that models a processor that is associated with a spotter category. It can spot items to be displayed in that category by reacting to a filter: message.
"
Class {
#name : #GTSpotterPragmaBasedProcessor,
#superclass : #Object,
#instVars : [
'allFilteredCandidates',
'order',
'running'
],
#classVars : [
'DefaultItemsLimit'
],
#category : #'GT-Spotter-Pragma-Based-Processors'
}
{ #category : #'accessing-defaults' }
GTSpotterPragmaBasedProcessor class >> defaultItemsLimit [
^ DefaultItemsLimit ifNil: [ DefaultItemsLimit := 25 ]
]
{ #category : #'accessing-defaults' }
GTSpotterPragmaBasedProcessor class >> defaultItemsLimit: aValue [
DefaultItemsLimit := aValue
]
{ #category : #'accessing-defaults' }
GTSpotterPragmaBasedProcessor class >> settingsOn: aBuilder [
"<systemsettings>
(aBuilder setting: #defaultItemsLimit)
target: self;
parent: #spotter;
label: 'Number of results per category';
default: 25;
order: 100;
description:
'Number of results per category to show in Spotter'"
]
{ #category : #public }
GTSpotterPragmaBasedProcessor >> actOn: anObject for: aStep [
anObject spotterActDefault: aStep
]
{ #category : #public }
GTSpotterPragmaBasedProcessor >> allFilteredCandidates [
^ allFilteredCandidates ifNil: [ allFilteredCandidates := OrderedCollection new ]
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> continueFilterInContext: aSpotterContext [
" We DO NOT prepare the context since we could no longer continue producing filtered candidates. "
(self shouldFilterInContext: aSpotterContext) ifTrue: [
" The continue-filter only puts more items on the stream but doesn't do any filtering at all. Therefore the original collection (=result/candidates) and its size remains the same and can be reused after the continue-filter has added more items. So we do not ressign the result to #allFilteredCandidates as it is done for the regular filter-loop. #allFilteredCandidates must never be modified more than once because the next #diveIntoCategory would render an invalid set of items !!! "
self doContinueFilterInContext: aSpotterContext ].
aSpotterContext stream
performSymbol: #onAmountChanged:in:
withArguments: { self allFilteredCandidates size . self }
]
{ #category : #printing }
GTSpotterPragmaBasedProcessor >> displayStringOn: stream [
stream
nextPutAll: 'Processor: ';
nextPutAll: self title asString
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> doContinueFilterInContext: aSpotterContext [
^ aSpotterContext doContinueFilterForProcessor: self
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> doFilterInContext: aSpotterContext [
"override this method to:
- add items to the stream
- return all found items at the end"
self subclassResponsibility
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> filterInContext: aSpotterContext [
running := true.
aSpotterContext stream
performSymbol: #processorStarted:
withArguments: { self }.
self prepareProcessorInContext: aSpotterContext.
(self shouldFilterInContext: aSpotterContext) ifTrue: [
allFilteredCandidates := self doFilterInContext: aSpotterContext ].
aSpotterContext stream
performSymbol: #onAmountChanged:in:
withArguments: { self allFilteredCandidates size . self }.
running := false.
aSpotterContext stream
performSymbol: #processorEnded:
withArguments: { self }.
]
{ #category : #printing }
GTSpotterPragmaBasedProcessor >> gtDisplayOn: stream [
stream
nextPutAll: 'Processor: ';
nextPutAll: self title asString
]
{ #category : #testing }
GTSpotterPragmaBasedProcessor >> hasFilteredCandidates [
^ self allFilteredCandidates notEmpty
]
{ #category : #initialization }
GTSpotterPragmaBasedProcessor >> initialize [
super initialize.
running := false
]
{ #category : #'key-bindings' }
GTSpotterPragmaBasedProcessor >> installKeymappingsOn: aGTSpotterMorph [
self keyBinding
ifNotNil: [ | keyCombination |
keyCombination := self keyBinding asKeyCombination.
aGTSpotterMorph
bindKeyCombination: keyCombination
ofProcessor: self
toAction: [ aGTSpotterMorph onKeyProcessor: self ] ]
]
{ #category : #testing }
GTSpotterPragmaBasedProcessor >> isRelevantForQuery: categoryQueryPrefix [
| trimmedProcessorTitle |
trimmedProcessorTitle := self title asLowercase
copyReplaceAll: String space
with: ''.
^ trimmedProcessorTitle beginsWith: categoryQueryPrefix
]
{ #category : #testing }
GTSpotterPragmaBasedProcessor >> isRunning [
^ running
]
{ #category : #'key-bindings' }
GTSpotterPragmaBasedProcessor >> keyBinding [
^ nil
]
{ #category : #accessing }
GTSpotterPragmaBasedProcessor >> order [
"Return assigned spotter order used to arrange categories in spotter UI"
<return: #Number>
^ order
]
{ #category : #accessing }
GTSpotterPragmaBasedProcessor >> order: aNumber [
"Assign to processor its spotter order to arrange categories
within spotter ui"
order := aNumber
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> prepareProcessorInContext: aContext [
allFilteredCandidates := nil
]
{ #category : #testing }
GTSpotterPragmaBasedProcessor >> shouldFilterInContext: aSpotterContext [
^ aSpotterContext notEmpty
or: [ self wantsToDisplayOnEmptyQuery ]
]
{ #category : #accessing }
GTSpotterPragmaBasedProcessor >> title [
self subclassResponsibility
]
{ #category : #accessing }
GTSpotterPragmaBasedProcessor >> wantsToDisplayOnEmptyQuery [
^ true
]
{ #category : #private }
GTSpotterPragmaBasedProcessor >> withItemsLimit: aLimit do: aBlock [
^ aBlock value
]