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