/[eiffelstudio]/branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/class_browser/eb_grid_quick_search_tool.e
ViewVC logotype

Contents of /branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/class_browser/eb_grid_quick_search_tool.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62171 - (show annotations)
Tue Aug 1 01:27:17 2006 UTC (13 years, 4 months ago) by larryl
File size: 16501 byte(s)
First commit docking tabbed Eiffel Studio.
1 indexing
2 description: "Objects that represents a quick search tool binded to an {EVS_SEARCHABLE_COMPONENT} object"
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 author: ""
6 date: "$Date$"
7 revision: "$Revision$"
8
9 class
10 EB_GRID_QUICK_SEARCH_TOOL
11
12 inherit
13 EVS_GRID_SEARCH_TOOL
14 undefine
15 copy,
16 is_equal,
17 default_create
18 end
19
20 QUICK_SEARCH_BAR
21 rename
22 make as make_search_bar
23 redefine
24 user_initialization,
25 recycle
26 end
27
28 EVS_UTILITY
29 undefine
30 copy,
31 is_equal,
32 default_create
33 end
34
35 EB_CLASS_BROWSER_UTILITY
36 undefine
37 copy,
38 is_equal,
39 default_create
40 end
41
42 REFACTORING_HELPER
43 undefine
44 copy,
45 is_equal,
46 default_create
47 end
48
49 create
50 make
51
52 feature{NONE} -- Initialization
53
54 make (a_dev_window: EB_DEVELOPMENT_WINDOW) is
55 -- Initialization
56 require
57 a_dev_window_attached: a_dev_window /= Void
58 do
59 make_search_bar (a_dev_window.tools.search_tool)
60 end
61
62 user_initialization is
63 -- Called by `initialize'.
64 do
65 Precursor
66 advanced_button.disable_sensitive
67 previous_button.select_actions.extend (agent search_previous (False))
68 next_button.select_actions.extend (agent search_next (False))
69 close_button.select_actions.extend (agent hide_tool)
70 set_key_press_action (agent on_key_pressed_on_search_tool)
71 keyword_field.change_actions.extend (agent on_keyword_field_text_change)
72 end
73
74 feature -- Registration/Implementation
75
76 internal_attach is
77 -- Attach current to `a_component'.
78 do
79 put_tool
80 set_activate_accelerator (accelerator_from_preference ("show_quick_search_bar"))
81 set_deactivate_accelerator (accelerator_from_preference ("hide_quick_search_bar"))
82 set_search_next_accelerator (accelerator_from_preference ("search_selection"))
83 set_search_previous_accelerator (accelerator_from_preference ("search_backward"))
84 set_store_keyword_accelerator (accelerator_from_preference ("store_search_keyword"))
85 safe_register_agent (on_key_pressed_agent, searchable_component.grid.key_press_actions)
86 hide
87 end
88
89 internal_detach is
90 -- Detach current to `a_componet'.
91 do
92 remove_tool
93 safe_remove_agent (on_key_pressed_agent, searchable_component.grid.key_press_actions)
94 hide
95 end
96
97 feature -- Display
98
99 show_tool is
100 -- Display current search tool.
101 do
102 show
103 keyword_field.set_focus
104 end
105
106 hide_tool is
107 -- Hide current search tool.
108 do
109 hide
110 end
111
112 ensure_tool_on_top is
113 -- Ensure current quick search bar be displayed on top of grid.
114 do
115 is_tool_on_top := True
116 put_tool
117 ensure
118 tool_on_top: is_tool_on_top
119 end
120
121 ensure_tool_on_bottom is
122 -- Ensure current quick search bar be displayed on bottom of grid.
123 do
124 is_tool_on_top:= False
125 put_tool
126 ensure
127 tool_on_bottom: is_tool_on_bottom
128 end
129
130 feature -- Setting
131
132 set_activate_accelerator (a_accelerator: like activate_accelerator) is
133 -- Set `activate_accelerator' with `a_accelerator'.
134 do
135 activate_accelerator := a_accelerator
136 ensure
137 activate_accelerator_set: activate_accelerator = a_accelerator
138 end
139
140 set_deactivate_accelerator (a_accelerator: like deactivate_accelerator) is
141 -- Set `active_accelerator' with `a_accelerator'.
142 do
143 deactivate_accelerator := a_accelerator
144 ensure
145 deactivate_accelerator_set: deactivate_accelerator = a_accelerator
146 end
147
148 set_search_previous_accelerator (a_accelerator: like search_previous_accelerator) is
149 -- Set `search_previous_accelerator' with `a_accelerator'.
150 do
151 search_previous_accelerator := a_accelerator
152 ensure
153 search_previous_accelerator_set: search_previous_accelerator = a_accelerator
154 end
155
156 set_search_next_accelerator (a_accelerator: like search_next_accelerator) is
157 -- Set `search_next_accelerator' with `a_accelerator'.
158 do
159 search_next_accelerator := a_accelerator
160 ensure
161 search_next_accelerator_set: search_next_accelerator = a_accelerator
162 end
163
164 set_store_keyword_accelerator (a_accelerator: like store_keyword_accelerator) is
165 -- Set `store_keyword_accelerator' with `a_accelerator'.
166 do
167 store_keyword_accelerator := a_accelerator
168 ensure
169 store_keyword_accelerator_set: store_keyword_accelerator = a_accelerator
170 end
171
172 feature -- Status report
173
174 is_tool_displayed: BOOLEAN is
175 -- Is current search tool displayed?
176 do
177 Result := is_displayed
178 end
179
180 is_tool_on_top: BOOLEAN
181 -- Is current quick search bar on top of grid?
182
183 is_tool_on_bottom: BOOLEAN is
184 -- Is current quick search bar on bottom of grid?
185 do
186 Result := not is_tool_on_top
187 ensure
188 good_result: Result implies not is_tool_on_top
189 end
190
191 feature -- Accelerator
192
193 activate_accelerator: EV_ACCELERATOR
194 -- Accelerator to show current quick search tool
195 -- This accelerator will be registered in `searchable_component'.`grid'.
196
197 deactivate_accelerator: EV_ACCELERATOR
198 -- Key accelerator to deactivate current quick search tool
199
200 search_previous_accelerator: EV_ACCELERATOR
201 -- Accelerator to search previous
202
203 search_next_accelerator: EV_ACCELERATOR
204 -- Accelerator to search next
205
206 store_keyword_accelerator: EV_ACCELERATOR
207 -- Key accelerator to store current search keyword in search bar
208 -- and do a search next
209
210 feature -- Recyclable
211
212 recycle is
213 -- Recycle
214 do
215 Precursor {QUICK_SEARCH_BAR}
216 searchable_component := Void
217 end
218
219 feature{NONE} -- Actions
220
221 on_key_pressed_agent: PROCEDURE [ANY, TUPLE [EV_KEY]] is
222 -- Agent wrapper of `on_key_pressed'
223 do
224 if on_key_pressed_agent_internal = Void then
225 on_key_pressed_agent_internal := agent on_key_pressed
226 end
227 Result := on_key_pressed_agent_internal
228 ensure
229 result_attached: Result /= Void
230 end
231
232 on_key_pressed_agent_internal: like on_key_pressed_agent
233 -- Internal `on_key_pressed_agent'
234
235 on_key_pressed (a_key: EV_KEY) is
236 -- Action performed when key pressed in `searchable_component'.`grid'
237 require
238 attached: is_tool_attached
239 a_key_attached: a_key /= Void
240 local
241 l_component: like searchable_component
242 l_acc: EV_ACCELERATOR
243 do
244 l_component := searchable_component
245 if l_component.is_search_enabled then
246 -- Key accelerator to show quick search bar
247 l_acc := activate_accelerator
248 if l_acc = Void then
249 l_acc := ctrl_f_accelerator
250 end
251 if is_accelerator_matched (a_key, l_acc) then
252 if not is_displayed and then l_component.is_search_enabled then
253 show_tool
254 end
255 end
256 -- Key accelerator to search previous
257 l_acc := search_previous_accelerator
258 if l_acc /= Void and then is_accelerator_matched (a_key, l_acc) then
259 search_previous (False)
260 end
261 -- Key accelerator to search next
262 l_acc := search_next_accelerator
263 if l_acc /= Void and then is_accelerator_matched (a_key, l_acc) then
264 search_next (False)
265 end
266 end
267 end
268
269 on_key_pressed_on_search_tool (a_key: EV_KEY) is
270 -- On key pressed on any widget of search bar.
271 local
272 l_acc: EV_ACCELERATOR
273 do
274 l_acc := accelerator_from_preference ("hide_quick_search_bar")
275 if l_acc = Void then
276 l_acc := escape_accelerator
277 end
278 if is_accelerator_matched (a_key, l_acc) then
279 hide_tool
280 end
281 l_acc := accelerator_from_preference ("store_search_keyword")
282 if l_acc = Void then
283 l_acc := enter_accelerator
284 end
285 if is_accelerator_matched (a_key, l_acc) then
286 record_current_searched
287 search_next (False)
288 end
289 l_acc := search_next_accelerator
290 if l_acc /= Void and then is_accelerator_matched (a_key, l_acc) then
291 search_next (False)
292 end
293 l_acc := search_previous_accelerator
294 if l_acc /= Void and then is_accelerator_matched (a_key, l_acc) then
295 search_previous (False)
296 end
297 end
298
299 on_keyword_field_text_change is
300 -- Action to be performed when text in keyword field changes
301 do
302 if keyword_field.text.count > 0 then
303 search_next (True)
304 end
305 end
306
307 enter_accelerator: EV_ACCELERATOR is
308 -- Enter accelerator key
309 once
310 create Result.make_with_key_combination (create {EV_KEY}.make_with_code ({EV_KEY_CONSTANTS}.key_enter), False, False, False)
311 ensure
312 result_attached: Result /= Void
313 end
314
315 escape_accelerator: EV_ACCELERATOR is
316 -- Escape accelerator key
317 once
318 create Result.make_with_key_combination (create {EV_KEY}.make_with_code ({EV_KEY_CONSTANTS}.key_escape), False, False, False)
319 ensure
320 result_attached: Result /= Void
321 end
322
323 Ctrl_f_accelerator: EV_ACCELERATOR is
324 -- Ctrl + F accelerator key
325 once
326 create Result.make_with_key_combination (create {EV_KEY}.make_with_code ({EV_KEY_CONSTANTS}.key_f5), True, False, False)
327 ensure
328 result_attached: Result /= Void
329 end
330
331 feature{NONE} -- Implementation/Search
332
333 search_previous (a_start_from_current: BOOLEAN) is
334 -- Search previous according to current first selected item in `searchable_component'.`grid'.
335 -- If `a_start_from_current' is True, search will start from current selected item, if any,
336 -- otherwise, it will start from next item of current selected item.
337 require
338 attached: is_tool_attached
339 search_enabled: searchable_component.is_search_enabled
340 do
341 search_with_direction (True, a_start_from_current)
342 if is_tool_attached then
343 searchable_component.grid.set_focus
344 end
345 searchable_component.grid.set_focus
346 end
347
348 search_next (a_start_from_current: BOOLEAN) is
349 -- Search next according to current first selected item in `searchable_component'.`grid'.
350 -- If `a_start_from_current' is True, search will start from current selected item, if any,
351 -- otherwise, it will start from next item of current selected item.
352 require
353 attached: is_tool_attached
354 search_enabled: searchable_component.is_search_enabled
355 do
356 search_with_direction (False, a_start_from_current)
357 if is_tool_attached and then not keyword_field.has_focus then
358 searchable_component.grid.set_focus
359 end
360 end
361
362 prepare_search_engine (a_engine: like search_engine) is
363 -- Prepare `a_engine' for search,
364 -- e.g. setup search conditions.
365 require
366 a_engine_attached: a_engine /= Void
367 do
368 a_engine.enable_wrap_search
369 a_engine.set_keyword (current_keyword)
370 if is_case_sensitive then
371 a_engine.enable_case_sensitive_match
372 else
373 a_engine.disable_case_sensitive_match
374 end
375 if is_regex then
376 a_engine.enable_regular_expression_match
377 else
378 a_engine.disable_regular_expression_match
379 end
380 a_engine.enable_wrap_search
381 -- Fixme: match whole word and match whole cell should be implemented.
382 to_implement ("Implement code here to test if `match whole word' is selected.")
383 end
384
385 feature{NONE} -- Implementation/Layout
386
387 put_tool is
388 -- Put current quick search bar into `searchable_component'.
389 require
390 attached: is_tool_attached
391 local
392 l_source_container: EV_BOX
393 l_target_container: EV_BOX
394 do
395 if is_tool_on_top then
396 l_source_container := searchable_component.grid_bottom_container
397 l_target_container := searchable_component.grid_top_container
398 else
399 l_source_container := searchable_component.grid_top_container
400 l_target_container := searchable_component.grid_bottom_container
401 end
402 remove_tool_from_container (l_source_container)
403 put_tool_into_container (l_target_container)
404 ensure
405 tool_in_container:
406 (is_tool_on_top implies searchable_component.grid_top_container.has (Current) and
407 is_tool_on_bottom implies searchable_component.grid_bottom_container.has (Current))
408 end
409
410 remove_tool is
411 -- Remove current quick search bar from `searchable_component'.
412 require
413 attached: is_tool_attached
414 do
415 if is_tool_on_top then
416 remove_tool_from_container (searchable_component.grid_top_container)
417 else
418 remove_tool_from_container (searchable_component.grid_bottom_container)
419 end
420 ensure
421 tool_removed:
422 (not searchable_component.grid_top_container.has (Current) and
423 not searchable_component.grid_bottom_container.has (Current))
424 end
425
426 put_tool_into_container (a_container: EV_BOX) is
427 -- Put current quick search bar into `a_container'.
428 require
429 attached: is_tool_attached
430 a_container_attached: a_container /= Void
431 do
432 if not a_container.has (Current) then
433 a_container.extend (Current)
434 a_container.disable_item_expand (Current)
435 end
436 ensure
437 tool_in_container: a_container.has (Current)
438 end
439
440 remove_tool_from_container (a_container: EV_BOX) is
441 -- Remove current quick search bar from `a_container'.
442 require
443 attached: is_tool_attached
444 a_container_attached: a_container /= Void
445 do
446 a_container.search (Current)
447 if not a_container.exhausted then
448 a_container.remove
449 end
450 ensure
451 tool_removed: not a_container.has (Current)
452 end
453
454 feature{NONE} -- Implementation
455
456 current_keyword: STRING is
457 -- Current keyword
458 do
459 Result := keyword_field.text
460 ensure
461 result_attached: Result /= Void
462 end
463
464 search_engine: EB_CLASS_BROWSER_QUICK_SEARCH_ENGINE is
465 -- Search engine
466 do
467 if search_engine_internal = Void then
468 create search_engine_internal
469 search_engine_internal.ensure_search_by_row
470 end
471 Result := search_engine_internal
472 ensure
473 result_attached: Result /= Void
474 end
475
476 search_engine_internal: like search_engine
477 -- Internal `search_engine'
478
479 search_with_direction (a_previous: BOOLEAN; a_start_from_current: BOOLEAN) is
480 -- If `a_previsou' is True, search forward, otherwise backward.
481 -- If `a_start_from_current' is True, search will start from current selected item, if any,
482 -- otherwise, it will start from next item of current selected item.
483 require
484 attached: is_tool_attached
485 search_enabled: searchable_component.is_search_enabled
486 local
487 l_engine: like search_engine
488 do
489 if not current_keyword.is_empty then
490 l_engine := search_engine
491 if a_previous then
492 l_engine.ensure_search_backward
493 else
494 l_engine.ensure_search_foreward
495 end
496 prepare_search_engine (l_engine)
497 l_engine.search (searchable_component, a_start_from_current)
498 if not l_engine.last_result.is_empty then
499 searchable_component.ensure_visible (l_engine.last_result.first, True)
500 keyword_field.set_background_color (normal_bgcolor)
501 else
502 keyword_field.set_background_color (no_result_bgcolor)
503 end
504 end
505 end
506
507 no_result_bgcolor: EV_COLOR is
508 -- Background color when no result for incremental search.
509 do
510 Result := preferences.search_tool_data.none_result_keyword_field_background_color
511 end
512
513 normal_bgcolor: EV_COLOR is
514 -- Normal background color.
515 local
516 l_comb: EV_COMBO_BOX
517 once
518 create l_comb
519 Result := l_comb.background_color
520 end
521
522 invariant
523 search_bar_position_correct:
524 (is_tool_on_top implies not is_tool_on_bottom) and (not is_tool_on_top implies is_tool_on_bottom)
525
526 indexing
527 copyright: "Copyright (c) 1984-2006, Eiffel Software"
528 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
529 licensing_options: "http://www.eiffel.com/licensing"
530 copying: "[
531 This file is part of Eiffel Software's Eiffel Development Environment.
532
533 Eiffel Software's Eiffel Development Environment is free
534 software; you can redistribute it and/or modify it under
535 the terms of the GNU General Public License as published
536 by the Free Software Foundation, version 2 of the License
537 (available at the URL listed under "license" above).
538
539 Eiffel Software's Eiffel Development Environment is
540 distributed in the hope that it will be useful, but
541 WITHOUT ANY WARRANTY; without even the implied warranty
542 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
543 See the GNU General Public License for more details.
544
545 You should have received a copy of the GNU General Public
546 License along with Eiffel Software's Eiffel Development
547 Environment; if not, write to the Free Software Foundation,
548 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
549 ]"
550 source: "[
551 Eiffel Software
552 356 Storke Road, Goleta, CA 93117 USA
553 Telephone 805-685-1006, Fax 805-685-6869
554 Website http://www.eiffel.com
555 Customer support http://support.eiffel.com
556 ]"
557
558
559 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23