aboutsummaryrefslogtreecommitdiffstats
path: root/src/bookmarks/ephy-bookmarks-menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bookmarks/ephy-bookmarks-menu.c')
-rw-r--r--src/bookmarks/ephy-bookmarks-menu.c443
1 files changed, 443 insertions, 0 deletions
diff --git a/src/bookmarks/ephy-bookmarks-menu.c b/src/bookmarks/ephy-bookmarks-menu.c
new file mode 100644
index 000000000..89348a5e8
--- /dev/null
+++ b/src/bookmarks/ephy-bookmarks-menu.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2002 Ricardo Fernández Pascual
+ *
+ * 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, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-bookmarks-menu.h"
+#include "ephy-bookmark-action.h"
+#include "egg-menu-merge.h"
+#include "ephy-shell.h"
+#include "ephy-node-common.h"
+#include "ephy-debug.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <libxml/entities.h>
+
+#define EMPTY_ACTION_NAME "GoBookmarkEmpty"
+
+/**
+ * Private data
+ */
+struct _EphyBookmarksMenuPrivate
+{
+ EphyWindow *window;
+ EphyBookmarks *bookmarks;
+ EggActionGroup *action_group;
+ guint ui_id;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_bookmarks_menu_class_init (EphyBookmarksMenuClass *klass);
+static void ephy_bookmarks_menu_init (EphyBookmarksMenu *menu);
+static void ephy_bookmarks_menu_finalize (GObject *o);
+
+enum
+{
+ PROP_0,
+ PROP_EPHY_WINDOW
+};
+
+static gpointer parent_class;
+
+GType
+ephy_bookmarks_menu_get_type (void)
+{
+ static GType ephy_bookmarks_menu_type = 0;
+
+ if (ephy_bookmarks_menu_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyBookmarksMenuClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_bookmarks_menu_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (EphyBookmarksMenu),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_bookmarks_menu_init
+ };
+
+ ephy_bookmarks_menu_type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyBookmarksMenu",
+ &our_info, 0);
+ }
+ return ephy_bookmarks_menu_type;
+}
+
+static void
+ephy_bookmarks_menu_clean (EphyBookmarksMenu *menu)
+{
+ EphyBookmarksMenuPrivate *p = menu->priv;
+ EggMenuMerge *merge = EGG_MENU_MERGE (p->window->ui_merge);
+
+ if (p->ui_id >= 0)
+ {
+ egg_menu_merge_remove_ui (merge, p->ui_id);
+ egg_menu_merge_ensure_update (merge);
+ }
+
+ if (p->action_group != NULL)
+ {
+ egg_menu_merge_remove_action_group (merge, p->action_group);
+ g_object_unref (p->action_group);
+ }
+}
+
+static void
+go_location_cb (EggAction *action, char *location, EphyWindow *window)
+{
+ EphyEmbed *embed;
+
+ embed = ephy_window_get_active_embed (window);
+ g_return_if_fail (embed != NULL);
+
+ ephy_embed_load_url (embed, location);
+}
+
+static int
+sort_topics (gconstpointer a, gconstpointer b)
+{
+ EphyNode *node_a = (EphyNode *)a;
+ EphyNode *node_b = (EphyNode *)b;
+ EphyNodePriority priority_a, priority_b;
+ char *str_a = NULL;
+ char *str_b = NULL;
+ int retval;
+
+ priority_a = ephy_node_get_property_int (node_a, EPHY_NODE_KEYWORD_PROP_PRIORITY);
+ priority_b = ephy_node_get_property_int (node_b, EPHY_NODE_KEYWORD_PROP_PRIORITY);
+
+ if (priority_a < priority_b)
+ {
+ retval = -1;
+ }
+ else if (priority_a > priority_b)
+ {
+ retval = 1;
+ }
+ else
+ {
+ str_a = g_utf8_casefold (ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME),
+ -1);
+ str_b = g_utf8_casefold (ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME),
+ -1);
+ retval = g_utf8_collate (str_a, str_b);
+ g_free (str_a);
+ g_free (str_b);
+ }
+
+ return retval;
+}
+
+static int
+sort_bookmarks (gconstpointer a, gconstpointer b)
+{
+ EphyNode *node_a = (EphyNode *)a;
+ EphyNode *node_b = (EphyNode *)b;
+ char *str_a = NULL;
+ char *str_b = NULL;
+ int retval;
+
+ str_a = g_utf8_casefold (ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE),
+ -1);
+ str_b = g_utf8_casefold (ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE),
+ -1);
+ retval = g_utf8_collate (str_a, str_b);
+ g_free (str_a);
+ g_free (str_b);
+
+ return retval;
+}
+
+static void
+add_bookmarks_menu (EphyBookmarksMenu *menu, EphyNode *node, GString *xml)
+{
+ GPtrArray *children;
+ EphyBookmarksMenuPrivate *p = menu->priv;
+
+ children = ephy_node_get_children (node);
+
+ if (children->len < 1)
+ {
+ g_string_append (xml, "<menuitem name=\"");
+ g_string_append (xml, EMPTY_ACTION_NAME"Menu");
+ g_string_append (xml, "Menu");
+ g_string_append (xml, "\" verb=\"");
+ g_string_append (xml, EMPTY_ACTION_NAME);
+ g_string_append (xml, "\"/>\n");
+ }
+ else
+ {
+ GList *node_list = NULL, *l;
+ int i;
+
+ for (i = 0; i < children->len; ++i)
+ {
+ node_list = g_list_append (node_list,
+ g_ptr_array_index (children, i));
+ }
+
+ node_list = g_list_sort (node_list, (GCompareFunc)sort_bookmarks);
+
+ for (l = node_list; l != NULL; l = l->next)
+ {
+ EggAction *action;
+ EphyNode *child;
+ long id;
+ char *verb;
+
+ child = l->data;
+ id = ephy_node_get_id (child);
+ verb = g_strdup_printf ("OpenBookmark%ld", id);
+
+ action = ephy_bookmark_action_new (verb, id);
+ egg_action_group_add_action (p->action_group, action);
+ g_object_unref (action);
+ g_signal_connect (action, "go_location",
+ G_CALLBACK (go_location_cb), p->window);
+
+ g_string_append (xml, "<menuitem name=\"");
+ g_string_append (xml, verb);
+ g_string_append (xml, "Menu");
+ g_string_append (xml, "\" verb=\"");
+ g_string_append (xml, verb);
+ g_string_append (xml, "\"/>\n");
+
+ g_free (verb);
+ }
+
+ g_list_free (node_list);
+ }
+
+ ephy_node_thaw (node);
+}
+
+static void
+ephy_bookmarks_menu_rebuild (EphyBookmarksMenu *menu)
+{
+ EphyBookmarksMenuPrivate *p = menu->priv;
+ GString *xml;
+ gint i;
+ EphyNode *topics;
+ EphyNode *not_categorized;
+ GPtrArray *children;
+ EggMenuMerge *merge = EGG_MENU_MERGE (p->window->ui_merge);
+ GList *node_list = NULL, *l;
+ EggAction *empty;
+
+ LOG ("Rebuilding recent history menu")
+
+ ephy_bookmarks_menu_clean (menu);
+
+ topics = ephy_bookmarks_get_keywords (p->bookmarks);
+ not_categorized = ephy_bookmarks_get_not_categorized (p->bookmarks);
+ children = ephy_node_get_children (topics);
+
+ xml = g_string_new (NULL);
+ g_string_append (xml, "<Root><menu><submenu name=\"BookmarksMenu\">"
+ "<placeholder name=\"BookmarksTree\">"
+ "<separator name=\"BookmarksSep1\"/>");
+
+ p->action_group = egg_action_group_new ("BookmarksActions");
+ egg_menu_merge_insert_action_group (merge, p->action_group, 0);
+
+ empty = g_object_new (EGG_TYPE_ACTION,
+ "name", EMPTY_ACTION_NAME,
+ "label", _("Empty"),
+ "sensitive", FALSE,
+ NULL);
+ egg_action_group_add_action (p->action_group, empty);
+ g_object_unref (empty);
+
+ for (i = 0; i < children->len; ++i)
+ {
+ EphyNode *kid;
+ EphyNodePriority priority;
+
+ kid = g_ptr_array_index (children, i);
+
+ priority = ephy_node_get_property_int
+ (kid, EPHY_NODE_KEYWORD_PROP_PRIORITY);
+
+ if (priority == EPHY_NODE_NORMAL_PRIORITY)
+ {
+ node_list = g_list_append (node_list, kid);
+ }
+ }
+ ephy_node_thaw (topics);
+
+ node_list = g_list_sort (node_list, (GCompareFunc)sort_topics);
+
+ for (l = node_list; l != NULL; l = l->next)
+ {
+ char *verb;
+ const char *title;
+ EphyNode *child;
+ EggAction *action;
+
+ child = l->data;
+ title = ephy_node_get_property_string (child, EPHY_NODE_KEYWORD_PROP_NAME);
+
+ verb = g_strdup_printf ("OpenTopic%ld", ephy_node_get_id (child));
+ action = g_object_new (EGG_TYPE_ACTION,
+ "name", verb,
+ "label", title,
+ NULL);
+ egg_action_group_add_action (p->action_group, action);
+ g_object_unref (action);
+
+ g_string_append (xml, "<submenu name=\"");
+ g_string_append (xml, verb);
+ g_string_append (xml, "Menu");
+ g_string_append (xml, "\" verb=\"");
+ g_string_append (xml, verb);
+ g_string_append (xml, "\">\n");
+
+ add_bookmarks_menu (menu, child, xml);
+
+ g_string_append (xml, "</submenu>");
+
+ g_free (verb);
+ }
+
+ add_bookmarks_menu (menu, not_categorized, xml);
+
+ g_string_append (xml, "</placeholder></submenu></menu></Root>");
+
+ if (children->len > 0)
+ {
+ GError *error = NULL;
+ LOG ("Merging ui\n%s",xml->str);
+ p->ui_id = egg_menu_merge_add_ui_from_string
+ (merge, xml->str, -1, &error);
+ }
+
+ g_string_free (xml, TRUE);
+ g_list_free (node_list);
+}
+
+static void
+ephy_bookmarks_menu_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyBookmarksMenu *m = EPHY_BOOKMARKS_MENU (object);
+
+ switch (prop_id)
+ {
+ case PROP_EPHY_WINDOW:
+ m->priv->window = g_value_get_object (value);
+ ephy_bookmarks_menu_rebuild (m);
+ break;
+ }
+}
+
+static void
+ephy_bookmarks_menu_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EphyBookmarksMenu *m = EPHY_BOOKMARKS_MENU (object);
+
+ switch (prop_id)
+ {
+ case PROP_EPHY_WINDOW:
+ g_value_set_object (value, m->priv->window);
+ break;
+ }
+}
+
+
+static void
+ephy_bookmarks_menu_class_init (EphyBookmarksMenuClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = ephy_bookmarks_menu_finalize;
+ object_class->set_property = ephy_bookmarks_menu_set_property;
+ object_class->get_property = ephy_bookmarks_menu_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_EPHY_WINDOW,
+ g_param_spec_object ("EphyWindow",
+ "EphyWindow",
+ "Parent window",
+ EPHY_WINDOW_TYPE,
+ G_PARAM_READWRITE));
+}
+
+static void
+bookmarks_tree_changed_cb (EphyBookmarks *bookmarks, EphyBookmarksMenu *menu)
+{
+ ephy_bookmarks_menu_rebuild (menu);
+}
+
+static void
+ephy_bookmarks_menu_init (EphyBookmarksMenu *menu)
+{
+ EphyBookmarksMenuPrivate *p = g_new0 (EphyBookmarksMenuPrivate, 1);
+
+ menu->priv = p;
+
+ menu->priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell);
+ g_signal_connect (menu->priv->bookmarks, "tree_changed",
+ G_CALLBACK (bookmarks_tree_changed_cb),
+ menu);
+
+ menu->priv->ui_id = -1;
+ menu->priv->action_group = NULL;
+}
+
+static void
+ephy_bookmarks_menu_finalize (GObject *o)
+{
+ EphyBookmarksMenu *menu = EPHY_BOOKMARKS_MENU (o);
+ EphyBookmarksMenuPrivate *p = menu->priv;
+
+ if (p->action_group != NULL)
+ {
+ egg_menu_merge_remove_action_group
+ (EGG_MENU_MERGE (p->window->ui_merge),
+ p->action_group);
+ g_object_unref (p->action_group);
+ }
+
+ g_free (p);
+
+ G_OBJECT_CLASS (parent_class)->finalize (o);
+}
+
+EphyBookmarksMenu *
+ephy_bookmarks_menu_new (EphyWindow *window)
+{
+ EphyBookmarksMenu *ret = g_object_new (EPHY_TYPE_BOOKMARKS_MENU,
+ "EphyWindow", window,
+ NULL);
+ return ret;
+}