evolution-3.6.4/widgets/misc/e-search-bar.c

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 }