From 69d92c409d333e5dd9cc82537c0834b201487c60 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 21 Dec 2004 17:41:03 +0000 Subject: Initial revision --- (limited to 'cut-n-paste/recent-files/egg-recent-view-bonobo.c') diff --git a/cut-n-paste/recent-files/egg-recent-view-bonobo.c b/cut-n-paste/recent-files/egg-recent-view-bonobo.c new file mode 100644 index 0000000..e728e70 --- /dev/null +++ b/cut-n-paste/recent-files/egg-recent-view-bonobo.c @@ -0,0 +1,714 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * Authors: + * James Willcox + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#ifndef USE_STABLE_LIBGNOMEUI +#include +#endif +#include +#include "egg-recent-model.h" +#include "egg-recent-view.h" +#include "egg-recent-view-bonobo.h" +#include "egg-recent-util.h" +#include "egg-recent-item.h" + +struct _EggRecentViewBonobo { + GObject parent_instance; /* We emit signals */ + + BonoboUIComponent *uic; + gchar *path; /* The menu path where our stuff + * will go + */ + + gulong changed_cb_id; + + gchar *uid; /* unique id used for the verb name */ + + gboolean show_icons; + gboolean show_numbers; +#ifndef USE_STABLE_LIBGNOMEUI + GnomeIconTheme *theme; +#endif + EggRecentViewBonoboTooltipFunc tooltip_func; + gpointer tooltip_func_data; + + EggRecentModel *model; + GConfClient *client; + GtkIconSize icon_size; +}; + + +struct _EggRecentViewBonoboMenuData { + EggRecentViewBonobo *view; + EggRecentItem *item; +}; + +typedef struct _EggRecentViewBonoboMenuData EggRecentViewBonoboMenuData; + +enum { + ACTIVATE, + LAST_SIGNAL +}; + +/* GObject properties */ +enum { + PROP_BOGUS, + PROP_UI_COMPONENT, + PROP_MENU_PATH, + PROP_SHOW_ICONS, + PROP_SHOW_NUMBERS +}; + +static guint egg_recent_view_bonobo_signals[LAST_SIGNAL] = { 0 }; + +static void +egg_recent_view_bonobo_clear (EggRecentViewBonobo *view) +{ + gint i=1; + gboolean done=FALSE; + EggRecentModel *model; + + g_return_if_fail (view->uic); + + model = egg_recent_view_get_model (EGG_RECENT_VIEW (view)); + + while (!done) + { + gchar *verb_name = g_strdup_printf ("%s-%d", view->uid, i); + gchar *item_path = g_strconcat (view->path, "/", verb_name, NULL); + if (bonobo_ui_component_path_exists (view->uic, item_path, NULL)) + bonobo_ui_component_rm (view->uic, item_path, NULL); + else + done=TRUE; + + g_free (item_path); + g_free (verb_name); + + i++; + } +} + +static void +egg_recent_view_bonobo_menu_cb (BonoboUIComponent *uic, gpointer data, const char *cname) +{ + EggRecentViewBonoboMenuData *md = (EggRecentViewBonoboMenuData *) data; + EggRecentItem *item; + + g_return_if_fail (md); + g_return_if_fail (md->item); + g_return_if_fail (md->view); + g_return_if_fail (EGG_IS_RECENT_VIEW_BONOBO (md->view)); + + item = md->item; + egg_recent_item_ref (item); + + g_signal_emit (G_OBJECT(md->view), + egg_recent_view_bonobo_signals[ACTIVATE], 0, + item); + + egg_recent_item_unref (item); +} + +static void +egg_recent_view_bonobo_menu_data_destroy_cb (gpointer data, GClosure *closure) +{ + EggRecentViewBonoboMenuData *md = data; + + egg_recent_item_unref (md->item); + g_free (md); +} + + +static void +egg_recent_view_bonobo_set_list (EggRecentViewBonobo *view, GList *list) +{ + BonoboUIComponent* ui_component; + unsigned int i; + gchar *label = NULL; + gchar *verb_name = NULL; + gchar *tip = NULL; + gchar *escaped_name = NULL; + gchar *item_path = NULL; + gchar *base_uri; + gchar *utf8_uri; + gchar *cmd; + gchar *xml_escaped_name; + EggRecentViewBonoboMenuData *md; + EggRecentModel *model; + GClosure *closure; + + g_return_if_fail (view); + + ui_component = view->uic; + g_return_if_fail (BONOBO_IS_UI_COMPONENT (ui_component)); + + + model = egg_recent_view_get_model (EGG_RECENT_VIEW (view)); + + egg_recent_view_bonobo_clear (view); + + + bonobo_ui_component_freeze (ui_component, NULL); + + for (i = 1; i <= g_list_length (list); ++i) + { + EggRecentItem *item = (EggRecentItem *)g_list_nth_data (list, i-1); + + utf8_uri = egg_recent_item_get_uri_for_display (item); + if (utf8_uri == NULL) + continue; + + /* this is what gets passed to our private "activate" callback */ + md = (EggRecentViewBonoboMenuData *)g_malloc (sizeof (EggRecentViewBonoboMenuData)); + md->view = view; + md->item = item; + + egg_recent_item_ref (md->item); + + base_uri = g_path_get_basename (utf8_uri); + xml_escaped_name = g_markup_escape_text (base_uri, + strlen (base_uri)); + + escaped_name = egg_recent_util_escape_underlines (xml_escaped_name); + g_free (xml_escaped_name); + + tip = NULL; + if (view->tooltip_func != NULL) { + gchar *tmp_tip; + tip = view->tooltip_func (item, + view->tooltip_func_data); + tmp_tip = g_markup_escape_text (tip, strlen (tip)); + g_free (tip); + tip = tmp_tip; + } + + if (tip == NULL) + tip = g_strdup (""); + + verb_name = g_strdup_printf ("%s-%d", view->uid, i); + + if (view->show_icons) { + GdkPixbuf *pixbuf; + gchar *mime_type; + gchar *uri; + + mime_type = egg_recent_item_get_mime_type (item); + uri = egg_recent_item_get_uri (item); +#ifndef USE_STABLE_LIBGNOMEUI + { + int width, height; + + gtk_icon_size_lookup_for_settings + (gtk_settings_get_default (), + view->icon_size, + &width, &height); + pixbuf = egg_recent_util_get_icon + (view->theme, + uri, mime_type, + height); + } +#else + pixbuf = NULL; +#endif + + + if (pixbuf != NULL) { + gchar *pixbuf_xml; + + /* Riiiiight.... */ + pixbuf_xml = bonobo_ui_util_pixbuf_to_xml (pixbuf); + + cmd = g_strdup_printf ("", verb_name, pixbuf_xml); + + g_free (pixbuf_xml); + g_object_unref (pixbuf); + } else { + cmd = g_strdup_printf (" ", + verb_name); + } + + g_free (mime_type); + g_free (uri); + } else + cmd = g_strdup_printf (" ", + verb_name); + bonobo_ui_component_set_translate (ui_component, "/commands/", cmd, NULL); + + closure = g_cclosure_new (G_CALLBACK (egg_recent_view_bonobo_menu_cb), + md, egg_recent_view_bonobo_menu_data_destroy_cb); + + bonobo_ui_component_add_verb_full (ui_component, verb_name, + closure); + + if (view->show_numbers) { + if (i < 10) + label = g_strdup_printf ("_%d. %s", i, + escaped_name); + else + label = g_strdup_printf ("%d. %s", i, escaped_name); + } else { + label = g_strdup (escaped_name); + } + + + + item_path = g_strconcat (view->path, "/", verb_name, NULL); + + if (bonobo_ui_component_path_exists (ui_component, item_path, NULL)) + { + bonobo_ui_component_set_prop (ui_component, item_path, + "label", label, NULL); + + bonobo_ui_component_set_prop (ui_component, item_path, + "tip", tip, NULL); + } + else + { + gchar *xml; + + xml = g_strdup_printf ("", + verb_name, verb_name, label, + tip); + + bonobo_ui_component_set_translate (ui_component, view->path, xml, NULL); + + g_free (xml); + } + + g_free (label); + g_free (verb_name); + g_free (tip); + g_free (escaped_name); + g_free (item_path); + g_free (utf8_uri); + g_free (base_uri); + g_free (cmd); + + } + + + bonobo_ui_component_thaw (ui_component, NULL); +} + +static void +model_changed_cb (EggRecentModel *model, GList *list, EggRecentViewBonobo *view) +{ + if (list != NULL) + egg_recent_view_bonobo_set_list (view, list); + else + egg_recent_view_bonobo_clear (view); +} + + +static EggRecentModel * +egg_recent_view_bonobo_get_model (EggRecentView *view_parent) +{ + EggRecentViewBonobo *view; + + g_return_val_if_fail (view_parent, NULL); + view = EGG_RECENT_VIEW_BONOBO (view_parent); + + return view->model; +} + +static void +egg_recent_view_bonobo_set_model (EggRecentView *view_parent, EggRecentModel *model) +{ + EggRecentViewBonobo *view; + + g_return_if_fail (view_parent); + view = EGG_RECENT_VIEW_BONOBO (view_parent); + + if (view->model) + g_signal_handler_disconnect (G_OBJECT (view->model), + view->changed_cb_id); + + view->model = model; + g_object_ref (view->model); + view->changed_cb_id = g_signal_connect_object (G_OBJECT (model), + "changed", + G_CALLBACK (model_changed_cb), + view, 0); + + egg_recent_model_changed (view->model); +} + +static void +egg_recent_view_bonobo_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EggRecentViewBonobo *view = EGG_RECENT_VIEW_BONOBO (object); + + switch (prop_id) + { + case PROP_UI_COMPONENT: + egg_recent_view_bonobo_set_ui_component (EGG_RECENT_VIEW_BONOBO (view), + BONOBO_UI_COMPONENT (g_value_get_object (value))); + break; + case PROP_MENU_PATH: + view->path = g_strdup (g_value_get_string (value)); + break; + case PROP_SHOW_ICONS: + egg_recent_view_bonobo_show_icons (view, + g_value_get_boolean (value)); + default: + case PROP_SHOW_NUMBERS: + egg_recent_view_bonobo_show_numbers (view, + g_value_get_boolean (value)); + break; + break; + } +} + +static void +egg_recent_view_bonobo_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EggRecentViewBonobo *view = EGG_RECENT_VIEW_BONOBO (object); + + switch (prop_id) + { + case PROP_UI_COMPONENT: + g_value_set_pointer (value, view->uic); + break; + case PROP_MENU_PATH: + g_value_set_string (value, g_strdup (view->path)); + break; + case PROP_SHOW_ICONS: + g_value_set_boolean (value, view->show_icons); + break; + case PROP_SHOW_NUMBERS: + g_value_set_boolean (value, view->show_numbers); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +egg_recent_view_bonobo_finalize (GObject *object) +{ + EggRecentViewBonobo *view = EGG_RECENT_VIEW_BONOBO (object); + + g_free (view->path); + g_free (view->uid); + + g_object_unref (view->model); + g_object_unref (view->uic); +#ifndef USE_STABLE_LIBGNOMEUI + g_object_unref (view->theme); +#endif + g_object_unref (view->client); +} + +static void +egg_recent_view_bonobo_class_init (EggRecentViewBonoboClass * klass) +{ + GObjectClass *object_class; + + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = egg_recent_view_bonobo_set_property; + object_class->get_property = egg_recent_view_bonobo_get_property; + object_class->finalize = egg_recent_view_bonobo_finalize; + + egg_recent_view_bonobo_signals[ACTIVATE] = g_signal_new ("activate", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggRecentViewBonoboClass, activate), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + EGG_TYPE_RECENT_ITEM); + + g_object_class_install_property (object_class, + PROP_UI_COMPONENT, + g_param_spec_object ("ui-component", + "UI Component", + "BonoboUIComponent for menus.", + bonobo_ui_component_get_type(), + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_MENU_PATH, + g_param_spec_string ("ui-path", + "Path", + "The path to put the menu items.", + "/menus/File/EggRecentDocuments", + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_SHOW_ICONS, + g_param_spec_boolean ("show-icons", + "Show Icons", + "Whether or not to show icons", + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_SHOW_NUMBERS, + g_param_spec_boolean ("show-numbers", + "Show Numbers", + "Whether or not to show numbers", + TRUE, + G_PARAM_READWRITE)); + + + + klass->activate = NULL; +} + +static void +egg_recent_view_init (EggRecentViewClass *iface) +{ + iface->do_get_model = egg_recent_view_bonobo_get_model; + iface->do_set_model = egg_recent_view_bonobo_set_model; +} + +static void +show_menus_changed_cb (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EggRecentViewBonobo *view) +{ + GConfValue *value; + + value = gconf_entry_get_value (entry); + + g_return_if_fail (value->type == GCONF_VALUE_BOOL); + + egg_recent_view_bonobo_show_icons (view, + gconf_value_get_bool (value)); + +} + +#ifndef USE_STABLE_LIBGNOMEUI +static void +theme_changed_cb (GnomeIconTheme *theme, EggRecentViewBonobo *view) +{ + if (view->model != NULL) + egg_recent_model_changed (view->model); +} +#endif + +static void +egg_recent_view_bonobo_init (EggRecentViewBonobo *view) +{ + view->uid = egg_recent_util_get_unique_id (); +#ifndef USE_STABLE_LIBGNOMEUI + view->theme = gnome_icon_theme_new (); + gnome_icon_theme_set_allow_svg (view->theme, TRUE); + g_signal_connect_object (view->theme, "changed", + G_CALLBACK (theme_changed_cb), view, 0); +#endif + + view->client = gconf_client_get_default (); + view->show_icons = + gconf_client_get_bool (view->client, + "/desktop/gnome/interface/menus_have_icons", + NULL); + + gconf_client_add_dir (view->client, "/desktop/gnome/interface", + GCONF_CLIENT_PRELOAD_NONE, + NULL); + gconf_client_notify_add (view->client, + "/desktop/gnome/interface/menus_have_icons", + (GConfClientNotifyFunc)show_menus_changed_cb, + view, NULL, NULL); + + view->tooltip_func = NULL; + view->tooltip_func_data = NULL; + + view->icon_size = GTK_ICON_SIZE_MENU; +} + +void +egg_recent_view_bonobo_set_icon_size (EggRecentViewBonobo *view, + GtkIconSize icon_size) +{ + if (view->icon_size != icon_size) { + view->icon_size = icon_size; + egg_recent_model_changed (view->model); + } else { + view->icon_size = icon_size; + } +} + +GtkIconSize +egg_recent_view_bonobo_get_icon_size (EggRecentViewBonobo *view) +{ + return view->icon_size; +} + +void +egg_recent_view_bonobo_show_icons (EggRecentViewBonobo *view, gboolean show) +{ + view->show_icons = show; + + if (view->model) + egg_recent_model_changed (view->model); +} + +void +egg_recent_view_bonobo_show_numbers (EggRecentViewBonobo *view, gboolean show) +{ + view->show_numbers = show; + + if (view->model) + egg_recent_model_changed (view->model); +} + +void +egg_recent_view_bonobo_set_ui_component (EggRecentViewBonobo *view, BonoboUIComponent *uic) +{ + g_return_if_fail (view); + g_return_if_fail (uic); + + view->uic = uic; + + g_object_ref (view->uic); +} + +void +egg_recent_view_bonobo_set_ui_path (EggRecentViewBonobo *view, const gchar *path) +{ + g_return_if_fail (view); + g_return_if_fail (path); + + view->path = g_strdup (path); +} + +const BonoboUIComponent * +egg_recent_view_bonobo_get_ui_component (EggRecentViewBonobo *view) +{ + g_return_val_if_fail (view, NULL); + + return view->uic; +} + +gchar * +egg_recent_view_bonobo_get_ui_path (EggRecentViewBonobo *view) +{ + g_return_val_if_fail (view, NULL); + + return g_strdup (view->path); +} + +void +egg_recent_view_bonobo_set_tooltip_func (EggRecentViewBonobo *view, + EggRecentViewBonoboTooltipFunc func, + gpointer user_data) +{ + view->tooltip_func = func; + view->tooltip_func_data = user_data; + + if (view->model) + egg_recent_model_changed (view->model); +} + +/** + * egg_recent_view_bonobo_new: + * @appname: The name of your application. + * @limit: The maximum number of items allowed. + * + * This creates a new EggRecentViewBonobo object. + * + * Returns: a EggRecentViewBonobo object + */ +EggRecentViewBonobo * +egg_recent_view_bonobo_new (BonoboUIComponent *uic, const gchar *path) +{ + EggRecentViewBonobo *view; + + g_return_val_if_fail (uic, NULL); + g_return_val_if_fail (path, NULL); + + view = EGG_RECENT_VIEW_BONOBO (g_object_new (egg_recent_view_bonobo_get_type (), + "ui-path", path, + "ui-component", uic, + "show-icons", FALSE, + "show-numbers", TRUE, NULL)); + + g_return_val_if_fail (view, NULL); + + return view; +} + +/** + * egg_recent_view_bonobo_get_type: + * @: + * + * This returns a GType representing a EggRecentViewBonobo object. + * + * Returns: a GType + */ +GType +egg_recent_view_bonobo_get_type (void) +{ + static GType egg_recent_view_bonobo_type = 0; + + if(!egg_recent_view_bonobo_type) { + static const GTypeInfo egg_recent_view_bonobo_info = { + sizeof (EggRecentViewBonoboClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc)egg_recent_view_bonobo_class_init, /* class init */ + NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EggRecentViewBonobo), + 0, + (GInstanceInitFunc) egg_recent_view_bonobo_init + }; + + static const GInterfaceInfo view_info = + { + (GInterfaceInitFunc) egg_recent_view_init, + NULL, + NULL + }; + + egg_recent_view_bonobo_type = g_type_register_static (G_TYPE_OBJECT, + "EggRecentViewBonobo", + &egg_recent_view_bonobo_info, 0); + g_type_add_interface_static (egg_recent_view_bonobo_type, + EGG_TYPE_RECENT_VIEW, + &view_info); + } + + return egg_recent_view_bonobo_type; +} + -- cgit v0.9.1