1 /* Copyright (C) 2004 Red Hat, Inc.
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public License as
5 published by the Free Software Foundation; either version 2 of the
6 License, or (at your option) any later version.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public
14 License along with the Gnome Library; see the file COPYING.LIB. If not,
15 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17 */
18
19 #include "config.h"
20
21 #include <string.h>
22
23 #include <glib/gi18n-lib.h>
24 #include <gtk/gtk.h>
25 #include <gdk/gdkkeysyms.h>
26
27 #include "eggfindbar.h"
28
29 struct _EggFindBarPrivate
30 {
31 gchar *search_string;
32
33 GtkToolItem *next_button;
34 GtkToolItem *previous_button;
35 GtkToolItem *status_separator;
36 GtkToolItem *status_item;
37 GtkToolItem *case_button;
38
39 GtkWidget *find_entry;
40 GtkWidget *status_label;
41
42 gulong set_focus_handler;
43 guint case_sensitive : 1;
44 };
45
46 #define EGG_FIND_BAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EGG_TYPE_FIND_BAR, EggFindBarPrivate))
47
48 enum {
49 PROP_0,
50 PROP_SEARCH_STRING,
51 PROP_CASE_SENSITIVE
52 };
53
54 static void egg_find_bar_finalize (GObject *object);
55 static void egg_find_bar_get_property (GObject *object,
56 guint prop_id,
57 GValue *value,
58 GParamSpec *pspec);
59 static void egg_find_bar_set_property (GObject *object,
60 guint prop_id,
61 const GValue *value,
62 GParamSpec *pspec);
63 static void egg_find_bar_show (GtkWidget *widget);
64 static void egg_find_bar_hide (GtkWidget *widget);
65 static void egg_find_bar_grab_focus (GtkWidget *widget);
66
67 G_DEFINE_TYPE (EggFindBar, egg_find_bar, GTK_TYPE_TOOLBAR);
68
69 enum
70 {
71 NEXT,
72 PREVIOUS,
73 CLOSE,
74 SCROLL,
75 LAST_SIGNAL
76 };
77
78 static guint find_bar_signals[LAST_SIGNAL] = { 0 };
79
80 static void
egg_find_bar_class_init(EggFindBarClass * klass)81 egg_find_bar_class_init (EggFindBarClass *klass)
82 {
83 GObjectClass *object_class;
84 GtkWidgetClass *widget_class;
85 GtkBindingSet *binding_set;
86
87 egg_find_bar_parent_class = g_type_class_peek_parent (klass);
88
89 object_class = (GObjectClass *)klass;
90 widget_class = (GtkWidgetClass *)klass;
91
92 object_class->set_property = egg_find_bar_set_property;
93 object_class->get_property = egg_find_bar_get_property;
94
95 object_class->finalize = egg_find_bar_finalize;
96
97 widget_class->show = egg_find_bar_show;
98 widget_class->hide = egg_find_bar_hide;
99
100 widget_class->grab_focus = egg_find_bar_grab_focus;
101
102 find_bar_signals[NEXT] =
103 g_signal_new ("next",
104 G_OBJECT_CLASS_TYPE (object_class),
105 G_SIGNAL_RUN_FIRST,
106 G_STRUCT_OFFSET (EggFindBarClass, next),
107 NULL, NULL,
108 g_cclosure_marshal_VOID__VOID,
109 G_TYPE_NONE, 0);
110 find_bar_signals[PREVIOUS] =
111 g_signal_new ("previous",
112 G_OBJECT_CLASS_TYPE (object_class),
113 G_SIGNAL_RUN_FIRST,
114 G_STRUCT_OFFSET (EggFindBarClass, previous),
115 NULL, NULL,
116 g_cclosure_marshal_VOID__VOID,
117 G_TYPE_NONE, 0);
118 find_bar_signals[CLOSE] =
119 g_signal_new ("close",
120 G_OBJECT_CLASS_TYPE (object_class),
121 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
122 G_STRUCT_OFFSET (EggFindBarClass, close),
123 NULL, NULL,
124 g_cclosure_marshal_VOID__VOID,
125 G_TYPE_NONE, 0);
126 find_bar_signals[SCROLL] =
127 g_signal_new ("scroll",
128 G_OBJECT_CLASS_TYPE (object_class),
129 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
130 G_STRUCT_OFFSET (EggFindBarClass, scroll),
131 NULL, NULL,
132 g_cclosure_marshal_VOID__ENUM,
133 G_TYPE_NONE, 1,
134 GTK_TYPE_SCROLL_TYPE);
135
136 /**
137 * EggFindBar:search_string:
138 *
139 * The current string to search for. NULL or empty string
140 * both mean no current string.
141 *
142 */
143 g_object_class_install_property (object_class,
144 PROP_SEARCH_STRING,
145 g_param_spec_string ("search_string",
146 ("Search string"),
147 ("The name of the string to be found"),
148 NULL,
149 G_PARAM_READWRITE));
150
151 /**
152 * EggFindBar:case_sensitive:
153 *
154 * TRUE for a case sensitive search.
155 *
156 */
157 g_object_class_install_property (object_class,
158 PROP_CASE_SENSITIVE,
159 g_param_spec_boolean ("case_sensitive",
160 ("Case sensitive"),
161 ("TRUE for a case sensitive search"),
162 FALSE,
163 G_PARAM_READWRITE));
164
165 /* Style properties */
166 gtk_widget_class_install_style_property (widget_class,
167 g_param_spec_boxed ("all_matches_color",
168 ("Highlight color"),
169 ("Color of highlight for all matches"),
170 GDK_TYPE_COLOR,
171 G_PARAM_READABLE));
172
173 gtk_widget_class_install_style_property (widget_class,
174 g_param_spec_boxed ("current_match_color",
175 ("Current color"),
176 ("Color of highlight for the current match"),
177 GDK_TYPE_COLOR,
178 G_PARAM_READABLE));
179
180 g_type_class_add_private (object_class, sizeof (EggFindBarPrivate));
181
182 binding_set = gtk_binding_set_by_class (klass);
183
184 gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
185 "close", 0);
186
187 gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
188 "scroll", 1,
189 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_BACKWARD);
190 gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
191 "scroll", 1,
192 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_FORWARD);
193 gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
194 "scroll", 1,
195 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_BACKWARD);
196 gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, 0,
197 "scroll", 1,
198 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_BACKWARD);
199 gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
200 "scroll", 1,
201 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_FORWARD);
202 gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, 0,
203 "scroll", 1,
204 GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_FORWARD);
205 }
206
207 static void
egg_find_bar_emit_next(EggFindBar * find_bar)208 egg_find_bar_emit_next (EggFindBar *find_bar)
209 {
210 g_signal_emit (find_bar, find_bar_signals[NEXT], 0);
211 }
212
213 static void
egg_find_bar_emit_previous(EggFindBar * find_bar)214 egg_find_bar_emit_previous (EggFindBar *find_bar)
215 {
216 g_signal_emit (find_bar, find_bar_signals[PREVIOUS], 0);
217 }
218
219 static void
next_clicked_callback(GtkButton * button,void * data)220 next_clicked_callback (GtkButton *button,
221 void *data)
222 {
223 EggFindBar *find_bar = EGG_FIND_BAR (data);
224
225 egg_find_bar_emit_next (find_bar);
226 }
227
228 static void
previous_clicked_callback(GtkButton * button,void * data)229 previous_clicked_callback (GtkButton *button,
230 void *data)
231 {
232 EggFindBar *find_bar = EGG_FIND_BAR (data);
233
234 egg_find_bar_emit_previous (find_bar);
235 }
236
237 static void
case_sensitive_toggled_callback(GtkCheckButton * button,void * data)238 case_sensitive_toggled_callback (GtkCheckButton *button,
239 void *data)
240 {
241 EggFindBar *find_bar = EGG_FIND_BAR (data);
242
243 egg_find_bar_set_case_sensitive (find_bar,
244 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)));
245 }
246
247 static void
entry_activate_callback(GtkEntry * entry,void * data)248 entry_activate_callback (GtkEntry *entry,
249 void *data)
250 {
251 EggFindBar *find_bar = EGG_FIND_BAR (data);
252
253 if (find_bar->priv->search_string != NULL)
254 egg_find_bar_emit_next (find_bar);
255 }
256
257 static void
entry_changed_callback(GtkEntry * entry,void * data)258 entry_changed_callback (GtkEntry *entry,
259 void *data)
260 {
261 EggFindBar *find_bar = EGG_FIND_BAR (data);
262 char *text;
263
264 /* paranoid strdup because set_search_string() sets
265 * the entry text
266 */
267 text = g_strdup (gtk_entry_get_text (entry));
268
269 egg_find_bar_set_search_string (find_bar, text);
270
271 g_free (text);
272 }
273
274 static void
set_focus_cb(GtkWidget * window,GtkWidget * widget,EggFindBar * bar)275 set_focus_cb (GtkWidget *window,
276 GtkWidget *widget,
277 EggFindBar *bar)
278 {
279 GtkWidget *wbar = GTK_WIDGET (bar);
280
281 while (widget != NULL && widget != wbar)
282 {
283 widget = gtk_widget_get_parent (widget);
284 }
285
286 /* if widget == bar, the new focus widget is in the bar, so we
287 * don't deactivate.
288 */
289 if (widget != wbar)
290 {
291 g_signal_emit (bar, find_bar_signals[CLOSE], 0);
292 }
293 }
294
295 static void
egg_find_bar_init(EggFindBar * find_bar)296 egg_find_bar_init (EggFindBar *find_bar)
297 {
298 EggFindBarPrivate *priv;
299 GtkWidget *label;
300 GtkWidget *alignment;
301 GtkWidget *box;
302 GtkToolItem *item;
303 GtkWidget *arrow;
304
305 /* Data */
306 priv = EGG_FIND_BAR_GET_PRIVATE (find_bar);
307
308 find_bar->priv = priv;
309 priv->search_string = NULL;
310
311 gtk_toolbar_set_style (GTK_TOOLBAR (find_bar), GTK_TOOLBAR_BOTH_HORIZ);
312
313 /* Find: |_____| */
314 item = gtk_tool_item_new ();
315 box = gtk_hbox_new (FALSE, 12);
316
317 alignment = gtk_alignment_new (0.0, 0.5, 1.0, 0.0);
318 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 2, 2);
319
320 label = gtk_label_new_with_mnemonic (_("Find:"));
321
322 priv->find_entry = gtk_entry_new ();
323 gtk_entry_set_width_chars (GTK_ENTRY (priv->find_entry), 32);
324 gtk_entry_set_max_length (GTK_ENTRY (priv->find_entry), 512);
325 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->find_entry);
326
327 /* Prev */
328 arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE);
329 priv->previous_button = gtk_tool_button_new (arrow, Q_("Find Previous"));
330 gtk_tool_item_set_is_important (priv->previous_button, TRUE);
331 #if GTK_CHECK_VERSION (2, 11, 5)
332 gtk_widget_set_tooltip_text (GTK_WIDGET (priv->previous_button),
333 _("Find previous occurrence of the search string"));
334 #else
335 gtk_tool_item_set_tooltip (priv->previous_button, GTK_TOOLBAR (find_bar)->tooltips,
336 _("Find previous occurrence of the search string"),
337 NULL);
338 #endif
339
340 /* Next */
341 arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
342 priv->next_button = gtk_tool_button_new (arrow, Q_("Find Next"));
343 gtk_tool_item_set_is_important (priv->next_button, TRUE);
344 #if GTK_CHECK_VERSION (2, 11, 5)
345 gtk_widget_set_tooltip_text (GTK_WIDGET (priv->next_button),
346 _("Find next occurrence of the search string"));
347 #else
348 gtk_tool_item_set_tooltip (priv->next_button, GTK_TOOLBAR (find_bar)->tooltips,
349 _("Find next occurrence of the search string"),
350 NULL);
351 #endif
352
353 /* Separator*/
354 priv->status_separator = gtk_separator_tool_item_new();
355
356 /* Case button */
357 priv->case_button = gtk_toggle_tool_button_new ();
358 g_object_set (G_OBJECT (priv->case_button), "label", _("C_ase Sensitive"), NULL);
359 gtk_tool_item_set_is_important (priv->case_button, TRUE);
360 #if GTK_CHECK_VERSION (2, 11, 5)
361 gtk_widget_set_tooltip_text (GTK_WIDGET (priv->case_button),
362 _("Toggle case sensitive search"));
363 #else
364 gtk_tool_item_set_tooltip (priv->case_button, GTK_TOOLBAR (find_bar)->tooltips,
365 _("Toggle case sensitive search"),
366 NULL);
367 #endif
368 /* Status */
369 priv->status_item = gtk_tool_item_new();
370 gtk_tool_item_set_expand (priv->status_item, TRUE);
371 priv->status_label = gtk_label_new (NULL);
372 gtk_label_set_ellipsize (GTK_LABEL (priv->status_label),
373 PANGO_ELLIPSIZE_END);
374 gtk_misc_set_alignment (GTK_MISC (priv->status_label), 0.0, 0.5);
375
376
377 g_signal_connect (priv->find_entry, "changed",
378 G_CALLBACK (entry_changed_callback),
379 find_bar);
380 g_signal_connect (priv->find_entry, "activate",
381 G_CALLBACK (entry_activate_callback),
382 find_bar);
383 g_signal_connect (priv->next_button, "clicked",
384 G_CALLBACK (next_clicked_callback),
385 find_bar);
386 g_signal_connect (priv->previous_button, "clicked",
387 G_CALLBACK (previous_clicked_callback),
388 find_bar);
389 g_signal_connect (priv->case_button, "toggled",
390 G_CALLBACK (case_sensitive_toggled_callback),
391 find_bar);
392
393 gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
394 gtk_box_pack_start (GTK_BOX (box), priv->find_entry, TRUE, TRUE, 0);
395 gtk_container_add (GTK_CONTAINER (alignment), box);
396 gtk_container_add (GTK_CONTAINER (item), alignment);
397 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), item, -1);
398 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), priv->previous_button, -1);
399 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), priv->next_button, -1);
400 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), priv->case_button, -1);
401 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), priv->status_separator, -1);
402 gtk_container_add (GTK_CONTAINER (priv->status_item), priv->status_label);
403 gtk_toolbar_insert (GTK_TOOLBAR (find_bar), priv->status_item, -1);
404
405 /* don't show status separator/label until they are set */
406
407 gtk_widget_show_all (GTK_WIDGET (item));
408 gtk_widget_show_all (GTK_WIDGET (priv->next_button));
409 gtk_widget_show_all (GTK_WIDGET (priv->previous_button));
410 gtk_widget_show (priv->status_label);
411 }
412
413 static void
egg_find_bar_finalize(GObject * object)414 egg_find_bar_finalize (GObject *object)
415 {
416 EggFindBar *find_bar = EGG_FIND_BAR (object);
417 EggFindBarPrivate *priv = (EggFindBarPrivate *)find_bar->priv;
418
419 g_free (priv->search_string);
420
421 G_OBJECT_CLASS (egg_find_bar_parent_class)->finalize (object);
422 }
423
424 static void
egg_find_bar_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)425 egg_find_bar_set_property (GObject *object,
426 guint prop_id,
427 const GValue *value,
428 GParamSpec *pspec)
429 {
430 EggFindBar *find_bar = EGG_FIND_BAR (object);
431
432 switch (prop_id)
433 {
434 case PROP_SEARCH_STRING:
435 egg_find_bar_set_search_string (find_bar, g_value_get_string (value));
436 break;
437 case PROP_CASE_SENSITIVE:
438 egg_find_bar_set_case_sensitive (find_bar, g_value_get_boolean (value));
439 break;
440 default:
441 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
442 break;
443 }
444 }
445
446 static void
egg_find_bar_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)447 egg_find_bar_get_property (GObject *object,
448 guint prop_id,
449 GValue *value,
450 GParamSpec *pspec)
451 {
452 EggFindBar *find_bar = EGG_FIND_BAR (object);
453 EggFindBarPrivate *priv = (EggFindBarPrivate *)find_bar->priv;
454
455 switch (prop_id)
456 {
457 case PROP_SEARCH_STRING:
458 g_value_set_string (value, priv->search_string);
459 break;
460 case PROP_CASE_SENSITIVE:
461 g_value_set_boolean (value, priv->case_sensitive);
462 break;
463 default:
464 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
465 break;
466 }
467 }
468
469 static void
egg_find_bar_show(GtkWidget * widget)470 egg_find_bar_show (GtkWidget *widget)
471 {
472 EggFindBar *bar = EGG_FIND_BAR (widget);
473 EggFindBarPrivate *priv = bar->priv;
474
475 GTK_WIDGET_CLASS (egg_find_bar_parent_class)->show (widget);
476
477 if (priv->set_focus_handler == 0)
478 {
479 GtkWidget *toplevel;
480
481 toplevel = gtk_widget_get_toplevel (widget);
482
483 priv->set_focus_handler =
484 g_signal_connect (toplevel, "set-focus",
485 G_CALLBACK (set_focus_cb), bar);
486 }
487 }
488
489 static void
egg_find_bar_hide(GtkWidget * widget)490 egg_find_bar_hide (GtkWidget *widget)
491 {
492 EggFindBar *bar = EGG_FIND_BAR (widget);
493 EggFindBarPrivate *priv = bar->priv;
494
495 if (priv->set_focus_handler != 0)
496 {
497 GtkWidget *toplevel;
498
499 toplevel = gtk_widget_get_toplevel (widget);
500
501 g_signal_handlers_disconnect_by_func
502 (toplevel, (void (*)) G_CALLBACK (set_focus_cb), bar);
503 priv->set_focus_handler = 0;
504 }
505
506 GTK_WIDGET_CLASS (egg_find_bar_parent_class)->hide (widget);
507 }
508
509 static void
egg_find_bar_grab_focus(GtkWidget * widget)510 egg_find_bar_grab_focus (GtkWidget *widget)
511 {
512 EggFindBar *find_bar = EGG_FIND_BAR (widget);
513 EggFindBarPrivate *priv = find_bar->priv;
514
515 gtk_widget_grab_focus (priv->find_entry);
516 }
517
518 /**
519 * egg_find_bar_new:
520 *
521 * Creates a new #EggFindBar.
522 *
523 * Returns: a newly created #EggFindBar
524 *
525 * Since: 2.6
526 */
527 GtkWidget *
egg_find_bar_new(void)528 egg_find_bar_new (void)
529 {
530 EggFindBar *find_bar;
531
532 find_bar = g_object_new (EGG_TYPE_FIND_BAR, NULL);
533
534 return GTK_WIDGET (find_bar);
535 }
536
537 /**
538 * egg_find_bar_set_search_string:
539 *
540 * Sets the string that should be found/highlighted in the document.
541 * Empty string is converted to NULL.
542 *
543 * Since: 2.6
544 */
545 void
egg_find_bar_set_search_string(EggFindBar * find_bar,const char * search_string)546 egg_find_bar_set_search_string (EggFindBar *find_bar,
547 const char *search_string)
548 {
549 EggFindBarPrivate *priv;
550
551 g_return_if_fail (EGG_IS_FIND_BAR (find_bar));
552
553 priv = (EggFindBarPrivate *)find_bar->priv;
554
555 g_object_freeze_notify (G_OBJECT (find_bar));
556
557 if (priv->search_string != search_string)
558 {
559 char *old;
560
561 old = priv->search_string;
562
563 if (search_string && *search_string == '\0')
564 search_string = NULL;
565
566 /* Only update if the string has changed; setting the entry
567 * will emit changed on the entry which will re-enter
568 * this function, but we'll handle that fine with this
569 * short-circuit.
570 */
571 if ((old && search_string == NULL) ||
572 (old == NULL && search_string) ||
573 (old && search_string &&
574 strcmp (old, search_string) != 0))
575 {
576 gboolean not_empty;
577
578 priv->search_string = g_strdup (search_string);
579 g_free (old);
580
581 gtk_entry_set_text (GTK_ENTRY (priv->find_entry),
582 priv->search_string ?
583 priv->search_string :
584 "");
585
586 not_empty = (search_string == NULL) ? FALSE : TRUE;
587
588 gtk_widget_set_sensitive (GTK_WIDGET (find_bar->priv->next_button), not_empty);
589 gtk_widget_set_sensitive (GTK_WIDGET (find_bar->priv->previous_button), not_empty);
590
591 g_object_notify (G_OBJECT (find_bar),
592 "search_string");
593 }
594 }
595
596 g_object_thaw_notify (G_OBJECT (find_bar));
597 }
598
599
600 /**
601 * egg_find_bar_get_search_string:
602 *
603 * Gets the string that should be found/highlighted in the document.
604 *
605 * Returns: the string
606 *
607 * Since: 2.6
608 */
609 const char*
egg_find_bar_get_search_string(EggFindBar * find_bar)610 egg_find_bar_get_search_string (EggFindBar *find_bar)
611 {
612 EggFindBarPrivate *priv;
613
614 g_return_val_if_fail (EGG_IS_FIND_BAR (find_bar), NULL);
615
616 priv = find_bar->priv;
617
618 return priv->search_string ? priv->search_string : "";
619 }
620
621 /**
622 * egg_find_bar_set_case_sensitive:
623 *
624 * Sets whether the search is case sensitive
625 *
626 * Since: 2.6
627 */
628 void
egg_find_bar_set_case_sensitive(EggFindBar * find_bar,gboolean case_sensitive)629 egg_find_bar_set_case_sensitive (EggFindBar *find_bar,
630 gboolean case_sensitive)
631 {
632 EggFindBarPrivate *priv;
633
634 g_return_if_fail (EGG_IS_FIND_BAR (find_bar));
635
636 priv = (EggFindBarPrivate *)find_bar->priv;
637
638 g_object_freeze_notify (G_OBJECT (find_bar));
639
640 case_sensitive = case_sensitive != FALSE;
641
642 if (priv->case_sensitive != case_sensitive)
643 {
644 priv->case_sensitive = case_sensitive;
645
646 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->case_button),
647 priv->case_sensitive);
648
649 g_object_notify (G_OBJECT (find_bar),
650 "case_sensitive");
651 }
652
653 g_object_thaw_notify (G_OBJECT (find_bar));
654 }
655
656 /**
657 * egg_find_bar_get_case_sensitive:
658 *
659 * Gets whether the search is case sensitive
660 *
661 * Returns: TRUE if it's case sensitive
662 *
663 * Since: 2.6
664 */
665 gboolean
egg_find_bar_get_case_sensitive(EggFindBar * find_bar)666 egg_find_bar_get_case_sensitive (EggFindBar *find_bar)
667 {
668 EggFindBarPrivate *priv;
669
670 g_return_val_if_fail (EGG_IS_FIND_BAR (find_bar), FALSE);
671
672 priv = (EggFindBarPrivate *)find_bar->priv;
673
674 return priv->case_sensitive;
675 }
676
677 static void
get_style_color(EggFindBar * find_bar,const char * style_prop_name,GdkColor * color)678 get_style_color (EggFindBar *find_bar,
679 const char *style_prop_name,
680 GdkColor *color)
681 {
682 GdkColor *style_color;
683
684 gtk_widget_ensure_style (GTK_WIDGET (find_bar));
685 gtk_widget_style_get (GTK_WIDGET (find_bar),
686 "color", &style_color, NULL);
687 if (style_color)
688 {
689 *color = *style_color;
690 gdk_color_free (style_color);
691 }
692 }
693
694 /**
695 * egg_find_bar_get_all_matches_color:
696 *
697 * Gets the color to use to highlight all the
698 * known matches.
699 *
700 * Since: 2.6
701 */
702 void
egg_find_bar_get_all_matches_color(EggFindBar * find_bar,GdkColor * color)703 egg_find_bar_get_all_matches_color (EggFindBar *find_bar,
704 GdkColor *color)
705 {
706 GdkColor found_color = { 0, 0, 0, 0x0f0f };
707
708 get_style_color (find_bar, "all_matches_color", &found_color);
709
710 *color = found_color;
711 }
712
713 /**
714 * egg_find_bar_get_current_match_color:
715 *
716 * Gets the color to use to highlight the match
717 * we're currently on.
718 *
719 * Since: 2.6
720 */
721 void
egg_find_bar_get_current_match_color(EggFindBar * find_bar,GdkColor * color)722 egg_find_bar_get_current_match_color (EggFindBar *find_bar,
723 GdkColor *color)
724 {
725 GdkColor found_color = { 0, 0, 0, 0xffff };
726
727 get_style_color (find_bar, "current_match_color", &found_color);
728
729 *color = found_color;
730 }
731
732 /**
733 * egg_find_bar_set_status_text:
734 *
735 * Sets some text to display if there's space; typical text would
736 * be something like "5 results on this page" or "No results"
737 *
738 * @text: the text to display
739 *
740 * Since: 2.6
741 */
742 void
egg_find_bar_set_status_text(EggFindBar * find_bar,const char * text)743 egg_find_bar_set_status_text (EggFindBar *find_bar,
744 const char *text)
745 {
746 EggFindBarPrivate *priv;
747
748 g_return_if_fail (EGG_IS_FIND_BAR (find_bar));
749
750 priv = (EggFindBarPrivate *)find_bar->priv;
751
752 gtk_label_set_text (GTK_LABEL (priv->status_label), text);
753 g_object_set (priv->status_separator, "visible", text != NULL && *text != '\0', NULL);
754 g_object_set (priv->status_item, "visible", text != NULL && *text !='\0', NULL);
755 }
756