Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/cut-n-paste/recent-files/egg-recent-view-uimanager.c
diff options
context:
space:
mode:
Diffstat (limited to 'cut-n-paste/recent-files/egg-recent-view-uimanager.c')
-rw-r--r--cut-n-paste/recent-files/egg-recent-view-uimanager.c746
1 files changed, 746 insertions, 0 deletions
diff --git a/cut-n-paste/recent-files/egg-recent-view-uimanager.c b/cut-n-paste/recent-files/egg-recent-view-uimanager.c
new file mode 100644
index 0000000..1ae6f3e
--- /dev/null
+++ b/cut-n-paste/recent-files/egg-recent-view-uimanager.c
@@ -0,0 +1,746 @@
+/* -*- 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 <jwillcox@cs.indiana.edu>
+ * Paolo Bacchilega <paobac@cvs.gnome.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs.h>
+#ifndef USE_STABLE_LIBGNOMEUI
+#include <libgnomeui/gnome-icon-theme.h>
+#endif
+#include <gconf/gconf-client.h>
+#include "egg-recent-model.h"
+#include "egg-recent-view.h"
+#include "egg-recent-view-uimanager.h"
+#include "egg-recent-util.h"
+#include "egg-recent-item.h"
+
+#define EGG_RECENT_NAME_PREFIX "EggRecentAction"
+#define EGG_RECENT_ACTION "EggRecentFile"
+#define EGG_RECENT_SEPARATOR (NULL)
+
+struct _EggRecentViewUIManager {
+ GObject parent_instance;
+
+ GCallback action_callback;
+ gpointer action_user_data;
+
+ gboolean leading_sep;
+ gboolean trailing_sep;
+
+ GtkUIManager *uimanager;
+ GtkActionGroup *action_group;
+ guint merge_id;
+ gulong changed_cb_id;
+
+ gchar *path;
+
+ gboolean show_icons;
+ gboolean show_numbers;
+#ifndef USE_STABLE_LIBGNOMEUI
+ GnomeIconTheme *theme;
+#endif
+
+ EggUIManagerTooltipFunc tooltip_func;
+ gpointer tooltip_func_data;
+
+ EggRecentModel *model;
+ GConfClient *client;
+ GtkIconSize icon_size;
+};
+
+
+struct _EggRecentViewUIManagerMenuData {
+ EggRecentViewUIManager *view;
+ EggRecentItem *item;
+};
+
+typedef struct _EggRecentViewUIManagerMenuData EggRecentViewUIManagerMenuData;
+
+enum {
+ ACTIVATE,
+ LAST_SIGNAL
+};
+
+/* GObject properties */
+enum {
+ PROP_BOGUS,
+ PROP_UIMANAGER,
+ PROP_PATH,
+ PROP_SHOW_ICONS,
+ PROP_SHOW_NUMBERS
+};
+
+static guint view_signals[LAST_SIGNAL] = { 0 };
+
+static void
+egg_recent_view_uimanager_clear (EggRecentViewUIManager *view)
+{
+ if (view->merge_id != 0) {
+ gtk_ui_manager_remove_ui (view->uimanager, view->merge_id);
+ view->merge_id = 0;
+ }
+
+ if (view->action_group != NULL) {
+ gtk_ui_manager_remove_action_group (view->uimanager, view->action_group);
+ g_object_unref (view->action_group);
+ view->action_group = NULL;
+ }
+
+ gtk_ui_manager_ensure_update (view->uimanager);
+}
+
+static void
+egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list)
+{
+ GList *scan;
+ guint index = 1;
+
+ g_return_if_fail (view);
+
+ egg_recent_view_uimanager_clear (view);
+
+ if (view->merge_id == 0)
+ view->merge_id = gtk_ui_manager_new_merge_id (view->uimanager);
+
+ if (view->action_group == NULL) {
+ gchar *group = g_strdup_printf ("EggRecentActions%u",
+ view->merge_id);
+ view->action_group = gtk_action_group_new (group);
+ gtk_ui_manager_insert_action_group (view->uimanager, view->action_group, 0);
+ g_free (group);
+ }
+
+ if (view->leading_sep) {
+ gchar *action = g_strdup_printf ("EggRecentLeadingSeparator%u",
+ view->merge_id);
+ gtk_ui_manager_add_ui (view->uimanager,
+ view->merge_id,
+ view->path,
+ action,
+ EGG_RECENT_SEPARATOR,
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+ g_free (action);
+ }
+
+ for (scan = list; scan; scan = scan->next, index++) {
+ EggRecentItem *item = scan->data;
+ GtkAction *action;
+ gchar *name;
+ gchar *uri;
+ gchar *basename;
+ gchar *escaped;
+ gchar *ellipsized;
+ gchar *label;
+ gchar *tooltip = NULL;
+
+ uri = egg_recent_item_get_uri_for_display (item);
+ if (uri == NULL)
+ continue;
+
+ name = g_strdup_printf (EGG_RECENT_NAME_PREFIX"%u-%u",
+ view->merge_id,
+ index);
+
+ if (view->tooltip_func != NULL)
+ tooltip = (*view->tooltip_func) (item, view->tooltip_func_data);
+
+ basename = g_path_get_basename (uri);
+ escaped = egg_recent_util_escape_underlines (basename);
+ g_free (basename);
+ g_free (uri);
+
+ if (strlen (escaped) > 40) {
+ ellipsized = g_strdup_printf ("%.40s...", escaped);
+ g_free (escaped);
+ } else {
+ ellipsized = escaped;
+ }
+
+ if (view->show_numbers) {
+ if (index >= 10)
+ label = g_strdup_printf ("%d. %s",
+ index,
+ ellipsized);
+ else
+ label = g_strdup_printf ("_%d. %s",
+ index,
+ ellipsized);
+ g_free (ellipsized);
+ } else
+ label = ellipsized;
+
+ action = g_object_new (GTK_TYPE_ACTION,
+ "name", name,
+ "label", label,
+ (view->show_icons)? "stock_id": NULL,
+ GTK_STOCK_OPEN,
+ NULL);
+ if (tooltip != NULL) {
+ g_object_set (action, "tooltip", tooltip, NULL);
+ g_free (tooltip);
+ }
+ egg_recent_item_ref (item);
+ g_object_set_data_full (G_OBJECT (action),
+ "egg_recent_uri",
+ item,
+ (GFreeFunc) egg_recent_item_unref);
+
+ if (view->action_callback != NULL) {
+ GClosure *closure;
+ closure = g_cclosure_new (view->action_callback, view->action_user_data, NULL);
+ g_signal_connect_closure (action, "activate", closure, FALSE);
+ }
+
+ gtk_action_group_add_action (view->action_group, action);
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (view->uimanager,
+ view->merge_id,
+ view->path,
+ name,
+ name,
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+
+ g_free (name);
+ g_free (label);
+ }
+
+ if (view->trailing_sep) {
+ gchar *action = g_strdup_printf ("EggRecentTrailingSeparator%u",
+ view->merge_id);
+ gtk_ui_manager_add_ui (view->uimanager,
+ view->merge_id,
+ view->path,
+ action,
+ EGG_RECENT_SEPARATOR,
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+ g_free (action);
+ }
+}
+
+static void
+model_changed_cb (EggRecentModel *model,
+ GList *list,
+ EggRecentViewUIManager *view)
+{
+ if (list != NULL)
+ egg_recent_view_uimanager_set_list (view, list);
+ else
+ egg_recent_view_uimanager_clear (view);
+ gtk_ui_manager_ensure_update (view->uimanager);
+}
+
+static EggRecentModel *
+egg_recent_view_uimanager_get_model (EggRecentView *view_parent)
+{
+ EggRecentViewUIManager *view;
+
+ g_return_val_if_fail (view_parent != NULL, NULL);
+ view = EGG_RECENT_VIEW_UIMANAGER (view_parent);
+ return view->model;
+}
+
+static void
+egg_recent_view_uimanager_set_model (EggRecentView *view_parent,
+ EggRecentModel *model)
+{
+ EggRecentViewUIManager *view;
+
+ g_return_if_fail (view_parent != NULL);
+ view = EGG_RECENT_VIEW_UIMANAGER (view_parent);
+
+ if (view->model != NULL) {
+ if (view->changed_cb_id != 0)
+ g_signal_handler_disconnect (G_OBJECT (view->model),
+ view->changed_cb_id);
+ g_object_unref (view->model);
+ }
+
+ 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);
+}
+
+void
+egg_recent_view_uimanager_set_leading_sep (EggRecentViewUIManager *view,
+ gboolean val)
+{
+ view->leading_sep = val;
+ egg_recent_view_uimanager_clear (view);
+ if (view->model)
+ egg_recent_model_changed (view->model);
+}
+
+void
+egg_recent_view_uimanager_set_trailing_sep (EggRecentViewUIManager *view,
+ gboolean val)
+{
+ view->trailing_sep = val;
+ egg_recent_view_uimanager_clear (view);
+ if (view->model)
+ egg_recent_model_changed (view->model);
+}
+
+static void
+egg_recent_view_uimanager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
+
+ switch (prop_id) {
+ case PROP_UIMANAGER:
+ egg_recent_view_uimanager_set_uimanager (view, (GtkUIManager*)g_value_get_object (value));
+ break;
+ case PROP_PATH:
+ egg_recent_view_uimanager_set_path (view, g_value_get_string (value));
+ break;
+ case PROP_SHOW_ICONS:
+ egg_recent_view_uimanager_show_icons (view, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_NUMBERS:
+ egg_recent_view_uimanager_show_numbers (view, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+egg_recent_view_uimanager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
+
+ switch (prop_id) {
+ case PROP_UIMANAGER:
+ g_value_set_object (value, view->uimanager);
+ break;
+ case PROP_PATH:
+ g_value_set_string (value, 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);
+ break;
+ }
+}
+
+static void
+egg_recent_view_uimanager_finalize (GObject *object)
+{
+ EggRecentViewUIManager *view = EGG_RECENT_VIEW_UIMANAGER (object);
+
+ if (view->changed_cb_id != 0) {
+ g_signal_handler_disconnect (G_OBJECT (view->model),
+ view->changed_cb_id);
+ view->changed_cb_id = 0;
+ }
+
+ g_free (view->path);
+
+ egg_recent_view_uimanager_clear (view);
+
+ if (view->action_group != NULL) {
+ g_object_unref (view->action_group);
+ view->action_group = NULL;
+ }
+
+ if (view->uimanager != NULL) {
+ g_object_unref (view->uimanager);
+ view->uimanager = NULL;
+ }
+
+ if (view->model != NULL) {
+ g_object_unref (view->model);
+ view->model = NULL;
+ }
+
+#ifndef USE_STABLE_LIBGNOMEUI
+ if (view->theme != NULL) {
+ g_object_unref (view->theme);
+ view->theme = NULL;
+ }
+#endif
+
+ if (view->client != NULL) {
+ g_object_unref (view->client);
+ view->client = NULL;
+ }
+}
+
+static void
+egg_recent_view_uimanager_class_init (EggRecentViewUIManagerClass * klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = egg_recent_view_uimanager_set_property;
+ object_class->get_property = egg_recent_view_uimanager_get_property;
+ object_class->finalize = egg_recent_view_uimanager_finalize;
+
+ view_signals[ACTIVATE] = g_signal_new ("activate",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggRecentViewUIManagerClass, activate),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ EGG_TYPE_RECENT_ITEM);
+
+ g_object_class_install_property (object_class,
+ PROP_UIMANAGER,
+ g_param_spec_object ("uimanager",
+ "UI Manager",
+ "The UI manager this object will use to update.the UI",
+ GTK_TYPE_UI_MANAGER,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_PATH,
+ g_param_spec_string ("path",
+ "Path",
+ "The UI path this object will update.",
+ NULL,
+ 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_uimanager_get_model;
+ iface->do_set_model = egg_recent_view_uimanager_set_model;
+}
+
+static void
+show_menus_changed_cb (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ EggRecentViewUIManager *view)
+{
+ GConfValue *value;
+
+ value = gconf_entry_get_value (entry);
+ g_return_if_fail (value->type == GCONF_VALUE_BOOL);
+
+ egg_recent_view_uimanager_show_icons (view, gconf_value_get_bool (value));
+}
+
+#ifndef USE_STABLE_LIBGNOMEUI
+static void
+theme_changed_cb (GnomeIconTheme *theme,
+ EggRecentViewUIManager *view)
+{
+ if (view->model != NULL)
+ egg_recent_model_changed (view->model);
+}
+#endif
+
+static void
+egg_recent_view_uimanager_init (EggRecentViewUIManager * view)
+{
+ 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->leading_sep = FALSE;
+ view->trailing_sep = FALSE;
+ view->show_numbers = TRUE;
+
+ view->uimanager = NULL;
+ view->action_group = NULL;
+ view->merge_id = 0;
+ view->changed_cb_id = 0;
+
+ view->path = NULL;
+
+#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->tooltip_func = NULL;
+ view->tooltip_func_data = NULL;
+
+ view->icon_size = GTK_ICON_SIZE_MENU;
+}
+
+void
+egg_recent_view_uimanager_set_icon_size (EggRecentViewUIManager *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_uimanager_get_icon_size (EggRecentViewUIManager *view)
+{
+ return view->icon_size;
+}
+
+void
+egg_recent_view_uimanager_show_icons (EggRecentViewUIManager *view,
+ gboolean show)
+{
+ view->show_icons = show;
+ if (view->model != NULL)
+ egg_recent_model_changed (view->model);
+}
+
+void
+egg_recent_view_uimanager_show_numbers (EggRecentViewUIManager *view,
+ gboolean show)
+{
+ view->show_numbers = show;
+ if (view->model != NULL)
+ egg_recent_model_changed (view->model);
+}
+
+void
+egg_recent_view_uimanager_set_tooltip_func (EggRecentViewUIManager *view,
+ EggUIManagerTooltipFunc 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_uimanager_set_uimanager:
+ * @view: A EggRecentViewUIManager object.
+ * @uimanager: The ui manager used to put the menu items in.
+ *
+ * Use this function to change the ui manager used to update the menu.
+ *
+ */
+void
+egg_recent_view_uimanager_set_uimanager (EggRecentViewUIManager *view,
+ GtkUIManager *uimanager)
+{
+ g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
+ g_return_if_fail (uimanager != NULL);
+
+ if (view->uimanager != NULL)
+ g_object_unref (view->uimanager);
+ view->uimanager = uimanager;
+ g_object_ref (view->uimanager);
+}
+
+/**
+ * egg_recent_view_uimanager_get_uimanager:
+ * @view: A EggRecentViewUIManager object.
+ *
+ */
+GtkUIManager*
+egg_recent_view_uimanager_get_uimanager (EggRecentViewUIManager *view)
+{
+ g_return_val_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view), NULL);
+ return view->uimanager;
+}
+
+/**
+ * egg_recent_view_uimanager_set_path:
+ * @view: A EggRecentViewUIManager object.
+ * @path: The path to put the menu items in.
+ *
+ * Use this function to change the path where the recent
+ * documents appear in.
+ *
+ */
+void
+egg_recent_view_uimanager_set_path (EggRecentViewUIManager *view,
+ const gchar *path)
+{
+ g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
+ g_return_if_fail (path);
+
+ g_free (view->path);
+ view->path = g_strdup (path);
+}
+
+/**
+ * egg_recent_view_uimanager_get_path:
+ * @view: A EggRecentViewUIManager object.
+ *
+ */
+G_CONST_RETURN gchar*
+egg_recent_view_uimanager_get_path (EggRecentViewUIManager *view)
+{
+ g_return_val_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view), NULL);
+ return view->path;
+}
+
+void
+egg_recent_view_uimanager_set_action_func (EggRecentViewUIManager *view,
+ GCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view));
+ view->action_callback = callback;
+ view->action_user_data = user_data;
+}
+
+/**
+ * egg_recent_view_uimanager_new:
+ * @appname: The name of your application.
+ * @limit: The maximum number of items allowed.
+ *
+ * This creates a new EggRecentViewUIManager object.
+ *
+ * Returns: a EggRecentViewUIManager object
+ */
+EggRecentViewUIManager *
+egg_recent_view_uimanager_new (GtkUIManager *uimanager,
+ const gchar *path,
+ GCallback callback,
+ gpointer user_data)
+{
+ GObject *view;
+
+ g_return_val_if_fail (uimanager, NULL);
+ g_return_val_if_fail (path, NULL);
+
+ view = g_object_new (egg_recent_view_uimanager_get_type (),
+ "uimanager", uimanager,
+ "path", path,
+ NULL);
+
+ g_return_val_if_fail (view, NULL);
+
+ egg_recent_view_uimanager_set_action_func (EGG_RECENT_VIEW_UIMANAGER (view),
+ callback,
+ user_data);
+
+ return EGG_RECENT_VIEW_UIMANAGER (view);
+}
+
+/**
+ * egg_recent_view_uimanager_get_type:
+ * @:
+ *
+ * This returns a GType representing a EggRecentViewUIManager object.
+ *
+ * Returns: a GType
+ */
+GType
+egg_recent_view_uimanager_get_type (void)
+{
+ static GType egg_recent_view_uimanager_type = 0;
+
+ if(!egg_recent_view_uimanager_type) {
+ static const GTypeInfo egg_recent_view_uimanager_info = {
+ sizeof (EggRecentViewUIManagerClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc)egg_recent_view_uimanager_class_init, /* class init */
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (EggRecentViewUIManager),
+ 0,
+ (GInstanceInitFunc) egg_recent_view_uimanager_init
+ };
+
+ static const GInterfaceInfo view_info =
+ {
+ (GInterfaceInitFunc) egg_recent_view_init,
+ NULL,
+ NULL
+ };
+
+ egg_recent_view_uimanager_type = g_type_register_static (G_TYPE_OBJECT,
+ "EggRecentViewUIManager",
+ &egg_recent_view_uimanager_info, 0);
+ g_type_add_interface_static (egg_recent_view_uimanager_type,
+ EGG_TYPE_RECENT_VIEW,
+ &view_info);
+ }
+
+ return egg_recent_view_uimanager_type;
+}
+
+EggRecentItem*
+egg_recent_view_uimanager_get_item (EggRecentViewUIManager *view,
+ GtkAction *action)
+{
+ return g_object_get_data (G_OBJECT(action), "egg_recent_uri");
+}