/
ClyBrowserSearchDialogWindow.class.st
176 lines (136 loc) · 5.08 KB
/
ClyBrowserSearchDialogWindow.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
"
I a a search dialog to select one or multiples items from the queries objects.
I am created by browser and users should call me using following methods:
browser searchDialog
requestSingleObject: 'Choose package' from: ClyAllPackages sorted.
browser searchDialog
requestMultipleObjects: 'Choose classes' from: ClyAllClasses sorted
I always force semi async execution of given query.
In case when query result include just a couple of items I hide default view filters.
To select items in the list users can use #enter key. To close dialog they can use #esc.
By default filter is focused. And as soon as dialog openes user can type filter.
If after filter there is only item in the list I will choose it when user submit the dialog.
If there are multiple items I try to find the item with exact same name as filter text.
Internal Representation and Key Implementation Points.
Instance Variables
browser: <ClyBrowser>
itemsView: <ClyQueryView>
"
Class {
#name : #ClyBrowserSearchDialogWindow,
#superclass : #DialogWindow,
#instVars : [
'browser',
'itemsView'
],
#category : #'Calypso-Browser-UI'
}
{ #category : #'instance creation' }
ClyBrowserSearchDialogWindow class >> for: aBrowser [
^self new
browser: aBrowser
]
{ #category : #accessing }
ClyBrowserSearchDialogWindow >> browser [
^ browser
]
{ #category : #accessing }
ClyBrowserSearchDialogWindow >> browser: anObject [
browser := anObject
]
{ #category : #controlling }
ClyBrowserSearchDialogWindow >> changeStateBy: aBlock [
aBlock value
]
{ #category : #controlling }
ClyBrowserSearchDialogWindow >> changeStateOf: aQueryView by: aBlock [
aBlock value
]
{ #category : #'events handling' }
ClyBrowserSearchDialogWindow >> defaultFocusMorph [
^itemsView filterField ifNil: [ itemsView dataSource table ]
]
{ #category : #private }
ClyBrowserSearchDialogWindow >> findObjectsSameAsFilter [
itemsView dataSource numberOfRows = 1 ifTrue: [
"single element means that it was found by filter and we can use it without extra search"
^itemsView dataSource allElements collect: #actualObject ].
^itemsView findItemsSameAsFilter
ifNotEmpty: [ :foundItems | foundItems collect: #actualObject ]
]
{ #category : #controlling }
ClyBrowserSearchDialogWindow >> ignoreNavigationDuring: aBlock [
aBlock value
]
{ #category : #controlling }
ClyBrowserSearchDialogWindow >> itemsChanged [
]
{ #category : #initialization }
ClyBrowserSearchDialogWindow >> newContentMorph [
itemsView := ClyQueryViewMorph for: self.
itemsView width: 250.
itemsView whenDoubleClickDo: [:ann | self ok ].
itemsView whenEnterKeyPressedDo: [:ann | self ok ].
itemsView whenEscapeKeyPressedDo: [:ann | self cancel ].
^itemsView
]
{ #category : #private }
ClyBrowserSearchDialogWindow >> openOn: aQuery withTitle: dialogTitle thenDo: resultActionBlock [
self showItemsOf: aQuery.
self title: dialogTitle.
self openModal.
^["Following two lines should prevent special condition
when filter background process modifies current table data source.
During this process it first closes existing data source
and only after that it sets up new filtered data source"
itemsView table cleanupFilter. "it ensures that filter process will not affect table anymore"
itemsView dataSource isClosed ifTrue: [
"This branch is consiquence of corner case when filter logic closes current data source
but does not yet set up new filtered data source.
In that case any query of items from closed data source will fail.
And to avoid it we simply abort search request"
CmdCommandAborted signal ].
self cancelled ifTrue: [ CmdCommandAborted signal ].
resultActionBlock value]
ensure: [ itemsView closeDataSource]
]
{ #category : #requests }
ClyBrowserSearchDialogWindow >> requestMultipleObjects: dialogTitle from: aQuery [
self
openOn: aQuery
withTitle: dialogTitle
thenDo: [
itemsView selection isEmpty ifTrue: [ ^self findObjectsSameAsFilter ].
^itemsView selection actualObjects]
]
{ #category : #requests }
ClyBrowserSearchDialogWindow >> requestMultipleObjects: dialogTitle from: aQuery inScope: aScope [
aScope bindTo: browser navigationEnvironment.
^self requestMultipleObjects: dialogTitle from: (aScope adoptQuery: aQuery)
]
{ #category : #requests }
ClyBrowserSearchDialogWindow >> requestSingleObject: dialogTitle from: aQuery [
self
openOn: aQuery
withTitle: dialogTitle
thenDo: [
itemsView selection isEmpty ifTrue: [
^self findObjectsSameAsFilter
ifEmpty: [ CmdCommandAborted signal ]
ifNotEmpty: [ :items | items first]].
^itemsView selection lastSelectedItem actualObject]
]
{ #category : #requests }
ClyBrowserSearchDialogWindow >> requestSingleObject: dialogTitle from: aQuery inScope: aScope [
aScope bindTo: browser navigationEnvironment.
^self requestSingleObject: dialogTitle from: (aScope adoptQuery: aQuery)
]
{ #category : #private }
ClyBrowserSearchDialogWindow >> showItemsOf: aQuery [
| actualQuery |
actualQuery := aQuery isBoundToEnvironment
ifTrue: [ aQuery ]
ifFalse: [ aQuery withScope: browser systemScope ]..
itemsView showQuery: actualQuery semiAsync.
itemsView adoptForDialog
]