]> www.fi.muni.cz Git - evince.git/blob - cut-n-paste/recent-files/egg-recent-view-gtk.c
Select first item
[evince.git] / cut-n-paste / recent-files / egg-recent-view-gtk.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU 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 program 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
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16  *
17  * Authors:
18  *   James Willcox <jwillcox@cs.indiana.edu>
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <gtk/gtk.h>
29 #include <libgnomevfs/gnome-vfs.h>
30 #ifndef USE_STABLE_LIBGNOMEUI
31 #include <libgnomeui/gnome-icon-theme.h>
32 #endif
33 #include <gconf/gconf-client.h>
34 #include "egg-recent-model.h"
35 #include "egg-recent-view.h"
36 #include "egg-recent-view-gtk.h"
37 #include "egg-recent-util.h"
38 #include "egg-recent-item.h"
39
40 struct _EggRecentViewGtk {
41         GObject parent_instance;        /* We emit signals */
42
43         GtkWidget *menu;
44         GtkWidget *start_menu_item;
45
46         gboolean leading_sep;
47         gboolean trailing_sep;
48
49         gulong changed_cb_id;
50
51         gchar *uid;
52
53         gboolean show_icons;
54         gboolean show_numbers;
55 #ifndef USE_STABLE_LIBGNOMEUI
56         GnomeIconTheme *theme;
57 #endif
58
59         GtkTooltips *tooltips;
60         EggRecentViewGtkTooltipFunc tooltip_func;
61         gpointer tooltip_func_data;
62
63         EggRecentModel *model;
64         GConfClient *client;
65         GtkIconSize icon_size;
66 };
67
68
69
70 struct _EggRecentViewGtkMenuData {
71         EggRecentViewGtk *view;
72         EggRecentItem *item;
73 };
74
75 typedef struct _EggRecentViewGtkMenuData EggRecentViewGtkMenuData;
76
77 enum {
78         ACTIVATE,
79         LAST_SIGNAL
80 };
81
82 /* GObject properties */
83 enum {
84         PROP_BOGUS,
85         PROP_MENU,
86         PROP_START_MENU_ITEM,
87         PROP_SHOW_ICONS,
88         PROP_SHOW_NUMBERS
89 };
90
91 static guint view_signals[LAST_SIGNAL] = { 0 };
92
93
94 static void
95 egg_recent_view_gtk_clear (EggRecentViewGtk *view)
96 {
97         GList *menu_children;
98         GList *p;
99         GObject *menu_item;
100         gint *menu_data=NULL;
101
102         if (view->menu == NULL)
103                 return;
104
105         menu_children = gtk_container_get_children (GTK_CONTAINER (view->menu));
106
107         p = menu_children;
108         while (p != NULL) {
109                 menu_item = (GObject *)p->data;
110
111                 menu_data = (gint *)g_object_get_data (menu_item,
112                                                        view->uid);
113         
114                 if (menu_data) {
115                         gtk_container_remove (GTK_CONTAINER (view->menu),
116                                              GTK_WIDGET (menu_item));
117
118                 }
119                 
120                 p = p->next;
121         }
122 }
123
124
125 static gint
126 egg_recent_view_gtk_find_menu_offset (EggRecentViewGtk *view)
127 {
128         gint i;
129         GList *menu_children;
130         GList *p;
131         GtkWidget *menu_item;
132         gint menu_loc=-1;
133
134         g_return_val_if_fail (view, 0);
135
136         menu_children = GTK_MENU_SHELL (view->menu)->children;
137
138         i = 0;
139         p = menu_children;
140         while (p != NULL) {
141                 menu_item = (GtkWidget *)p->data;
142
143                 if (menu_item == view->start_menu_item) {
144                         menu_loc = i;
145                         break;
146                 }
147
148                 p = p->next;
149                 i++;
150         }
151
152         return menu_loc;
153 }
154
155 static void
156 egg_recent_view_gtk_menu_cb (GtkWidget *menu, gpointer data)
157 {
158         EggRecentViewGtkMenuData *md = (EggRecentViewGtkMenuData *) data;
159         EggRecentItem *item;
160
161         g_return_if_fail (md);
162         g_return_if_fail (md->item);
163         g_return_if_fail (md->view);
164         g_return_if_fail (EGG_IS_RECENT_VIEW_GTK (md->view));
165
166         item = md->item;
167         
168         egg_recent_item_ref (item);
169         
170         g_signal_emit (G_OBJECT(md->view), view_signals[ACTIVATE], 0,
171                        item);
172
173         egg_recent_item_unref (item);
174 }
175
176 static void
177 egg_recent_view_gtk_destroy_cb (gpointer data, GClosure *closure)
178 {
179         EggRecentViewGtkMenuData *md = data;
180
181         egg_recent_item_unref (md->item);
182         g_free (md);
183 }
184
185 static GtkWidget *
186 egg_recent_view_gtk_new_separator (EggRecentViewGtk *view)
187 {
188         GtkWidget *retval;
189
190         g_return_val_if_fail (view, NULL);
191         
192         retval = gtk_separator_menu_item_new ();
193
194         /*
195          * this is a tag so we can distinguish our menu items
196          * from others that may be in the menu.
197          */
198         g_object_set_data (G_OBJECT (retval),
199                            view->uid,
200                            GINT_TO_POINTER (1));
201
202
203         gtk_widget_show (retval);
204
205         return retval;
206 }
207
208 static GtkWidget *
209 egg_recent_view_gtk_new_menu_item (EggRecentViewGtk *view,
210                                    EggRecentItem *item,
211                                    gint index)
212 {
213         GtkWidget *menu_item;
214         EggRecentViewGtkMenuData *md;
215         gchar *mime_type;
216         GtkWidget *image;
217         GdkPixbuf *pixbuf;
218         gchar *text;
219         gchar *short_name;
220         gchar *escaped;
221
222         g_return_val_if_fail (view, NULL);
223         g_return_val_if_fail (item, NULL);
224
225         short_name = egg_recent_item_get_short_name (item);
226         if (!short_name)
227                 return NULL;
228
229         escaped = egg_recent_util_escape_underlines (short_name);
230         g_free (short_name);
231
232         if (view->show_numbers) {
233                 /* avoid having conflicting mnemonics */
234                 if (index >= 10)
235                         text = g_strdup_printf ("%d.  %s", index,
236                                                 escaped);
237                 else
238                         text = g_strdup_printf ("_%d.  %s", index,
239                                                 escaped);
240                 g_free (escaped);
241         } else {
242                 text = escaped;
243         }
244
245         mime_type = egg_recent_item_get_mime_type (item);
246 #ifndef USE_STABLE_LIBGNOMEUI
247         {
248                 int width, height;
249                 gchar *uri;
250
251                 gtk_icon_size_lookup_for_settings
252                         (gtk_widget_get_settings (view->menu),
253                          view->icon_size,
254                          &width, &height);
255
256                 uri = egg_recent_item_get_uri (item);
257                 pixbuf = egg_recent_util_get_icon (view->theme, uri,
258                                                    mime_type,
259                                                    height);
260                 g_free (uri);
261         }
262 #else
263         pixbuf = NULL;
264 #endif
265         image = gtk_image_new_from_pixbuf (pixbuf);
266         if (pixbuf)
267                 g_object_unref (pixbuf);
268
269         if (view->show_icons)
270                 gtk_widget_show (image);
271
272         menu_item = gtk_image_menu_item_new_with_mnemonic (text);
273         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
274                                        image);
275
276         md = g_new0 (EggRecentViewGtkMenuData, 1);
277         md->view = view;
278         md->item = egg_recent_item_ref (item);
279
280         g_signal_connect_data (G_OBJECT (menu_item), "activate",
281                                G_CALLBACK (egg_recent_view_gtk_menu_cb),
282                                md,
283                                (GClosureNotify)egg_recent_view_gtk_destroy_cb,
284                                0);
285
286         g_free (mime_type);
287         g_free (text);
288
289         /*
290          * this is a tag so we can distinguish our menu items
291          * from others that may be in the menu.
292          */
293         g_object_set_data (G_OBJECT (menu_item),
294                            view->uid,
295                            GINT_TO_POINTER (1));
296
297
298         gtk_widget_show (menu_item);
299
300         return menu_item;
301 }
302
303 static void
304 egg_recent_view_gtk_add_to_menu (EggRecentViewGtk *view,
305                                  EggRecentItem *item,
306                                  gint display,
307                                  gint index)
308 {
309         GtkWidget *menu_item;
310         gint menu_offset;
311         
312         g_return_if_fail (view);
313         g_return_if_fail (view->menu);
314
315         menu_offset = egg_recent_view_gtk_find_menu_offset (view);
316
317         if (item != NULL)
318                 menu_item = egg_recent_view_gtk_new_menu_item (view, item, display);
319         else
320                 menu_item = egg_recent_view_gtk_new_separator (view);
321
322         if (view->tooltip_func != NULL && menu_item != NULL) {
323                 view->tooltip_func (view->tooltips, menu_item,
324                                     item, view->tooltip_func_data);
325         }
326         
327         if (menu_item)
328                 gtk_menu_shell_insert (GTK_MENU_SHELL (view->menu), menu_item,
329                                menu_offset+index);
330 }
331
332 static void
333 egg_recent_view_gtk_set_list (EggRecentViewGtk *view, GList *list)
334 {
335         EggRecentItem *item;
336         GList *p;
337         gint display=1;
338         gint index=1;
339
340         if (view->menu == NULL)
341                 return;
342
343         egg_recent_view_gtk_clear (view);
344
345         if (view->leading_sep) {
346                 egg_recent_view_gtk_add_to_menu (view, NULL, display, index);
347                 index++;
348         }
349
350         p = list;
351         while (p != NULL) {
352                 item = (EggRecentItem *)p->data;
353
354                 egg_recent_view_gtk_add_to_menu (view, item, display, index);
355
356                 p = p->next;
357                 display++;
358                 index++;
359         }
360
361         if (view->trailing_sep)
362                 egg_recent_view_gtk_add_to_menu (view, NULL, display, index);
363 }
364
365 static void
366 model_changed_cb (EggRecentModel *model, GList *list, EggRecentViewGtk *view)
367 {
368         if (list != NULL)
369                 egg_recent_view_gtk_set_list (view, list);
370         else
371                 egg_recent_view_gtk_clear (view);
372 }
373
374 static EggRecentModel *
375 egg_recent_view_gtk_get_model (EggRecentView *view_parent)
376 {
377         EggRecentViewGtk *view;
378         
379         g_return_val_if_fail (view_parent != NULL, NULL);
380         view = EGG_RECENT_VIEW_GTK (view_parent);
381         return view->model;
382 }
383
384 static void
385 egg_recent_view_gtk_set_model (EggRecentView *view_parent,
386                                  EggRecentModel *model)
387 {
388         EggRecentViewGtk *view;
389         
390         g_return_if_fail (view_parent != NULL);
391         view = EGG_RECENT_VIEW_GTK (view_parent);
392
393         if (view->model != NULL) {
394                 g_object_unref (view->model);
395                 g_signal_handler_disconnect (G_OBJECT (model),
396                                              view->changed_cb_id);
397         }
398         
399         view->model = model;
400         g_object_ref (view->model);
401
402         view->changed_cb_id = g_signal_connect_object (G_OBJECT (model),
403                                                 "changed",
404                                                 G_CALLBACK (model_changed_cb),
405                                                 view, 0);
406
407         egg_recent_model_changed (view->model);
408 }
409
410 void
411 egg_recent_view_gtk_set_leading_sep (EggRecentViewGtk *view, gboolean val)
412 {
413         view->leading_sep = val;
414
415         egg_recent_view_gtk_clear (view);
416
417         if (view->model)
418                 egg_recent_model_changed (view->model);
419 }
420
421 void
422 egg_recent_view_gtk_set_trailing_sep (EggRecentViewGtk *view, gboolean val)
423 {
424         view->trailing_sep = val;
425
426         egg_recent_view_gtk_clear (view);
427
428         if (view->model)
429                 egg_recent_model_changed (view->model);
430 }
431
432 static void
433 egg_recent_view_gtk_set_property (GObject *object,
434                            guint prop_id,
435                            const GValue *value,
436                            GParamSpec *pspec)
437 {
438         EggRecentViewGtk *view = EGG_RECENT_VIEW_GTK (object);
439
440         switch (prop_id)
441         {
442                 case PROP_MENU:
443                         egg_recent_view_gtk_set_menu (view,
444                                                GTK_WIDGET (g_value_get_object (value)));
445                 break;
446                 case PROP_START_MENU_ITEM:
447                         egg_recent_view_gtk_set_start_menu_item (view,
448                                         g_value_get_object (value));
449                 break;
450                 case PROP_SHOW_ICONS:
451                         egg_recent_view_gtk_show_icons (view,
452                                         g_value_get_boolean (value));
453                 break;
454                 case PROP_SHOW_NUMBERS:
455                         egg_recent_view_gtk_show_numbers (view,
456                                         g_value_get_boolean (value));
457                 break;
458                 default:
459                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
460                 break;
461         }
462 }
463
464 static void
465 egg_recent_view_gtk_get_property (GObject *object,
466                            guint prop_id,
467                            GValue *value,
468                            GParamSpec *pspec)
469 {
470         EggRecentViewGtk *view = EGG_RECENT_VIEW_GTK (object);
471
472         switch (prop_id)
473         {
474                 case PROP_MENU:
475                         g_value_set_object (value, view->menu);
476                 break;
477                 case PROP_START_MENU_ITEM:
478                         g_value_set_object (value, view->start_menu_item);
479                 break;
480                 case PROP_SHOW_ICONS:
481                         g_value_set_boolean (value, view->show_icons);
482                 break;
483                 case PROP_SHOW_NUMBERS:
484                         g_value_set_boolean (value, view->show_numbers);
485                 break;
486                 default:
487                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
488                 break;
489         }
490 }
491
492 static void
493 egg_recent_view_gtk_finalize (GObject *object)
494 {
495         EggRecentViewGtk *view = EGG_RECENT_VIEW_GTK (object);
496
497         g_signal_handler_disconnect (G_OBJECT (view->model),
498                                      view->changed_cb_id);
499
500         g_free (view->uid);
501
502         g_object_unref (view->model);
503 #ifndef USE_STABLE_LIBGNOMEUI
504         g_object_unref (view->theme);
505 #endif
506         g_object_unref (view->client);
507
508         g_object_unref (view->tooltips);
509 }
510
511 static void
512 egg_recent_view_gtk_class_init (EggRecentViewGtkClass * klass)
513 {
514         GObjectClass *object_class;
515
516         object_class = G_OBJECT_CLASS (klass);
517
518         object_class->set_property = egg_recent_view_gtk_set_property;
519         object_class->get_property = egg_recent_view_gtk_get_property;
520         object_class->finalize     = egg_recent_view_gtk_finalize;
521
522         view_signals[ACTIVATE] = g_signal_new ("activate",
523                         G_OBJECT_CLASS_TYPE (object_class),
524                         G_SIGNAL_RUN_LAST,
525                         G_STRUCT_OFFSET (EggRecentViewGtkClass, activate),
526                         NULL, NULL,
527                         g_cclosure_marshal_VOID__BOXED,
528                         G_TYPE_NONE, 1,
529                         EGG_TYPE_RECENT_ITEM);
530
531         g_object_class_install_property (object_class,
532                                          PROP_MENU,
533                                          g_param_spec_object ("menu",
534                                                               "Menu",
535                                                               "The GtkMenuShell this object will update.",
536                                                               gtk_menu_get_type(),
537                                                               G_PARAM_READWRITE));
538         g_object_class_install_property (object_class,
539                                          PROP_START_MENU_ITEM,
540                                          g_param_spec_object ("start-menu-item",
541                                                               "Start Menu Item",
542                                                               "The menu item that precedes where are menu items will go",
543                                                               gtk_menu_item_get_type (),
544                                                               G_PARAM_READWRITE));
545
546         g_object_class_install_property (object_class,
547                                          PROP_SHOW_ICONS,
548                                          g_param_spec_boolean ("show-icons",
549                                            "Show Icons",
550                                            "Whether or not to show icons",
551                                            FALSE,
552                                            G_PARAM_READWRITE));
553
554         g_object_class_install_property (object_class,
555                                          PROP_SHOW_NUMBERS,
556                                          g_param_spec_boolean ("show-numbers",
557                                            "Show Numbers",
558                                            "Whether or not to show numbers",
559                                            TRUE,
560                                            G_PARAM_READWRITE));
561
562         klass->activate = NULL;
563 }
564
565 static void
566 egg_recent_view_init (EggRecentViewClass *iface)
567 {
568         iface->do_get_model = egg_recent_view_gtk_get_model;
569         iface->do_set_model = egg_recent_view_gtk_set_model;
570 }
571
572 static void
573 show_menus_changed_cb (GConfClient *client,
574                        guint cnxn_id,
575                        GConfEntry *entry,
576                        EggRecentViewGtk *view)
577 {
578         GConfValue *value;
579
580         value = gconf_entry_get_value (entry);
581
582         g_return_if_fail (value->type == GCONF_VALUE_BOOL);
583
584         egg_recent_view_gtk_show_icons (view,
585                                 gconf_value_get_bool (value));
586
587 }
588
589 #ifndef USE_STABLE_LIBGNOMEUI
590 static void
591 theme_changed_cb (GnomeIconTheme *theme, EggRecentViewGtk *view)
592 {
593         if (view->model != NULL)
594                 egg_recent_model_changed (view->model);
595 }
596 #endif
597
598 static void
599 egg_recent_view_gtk_init (EggRecentViewGtk * view)
600 {
601         view->client = gconf_client_get_default ();
602
603         view->show_icons =
604                 gconf_client_get_bool (view->client,
605                         "/desktop/gnome/interface/menus_have_icons",
606                         NULL);
607
608         gconf_client_add_dir (view->client, "/desktop/gnome/interface",
609                               GCONF_CLIENT_PRELOAD_NONE,
610                               NULL);
611         gconf_client_notify_add (view->client,
612                         "/desktop/gnome/interface/menus_have_icons",
613                         (GConfClientNotifyFunc)show_menus_changed_cb,
614                         view, NULL, NULL);
615
616
617         view->leading_sep = FALSE;
618         view->trailing_sep = FALSE;
619
620         view->uid = egg_recent_util_get_unique_id ();
621 #ifndef USE_STABLE_LIBGNOMEUI
622         view->theme = gnome_icon_theme_new ();
623         gnome_icon_theme_set_allow_svg (view->theme, TRUE);
624         g_signal_connect_object (view->theme, "changed",
625                                  G_CALLBACK (theme_changed_cb), view, 0);
626 #endif
627         view->tooltips = gtk_tooltips_new ();
628         g_object_ref (view->tooltips);
629         gtk_object_sink (GTK_OBJECT (view->tooltips));
630         view->tooltip_func = NULL;
631         view->tooltip_func_data = NULL;
632
633         view->icon_size = GTK_ICON_SIZE_MENU;
634 }
635
636 void
637 egg_recent_view_gtk_set_icon_size (EggRecentViewGtk *view,
638                                    GtkIconSize icon_size)
639 {
640         if (view->icon_size != icon_size) {
641                 view->icon_size = icon_size;
642                 egg_recent_model_changed (view->model);
643         } else {
644                 view->icon_size = icon_size;
645         }
646 }
647
648 GtkIconSize
649 egg_recent_view_gtk_get_icon_size (EggRecentViewGtk *view)
650 {
651         return view->icon_size;
652 }
653
654 void
655 egg_recent_view_gtk_show_icons (EggRecentViewGtk *view, gboolean show)
656 {
657         view->show_icons = show;
658
659         if (view->model)
660                 egg_recent_model_changed (view->model);
661 }
662
663 void
664 egg_recent_view_gtk_show_numbers (EggRecentViewGtk *view, gboolean show)
665 {
666         view->show_numbers = show;
667
668         if (view->model)
669                 egg_recent_model_changed (view->model);
670 }
671
672 void
673 egg_recent_view_gtk_set_tooltip_func (EggRecentViewGtk *view,
674                                       EggRecentViewGtkTooltipFunc func,
675                                       gpointer user_data)
676 {
677         view->tooltip_func = func;
678         view->tooltip_func_data = user_data;
679         
680         if (view->model)
681                 egg_recent_model_changed (view->model);
682 }
683
684 /**
685  * egg_recent_view_gtk_set_menu:
686  * @view: A EggRecentViewGtk object.
687  * @menu: The GtkMenuShell to put the menu items in.
688  *
689  * Use this function to change the GtkMenuShell that the recent
690  * documents appear in.
691  *
692  */
693 void
694 egg_recent_view_gtk_set_menu (EggRecentViewGtk *view,
695                                 GtkWidget *menu)
696 {
697         g_return_if_fail (view);
698         g_return_if_fail (EGG_IS_RECENT_VIEW_GTK (view));
699
700         if (view->menu != NULL)
701                 g_object_remove_weak_pointer (G_OBJECT (view->menu),
702                                               (gpointer *) &view->menu);
703         
704         view->menu = menu;
705
706         if (view->menu != NULL)
707                 g_object_add_weak_pointer (G_OBJECT (view->menu),
708                                            (gpointer *) &view->menu);
709 }
710
711 /**
712  * egg_recent_view_gtk_set_start_menu_item:
713  * @view: A EggRecentViewGtk object.
714  * @start_menu_item: The menu item that appears just before where our menu
715  * items should appear
716  *
717  */
718 void
719 egg_recent_view_gtk_set_start_menu_item (EggRecentViewGtk *view,
720                                          GtkWidget *menu_item)
721 {
722         g_return_if_fail (view);
723         g_return_if_fail (EGG_IS_RECENT_VIEW_GTK (view));
724         
725         view->start_menu_item = menu_item;
726 }
727
728 /**
729  * egg_recent_view_gtk_get_menu:
730  * @view: A EggRecentViewGtk object.
731  *
732  */
733 GtkWidget *
734 egg_recent_view_gtk_get_menu (EggRecentViewGtk *view)
735 {
736         return view->menu;
737 }
738
739 /**
740  * egg_recent_view_gtk_get_start_menu_item
741  * @view: A EggRecentViewGtk object.
742  *
743  */
744 GtkWidget *
745 egg_recent_view_gtk_get_start_menu_item (EggRecentViewGtk *view)
746 {
747         return view->start_menu_item;
748 }
749
750
751 /**
752  * egg_recent_view_gtk_new:
753  * @appname: The name of your application.
754  * @limit:  The maximum number of items allowed.
755  *
756  * This creates a new EggRecentViewGtk object.
757  *
758  * Returns: a EggRecentViewGtk object
759  */
760 EggRecentViewGtk *
761 egg_recent_view_gtk_new (GtkWidget *menu, GtkWidget *start_menu_item)
762 {
763         EggRecentViewGtk *view;
764
765         g_return_val_if_fail (menu, NULL);
766
767         view = EGG_RECENT_VIEW_GTK (g_object_new (egg_recent_view_gtk_get_type (),
768                                            "start-menu-item",
769                                            start_menu_item,
770                                            "menu", menu,
771                                            "show-numbers", TRUE, NULL));
772
773         g_return_val_if_fail (view, NULL);
774         
775         return view;
776 }
777
778 /**
779  * egg_recent_view_gtk_get_type:
780  *
781  * This returns a GType representing a EggRecentViewGtk object.
782  *
783  * Returns: a GType
784  */
785 GType
786 egg_recent_view_gtk_get_type (void)
787 {
788         static GType egg_recent_view_gtk_type = 0;
789
790         if(!egg_recent_view_gtk_type) {
791                 static const GTypeInfo egg_recent_view_gtk_info = {
792                         sizeof (EggRecentViewGtkClass),
793                         NULL, /* base init */
794                         NULL, /* base finalize */
795                         (GClassInitFunc)egg_recent_view_gtk_class_init, /* class init */
796                         NULL, /* class finalize */
797                         NULL, /* class data */
798                         sizeof (EggRecentViewGtk),
799                         0,
800                         (GInstanceInitFunc) egg_recent_view_gtk_init
801                 };
802
803                 static const GInterfaceInfo view_info =
804                 {
805                         (GInterfaceInitFunc) egg_recent_view_init,
806                         NULL,
807                         NULL
808                 };
809
810                 egg_recent_view_gtk_type = g_type_register_static (G_TYPE_OBJECT,
811                                                         "EggRecentViewGtk",
812                                                         &egg_recent_view_gtk_info, 0);
813                 g_type_add_interface_static (egg_recent_view_gtk_type,
814                                              EGG_TYPE_RECENT_VIEW,
815                                              &view_info);
816         }
817
818         return egg_recent_view_gtk_type;
819 }
820