1 /*
2  * xed-panel.c
3  * This file is part of xed
4  *
5  * Copyright (C) 2005 - Paolo Maggi
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 /*
24  * Modified by the xed Team, 2005. See the AUTHORS file for a
25  * list of people on the xed Team.
26  * See the ChangeLog files for a list of changes.
27  *
28  * $Id$
29  */
30 
31 #include "xed-panel.h"
32 
33 #include <glib/gi18n.h>
34 #include <gtk/gtk.h>
35 #include <gdk/gdk.h>
36 #include <gdk/gdkkeysyms.h>
37 
38 #include "xed-close-button.h"
39 #include "xed-window.h"
40 #include "xed-debug.h"
41 
42 #define PANEL_ITEM_KEY "XedPanelItemKey"
43 
44 struct _XedPanelPrivate
45 {
46     GtkOrientation orientation;
47 
48     GtkWidget *main_box;
49     GtkWidget *notebook;
50 };
51 
52 typedef struct _XedPanelItem XedPanelItem;
53 
54 struct _XedPanelItem
55 {
56     gchar     *name;
57     GtkWidget *icon;
58 };
59 
60 /* Properties */
61 enum
62 {
63     PROP_0,
64     PROP_ORIENTATION
65 };
66 
67 /* Signals */
68 enum
69 {
70     ITEM_ADDED,
71     ITEM_REMOVED,
72     CLOSE,
73     FOCUS_DOCUMENT,
74     LAST_SIGNAL
75 };
76 
77 static guint signals[LAST_SIGNAL] = { 0 };
78 
79 static GObject *xed_panel_constructor (GType                  type,
80                                        guint                  n_construct_properties,
81                                        GObjectConstructParam *construct_properties);
82 
83 
G_DEFINE_TYPE_WITH_PRIVATE(XedPanel,xed_panel,GTK_TYPE_BIN)84 G_DEFINE_TYPE_WITH_PRIVATE (XedPanel, xed_panel, GTK_TYPE_BIN)
85 
86 static void
87 xed_panel_finalize (GObject *obj)
88 {
89     if (G_OBJECT_CLASS (xed_panel_parent_class)->finalize)
90     {
91         (*G_OBJECT_CLASS (xed_panel_parent_class)->finalize) (obj);
92     }
93 }
94 
95 static void
xed_panel_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)96 xed_panel_get_property (GObject    *object,
97                         guint       prop_id,
98                         GValue     *value,
99                         GParamSpec *pspec)
100 {
101     XedPanel *panel = XED_PANEL (object);
102 
103     switch (prop_id)
104     {
105         case PROP_ORIENTATION:
106             g_value_set_enum(value, panel->priv->orientation);
107             break;
108         default:
109             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
110             break;
111     }
112 }
113 
114 static void
xed_panel_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)115 xed_panel_set_property (GObject      *object,
116                         guint         prop_id,
117                         const GValue *value,
118                         GParamSpec   *pspec)
119 {
120     XedPanel *panel = XED_PANEL (object);
121 
122     switch (prop_id)
123     {
124         case PROP_ORIENTATION:
125             panel->priv->orientation = g_value_get_enum (value);
126             break;
127         default:
128             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
129             break;
130     }
131 }
132 
133 static void
xed_panel_focus_document(XedPanel * panel)134 xed_panel_focus_document (XedPanel *panel)
135 {
136     GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
137     if (gtk_widget_is_toplevel (toplevel) && XED_IS_WINDOW (toplevel))
138     {
139         XedView *view;
140 
141         view = xed_window_get_active_view (XED_WINDOW (toplevel));
142         if (view != NULL)
143         {
144             gtk_widget_grab_focus (GTK_WIDGET (view));
145         }
146     }
147 }
148 
149 static void
xed_panel_get_size(GtkWidget * widget,GtkOrientation orientation,gint * minimum,gint * natural)150 xed_panel_get_size (GtkWidget      *widget,
151                     GtkOrientation  orientation,
152                     gint           *minimum,
153                     gint           *natural)
154 {
155     GtkBin *bin = GTK_BIN (widget);
156     GtkWidget *child;
157 
158     if (minimum)
159     {
160         *minimum = 0;
161     }
162 
163     if (natural)
164     {
165         *natural = 0;
166     }
167 
168     child = gtk_bin_get_child (bin);
169     if (child && gtk_widget_get_visible (child))
170     {
171         if (orientation == GTK_ORIENTATION_HORIZONTAL)
172         {
173             gtk_widget_get_preferred_width (child, minimum, natural);
174         }
175         else
176         {
177             gtk_widget_get_preferred_height (child, minimum, natural);
178         }
179     }
180 }
181 
182 static void
xed_panel_get_preferred_width(GtkWidget * widget,gint * minimum,gint * natural)183 xed_panel_get_preferred_width (GtkWidget *widget,
184                                gint      *minimum,
185                                gint      *natural)
186 {
187     xed_panel_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
188 }
189 
190 static void
xed_panel_get_preferred_height(GtkWidget * widget,gint * minimum,gint * natural)191 xed_panel_get_preferred_height (GtkWidget *widget,
192                                 gint      *minimum,
193                                 gint      *natural)
194 {
195    xed_panel_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum, natural);
196 }
197 
198 static void
xed_panel_size_allocate(GtkWidget * widget,GtkAllocation * allocation)199 xed_panel_size_allocate (GtkWidget     *widget,
200                          GtkAllocation *allocation)
201 {
202     GtkBin *bin = GTK_BIN (widget);
203     GtkWidget *child;
204 
205     GTK_WIDGET_CLASS (xed_panel_parent_class)->size_allocate (widget, allocation);
206 
207     child = gtk_bin_get_child (bin);
208     if (child && gtk_widget_get_visible (child))
209     {
210        gtk_widget_size_allocate (child, allocation);
211     }
212 }
213 
214 static void
xed_panel_grab_focus(GtkWidget * w)215 xed_panel_grab_focus (GtkWidget *w)
216 {
217     gint n;
218     GtkWidget *tab;
219     XedPanel *panel = XED_PANEL (w);
220 
221     n = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook));
222     if (n == -1)
223     {
224         return;
225     }
226 
227     tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), n);
228     g_return_if_fail (tab != NULL);
229 
230     gtk_widget_grab_focus (tab);
231 }
232 
233 static void
xed_panel_class_init(XedPanelClass * klass)234 xed_panel_class_init (XedPanelClass *klass)
235 {
236     GtkBindingSet *binding_set;
237     GObjectClass *object_class = G_OBJECT_CLASS (klass);
238     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
239 
240     object_class->constructor = xed_panel_constructor;
241     object_class->finalize = xed_panel_finalize;
242     object_class->get_property = xed_panel_get_property;
243     object_class->set_property = xed_panel_set_property;
244 
245     widget_class->get_preferred_width = xed_panel_get_preferred_width;
246     widget_class->get_preferred_height = xed_panel_get_preferred_height;
247     widget_class->size_allocate = xed_panel_size_allocate;
248     widget_class->grab_focus = xed_panel_grab_focus;
249 
250     klass->focus_document = xed_panel_focus_document;
251 
252     g_object_class_install_property (object_class,
253                                      PROP_ORIENTATION,
254                                      g_param_spec_enum ("orientation",
255                                                         "Panel Orientation",
256                                                         "The panel's orientation",
257                                                         GTK_TYPE_ORIENTATION,
258                                                         GTK_ORIENTATION_VERTICAL,
259                                                         G_PARAM_READWRITE |
260                                                         G_PARAM_CONSTRUCT_ONLY |
261                                                         G_PARAM_STATIC_STRINGS));
262 
263     signals[ITEM_ADDED] =
264         g_signal_new ("item_added",
265                       G_OBJECT_CLASS_TYPE (klass),
266                       G_SIGNAL_RUN_FIRST,
267                       G_STRUCT_OFFSET (XedPanelClass, item_added),
268                       NULL, NULL,
269                       g_cclosure_marshal_VOID__OBJECT,
270                       G_TYPE_NONE,
271                       1,
272                       GTK_TYPE_WIDGET);
273     signals[ITEM_REMOVED] =
274         g_signal_new ("item_removed",
275                       G_OBJECT_CLASS_TYPE (klass),
276                       G_SIGNAL_RUN_FIRST,
277                       G_STRUCT_OFFSET (XedPanelClass, item_removed),
278                       NULL, NULL,
279                       g_cclosure_marshal_VOID__OBJECT,
280                       G_TYPE_NONE,
281                       1,
282                       GTK_TYPE_WIDGET);
283 
284     /* Keybinding signals */
285     signals[CLOSE] =
286         g_signal_new ("close",
287                       G_OBJECT_CLASS_TYPE (klass),
288                       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
289                       G_STRUCT_OFFSET (XedPanelClass, close),
290                       NULL, NULL,
291                       g_cclosure_marshal_VOID__VOID,
292                       G_TYPE_NONE, 0);
293     signals[FOCUS_DOCUMENT] =
294         g_signal_new ("focus_document",
295                       G_OBJECT_CLASS_TYPE (klass),
296                       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
297                       G_STRUCT_OFFSET (XedPanelClass, focus_document),
298                       NULL, NULL,
299                       g_cclosure_marshal_VOID__VOID,
300                       G_TYPE_NONE, 0);
301     binding_set = gtk_binding_set_by_class (klass);
302 
303     gtk_binding_entry_add_signal (binding_set,
304                                   GDK_KEY_Escape,
305                                   0,
306                                   "close",
307                                   0);
308     gtk_binding_entry_add_signal (binding_set,
309                                   GDK_KEY_Return,
310                                   GDK_CONTROL_MASK,
311                                   "focus_document",
312                                   0);
313 }
314 
315 static void
xed_panel_init(XedPanel * panel)316 xed_panel_init (XedPanel *panel)
317 {
318     panel->priv = xed_panel_get_instance_private (panel);
319 
320     panel->priv->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
321     gtk_widget_show (panel->priv->main_box);
322     gtk_container_add (GTK_CONTAINER (panel), panel->priv->main_box);
323 }
324 
325 static void
build_notebook_for_panel(XedPanel * panel)326 build_notebook_for_panel (XedPanel *panel)
327 {
328     /* Create the panel notebook */
329     panel->priv->notebook = gtk_notebook_new ();
330 
331     gtk_notebook_set_scrollable (GTK_NOTEBOOK (panel->priv->notebook), TRUE);
332     gtk_notebook_popup_enable (GTK_NOTEBOOK (panel->priv->notebook));
333     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook), FALSE);
334     gtk_notebook_set_show_border (GTK_NOTEBOOK (panel->priv->notebook), FALSE);
335 
336     gtk_widget_show (GTK_WIDGET (panel->priv->notebook));
337 }
338 
339 static GObject *
xed_panel_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)340 xed_panel_constructor (GType                  type,
341                        guint                  n_construct_properties,
342                        GObjectConstructParam *construct_properties)
343 {
344 
345     /* Invoke parent constructor. */
346     XedPanelClass *klass = XED_PANEL_CLASS (g_type_class_peek (XED_TYPE_PANEL));
347     GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
348     GObject *obj = parent_class->constructor (type, n_construct_properties, construct_properties);
349 
350     /* Build the panel, now that we know the orientation (_init has been called previously) */
351     XedPanel *panel = XED_PANEL (obj);
352 
353     build_notebook_for_panel (panel);
354     gtk_box_pack_start (GTK_BOX (panel->priv->main_box), panel->priv->notebook, TRUE, TRUE, 0);
355 
356     gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "xed-panel");
357 
358     if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL)
359     {
360         gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "side");
361     }
362     else
363     {
364         gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "bottom");
365     }
366 
367     return obj;
368 }
369 
370 /**
371  * xed_panel_new:
372  * @orientation: a #GtkOrientation
373  *
374  * Creates a new #XedPanel with the given @orientation. You shouldn't create
375  * a new panel use xed_window_get_side_panel() or xed_window_get_bottom_panel()
376  * instead.
377  *
378  * Returns: a new #XedPanel object.
379  */
380 GtkWidget *
xed_panel_new(GtkOrientation orientation)381 xed_panel_new (GtkOrientation orientation)
382 {
383     return GTK_WIDGET (g_object_new (XED_TYPE_PANEL, "orientation", orientation, NULL));
384 }
385 
386 static GtkWidget *
build_tab_label(XedPanel * panel,GtkWidget * item,const gchar * name,GtkWidget * icon)387 build_tab_label (XedPanel    *panel,
388                  GtkWidget   *item,
389                  const gchar *name,
390                  GtkWidget   *icon)
391 {
392     GtkWidget *hbox;
393     GtkWidget *label_hbox;
394     GtkWidget *label_ebox;
395     GtkWidget *label;
396 
397     /* set hbox spacing and label padding (see below) so that there's an
398      * equal amount of space around the label */
399     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
400 
401     label_ebox = gtk_event_box_new ();
402     gtk_event_box_set_visible_window (GTK_EVENT_BOX (label_ebox), FALSE);
403     gtk_box_pack_start (GTK_BOX (hbox), label_ebox, TRUE, TRUE, 0);
404 
405     label_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
406     gtk_container_add (GTK_CONTAINER (label_ebox), label_hbox);
407 
408     /* setup icon */
409     gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0);
410 
411     /* setup label */
412     label = gtk_label_new (name);
413 
414     gtk_widget_set_halign (label, GTK_ALIGN_START);
415     gtk_widget_set_margin_start (label, 0);
416     gtk_widget_set_margin_end (label, 0);
417     gtk_widget_set_margin_top (label, 0);
418     gtk_widget_set_margin_bottom (label, 0);
419 
420     gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0);
421 
422     gtk_widget_set_tooltip_text (label_ebox, name);
423 
424     gtk_widget_show_all (hbox);
425 
426     if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL)
427     {
428         gtk_widget_hide(label);
429     }
430 
431     g_object_set_data (G_OBJECT (item), "label", label);
432     g_object_set_data (G_OBJECT (item), "hbox", hbox);
433 
434     return hbox;
435 }
436 
437 static void
update_tabs_visibility(XedPanel * panel)438 update_tabs_visibility (XedPanel *panel)
439 {
440     gboolean show_tabs;
441 
442     show_tabs = (gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)) > 1);
443     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook), show_tabs);
444 }
445 
446 /**
447  * xed_panel_add_item:
448  * @panel: a #XedPanel
449  * @item: the #GtkWidget to add to the @panel
450  * @name: the name to be shown in the @panel
451  * @icon_name: the name of the icon to be shown in the @panel
452  *
453  * Adds a new item to the @panel.
454  */
455 void
xed_panel_add_item(XedPanel * panel,GtkWidget * item,const gchar * name,const gchar * icon_name)456 xed_panel_add_item (XedPanel    *panel,
457                     GtkWidget   *item,
458                     const gchar *name,
459                     const gchar *icon_name)
460 {
461     XedPanelItem *data;
462     GtkWidget *tab_label;
463     GtkWidget *menu_label;
464 
465     g_return_if_fail (XED_IS_PANEL (panel));
466     g_return_if_fail (GTK_IS_WIDGET (item));
467     g_return_if_fail (name != NULL);
468 
469     data = g_new (XedPanelItem, 1);
470 
471     data->name = g_strdup (name);
472 
473     if (icon_name)
474     {
475         data->icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
476     }
477     else
478     {
479         data->icon = gtk_image_new_from_icon_name ("text-x-generic", GTK_ICON_SIZE_MENU);
480     }
481 
482     g_object_set_data (G_OBJECT (item), PANEL_ITEM_KEY, data);
483 
484     tab_label = build_tab_label (panel, item, data->name, data->icon);
485 
486     menu_label = gtk_label_new (name);
487 
488     gtk_widget_set_halign (menu_label, GTK_ALIGN_START);
489 
490     if (!gtk_widget_get_visible (item))
491     {
492         gtk_widget_show (item);
493     }
494 
495     gtk_notebook_append_page_menu (GTK_NOTEBOOK (panel->priv->notebook), item, tab_label, menu_label);
496     update_tabs_visibility (panel);
497 
498     g_signal_emit (G_OBJECT (panel), signals[ITEM_ADDED], 0, item);
499 }
500 
501 /**
502  * xed_panel_remove_item:
503  * @panel: a #XedPanel
504  * @item: the item to be removed from the panel
505  *
506  * Removes the widget @item from the panel if it is in the @panel and returns
507  * %TRUE if there was not any problem.
508  *
509  * Returns: %TRUE if it was well removed.
510  */
511 gboolean
xed_panel_remove_item(XedPanel * panel,GtkWidget * item)512 xed_panel_remove_item (XedPanel  *panel,
513                        GtkWidget *item)
514 {
515     XedPanelItem *data;
516     gint page_num;
517 
518     g_return_val_if_fail (XED_IS_PANEL (panel), FALSE);
519     g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
520 
521     page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item);
522 
523     if (page_num == -1)
524     {
525         return FALSE;
526     }
527 
528     data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY);
529     g_return_val_if_fail (data != NULL, FALSE);
530 
531     g_free (data->name);
532     g_free (data);
533 
534     g_object_set_data (G_OBJECT (item), PANEL_ITEM_KEY, NULL);
535 
536     /* ref the item to keep it alive during signal emission */
537     g_object_ref (G_OBJECT (item));
538 
539     gtk_notebook_remove_page (GTK_NOTEBOOK (panel->priv->notebook), page_num);
540     update_tabs_visibility (panel);
541 
542     g_signal_emit (G_OBJECT (panel), signals[ITEM_REMOVED], 0, item);
543 
544     g_object_unref (G_OBJECT (item));
545 
546     return TRUE;
547 }
548 
549 /**
550  * xed_panel_activate_item:
551  * @panel: a #XedPanel
552  * @item: the item to be activated
553  *
554  * Switches to the page that contains @item.
555  *
556  * Returns: %TRUE if it was activated
557  */
558 gboolean
xed_panel_activate_item(XedPanel * panel,GtkWidget * item)559 xed_panel_activate_item (XedPanel  *panel,
560                          GtkWidget *item)
561 {
562     gint page_num;
563 
564     g_return_val_if_fail (XED_IS_PANEL (panel), FALSE);
565     g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
566 
567     page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item);
568 
569     if (page_num == -1)
570     {
571         return FALSE;
572     }
573 
574     gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook), page_num);
575 
576     return TRUE;
577 }
578 
579 /**
580  * xed_panel_item_is_active:
581  * @panel: a #XedPanel
582  * @item: a #GtkWidget
583  *
584  * Returns whether @item is the active widget in @panel
585  *
586  * Returns: %TRUE if @item is the active widget
587  */
588 gboolean
xed_panel_item_is_active(XedPanel * panel,GtkWidget * item)589 xed_panel_item_is_active (XedPanel  *panel,
590                           GtkWidget *item)
591 {
592     gint cur_page;
593     gint page_num;
594 
595     g_return_val_if_fail (XED_IS_PANEL (panel), FALSE);
596     g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
597 
598     page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item);
599 
600     if (page_num == -1)
601     {
602         return FALSE;
603     }
604 
605     cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook));
606 
607     return (page_num == cur_page);
608 }
609 
610 /**
611  * xed_panel_get_orientation:
612  * @panel: a #XedPanel
613  *
614  * Gets the orientation of the @panel.
615  *
616  * Returns: the #GtkOrientation of #XedPanel
617  */
618 GtkOrientation
xed_panel_get_orientation(XedPanel * panel)619 xed_panel_get_orientation (XedPanel *panel)
620 {
621     g_return_val_if_fail (XED_IS_PANEL (panel), GTK_ORIENTATION_VERTICAL);
622 
623     return panel->priv->orientation;
624 }
625 
626 /**
627  * xed_panel_get_n_items:
628  * @panel: a #XedPanel
629  *
630  * Gets the number of items in a @panel.
631  *
632  * Returns: the number of items contained in #XedPanel
633  */
634 gint
xed_panel_get_n_items(XedPanel * panel)635 xed_panel_get_n_items (XedPanel *panel)
636 {
637     g_return_val_if_fail (XED_IS_PANEL (panel), -1);
638 
639     return gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook));
640 }
641 
642 gint
_xed_panel_get_active_item_id(XedPanel * panel)643 _xed_panel_get_active_item_id (XedPanel *panel)
644 {
645     gint cur_page;
646     GtkWidget *item;
647     XedPanelItem *data;
648 
649     g_return_val_if_fail (XED_IS_PANEL (panel), 0);
650 
651     cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook));
652     if (cur_page == -1)
653     {
654         return 0;
655     }
656 
657     item = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), cur_page);
658 
659     /* FIXME: for now we use as the hash of the name as id.
660      * However the name is not guaranteed to be unique and
661      * it is a translated string, so it's subotimal, but should
662      * be good enough for now since we don't want to add an
663      * ad hoc id argument.
664      */
665 
666     data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY);
667     g_return_val_if_fail (data != NULL, 0);
668 
669     return g_str_hash (data->name);
670 }
671 
672 void
_xed_panel_set_active_item_by_id(XedPanel * panel,gint id)673 _xed_panel_set_active_item_by_id (XedPanel *panel,
674                                   gint      id)
675 {
676     gint n, i;
677 
678     g_return_if_fail (XED_IS_PANEL (panel));
679 
680     if (id == 0)
681     {
682         return;
683     }
684 
685     n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook));
686 
687     for (i = 0; i < n; i++)
688     {
689         GtkWidget *item;
690         XedPanelItem *data;
691 
692         item = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), i);
693 
694         data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY);
695         g_return_if_fail (data != NULL);
696 
697         if (g_str_hash (data->name) == id)
698         {
699             gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook), i);
700 
701             return;
702         }
703     }
704 }
705