1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19 * James Willcox <jwillcox@cs.indiana.edu>
20 * Paolo Bacchilega <paobac@cvs.gnome.org>
31 #include <libgnomevfs/gnome-vfs.h>
32 #ifndef USE_STABLE_LIBGNOMEUI
33 #include <libgnomeui/gnome-icon-theme.h>
35 #include <gconf/gconf-client.h>
36 #include "egg-recent-model.h"
37 #include "egg-recent-view.h"
38 #include "egg-recent-view-uimanager.h"
39 #include "egg-recent-util.h"
40 #include "egg-recent-item.h"
42 #define EGG_RECENT_NAME_PREFIX "EggRecentAction"
43 #define EGG_RECENT_ACTION "EggRecentFile"
44 #define EGG_RECENT_SEPARATOR (NULL)
46 struct _EggRecentViewUIManager {
47 GObject parent_instance;
49 GCallback action_callback;
50 gpointer action_user_data;
53 gboolean trailing_sep;
55 GtkUIManager *uimanager;
56 GtkActionGroup *action_group;
63 gboolean show_numbers;
64 #ifndef USE_STABLE_LIBGNOMEUI
65 GnomeIconTheme *theme;
68 EggUIManagerTooltipFunc tooltip_func;
69 gpointer tooltip_func_data;
71 EggRecentModel *model;
73 GtkIconSize icon_size;
77 struct _EggRecentViewUIManagerMenuData {
78 EggRecentViewUIManager *view;
82 typedef struct _EggRecentViewUIManagerMenuData EggRecentViewUIManagerMenuData;
89 /* GObject properties */
98 static guint view_signals[LAST_SIGNAL] = { 0 };
101 egg_recent_view_uimanager_clear (EggRecentViewUIManager *view)
103 if (view->merge_id != 0) {
104 gtk_ui_manager_remove_ui (view->uimanager, view->merge_id);
108 if (view->action_group != NULL) {
109 gtk_ui_manager_remove_action_group (view->uimanager, view->action_group);
110 g_object_unref (view->action_group);
111 view->action_group = NULL;
114 gtk_ui_manager_ensure_update (view->uimanager);
118 egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list)
123 g_return_if_fail (view);
125 egg_recent_view_uimanager_clear (view);
127 if (view->merge_id == 0)
128 view->merge_id = gtk_ui_manager_new_merge_id (view->uimanager);
130 if (view->action_group == NULL) {
131 gchar *group = g_strdup_printf ("EggRecentActions%u",
133 view->action_group = gtk_action_group_new (group);
134 gtk_ui_manager_insert_action_group (view->uimanager, view->action_group, 0);
138 if (view->leading_sep) {
139 gchar *action = g_strdup_printf ("EggRecentLeadingSeparator%u",
141 gtk_ui_manager_add_ui (view->uimanager,
145 EGG_RECENT_SEPARATOR,
151 for (scan = list; scan; scan = scan->next, index++) {
152 EggRecentItem *item = scan->data;
160 gchar *tooltip = NULL;
162 uri = egg_recent_item_get_uri_for_display (item);
166 name = g_strdup_printf (EGG_RECENT_NAME_PREFIX"%u-%u",
170 if (view->tooltip_func != NULL)
171 tooltip = (*view->tooltip_func) (item, view->tooltip_func_data);
173 basename = g_path_get_basename (uri);
174 escaped = egg_recent_util_escape_underlines (basename);
178 if (strlen (escaped) > 40) {
179 ellipsized = g_strdup_printf ("%.40s...", escaped);
182 ellipsized = escaped;
185 if (view->show_numbers) {
187 label = g_strdup_printf ("%d. %s",
191 label = g_strdup_printf ("_%d. %s",
198 action = g_object_new (GTK_TYPE_ACTION,
201 (view->show_icons)? "stock_id": NULL,
204 if (tooltip != NULL) {
205 g_object_set (action, "tooltip", tooltip, NULL);
208 egg_recent_item_ref (item);
209 g_object_set_data_full (G_OBJECT (action),
212 (GFreeFunc) egg_recent_item_unref);
214 if (view->action_callback != NULL) {
216 closure = g_cclosure_new (view->action_callback, view->action_user_data, NULL);
217 g_signal_connect_closure (action, "activate", closure, FALSE);
220 gtk_action_group_add_action (view->action_group, action);
221 g_object_unref (action);
223 gtk_ui_manager_add_ui (view->uimanager,
235 if (view->trailing_sep) {
236 gchar *action = g_strdup_printf ("EggRecentTrailingSeparator%u",
238 gtk_ui_manager_add_ui (view->uimanager,
242 EGG_RECENT_SEPARATOR,
250 model_changed_cb (EggRecentModel *model,
252 EggRecentViewUIManager *view)
255 egg_recent_view_uimanager_set_list (view, list);
257 egg_recent_view_uimanager_clear (view);
258 gtk_ui_manager_ensure_update (view->uimanager);
261 static EggRecentModel *
262 egg_recent_view_uimanager_get_model (EggRecentView *view_parent)
264 EggRecentViewUIManager *view;
266 g_return_val_if_fail (view_parent != NULL, NULL);
267 view = EGG_RECENT_VIEW_UIMANAGER (view_parent);
272 egg_recent_view_uimanager_set_model (EggRecentView *view_parent,
273 EggRecentModel *model)
275 EggRecentViewUIManager *view;
277 g_return_if_fail (view_parent != NULL);
278 view = EGG_RECENT_VIEW_UIMANAGER (view_parent);
280 if (view->model != NULL) {
281 if (view->changed_cb_id != 0)
282 g_signal_handler_disconnect (G_OBJECT (view->model),
283 view->changed_cb_id);
284 g_object_unref (view->model);
288 g_object_ref (view->model);
290 view->changed_cb_id = g_signal_connect_object (G_OBJECT (model),
292 G_CALLBACK (model_changed_cb),
295 egg_recent_model_changed (view->model);
299 egg_recent_view_uimanager_set_leading_sep (EggRecentViewUIManager *view,
302 view->leading_sep = val;
303 egg_recent_view_uimanager_clear (view);
305 egg_recent_model_changed (view->model);
309 egg_recent_view_uimanager_set_trailing_sep (EggRecentViewUIManager *view,
312 view->trailing_sep = val;
313 egg_recent_view_uimanager_clear (view);
315 egg_recent_model_changed (view->model);
319 egg_recent_view_uimanager_set_property (GObject *object,
324 EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
328 egg_recent_view_uimanager_set_uimanager (view, (GtkUIManager*)g_value_get_object (value));
331 egg_recent_view_uimanager_set_path (view, g_value_get_string (value));
333 case PROP_SHOW_ICONS:
334 egg_recent_view_uimanager_show_icons (view, g_value_get_boolean (value));
336 case PROP_SHOW_NUMBERS:
337 egg_recent_view_uimanager_show_numbers (view, g_value_get_boolean (value));
340 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
346 egg_recent_view_uimanager_get_property (GObject *object,
351 EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
355 g_value_set_object (value, view->uimanager);
358 g_value_set_string (value, view->path);
360 case PROP_SHOW_ICONS:
361 g_value_set_boolean (value, view->show_icons);
363 case PROP_SHOW_NUMBERS:
364 g_value_set_boolean (value, view->show_numbers);
367 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
373 egg_recent_view_uimanager_finalize (GObject *object)
375 EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
377 if (view->changed_cb_id != 0) {
378 g_signal_handler_disconnect (G_OBJECT (view->model),
379 view->changed_cb_id);
380 view->changed_cb_id = 0;
385 egg_recent_view_uimanager_clear (view);
387 if (view->action_group != NULL) {
388 g_object_unref (view->action_group);
389 view->action_group = NULL;
392 if (view->uimanager != NULL) {
393 g_object_unref (view->uimanager);
394 view->uimanager = NULL;
397 if (view->model != NULL) {
398 g_object_unref (view->model);
402 #ifndef USE_STABLE_LIBGNOMEUI
403 if (view->theme != NULL) {
404 g_object_unref (view->theme);
409 if (view->client != NULL) {
410 g_object_unref (view->client);
416 egg_recent_view_uimanager_class_init (EggRecentViewUIManagerClass * klass)
418 GObjectClass *object_class;
420 object_class = G_OBJECT_CLASS (klass);
422 object_class->set_property = egg_recent_view_uimanager_set_property;
423 object_class->get_property = egg_recent_view_uimanager_get_property;
424 object_class->finalize = egg_recent_view_uimanager_finalize;
426 view_signals[ACTIVATE] = g_signal_new ("activate",
427 G_OBJECT_CLASS_TYPE (object_class),
429 G_STRUCT_OFFSET (EggRecentViewUIManagerClass, activate),
431 g_cclosure_marshal_VOID__BOXED,
433 EGG_TYPE_RECENT_ITEM);
435 g_object_class_install_property (object_class,
437 g_param_spec_object ("uimanager",
439 "The UI manager this object will use to update.the UI",
442 g_object_class_install_property (object_class,
444 g_param_spec_string ("path",
446 "The UI path this object will update.",
449 g_object_class_install_property (object_class,
451 g_param_spec_boolean ("show-icons",
453 "Whether or not to show icons",
457 g_object_class_install_property (object_class,
459 g_param_spec_boolean ("show-numbers",
461 "Whether or not to show numbers",
465 klass->activate = NULL;
469 egg_recent_view_init (EggRecentViewClass *iface)
471 iface->do_get_model = egg_recent_view_uimanager_get_model;
472 iface->do_set_model = egg_recent_view_uimanager_set_model;
476 show_menus_changed_cb (GConfClient *client,
479 EggRecentViewUIManager *view)
483 value = gconf_entry_get_value (entry);
484 g_return_if_fail (value->type == GCONF_VALUE_BOOL);
486 egg_recent_view_uimanager_show_icons (view, gconf_value_get_bool (value));
489 #ifndef USE_STABLE_LIBGNOMEUI
491 theme_changed_cb (GnomeIconTheme *theme,
492 EggRecentViewUIManager *view)
494 if (view->model != NULL)
495 egg_recent_model_changed (view->model);
500 egg_recent_view_uimanager_init (EggRecentViewUIManager * view)
502 view->client = gconf_client_get_default ();
504 view->show_icons = gconf_client_get_bool (view->client,
505 "/desktop/gnome/interface/menus_have_icons",
508 gconf_client_add_dir (view->client, "/desktop/gnome/interface",
509 GCONF_CLIENT_PRELOAD_NONE,
511 gconf_client_notify_add (view->client,
512 "/desktop/gnome/interface/menus_have_icons",
513 (GConfClientNotifyFunc)show_menus_changed_cb,
517 view->leading_sep = FALSE;
518 view->trailing_sep = FALSE;
519 view->show_numbers = TRUE;
521 view->uimanager = NULL;
522 view->action_group = NULL;
524 view->changed_cb_id = 0;
528 #ifndef USE_STABLE_LIBGNOMEUI
529 view->theme = gnome_icon_theme_new ();
530 gnome_icon_theme_set_allow_svg (view->theme, TRUE);
531 g_signal_connect_object (view->theme, "changed",
532 G_CALLBACK (theme_changed_cb), view, 0);
535 view->tooltip_func = NULL;
536 view->tooltip_func_data = NULL;
538 view->icon_size = GTK_ICON_SIZE_MENU;
542 egg_recent_view_uimanager_set_icon_size (EggRecentViewUIManager *view,
543 GtkIconSize icon_size)
545 if (view->icon_size != icon_size) {
546 view->icon_size = icon_size;
547 egg_recent_model_changed (view->model);
549 view->icon_size = icon_size;
554 egg_recent_view_uimanager_get_icon_size (EggRecentViewUIManager *view)
556 return view->icon_size;
560 egg_recent_view_uimanager_show_icons (EggRecentViewUIManager *view,
563 view->show_icons = show;
564 if (view->model != NULL)
565 egg_recent_model_changed (view->model);
569 egg_recent_view_uimanager_show_numbers (EggRecentViewUIManager *view,
572 view->show_numbers = show;
573 if (view->model != NULL)
574 egg_recent_model_changed (view->model);
578 egg_recent_view_uimanager_set_tooltip_func (EggRecentViewUIManager *view,
579 EggUIManagerTooltipFunc func,
582 view->tooltip_func = func;
583 view->tooltip_func_data = user_data;
585 egg_recent_model_changed (view->model);
589 * egg_recent_view_uimanager_set_uimanager:
590 * @view: A EggRecentViewUIManager object.
591 * @uimanager: The ui manager used to put the menu items in.
593 * Use this function to change the ui manager used to update the menu.
597 egg_recent_view_uimanager_set_uimanager (EggRecentViewUIManager *view,
598 GtkUIManager *uimanager)
600 g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
601 g_return_if_fail (uimanager != NULL);
603 if (view->uimanager != NULL)
604 g_object_unref (view->uimanager);
605 view->uimanager = uimanager;
606 g_object_ref (view->uimanager);
610 * egg_recent_view_uimanager_get_uimanager:
611 * @view: A EggRecentViewUIManager object.
615 egg_recent_view_uimanager_get_uimanager (EggRecentViewUIManager *view)
617 g_return_val_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view), NULL);
618 return view->uimanager;
622 * egg_recent_view_uimanager_set_path:
623 * @view: A EggRecentViewUIManager object.
624 * @path: The path to put the menu items in.
626 * Use this function to change the path where the recent
627 * documents appear in.
631 egg_recent_view_uimanager_set_path (EggRecentViewUIManager *view,
634 g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
635 g_return_if_fail (path);
638 view->path = g_strdup (path);
642 * egg_recent_view_uimanager_get_path:
643 * @view: A EggRecentViewUIManager object.
646 G_CONST_RETURN gchar*
647 egg_recent_view_uimanager_get_path (EggRecentViewUIManager *view)
649 g_return_val_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view), NULL);
654 egg_recent_view_uimanager_set_action_func (EggRecentViewUIManager *view,
658 g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
659 view->action_callback = callback;
660 view->action_user_data = user_data;
664 * egg_recent_view_uimanager_new:
665 * @appname: The name of your application.
666 * @limit: The maximum number of items allowed.
668 * This creates a new EggRecentViewUIManager object.
670 * Returns: a EggRecentViewUIManager object
672 EggRecentViewUIManager *
673 egg_recent_view_uimanager_new (GtkUIManager *uimanager,
680 g_return_val_if_fail (uimanager, NULL);
681 g_return_val_if_fail (path, NULL);
683 view = g_object_new (egg_recent_view_uimanager_get_type (),
684 "uimanager", uimanager,
688 g_return_val_if_fail (view, NULL);
690 egg_recent_view_uimanager_set_action_func (EGG_RECENT_VIEW_UIMANAGER (view),
694 return EGG_RECENT_VIEW_UIMANAGER (view);
698 * egg_recent_view_uimanager_get_type:
701 * This returns a GType representing a EggRecentViewUIManager object.
706 egg_recent_view_uimanager_get_type (void)
708 static GType egg_recent_view_uimanager_type = 0;
710 if(!egg_recent_view_uimanager_type) {
711 static const GTypeInfo egg_recent_view_uimanager_info = {
712 sizeof (EggRecentViewUIManagerClass),
713 NULL, /* base init */
714 NULL, /* base finalize */
715 (GClassInitFunc)egg_recent_view_uimanager_class_init, /* class init */
716 NULL, /* class finalize */
717 NULL, /* class data */
718 sizeof (EggRecentViewUIManager),
720 (GInstanceInitFunc) egg_recent_view_uimanager_init
723 static const GInterfaceInfo view_info =
725 (GInterfaceInitFunc) egg_recent_view_init,
730 egg_recent_view_uimanager_type = g_type_register_static (G_TYPE_OBJECT,
731 "EggRecentViewUIManager",
732 &egg_recent_view_uimanager_info, 0);
733 g_type_add_interface_static (egg_recent_view_uimanager_type,
734 EGG_TYPE_RECENT_VIEW,
738 return egg_recent_view_uimanager_type;
742 egg_recent_view_uimanager_get_item (EggRecentViewUIManager *view,
745 return g_object_get_data (G_OBJECT(action), "egg_recent_uri");