No issues found
1 /*
2 * e-search-bar.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-search-bar.h"
27
28 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
30
31 #define E_SEARCH_BAR_GET_PRIVATE(obj) \
32 (G_TYPE_INSTANCE_GET_PRIVATE \
33 ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate))
34
35 struct _ESearchBarPrivate {
36 EWebView *web_view;
37 GtkWidget *entry;
38 GtkWidget *case_sensitive_button;
39 GtkWidget *wrapped_next_box;
40 GtkWidget *wrapped_prev_box;
41 GtkWidget *matches_label;
42
43 gchar *active_search;
44
45 guint rerun_search : 1;
46 };
47
48 enum {
49 PROP_0,
50 PROP_ACTIVE_SEARCH,
51 PROP_CASE_SENSITIVE,
52 PROP_TEXT,
53 PROP_WEB_VIEW
54 };
55
56 enum {
57 CHANGED,
58 CLEAR,
59 LAST_SIGNAL
60 };
61
62 static guint signals[LAST_SIGNAL];
63
64 G_DEFINE_TYPE (
65 ESearchBar,
66 e_search_bar,
67 GTK_TYPE_HBOX)
68
69 static void
70 search_bar_update_matches (ESearchBar *search_bar,
71 guint matches)
72 {
73 GtkWidget *matches_label;
74 gchar *text;
75
76 search_bar->priv->rerun_search = FALSE;
77 matches_label = search_bar->priv->matches_label;
78
79 text = g_strdup_printf (_("Matches: %u"), matches);
80 gtk_label_set_text (GTK_LABEL (matches_label), text);
81 gtk_widget_show (matches_label);
82 g_free (text);
83 }
84
85 static void
86 search_bar_update_highlights (ESearchBar *search_bar)
87 {
88 EWebView *web_view;
89 gboolean visible;
90
91 web_view = e_search_bar_get_web_view (search_bar);
92
93 visible = gtk_widget_get_visible (GTK_WIDGET (search_bar));
94
95 webkit_web_view_set_highlight_text_matches (
96 WEBKIT_WEB_VIEW (web_view), visible);
97
98 e_search_bar_changed (search_bar);
99 }
100
101 static void
102 search_bar_find (ESearchBar *search_bar,
103 gboolean search_forward)
104 {
105 EWebView *web_view;
106 GtkWidget *widget;
107 gboolean case_sensitive;
108 gboolean new_search;
109 gboolean wrapped = FALSE;
110 gboolean success;
111 gchar *text;
112
113 web_view = e_search_bar_get_web_view (search_bar);
114 case_sensitive = e_search_bar_get_case_sensitive (search_bar);
115 text = e_search_bar_get_text (search_bar);
116
117 if (text == NULL || *text == '\0') {
118 e_search_bar_clear (search_bar);
119 g_free (text);
120 return;
121 }
122
123 new_search =
124 (search_bar->priv->active_search == NULL) ||
125 (g_strcmp0 (text, search_bar->priv->active_search) != 0);
126
127 if (new_search) {
128 guint matches;
129
130 webkit_web_view_unmark_text_matches (
131 WEBKIT_WEB_VIEW (web_view));
132 matches = webkit_web_view_mark_text_matches (
133 WEBKIT_WEB_VIEW (web_view),
134 text, case_sensitive, 0);
135 webkit_web_view_set_highlight_text_matches (
136 WEBKIT_WEB_VIEW (web_view), TRUE);
137 search_bar_update_matches (search_bar, matches);
138 }
139
140 success = webkit_web_view_search_text (
141 WEBKIT_WEB_VIEW (web_view),
142 text, case_sensitive, search_forward, FALSE);
143
144 if (!success)
145 wrapped = webkit_web_view_search_text (
146 WEBKIT_WEB_VIEW (web_view),
147 text, case_sensitive, search_forward, TRUE);
148
149 g_free (search_bar->priv->active_search);
150 search_bar->priv->active_search = text;
151
152 g_object_notify (G_OBJECT (search_bar), "active-search");
153
154 /* Update wrapped label visibility. */
155
156 widget = search_bar->priv->wrapped_next_box;
157
158 if (wrapped && search_forward)
159 gtk_widget_show (widget);
160 else
161 gtk_widget_hide (widget);
162
163 widget = search_bar->priv->wrapped_prev_box;
164
165 if (wrapped && !search_forward)
166 gtk_widget_show (widget);
167 else
168 gtk_widget_hide (widget);
169 }
170
171 static void
172 search_bar_changed_cb (ESearchBar *search_bar)
173 {
174 g_object_notify (G_OBJECT (search_bar), "text");
175 }
176
177 static void
178 search_bar_find_next_cb (ESearchBar *search_bar)
179 {
180 search_bar_find (search_bar, TRUE);
181 }
182
183 static void
184 search_bar_find_previous_cb (ESearchBar *search_bar)
185 {
186 search_bar_find (search_bar, FALSE);
187 }
188
189 static void
190 search_bar_icon_release_cb (ESearchBar *search_bar,
191 GtkEntryIconPosition icon_pos,
192 GdkEvent *event)
193 {
194 g_return_if_fail (icon_pos == GTK_ENTRY_ICON_SECONDARY);
195
196 e_search_bar_clear (search_bar);
197 gtk_widget_grab_focus (search_bar->priv->entry);
198 }
199
200 static void
201 search_bar_toggled_cb (ESearchBar *search_bar)
202 {
203 g_free (search_bar->priv->active_search);
204 search_bar->priv->active_search = NULL;
205
206 g_object_notify (G_OBJECT (search_bar), "active-search");
207 g_object_notify (G_OBJECT (search_bar), "case-sensitive");
208 }
209
210 static void
211 search_bar_set_web_view (ESearchBar *search_bar,
212 EWebView *web_view)
213 {
214 g_return_if_fail (E_IS_WEB_VIEW (web_view));
215 g_return_if_fail (search_bar->priv->web_view == NULL);
216
217 search_bar->priv->web_view = g_object_ref (web_view);
218 }
219
220 static void
221 search_bar_set_property (GObject *object,
222 guint property_id,
223 const GValue *value,
224 GParamSpec *pspec)
225 {
226 switch (property_id) {
227 case PROP_CASE_SENSITIVE:
228 e_search_bar_set_case_sensitive (
229 E_SEARCH_BAR (object),
230 g_value_get_boolean (value));
231 return;
232
233 case PROP_TEXT:
234 e_search_bar_set_text (
235 E_SEARCH_BAR (object),
236 g_value_get_string (value));
237 return;
238
239 case PROP_WEB_VIEW:
240 search_bar_set_web_view (
241 E_SEARCH_BAR (object),
242 g_value_get_object (value));
243 return;
244 }
245
246 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
247 }
248
249 static void
250 search_bar_get_property (GObject *object,
251 guint property_id,
252 GValue *value,
253 GParamSpec *pspec)
254 {
255 switch (property_id) {
256 case PROP_ACTIVE_SEARCH:
257 g_value_set_boolean (
258 value, e_search_bar_get_active_search (
259 E_SEARCH_BAR (object)));
260 return;
261
262 case PROP_CASE_SENSITIVE:
263 g_value_set_boolean (
264 value, e_search_bar_get_case_sensitive (
265 E_SEARCH_BAR (object)));
266 return;
267
268 case PROP_TEXT:
269 g_value_take_string (
270 value, e_search_bar_get_text (
271 E_SEARCH_BAR (object)));
272 return;
273
274 case PROP_WEB_VIEW:
275 g_value_set_object (
276 value, e_search_bar_get_web_view (
277 E_SEARCH_BAR (object)));
278 return;
279 }
280
281 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
282 }
283
284 static void
285 search_bar_dispose (GObject *object)
286 {
287 ESearchBarPrivate *priv;
288
289 priv = E_SEARCH_BAR_GET_PRIVATE (object);
290
291 if (priv->web_view != NULL) {
292 g_object_unref (priv->web_view);
293 priv->web_view = NULL;
294 }
295
296 if (priv->entry != NULL) {
297 g_object_unref (priv->entry);
298 priv->entry = NULL;
299 }
300
301 if (priv->case_sensitive_button != NULL) {
302 g_object_unref (priv->case_sensitive_button);
303 priv->case_sensitive_button = NULL;
304 }
305
306 if (priv->wrapped_next_box != NULL) {
307 g_object_unref (priv->wrapped_next_box);
308 priv->wrapped_next_box = NULL;
309 }
310
311 if (priv->wrapped_prev_box != NULL) {
312 g_object_unref (priv->wrapped_prev_box);
313 priv->wrapped_prev_box = NULL;
314 }
315
316 if (priv->matches_label != NULL) {
317 g_object_unref (priv->matches_label);
318 priv->matches_label = NULL;
319 }
320
321 /* Chain up to parent's dispose() method. */
322 G_OBJECT_CLASS (e_search_bar_parent_class)->dispose (object);
323 }
324
325 static void
326 search_bar_finalize (GObject *object)
327 {
328 ESearchBarPrivate *priv;
329
330 priv = E_SEARCH_BAR_GET_PRIVATE (object);
331
332 g_free (priv->active_search);
333
334 /* Chain up to parent's finalize() method. */
335 G_OBJECT_CLASS (e_search_bar_parent_class)->finalize (object);
336 }
337
338 static void
339 search_bar_constructed (GObject *object)
340 {
341 ESearchBarPrivate *priv;
342
343 priv = E_SEARCH_BAR_GET_PRIVATE (object);
344
345 g_object_bind_property (
346 object, "case-sensitive",
347 priv->case_sensitive_button, "active",
348 G_BINDING_BIDIRECTIONAL |
349 G_BINDING_SYNC_CREATE);
350
351 /* Chain up to parent's constructed() method. */
352 G_OBJECT_CLASS (e_search_bar_parent_class)->constructed (object);
353 }
354
355 static void
356 search_bar_show (GtkWidget *widget)
357 {
358 ESearchBar *search_bar;
359
360 search_bar = E_SEARCH_BAR (widget);
361
362 /* Chain up to parent's show() method. */
363 GTK_WIDGET_CLASS (e_search_bar_parent_class)->show (widget);
364
365 gtk_widget_grab_focus (search_bar->priv->entry);
366
367 search_bar_update_highlights (search_bar);
368 }
369
370 static void
371 search_bar_hide (GtkWidget *widget)
372 {
373 ESearchBar *search_bar;
374
375 search_bar = E_SEARCH_BAR (widget);
376
377 /* Chain up to parent's hide() method. */
378 GTK_WIDGET_CLASS (e_search_bar_parent_class)->hide (widget);
379
380 search_bar_update_highlights (search_bar);
381 }
382
383 static gboolean
384 search_bar_key_press_event (GtkWidget *widget,
385 GdkEventKey *event)
386 {
387 GtkWidgetClass *widget_class;
388
389 if (event->keyval == GDK_KEY_Escape) {
390 gtk_widget_hide (widget);
391 return TRUE;
392 }
393
394 /* Chain up to parent's key_press_event() method. */
395 widget_class = GTK_WIDGET_CLASS (e_search_bar_parent_class);
396 return widget_class->key_press_event (widget, event);
397 }
398
399 static void
400 search_bar_clear (ESearchBar *search_bar)
401 {
402 WebKitWebView *web_view;
403
404 g_free (search_bar->priv->active_search);
405 search_bar->priv->active_search = NULL;
406
407 gtk_entry_set_text (GTK_ENTRY (search_bar->priv->entry), "");
408
409 gtk_widget_hide (search_bar->priv->wrapped_next_box);
410 gtk_widget_hide (search_bar->priv->wrapped_prev_box);
411 gtk_widget_hide (search_bar->priv->matches_label);
412
413 search_bar_update_highlights (search_bar);
414
415 web_view = WEBKIT_WEB_VIEW (search_bar->priv->web_view);
416 webkit_web_view_unmark_text_matches (web_view);
417
418 g_object_notify (G_OBJECT (search_bar), "active-search");
419 }
420
421 static void
422 e_search_bar_class_init (ESearchBarClass *class)
423 {
424 GObjectClass *object_class;
425 GtkWidgetClass *widget_class;
426
427 g_type_class_add_private (class, sizeof (ESearchBarPrivate));
428
429 object_class = G_OBJECT_CLASS (class);
430 object_class->set_property = search_bar_set_property;
431 object_class->get_property = search_bar_get_property;
432 object_class->dispose = search_bar_dispose;
433 object_class->finalize = search_bar_finalize;
434 object_class->constructed = search_bar_constructed;
435
436 widget_class = GTK_WIDGET_CLASS (class);
437 widget_class->show = search_bar_show;
438 widget_class->hide = search_bar_hide;
439 widget_class->key_press_event = search_bar_key_press_event;
440
441 class->clear = search_bar_clear;
442
443 g_object_class_install_property (
444 object_class,
445 PROP_ACTIVE_SEARCH,
446 g_param_spec_boolean (
447 "active-search",
448 "Active Search",
449 NULL,
450 FALSE,
451 G_PARAM_READABLE));
452
453 g_object_class_install_property (
454 object_class,
455 PROP_CASE_SENSITIVE,
456 g_param_spec_boolean (
457 "case-sensitive",
458 "Case Sensitive",
459 NULL,
460 FALSE,
461 G_PARAM_READWRITE));
462
463 g_object_class_install_property (
464 object_class,
465 PROP_TEXT,
466 g_param_spec_string (
467 "text",
468 "Search Text",
469 NULL,
470 NULL,
471 G_PARAM_READWRITE));
472
473 g_object_class_install_property (
474 object_class,
475 PROP_WEB_VIEW,
476 g_param_spec_object (
477 "web-view",
478 "Web View",
479 NULL,
480 E_TYPE_WEB_VIEW,
481 G_PARAM_READWRITE |
482 G_PARAM_CONSTRUCT_ONLY));
483
484 signals[CHANGED] = g_signal_new (
485 "changed",
486 G_TYPE_FROM_CLASS (class),
487 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
488 G_STRUCT_OFFSET (ESearchBarClass, changed),
489 NULL, NULL,
490 g_cclosure_marshal_VOID__VOID,
491 G_TYPE_NONE, 0);
492
493 signals[CLEAR] = g_signal_new (
494 "clear",
495 G_TYPE_FROM_CLASS (class),
496 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
497 G_STRUCT_OFFSET (ESearchBarClass, clear),
498 NULL, NULL,
499 g_cclosure_marshal_VOID__VOID,
500 G_TYPE_NONE, 0);
501 }
502
503 static void
504 e_search_bar_init (ESearchBar *search_bar)
505 {
506 GtkWidget *label;
507 GtkWidget *widget;
508 GtkWidget *container;
509
510 search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar);
511
512 gtk_box_set_spacing (GTK_BOX (search_bar), 12);
513
514 container = GTK_WIDGET (search_bar);
515
516 widget = gtk_hbox_new (FALSE, 1);
517 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
518 gtk_widget_show (widget);
519
520 container = widget;
521
522 widget = gtk_button_new ();
523 gtk_button_set_image (
524 GTK_BUTTON (widget), gtk_image_new_from_stock (
525 GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
526 gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
527 gtk_widget_set_tooltip_text (widget, _("Close the find bar"));
528 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
529 gtk_widget_show (widget);
530
531 g_signal_connect_swapped (
532 widget, "clicked",
533 G_CALLBACK (gtk_widget_hide), search_bar);
534
535 widget = gtk_label_new_with_mnemonic (_("Fin_d:"));
536 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 3);
537 gtk_widget_show (widget);
538
539 label = widget;
540
541 widget = gtk_entry_new ();
542 gtk_entry_set_icon_from_stock (
543 GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY,
544 GTK_STOCK_CLEAR);
545 gtk_entry_set_icon_tooltip_text (
546 GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY,
547 _("Clear the search"));
548 gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
549 gtk_widget_set_size_request (widget, 200, -1);
550 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
551 search_bar->priv->entry = g_object_ref (widget);
552 gtk_widget_show (widget);
553
554 g_object_bind_property (
555 search_bar, "active-search",
556 widget, "secondary-icon-sensitive",
557 G_BINDING_SYNC_CREATE);
558
559 g_signal_connect_swapped (
560 widget, "activate",
561 G_CALLBACK (search_bar_find_next_cb), search_bar);
562
563 g_signal_connect_swapped (
564 widget, "changed",
565 G_CALLBACK (search_bar_changed_cb), search_bar);
566
567 g_signal_connect_swapped (
568 widget, "icon-release",
569 G_CALLBACK (search_bar_icon_release_cb), search_bar);
570
571 widget = gtk_button_new_with_mnemonic (_("_Previous"));
572 gtk_button_set_image (
573 GTK_BUTTON (widget), gtk_image_new_from_stock (
574 GTK_STOCK_GO_BACK, GTK_ICON_SIZE_MENU));
575 gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
576 gtk_widget_set_tooltip_text (
577 widget, _("Find the previous occurrence of the phrase"));
578 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
579 gtk_widget_show (widget);
580
581 g_object_bind_property (
582 search_bar, "active-search",
583 widget, "sensitive",
584 G_BINDING_SYNC_CREATE);
585
586 g_signal_connect_swapped (
587 widget, "clicked",
588 G_CALLBACK (search_bar_find_previous_cb), search_bar);
589
590 widget = gtk_button_new_with_mnemonic (_("_Next"));
591 gtk_button_set_image (
592 GTK_BUTTON (widget), gtk_image_new_from_stock (
593 GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU));
594 gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
595 gtk_widget_set_tooltip_text (
596 widget, _("Find the next occurrence of the phrase"));
597 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
598 gtk_widget_show (widget);
599
600 g_object_bind_property (
601 search_bar, "active-search",
602 widget, "sensitive",
603 G_BINDING_SYNC_CREATE);
604
605 g_signal_connect_swapped (
606 widget, "clicked",
607 G_CALLBACK (search_bar_find_next_cb), search_bar);
608
609 widget = gtk_check_button_new_with_mnemonic (_("Mat_ch case"));
610 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
611 search_bar->priv->case_sensitive_button = g_object_ref (widget);
612 gtk_widget_show (widget);
613
614 g_signal_connect_swapped (
615 widget, "toggled",
616 G_CALLBACK (search_bar_toggled_cb), search_bar);
617
618 g_signal_connect_swapped (
619 widget, "toggled",
620 G_CALLBACK (search_bar_find_next_cb), search_bar);
621
622 container = GTK_WIDGET (search_bar);
623
624 widget = gtk_hbox_new (FALSE, 6);
625 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
626 search_bar->priv->wrapped_next_box = g_object_ref (widget);
627 gtk_widget_hide (widget);
628
629 container = widget;
630
631 widget = gtk_image_new_from_icon_name (
632 "wrapped", GTK_ICON_SIZE_MENU);
633 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
634 gtk_widget_show (widget);
635
636 widget = gtk_label_new (
637 _("Reached bottom of page, continued from top"));
638 gtk_label_set_ellipsize (
639 GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
640 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
641 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
642 gtk_widget_show (widget);
643
644 container = GTK_WIDGET (search_bar);
645
646 widget = gtk_hbox_new (FALSE, 6);
647 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
648 search_bar->priv->wrapped_prev_box = g_object_ref (widget);
649 gtk_widget_hide (widget);
650
651 container = widget;
652
653 widget = gtk_image_new_from_icon_name (
654 "wrapped", GTK_ICON_SIZE_MENU);
655 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
656 gtk_widget_show (widget);
657
658 widget = gtk_label_new (
659 _("Reached top of page, continued from bottom"));
660 gtk_label_set_ellipsize (
661 GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
662 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
663 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
664 gtk_widget_show (widget);
665
666 container = GTK_WIDGET (search_bar);
667
668 widget = gtk_label_new (NULL);
669 gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 12);
670 search_bar->priv->matches_label = g_object_ref (widget);
671 gtk_widget_show (widget);
672 }
673
674 GtkWidget *
675 e_search_bar_new (EWebView *web_view)
676 {
677 g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
678
679 return g_object_new (
680 E_TYPE_SEARCH_BAR, "web-view", web_view, NULL);
681 }
682
683 void
684 e_search_bar_clear (ESearchBar *search_bar)
685 {
686 g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
687
688 g_signal_emit (search_bar, signals[CLEAR], 0);
689 }
690
691 void
692 e_search_bar_changed (ESearchBar *search_bar)
693 {
694 g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
695
696 g_signal_emit (search_bar, signals[CHANGED], 0);
697 }
698
699 EWebView *
700 e_search_bar_get_web_view (ESearchBar *search_bar)
701 {
702 g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL);
703
704 return search_bar->priv->web_view;
705 }
706
707 gboolean
708 e_search_bar_get_active_search (ESearchBar *search_bar)
709 {
710 g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE);
711
712 return (search_bar->priv->active_search != NULL);
713 }
714
715 gboolean
716 e_search_bar_get_case_sensitive (ESearchBar *search_bar)
717 {
718 GtkToggleButton *button;
719
720 g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE);
721
722 button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button);
723
724 return gtk_toggle_button_get_active (button);
725 }
726
727 void
728 e_search_bar_set_case_sensitive (ESearchBar *search_bar,
729 gboolean case_sensitive)
730 {
731 GtkToggleButton *button;
732
733 g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
734
735 button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button);
736
737 gtk_toggle_button_set_active (button, case_sensitive);
738
739 g_object_notify (G_OBJECT (search_bar), "case-sensitive");
740 }
741
742 gchar *
743 e_search_bar_get_text (ESearchBar *search_bar)
744 {
745 GtkEntry *entry;
746 const gchar *text;
747
748 g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL);
749
750 entry = GTK_ENTRY (search_bar->priv->entry);
751 text = gtk_entry_get_text (entry);
752
753 return g_strstrip (g_strdup (text));
754 }
755
756 void
757 e_search_bar_set_text (ESearchBar *search_bar,
758 const gchar *text)
759 {
760 GtkEntry *entry;
761
762 g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
763
764 entry = GTK_ENTRY (search_bar->priv->entry);
765
766 if (text == NULL)
767 text = "";
768
769 /* This will trigger a "notify::text" signal. */
770 gtk_entry_set_text (entry, text);
771 }