diff options
author | Peter Harvey <pah06@uow.edu.au> | 2005-10-17 04:29:26 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2005-10-17 04:29:26 +0800 |
commit | d21007362f8d0701d63e50fe6b219de067d95a87 (patch) | |
tree | 46326d5633d4f3c8504049476d0e72ae7ed0ca2c /src | |
parent | 35b9deda1f37ac0cc81d926b5295983de6b55dcf (diff) | |
download | gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar.gz gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar.bz2 gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar.lz gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar.xz gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.tar.zst gsoc2013-epiphany-d21007362f8d0701d63e50fe6b219de067d95a87.zip |
H18 patch, by Peter Harvey <pah06@uow.edu.au>.
2005-10-16 Peter Harvey <pah06@uow.edu.au>
H18 patch, by Peter Harvey <pah06@uow.edu.au>.
* data/ui/epiphany-bookmark-editor-ui.xml:
* data/ui/epiphany-ui.xml:
* lib/egg/egg-editable-toolbar.c: (get_dock_position),
(get_toolbar_position), (get_toolbar_nth), (find_action),
(drag_data_delete_cb), (drag_begin_cb), (drag_end_cb),
(drag_data_get_cb), (move_item_cb), (set_dock_visible),
(remove_item_cb), (remove_toolbar_cb), (toggle_visibility_cb),
(egg_editable_toolbar_add_visibility_items),
(egg_editable_toolbar_add_popup_items), (popup_context_menu_cb),
(button_press_event_cb), (configure_item_sensitivity),
(configure_item_cursor), (connect_widget_signals),
(action_sensitive_cb), (create_item_from_action),
(create_item_from_position), (toolbar_drag_data_received_cb),
(toolbar_drag_drop_cb), (toolbar_drag_motion_cb),
(toolbar_drag_leave_cb), (configure_drag_dest), (create_dock),
(toolbar_changed_cb), (unparent_fixed), (update_fixed),
(toolbar_added_cb), (toolbar_removed_cb), (item_added_cb),
(item_removed_cb), (egg_editable_toolbar_construct),
(egg_editable_toolbar_set_ui_manager),
(egg_editable_toolbar_set_property),
(egg_editable_toolbar_get_property), (egg_editable_toolbar_init),
(egg_editable_toolbar_finalize),
(egg_editable_toolbar_get_edit_mode),
(egg_editable_toolbar_set_edit_mode),
(egg_editable_toolbar_set_fixed):
* lib/egg/egg-editable-toolbar.h:
* lib/egg/egg-toolbar-editor.c: (compare_items),
(item_added_or_removed_cb), (toolbar_removed_cb),
(egg_toolbar_editor_set_model), (egg_toolbar_editor_finalize),
(drag_begin_cb), (drag_end_cb), (drag_data_get_cb),
(editor_create_item), (editor_create_item_from_name),
(append_table), (update_editor_sheet), (egg_toolbar_editor_init):
* lib/egg/egg-toolbar-editor.h:
* lib/egg/egg-toolbars-model.c: (egg_toolbars_model_to_xml),
(egg_toolbars_model_save), (toolbar_node_new), (item_node_new),
(item_node_free), (toolbar_node_free),
(egg_toolbars_model_get_flags), (egg_toolbars_model_set_flags),
(egg_toolbars_model_get_data), (egg_toolbars_model_get_name),
(impl_add_item), (egg_toolbars_model_add_item),
(egg_toolbars_model_add_toolbar), (parse_data_list),
(parse_item_list), (parse_toolbars), (egg_toolbars_model_load),
(egg_toolbars_model_class_init), (egg_toolbars_model_init),
(egg_toolbars_model_finalize), (egg_toolbars_model_remove_toolbar),
(egg_toolbars_model_remove_item), (egg_toolbars_model_move_item),
(egg_toolbars_model_n_items), (egg_toolbars_model_item_nth),
(egg_toolbars_model_n_toolbars), (egg_toolbars_model_toolbar_nth),
(egg_toolbars_model_get_types), (egg_toolbars_model_set_types),
(fill_avail_array), (egg_toolbars_model_get_avail),
(egg_toolbars_model_get_n_avail), (egg_toolbars_model_set_n_avail):
* lib/egg/egg-toolbars-model.h:
* src/bookmarks/Makefile.am:
* src/bookmarks/ephy-bookmark-action-group.c: (smart_added_cb),
(smart_removed_cb), (node_changed_cb), (node_added_cb),
(node_removed_cb), (ephy_bookmark_group_new):
* src/bookmarks/ephy-bookmark-action-group.h:
* src/bookmarks/ephy-bookmark-action.c: (create_tool_item),
(ephy_bookmark_action_sync_icon), (show_context_menu),
(popup_menu_cb), (button_press_cb), (button_release_cb),
(connect_proxy), (ephy_bookmark_action_updated),
(ephy_bookmark_action_get_bookmark),
(ephy_bookmark_action_set_bookmark),
(ephy_bookmark_action_set_property),
(ephy_bookmark_action_get_property),
(ephy_bookmark_action_finalize), (ephy_bookmark_action_class_init),
(ephy_bookmark_action_init), (ephy_bookmark_action_name),
(ephy_bookmark_action_new):
* src/bookmarks/ephy-bookmark-action.h:
* src/bookmarks/ephy-bookmark-factory-action.c:
(ephy_bookmark_factory_action_get_type), (activate_item_cb),
(build_menu_for_topic), (build_menu), (remove_placeholder_cb),
(activate_placeholder_cb), (clicked_placeholder_cb),
(realize_placeholder_cb), (create_tool_item), (connect_proxy),
(ephy_bookmark_factory_action_class_init),
(ephy_bookmark_factory_action_new):
* src/bookmarks/ephy-bookmark-factory-action.h:
* src/bookmarks/ephy-bookmark-properties.c:
(ephy_bookmark_properties_set_property),
(ephy_bookmark_properties_get_property),
(bookmark_properties_response_cb), (update_entry),
(location_entry_changed_cb), (build_ui):
* src/bookmarks/ephy-bookmarks-editor.c: (add_entry_monitor),
(cmd_add_topic), (delete_topic_dialog_construct),
(cmd_bookmarks_import), (ephy_bookmarks_editor_finalize),
(ephy_bookmarks_editor_node_activated_cb),
(ephy_bookmarks_editor_update_menu), (view_focus_cb),
(add_focus_monitor), (remove_focus_monitor), (bookmarks_filter),
(search_entry_search_cb), (ephy_bookmarks_editor_construct),
(ephy_bookmarks_editor_set_parent),
(ephy_bookmarks_editor_set_property),
(ephy_bookmarks_editor_get_property), (ephy_bookmarks_editor_init):
* src/bookmarks/ephy-bookmarks-menu.c: (append_bookmarks),
(append_menu), (ephy_bookmarks_menu_build):
* src/bookmarks/ephy-bookmarks-menu.h:
* src/bookmarks/ephy-bookmarks-ui.c: (find_action),
(activate_bookmarks_menu), (activate_favorites_menu),
(erase_bookmarks_menu), (erase_favorites_menu), (tree_changed_cb),
(node_added_cb), (node_changed_cb), (node_removed_cb),
(ephy_bookmarks_ui_attach_window),
(ephy_bookmarks_ui_detach_window), (toolbar_node_removed_cb),
(topic_has_data), (topic_get_data), (topic_get_name),
(bookmark_has_data), (bookmark_get_data), (bookmark_get_name),
(bookmark_new_name), (ephy_bookmarks_ui_attach_toolbar_model),
(ephy_bookmarks_ui_detach_toolbar_model):
* src/bookmarks/ephy-bookmarks-ui.h:
* src/bookmarks/ephy-bookmarks.c: (ephy_bookmarks_get_type),
(ephy_bookmarks_init_defaults), (ephy_bookmarks_class_init),
(ephy_bookmarks_save_delayed), (add_to_favorites),
(update_bookmark_keywords), (ephy_bookmarks_init),
(ephy_bookmarks_finalize), (ephy_bookmarks_add),
(ephy_bookmarks_set_address), (ephy_bookmarks_set_icon),
(ephy_bookmarks_add_keyword),
(ephy_bookmarks_show_bookmark_properties),
(ephy_bookmarks_get_from_id), (ephy_bookmarks_compare_topics),
(ephy_bookmarks_compare_topic_pointers),
(ephy_bookmarks_compare_bookmarks),
(ephy_bookmarks_compare_bookmark_pointers):
* src/bookmarks/ephy-bookmarks.h:
* src/bookmarks/ephy-bookmarksbar-model.c:
* src/bookmarks/ephy-bookmarksbar-model.h:
* src/bookmarks/ephy-bookmarksbar.c:
* src/bookmarks/ephy-bookmarksbar.h:
* src/bookmarks/ephy-favorites-menu.c:
* src/bookmarks/ephy-favorites-menu.h:
* src/bookmarks/ephy-new-bookmark.c: (ephy_new_bookmark_add),
(build_editing_table), (ephy_new_bookmark_construct),
(ephy_new_bookmark_set_property), (ephy_new_bookmark_get_property):
* src/bookmarks/ephy-nodes-cover.c: (ephy_nodes_count_covered),
(ephy_nodes_remove_covered), (ephy_nodes_remove_not_covered),
(ephy_nodes_get_covered), (ephy_nodes_covered),
(ephy_nodes_get_covering):
* src/bookmarks/ephy-nodes-cover.h:
* src/bookmarks/ephy-open-tabs-action.c: (activate_cb),
(node_added_cb), (node_removed_cb), (ephy_open_tabs_group_new),
(ephy_open_tabs_action_name):
* src/bookmarks/ephy-open-tabs-action.h:
* src/bookmarks/ephy-related-action.c: (node_changed),
(node_destroyed), (open_link), (iface_init),
(ephy_related_action_get_type), (ephy_related_action_new):
* src/bookmarks/ephy-related-action.h:
* src/bookmarks/ephy-topic-action-group.c: (node_changed_cb),
(node_added_cb), (node_removed_cb), (ephy_topic_group_new):
* src/bookmarks/ephy-topic-action-group.h:
* src/bookmarks/ephy-topic-action.c: (ephy_topic_action_get_type),
(create_tool_item), (ephy_topic_action_sync_label), (get_popup),
(erase_popup), (child_added_cb), (child_changed_cb),
(child_removed_cb), (menu_destroy_cb), (menu_init_cb),
(button_deactivate_cb), (button_toggled_cb), (button_release_cb),
(button_press_cb), (connect_proxy), (ephy_topic_action_updated),
(ephy_topic_action_get_topic), (ephy_topic_action_set_topic),
(ephy_topic_action_set_property), (ephy_topic_action_get_property),
(ephy_topic_action_class_init), (ephy_topic_action_init),
(ephy_topic_action_name), (ephy_topic_action_new):
* src/bookmarks/ephy-topic-action.h:
* src/bookmarks/ephy-topic-factory-action.c:
(ephy_topic_factory_action_get_type), (sort_topics),
(activate_item_cb), (build_menu), (remove_placeholder_cb),
(activate_placeholder_cb), (clicked_placeholder_cb),
(realize_placeholder_cb), (create_tool_item), (connect_proxy),
(ephy_topic_factory_action_class_init),
(ephy_topic_factory_action_new):
* src/bookmarks/ephy-topic-factory-action.h:
* src/ephy-link-action.c: (ephy_link_action_group_get_type),
(ephy_link_action_group_new):
* src/ephy-link-action.h:
* src/ephy-lockdown.c: (find_name), (find_action_group),
(update_window):
* src/ephy-notebook.c: (move_tab_to_another_notebook),
(ephy_notebook_switch_page_cb), (ephy_notebook_init),
(tab_label_style_set_cb), (build_tab_label),
(ephy_notebook_add_tab):
* src/ephy-shell.c: (ephy_shell_get_toolbars_model):
* src/ephy-toolbar-editor.c: (ephy_toolbar_editor_constructor),
(ephy_toolbar_editor_finalize), (ephy_toolbar_editor_set_property),
(ephy_toolbar_editor_class_init):
* src/ephy-toolbar.c: (ephy_toolbar_realize),
(ephy_toolbar_unrealize), (ephy_toolbar_finalize):
* src/ephy-toolbars-model.c: (update_flags),
(ephy_toolbars_model_load):
* src/ephy-window.c: (ephy_window_get_type),
(get_chromes_visibility), (sync_chromes_visibility),
(ephy_window_key_press_event), (tool_item_enter_cb),
(tool_item_leave_cb), (tool_item_drag_begin_cb),
(connect_tool_item), (disconnect_tool_item), (disconnect_proxy_cb),
(connect_proxy_cb), (update_chromes_actions), (show_embed_popup),
(tab_added_cb), (tab_removed_cb), (ephy_window_set_chrome),
(ephy_window_dispose), (ephy_window_class_init),
(ephy_window_init), (ephy_window_finalize),
(ephy_window_remove_tab), (ephy_window_set_zoom),
(sync_prefs_with_chrome), (ephy_window_view_toolbar_cb):
* src/ephy-window.h:
Revision history:
h18, released 2005/09/23, for Epiphany 1.8.0
* Just an update for 1.8.0.
h17, released 2005/08/30, for Epiphany 1.7.6 or CVS HEAD
* Mostly just an update for 1.7.6.
* Topic menus on the toolbar now open without releasing the mouse button.
* Topic menus on the toolbar are now also hierarchical (see if you like it.
h16, released 2005/08/25, for Epiphany 1.7.5 or CVS HEAD
* Just an update for 1.7.5. Sorry, I've been busy. :)
h15, released 2005/07/19, for Epiphany 1.7.2 or CVS HEAD
* Code cleanup
h14, released 2005/07/9, for Epiphany 1.7.1 or CVS HEAD
* Improved helpful tip when adding a bookmark
* Improved toolbar context menu
* Toolbar visibility state is now saved
* Separated bookmark/topic action groups into separate files
* Topics in the overflow menu now behave as submenus
* Now importing old bookmarksbar, and saving to new filename
* Incremented toolbar file format version number to 1.1
* Fixed the 'sticky' statusbar help
* Fixed a crashing bug (dnd then open a topic on the toolbar)
h13, released 2005/05/12, for CVS HEAD
* Added middle-mouse drag-drop for the editable toolbar.
* Fixed some warnings at compile and run time.
* Added brief help for the user when adding a new bookmark.
* Cleaned up the editable toolbar code a little.
h12, released 2005/05/10, for CVS HEAD
* Added new editing facilities for the editable toolbar.
h11, released 2005/04/29, for CVS HEAD
* Fixed bug in statusbar information for toolbar items.
* Added an all-new 'Related' toolbar widget which changes to show
the most related topic whenever a bookmark is activated.
h10, released 2005/04/15, for Epiphany 1.6.2 or CVS HEAD
* Added statusbar information for all toolbar items.
* Empty toolbars are now only deleted when exiting edit mode.
* Fixed regression of middle-click for bookmarks on toolbar.
* Fixed regression of ellipsized bookmark names in menus.
h9, released 2005/04/12, for Epiphany 1.6.1
* Updated patch for 1.6.1. Long time no see.
* Now using EphyLink objects everywhere.
h7, released 2004/10/21, for Epiphany 1.4.4
* Updated patch for 1.4.4.
* Fixed bugs causing crashes when bookmarks were added (thanks Reinout).
* Added "Open in Tabs" back into bookmark menus where suitable.
h6, released 2004/09/20, for Epiphany 1.4.0
* Updated patch for 1.4.0.
* Removed the bookmarks bar.
* Generate shared XML string for bookmarks menu.
* Slightly improve performance of node-cover code.
* Delay adding bookmarks menu until it is first used.
* Fixed bug(?) in ephy-node.
h4, released 2004/08/08, for Epiphany 1.3.4
* Updated patch due to changes to topics selector.
* Removed 'Most Visited' from the min-cover calculations.
* Fixed Epiphany 1.3.4 bug where topics in selector aren't sorted.
* Updated patch due to other changes in Epiphany 1.3.4 source.
h3, released 2004/07/12, for Epiphany 1.3.2
* Simple update for Epiphany 1.3.2
h3, released 2004/05/24, for Epiphany 1.2.5
* Moved duplicated functions into a seperate file.
* Improved topic selector.
* Bookmarks toolbar topic menus now have subdivisions.
* Topic names in menu now change if modified in the bookmarks editor.
h2, released 2004/05/23, for Epiphany 1.2.5
* Significantly cleaned up the code.
* 'Most Visited' no longer appears as a submenu.
* Subtopics are selected much more intelligently, giving a better
approximation to a true minimum cover.
* Topic selector now shows suggestions with arrows, not bold font.
h1, released 2004/05/19, for Epiphany 1.2.5
* Initial release.
Diffstat (limited to 'src')
44 files changed, 3417 insertions, 4109 deletions
diff --git a/src/bookmarks/Makefile.am b/src/bookmarks/Makefile.am index 128ea9232..29c85d9c5 100644 --- a/src/bookmarks/Makefile.am +++ b/src/bookmarks/Makefile.am @@ -13,14 +13,19 @@ NOINST_H_FILES = \ ephy-bookmarks-editor.h \ ephy-bookmarks-export.h \ ephy-bookmarks-import.h \ + ephy-bookmarks-ui.h \ ephy-bookmarks-menu.h \ - ephy-bookmarksbar-model.h \ - ephy-bookmarksbar.h \ ephy-bookmark-properties.h \ - ephy-favorites-menu.h \ ephy-new-bookmark.h \ ephy-topic-action.h \ - ephy-topics-selector.h + ephy-related-action.h \ + ephy-open-tabs-action.h \ + ephy-topic-factory-action.h \ + ephy-bookmark-factory-action.h \ + ephy-topic-action-group.h \ + ephy-bookmark-action-group.h \ + ephy-topics-selector.h \ + ephy-nodes-cover.h libephybookmarks_la_SOURCES = \ $(BUILT_SOURCES) \ @@ -29,14 +34,19 @@ libephybookmarks_la_SOURCES = \ ephy-bookmarks-editor.c \ ephy-bookmarks-export.c \ ephy-bookmarks-import.c \ + ephy-bookmarks-ui.c \ ephy-bookmarks-menu.c \ - ephy-bookmarksbar-model.c \ - ephy-bookmarksbar.c \ ephy-bookmark-properties.c \ - ephy-favorites-menu.c \ ephy-new-bookmark.c \ ephy-topic-action.c \ + ephy-related-action.c \ + ephy-open-tabs-action.c \ + ephy-topic-factory-action.c \ + ephy-bookmark-factory-action.c \ + ephy-topic-action-group.c \ + ephy-bookmark-action-group.c \ ephy-topics-selector.c \ + ephy-nodes-cover.c \ $(NOINST_H_FILES) \ $(INST_H_FILES) diff --git a/src/bookmarks/ephy-bookmark-action-group.c b/src/bookmarks/ephy-bookmark-action-group.c new file mode 100644 index 000000000..e9b2c970c --- /dev/null +++ b/src/bookmarks/ephy-bookmark-action-group.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#include "config.h" + +#include "ephy-shell.h" +#include "ephy-bookmark-action-group.h" +#include "ephy-bookmark-action.h" +#include "ephy-bookmarks.h" +#include "ephy-link.h" +#include "ephy-node.h" +#include "ephy-node-common.h" +#include "ephy-debug.h" + +#include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> +#include <string.h> + +static void +smart_added_cb (EphyNode *parent, + EphyNode *child, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_bookmark_action_name (child); + g_return_if_fail (name); + action = gtk_action_group_get_action (actions, name); + + if (action) + { + ephy_bookmark_action_updated + (EPHY_BOOKMARK_ACTION (action)); + } + + g_free (name); +} + + +static void +smart_removed_cb (EphyNode *parent, + EphyNode *child, + guint index, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_bookmark_action_name (child); + g_return_if_fail (name); + action = gtk_action_group_get_action (actions, name); + + if (action) + { + ephy_bookmark_action_updated + (EPHY_BOOKMARK_ACTION (action)); + } + + g_free (name); +} + +static void +node_changed_cb (EphyNode *parent, + EphyNode *child, + guint property_id, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_bookmark_action_name (child); + g_return_if_fail (name); + action = gtk_action_group_get_action (actions, name); + + if (action) + { + ephy_bookmark_action_updated + (EPHY_BOOKMARK_ACTION (action)); + } + + g_free (name); +} + +static void +node_added_cb (EphyNode *parent, + EphyNode *child, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name, *accel; + + name = ephy_bookmark_action_name (child); + action = ephy_bookmark_action_new (child, name); + accel = g_strjoin ("/", "<Actions>", + gtk_action_group_get_name (actions), + name, NULL); + gtk_action_set_accel_path (action, accel); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + g_free (accel); + + ephy_bookmark_action_updated (EPHY_BOOKMARK_ACTION (action)); + + g_signal_connect_swapped (G_OBJECT(action), "open-link", + G_CALLBACK (ephy_link_open), actions); +} + +static void +node_removed_cb (EphyNode *parent, + EphyNode *child, + guint index, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_bookmark_action_name (child); + g_return_if_fail (name); + action = gtk_action_group_get_action (actions, name); + + if (action) + { + gtk_action_group_remove_action (actions, action); + } + + g_free (name); +} + +GtkActionGroup * +ephy_bookmark_group_new (EphyNode *node) +{ + EphyBookmarks *bookmarks = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *smart = ephy_bookmarks_get_smart_bookmarks (bookmarks); + + GPtrArray *children = ephy_node_get_children (node); + GObject *actions = (GObject *) ephy_link_action_group_new ("BA"); + guint i; + + for (i = 0; i < children->len; i++) + { + node_added_cb (node, g_ptr_array_index (children, i), (GtkActionGroup *) actions); + } + + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + actions); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + actions); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + actions); + + ephy_node_signal_connect_object (smart, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)smart_added_cb, + actions); + ephy_node_signal_connect_object (smart, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)smart_removed_cb, + actions); + + return GTK_ACTION_GROUP (actions); +} diff --git a/src/bookmarks/ephy-bookmark-action-group.h b/src/bookmarks/ephy-bookmark-action-group.h new file mode 100644 index 000000000..fc401a4a4 --- /dev/null +++ b/src/bookmarks/ephy-bookmark-action-group.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#ifndef EPHY_BOOKMARK_ACTION_GROUP_H +#define EPHY_BOOKMARK_ACTION_GROUP_H + +#include "ephy-link-action.h" +#include "ephy-node.h" + +#include <gtk/gtkactiongroup.h> + +G_BEGIN_DECLS + +GtkActionGroup * ephy_bookmark_group_new (EphyNode *node); + +G_END_DECLS + +#endif diff --git a/src/bookmarks/ephy-bookmark-action.c b/src/bookmarks/ephy-bookmark-action.c index a4154b298..db93b5824 100644 --- a/src/bookmarks/ephy-bookmark-action.c +++ b/src/bookmarks/ephy-bookmark-action.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2003, 2004 Marco Pesenti Gritti * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2005 Peter Harvey * * 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 @@ -21,12 +22,11 @@ #include "config.h" +#include "egg-editable-toolbar.h" #include "ephy-bookmark-action.h" -#include "ephy-bookmarksbar-model.h" -#include "ephy-bookmarksbar.h" #include "ephy-bookmarks.h" +#include "ephy-link-action.h" #include "ephy-link.h" -#include "ephy-dnd.h" #include "ephy-favicon-cache.h" #include "ephy-shell.h" #include "ephy-gui.h" @@ -37,16 +37,13 @@ #include <gtk/gtkhbox.h> #include <gtk/gtklabel.h> #include <gtk/gtkbutton.h> -#include <gtk/gtkentry.h> #include <gtk/gtkstock.h> #include <gtk/gtkimage.h> #include <gtk/gtkmenuitem.h> #include <gtk/gtkimagemenuitem.h> #include <gtk/gtkseparatormenuitem.h> -#include <gtk/gtkmenushell.h> -#include <gtk/gtkmenu.h> +#include <gtk/gtkentry.h> #include <gtk/gtktoolitem.h> -#include <gtk/gtktoolbar.h> #include <gtk/gtkmain.h> #include <libgnomevfs/gnome-vfs-uri.h> @@ -62,20 +59,11 @@ static void ephy_bookmark_action_class_init (EphyBookmarkActionClass *class); #define EPHY_BOOKMARK_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARK_ACTION, EphyBookmarkActionPrivate)) -static GtkTargetEntry drag_targets[] = -{ - { EPHY_DND_URL_TYPE, 0, 0 } -}; -static int n_drag_targets = G_N_ELEMENTS (drag_targets); - struct _EphyBookmarkActionPrivate { EphyNode *node; gboolean smart_url; guint cache_handler; - guint motion_handler; - gint drag_x; - gint drag_y; }; enum @@ -138,6 +126,7 @@ create_tool_item (GtkAction *action) gtk_widget_show (button); gtk_container_add (GTK_CONTAINER (hbox), button); g_object_set_data (G_OBJECT (item), "button", button); + g_object_set_data (G_OBJECT (item), "egg-drag-source", button); entry = gtk_entry_new (); gtk_entry_set_width_chars (GTK_ENTRY (entry), ENTRY_WIDTH_CHARS); @@ -247,7 +236,7 @@ ephy_bookmark_action_sync_icon (GtkAction *action, GParamSpec *pspec, GtkWidget if (pixbuf == NULL) { pixbuf = gtk_widget_render_icon (proxy, GTK_STOCK_NEW, - GTK_ICON_SIZE_MENU, NULL); + GTK_ICON_SIZE_MENU, NULL); } gtk_image_set_from_pixbuf (icon, pixbuf); @@ -379,142 +368,6 @@ activate_cb (GtkWidget *widget, } static void -stop_drag_check (EphyBookmarkAction *action, GtkWidget *widget) -{ - if (action->priv->motion_handler) - { - g_signal_handler_disconnect (widget, action->priv->motion_handler); - action->priv->motion_handler = 0; - } -} - -static void -drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, - GtkSelectionData *selection_data, guint info, - guint32 time, EphyBookmarkAction *action) -{ - const char *address, *title; - char *data; - - g_return_if_fail (action->priv->node != NULL); - - address = ephy_node_get_property_string (action->priv->node, - EPHY_NODE_BMK_PROP_LOCATION); - g_return_if_fail (address != NULL); - - title = ephy_node_get_property_string (action->priv->node, - EPHY_NODE_BMK_PROP_TITLE); - g_return_if_fail (title != NULL); - - data = g_strdup_printf ("%s\n%s", address, title); - gtk_selection_data_set (selection_data, selection_data->target, 8, - (unsigned char *) data, strlen (data)); - g_free (data); -} - -static int -get_item_position (GtkWidget *widget, gboolean *last) -{ - GtkWidget *item, *toolbar; - int index; - - item = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - g_return_val_if_fail (item != NULL, -1); - - toolbar = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR); - g_return_val_if_fail (toolbar != NULL, -1); - - index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (item)); - if (last) - { - int n_items; - - n_items = gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar)); - *last = (index == n_items - 1); - } - - return index; -} - -static void -remove_from_model (GtkWidget *widget) -{ - EphyBookmarks *bookmarks; - EggToolbarsModel *model; - int pos; - - pos = get_item_position (widget, NULL); - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - model = EGG_TOOLBARS_MODEL (ephy_bookmarks_get_toolbars_model (bookmarks)); - - egg_toolbars_model_remove_item (model, 0, pos); -} - -static void -move_in_model (GtkWidget *widget, int direction) -{ - EphyBookmarks *bookmarks; - EggToolbarsModel *model; - int pos, new_pos; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - model = EGG_TOOLBARS_MODEL (ephy_bookmarks_get_toolbars_model (bookmarks)); - - pos = get_item_position (widget, NULL); - new_pos = MAX (0, pos + direction); - - egg_toolbars_model_move_item (model, 0, pos, 0, new_pos); -} - -static void -drag_data_delete_cb (GtkWidget *widget, GdkDragContext *context, - EphyBookmarkAction *action) -{ - remove_from_model (widget); -} - -static gboolean -drag_motion_cb (GtkWidget *widget, GdkEventMotion *event, EphyBookmarkAction *action) -{ - if (gtk_drag_check_threshold (widget, action->priv->drag_x, - action->priv->drag_y, event->x, event->y)) - { - GtkTargetList *target_list; - - target_list = gtk_target_list_new (drag_targets, n_drag_targets); - - stop_drag_check (action, widget); - gtk_drag_begin (widget, target_list, GDK_ACTION_ASK | - GDK_ACTION_MOVE | GDK_ACTION_COPY, 1, - (GdkEvent*)event); - - gtk_target_list_unref (target_list); - } - - return TRUE; -} - -static void -remove_activate_cb (GtkWidget *menu, GtkWidget *proxy) -{ - remove_from_model (proxy); -} - -static void -move_left_activate_cb (GtkWidget *menu, GtkWidget *proxy) -{ - move_in_model (proxy, -1); -} - -static void -move_right_activate_cb (GtkWidget *menu, GtkWidget *proxy) -{ - move_in_model (proxy, +1); -} - -static void properties_activate_cb (GtkWidget *menu, EphyBookmarkAction *action) { @@ -535,8 +388,7 @@ show_context_menu (EphyBookmarkAction *action, GdkEventButton *event, GtkMenuPositionFunc func) { - GtkWidget *menu, *item, *image; - gboolean last; + GtkWidget *menu, *item; menu = gtk_menu_new (); @@ -562,38 +414,8 @@ show_context_menu (EphyBookmarkAction *action, gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (item, "activate", G_CALLBACK (properties_activate_cb), action); - - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove from Toolbar")); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (remove_activate_cb), proxy); - - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_menu_item_new_with_mnemonic (_("Move _Left")); - gtk_widget_set_sensitive (item, get_item_position (proxy, NULL) > 0); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (move_left_activate_cb), proxy); - - item = gtk_menu_item_new_with_mnemonic (_("Move Ri_ght")); - get_item_position (proxy, &last); - gtk_widget_set_sensitive (item, !last); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (move_right_activate_cb), proxy); + + egg_editable_toolbar_add_popup_items (proxy, GTK_MENU (menu)); if (event != NULL) { @@ -611,14 +433,8 @@ show_context_menu (EphyBookmarkAction *action, static gboolean popup_menu_cb (GtkWidget *widget, EphyBookmarkAction *action) { - if (gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) - { - show_context_menu (action, widget, NULL, - ephy_gui_menu_position_under_widget); - return TRUE; - } - - return FALSE; + show_context_menu (action, widget, NULL, ephy_gui_menu_position_under_widget); + return TRUE; } static gboolean @@ -626,8 +442,7 @@ button_press_cb (GtkWidget *widget, GdkEventButton *event, EphyBookmarkAction *action) { - if (event->button == 3 && - gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) + if (event->button == 3) { show_context_menu (action, widget, event, NULL); return TRUE; @@ -636,35 +451,24 @@ button_press_cb (GtkWidget *widget, { gtk_button_pressed (GTK_BUTTON (widget)); } - else if (event->button == 1 && - gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) - { - action->priv->drag_x = event->x; - action->priv->drag_y = event->y; - action->priv->motion_handler = g_signal_connect - (widget, "motion_notify_event", G_CALLBACK (drag_motion_cb), action); - } return FALSE; } static gboolean button_release_cb (GtkWidget *widget, - GdkEventButton *event, + GdkEventButton *event, EphyBookmarkAction *action) { if (event->button == 2) { gtk_button_released (GTK_BUTTON (widget)); } - else if (event->button == 1) - { - stop_drag_check (action, widget); - } return FALSE; } + static void connect_proxy (GtkAction *action, GtkWidget *proxy) { @@ -676,11 +480,11 @@ connect_proxy (GtkAction *action, GtkWidget *proxy) ephy_bookmark_action_sync_icon (action, NULL, proxy); g_signal_connect_object (action, "notify::icon", - G_CALLBACK (ephy_bookmark_action_sync_icon), proxy, 0); + G_CALLBACK (ephy_bookmark_action_sync_icon), proxy, 0); ephy_bookmark_action_sync_smart_url (action, NULL, proxy); g_signal_connect_object (action, "notify::smarturl", - G_CALLBACK (ephy_bookmark_action_sync_smart_url), proxy, 0); + G_CALLBACK (ephy_bookmark_action_sync_smart_url), proxy, 0); if (GTK_IS_TOOL_ITEM (proxy)) { @@ -696,10 +500,6 @@ connect_proxy (GtkAction *action, GtkWidget *proxy) G_CALLBACK (button_press_cb), action); g_signal_connect (button, "button-release-event", G_CALLBACK (button_release_cb), action); - g_signal_connect (button, "drag_data_get", - G_CALLBACK (drag_data_get_cb), action); - g_signal_connect (button, "drag_data_delete", - G_CALLBACK (drag_data_delete_cb), action); entry = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "entry")); g_signal_connect (entry, "activate", G_CALLBACK (activate_cb), action); @@ -718,73 +518,73 @@ connect_proxy (GtkAction *action, GtkWidget *proxy) } } -static void -bookmark_changed_cb (EphyNode *node, - guint property_id, - EphyBookmarkAction *action) +void +ephy_bookmark_action_updated (EphyBookmarkAction *action) { - if (property_id == EPHY_NODE_BMK_PROP_TITLE) - { - GValue value = { 0, }; - const char *title; + GValue value = { 0, }; + EphyBookmarks *bookmarks = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *smart = ephy_bookmarks_get_smart_bookmarks (bookmarks); + EphyNode *node = action->priv->node; + const char *title; + + g_return_if_fail (action != NULL); + g_return_if_fail (node != NULL); + + g_object_freeze_notify (G_OBJECT (action)); - title = ephy_node_get_property_string - (node, EPHY_NODE_BMK_PROP_TITLE); - g_value_init (&value, G_TYPE_STRING); - g_value_set_static_string (&value, title); - g_object_set_property (G_OBJECT (action), "label", &value); - g_value_unset (&value); - } - else if (property_id == EPHY_NODE_BMK_PROP_ICON) - { - g_object_notify (G_OBJECT (action), "icon"); - } + // Set smart_url + action->priv->smart_url = ephy_node_has_child (smart, node); + g_object_notify (G_OBJECT (action), "smarturl"); + + // Set title + title = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_TITLE); + g_value_init (&value, G_TYPE_STRING); + g_value_set_static_string (&value, title); + g_object_set_property (G_OBJECT (action), "label", &value); + g_value_unset (&value); + + // Notify all other properties + g_object_notify (G_OBJECT (action), "location"); + g_object_notify (G_OBJECT (action), "tooltip"); + g_object_notify (G_OBJECT (action), "icon"); + + g_object_thaw_notify (G_OBJECT (action)); } -static void -bookmark_destroy_cb (EphyNode *node, EphyBookmarkAction *action) +EphyNode * +ephy_bookmark_action_get_bookmark (EphyBookmarkAction *action) { - action->priv->node = NULL; + return action->priv->node; } -static void +void ephy_bookmark_action_set_bookmark (EphyBookmarkAction *action, EphyNode *node) -{ - EphyBookmarks *bookmarks; - EphyNode *smart_bmks; - +{ g_return_if_fail (node != NULL); - + action->priv->node = node; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - smart_bmks = ephy_bookmarks_get_smart_bookmarks (bookmarks); - action->priv->smart_url = ephy_node_has_child (smart_bmks, node); - - bookmark_changed_cb (node, EPHY_NODE_BMK_PROP_TITLE, action); -// bookmark_changed_cb (node, EPHY_NODE_BMK_PROP_ICON, action); - ephy_node_signal_connect_object (node, EPHY_NODE_CHANGED, - (EphyNodeCallback) bookmark_changed_cb, - G_OBJECT (action)); - ephy_node_signal_connect_object (node, EPHY_NODE_DESTROY, - (EphyNodeCallback) bookmark_destroy_cb, - G_OBJECT (action)); + + g_object_freeze_notify (G_OBJECT (action)); + + g_object_notify (G_OBJECT (action), "bookmark"); + ephy_bookmark_action_updated (action); + + g_object_thaw_notify (G_OBJECT (action)); } static void ephy_bookmark_action_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { EphyBookmarkAction *action = EPHY_BOOKMARK_ACTION (object); switch (prop_id) { case PROP_BOOKMARK: - ephy_bookmark_action_set_bookmark - (action, g_value_get_pointer (value)); + ephy_bookmark_action_set_bookmark (action, g_value_get_pointer (value)); break; case PROP_TOOLTIP: case PROP_LOCATION: @@ -797,9 +597,9 @@ ephy_bookmark_action_set_property (GObject *object, static void ephy_bookmark_action_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { EphyBookmarkAction *action = EPHY_BOOKMARK_ACTION (object); @@ -830,8 +630,6 @@ ephy_bookmark_action_get_property (GObject *object, static void ephy_bookmark_action_finalize (GObject *object) { - /* EphyBookmarkAction *eba = EPHY_BOOKMARK_ACTION (object);*/ - LOG ("Bookmark action %p finalized", object); parent_class->finalize (object); @@ -855,7 +653,7 @@ ephy_bookmark_action_class_init (EphyBookmarkActionClass *class) object_class->get_property = ephy_bookmark_action_get_property; g_object_class_install_property (object_class, - PROP_BOOKMARK, + PROP_BOOKMARK, g_param_spec_pointer ("bookmark", "Bookmark", "Bookmark", @@ -864,89 +662,63 @@ ephy_bookmark_action_class_init (EphyBookmarkActionClass *class) /* overwrite GtkActionClass::tooltip, so we can use the url as tooltip */ g_object_class_install_property (object_class, - PROP_TOOLTIP, - g_param_spec_string ("tooltip", - "Tooltip", - "Tooltip", - NULL, - G_PARAM_READABLE)); - + PROP_TOOLTIP, + g_param_spec_string ("tooltip", + "Tooltip", + "Tooltip", + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, - PROP_LOCATION, - g_param_spec_string ("location", - "Location", - "Location", - NULL, - G_PARAM_READABLE)); + PROP_LOCATION, + g_param_spec_string ("location", + "Location", + "Location", + NULL, + G_PARAM_READABLE)); g_object_class_install_property (object_class, - PROP_SMART_URL, - g_param_spec_boolean ("smarturl", - "Smart url", - "Smart url", - FALSE, - G_PARAM_READABLE)); + PROP_SMART_URL, + g_param_spec_boolean ("smarturl", + "Smart url", + "Smart url", + FALSE, + G_PARAM_READABLE)); g_object_class_install_property (object_class, - PROP_ICON, - g_param_spec_string ("icon", - "Icon", - "Icon", - NULL, - G_PARAM_READABLE)); + PROP_ICON, + g_param_spec_string ("icon", + "Icon", + "Icon", + NULL, + G_PARAM_READABLE)); g_type_class_add_private (object_class, sizeof(EphyBookmarkActionPrivate)); } static void -smart_child_added_cb (EphyNode *smart_bmks, - EphyNode *child, - EphyBookmarkAction *action) -{ - if (ephy_node_get_id (action->priv->node) == ephy_node_get_id (child)) - { - action->priv->smart_url = TRUE; - g_object_notify (G_OBJECT (action), "smarturl"); - } -} - -static void -smart_child_removed_cb (EphyNode *smart_bmks, - EphyNode *child, - guint old_index, - EphyBookmarkAction *action) -{ - if (ephy_node_get_id (action->priv->node) == ephy_node_get_id (child)) - { - action->priv->smart_url = FALSE; - g_object_notify (G_OBJECT (action), "smarturl"); - } -} - -static void ephy_bookmark_action_init (EphyBookmarkAction *action) { - EphyBookmarks *bookmarks; - EphyNode *node; - action->priv = EPHY_BOOKMARK_ACTION_GET_PRIVATE (action); + action->priv->cache_handler = 0; +} - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - node = ephy_bookmarks_get_smart_bookmarks (bookmarks); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, - (EphyNodeCallback) smart_child_added_cb, - G_OBJECT (action)); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) smart_child_removed_cb, - G_OBJECT (action)); +char * +ephy_bookmark_action_name (EphyNode *node) +{ + return g_strdup_printf("Bmk%u", ephy_node_get_id (node)); } GtkAction * -ephy_bookmark_action_new (const char *name, - EphyNode *node) +ephy_bookmark_action_new (EphyNode *node, char *name) { - g_return_val_if_fail (node != NULL, NULL); + GtkAction *action; + + if(!name) name = ephy_bookmark_action_name (node); + g_return_val_if_fail (name, NULL); + + action = GTK_ACTION (g_object_new (EPHY_TYPE_BOOKMARK_ACTION, + "name", name, + "bookmark", node, + NULL)); - return g_object_new (EPHY_TYPE_BOOKMARK_ACTION, - "name", name, - "bookmark", node, - NULL); + return action; } diff --git a/src/bookmarks/ephy-bookmark-action.h b/src/bookmarks/ephy-bookmark-action.h index 01d2c65d3..fbda7f371 100644 --- a/src/bookmarks/ephy-bookmark-action.h +++ b/src/bookmarks/ephy-bookmark-action.h @@ -25,6 +25,8 @@ #include "ephy-link-action.h" #include "ephy-node.h" +#include <gtk/gtkactiongroup.h> + G_BEGIN_DECLS #define EPHY_TYPE_BOOKMARK_ACTION (ephy_bookmark_action_get_type ()) @@ -51,11 +53,20 @@ struct _EphyBookmarkActionClass EphyLinkActionClass parent_class; }; -GType ephy_bookmark_action_get_type (void); -GtkAction *ephy_bookmark_action_new (const char *name, - EphyNode *node); +GType ephy_bookmark_action_get_type (void); + +char * ephy_bookmark_action_name (EphyNode *node); + +GtkAction * ephy_bookmark_action_new (EphyNode *node, char *name); + + +void ephy_bookmark_action_set_bookmark (EphyBookmarkAction *action, EphyNode *node); + +EphyNode * ephy_bookmark_action_get_bookmark (EphyBookmarkAction *action); + +void ephy_bookmark_action_updated (EphyBookmarkAction *action); G_END_DECLS -#endif /* EPHY_BOOKMARK_ACTION_H */ +#endif diff --git a/src/bookmarks/ephy-bookmark-factory-action.c b/src/bookmarks/ephy-bookmark-factory-action.c new file mode 100644 index 000000000..89df8d05b --- /dev/null +++ b/src/bookmarks/ephy-bookmark-factory-action.c @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + * + */ + +#include "config.h" + +#include <gtk/gtktoolitem.h> +#include <glib/gi18n.h> + +#include "ephy-bookmark-factory-action.h" +#include "ephy-bookmark-action.h" +#include "ephy-node-common.h" +#include "ephy-shell.h" +#include "ephy-stock-icons.h" +#include "egg-editable-toolbar.h" + +static void ephy_bookmark_factory_action_class_init (EphyBookmarkFactoryActionClass *class); + +#define EPHY_BOOKMARK_FACTORY_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARK_FACTORY_ACTION, EphyBookmarkActionPrivate)) +#define EGG_TOOLBARS_MODEL_DATA "ephy-bookmark-factory-menu" + +static GObjectClass *parent_class = NULL; + +GType +ephy_bookmark_factory_action_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo type_info = + { + sizeof (EphyBookmarkFactoryActionClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) ephy_bookmark_factory_action_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (EphyBookmarkFactoryAction), + 0, /* n_preallocs */ + NULL + }; + + type = g_type_register_static (GTK_TYPE_ACTION, + "EphyBookmarkFactoryAction", + &type_info, 0); + } + return type; +} + +static void +activate_item_cb (GtkWidget *menuitem, GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item; + EggToolbarsModel *model; + GList *children; + gint index, pos; + char *id; + + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_if_fail (item); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_if_fail (toolbar); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_if_fail (etoolbar); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_if_fail (model); + + children = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + pos = g_list_index (children, toolbar->parent); + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + g_list_free (children); + + id = g_object_get_data (G_OBJECT (menuitem), "ephy-action"); + egg_toolbars_model_add_item (model, pos, index, id); +} + +static GtkWidget * +build_menu_for_topic (GtkWidget *placeholder, EggToolbarsModel *model, EphyNode *topic) +{ + GtkWidget *menu, *item; + EphyNode *node; + GPtrArray *children, *bookmarks; + const char *name, *action; + gint i; + + children = ephy_node_get_children (topic); + bookmarks = g_ptr_array_sized_new (children->len); + for (i = 0; i < children->len; i++) + g_ptr_array_add (bookmarks, g_ptr_array_index (children, i)); + g_ptr_array_sort (bookmarks, (GCompareFunc)ephy_bookmarks_compare_bookmark_pointers); + + menu = NULL; + + for (i = 0; i < bookmarks->len; i++) + { + node = g_ptr_array_index (bookmarks, i); + + action = ephy_bookmark_action_name (node); + if (egg_toolbars_model_get_n_avail (model, action) < 0) + continue; + + name = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_TITLE); + item = gtk_menu_item_new_with_label (name); + + g_object_set_data_full (G_OBJECT (item), "ephy-action", (gpointer) action, g_free); + g_signal_connect (item, "activate", G_CALLBACK (activate_item_cb), placeholder); + gtk_widget_show (item); + + if (menu == NULL) menu = gtk_menu_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + } + g_ptr_array_free (bookmarks, TRUE); + + return menu; +} + +static GtkWidget * +build_menu (GtkWidget *placeholder, EggToolbarsModel *model) +{ + GtkWidget *menu, *submenu, *item; + + EphyBookmarks *eb; + EphyNode *node; + GPtrArray *children, *topics; + + const char *name; + gint i, priority = -1, ptmp; + + /* Get a sorted list of topics. */ + eb = ephy_shell_get_bookmarks (ephy_shell); + node = ephy_bookmarks_get_keywords (eb); + children = ephy_node_get_children (node); + topics = g_ptr_array_sized_new (children->len); + for (i = 0; i < children->len; i++) + g_ptr_array_add (topics, g_ptr_array_index (children, i)); + g_ptr_array_sort (topics, (GCompareFunc)ephy_bookmarks_compare_topic_pointers); + + menu = gtk_menu_new (); + for (i = 0; i < topics->len; i++) + { + node = g_ptr_array_index (topics, i); + + ptmp = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (ptmp == EPHY_NODE_ALL_PRIORITY) + continue; + + submenu = build_menu_for_topic (placeholder, model, node); + if (submenu == NULL) + continue; + + if (ptmp != priority && priority >= 0) + { + item = gtk_separator_menu_item_new (); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + } + priority = ptmp; + + name = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); + item = gtk_menu_item_new_with_label (name); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + + gtk_widget_show (item); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + } + g_ptr_array_free (topics, TRUE); + + return menu; +} + +static void +remove_placeholder_cb (GtkMenuShell *menushell, + GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item; + EggToolbarsModel *model; + GList *children; + gint index, pos; + + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_if_fail (item); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_if_fail (toolbar); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_if_fail (etoolbar); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_if_fail (model); + + g_object_set_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA, NULL); + + children = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + pos = g_list_index (children, toolbar->parent); + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + g_list_free (children); + + egg_toolbars_model_remove_item (model, pos, index); +} + +static gboolean +activate_placeholder_cb (GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item, *menu; + EggToolbarsModel *model; + gint index; + + /* Get our position on a toolbar. */ + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_val_if_fail (item, FALSE); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_val_if_fail (toolbar, FALSE); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_val_if_fail (etoolbar, FALSE); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_val_if_fail (model, FALSE); + + /* If we are not yet on the toolbar, abort. */ + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + if (index < 0 || index >= gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar))) + return FALSE; + + /* If there is already a popup menu, abort. */ + menu = g_object_get_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA); + if (menu != NULL) return FALSE; + + /* Create the menu and store it's pointer to ensure noone else creates a menu. */ + menu = build_menu (placeholder, model); + g_object_set_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA, menu); + + g_signal_connect (menu, "selection-done", + G_CALLBACK (remove_placeholder_cb), placeholder); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, + gtk_get_current_event_time ()); + + return FALSE; +} + +static void +clicked_placeholder_cb (GtkWidget *placeholder, GdkEventButton *event, gpointer user) +{ + activate_placeholder_cb (placeholder); +} + +static void +realize_placeholder_cb (GtkWidget *placeholder, gpointer user) +{ + g_idle_add ((GSourceFunc) activate_placeholder_cb, placeholder); +} + +static GtkWidget * +create_tool_item (GtkAction *action) +{ + GtkWidget *item = GTK_WIDGET (gtk_tool_item_new ()); + GtkWidget *widget = gtk_button_new_with_label (" ? "); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + + gtk_container_add (GTK_CONTAINER (item), widget); + gtk_widget_show (widget); + + return item; +} + +static void +connect_proxy (GtkAction *action, GtkWidget *proxy) +{ + GtkWidget *widget; + + (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy); + + g_return_if_fail (GTK_IS_TOOL_ITEM (proxy)); + + widget = gtk_bin_get_child (GTK_BIN (proxy)); + + g_signal_connect (widget, "realize", + G_CALLBACK (realize_placeholder_cb), + action); + g_signal_connect (widget, "clicked", + G_CALLBACK (clicked_placeholder_cb), + action); +} + +static void +ephy_bookmark_factory_action_class_init (EphyBookmarkFactoryActionClass *class) +{ + GtkActionClass *action_class = GTK_ACTION_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM; + action_class->connect_proxy = connect_proxy; + action_class->create_tool_item = create_tool_item; +} + +GtkAction * +ephy_bookmark_factory_action_new (const char *name) +{ + return GTK_ACTION (g_object_new (EPHY_TYPE_BOOKMARK_FACTORY_ACTION, + "name", name, + "label", _("Quick Bookmark"), + "stock-id", GTK_STOCK_ADD, + NULL)); +} diff --git a/src/bookmarks/ephy-bookmark-factory-action.h b/src/bookmarks/ephy-bookmark-factory-action.h new file mode 100644 index 000000000..472828726 --- /dev/null +++ b/src/bookmarks/ephy-bookmark-factory-action.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2004 Peter Harvey + * + * 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. + * + */ + +#ifndef EPHY_BOOKMARK_FACTORY_ACTION_H +#define EPHY_BOOKMARK_FACTORY_ACTION_H + +#include "ephy-node.h" +#include "ephy-window.h" + +#include <gtk/gtk.h> +#include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> + +#define EPHY_TYPE_BOOKMARK_FACTORY_ACTION (ephy_bookmark_factory_action_get_type ()) +#define EPHY_BOOKMARK_FACTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_BOOKMARK_FACTORY_ACTION, EphyBookmarkFactoryAction)) +#define EPHY_BOOKMARK_FACTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_BOOKMARK_FACTORY_ACTION, EphyBookmarkFactoryActionClass)) +#define EPHY_IS_BOOKMARK_FACTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_BOOKMARK_FACTORY_ACTION)) +#define EPHY_IS_BOOKMARK_FACTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_BOOKMARK_FACTORY_ACTION)) +#define EPHY_BOOKMARK_FACTORY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_BOOKMARK_FACTORY_ACTION, EphyBookmarkFactoryActionClass)) + +typedef struct _EphyBookmarkFactoryAction EphyBookmarkFactoryAction; +typedef struct _EphyBookmarkFactoryActionClass EphyBookmarkFactoryActionClass; + +struct _EphyBookmarkFactoryAction +{ + GtkAction parent; +}; + +struct _EphyBookmarkFactoryActionClass +{ + GtkActionClass parent_class; +}; + +GType ephy_bookmark_factory_action_get_type (void); + +GtkAction * ephy_bookmark_factory_action_new (const char *name); + +#endif diff --git a/src/bookmarks/ephy-bookmark-properties.c b/src/bookmarks/ephy-bookmark-properties.c index 6749b58ec..07b83d319 100644 --- a/src/bookmarks/ephy-bookmark-properties.c +++ b/src/bookmarks/ephy-bookmark-properties.c @@ -20,7 +20,6 @@ #include "config.h" -#include "ephy-bookmarksbar-model.h" #include "ephy-bookmark-properties.h" #include "ephy-topics-selector.h" #include "ephy-debug.h" @@ -43,13 +42,13 @@ static void ephy_bookmark_properties_class_init (EphyBookmarkPropertiesClass *klass); static void ephy_bookmark_properties_init (EphyBookmarkProperties *editor); static void ephy_bookmark_properties_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void ephy_bookmark_properties_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); + guint prop_id, + GValue *value, + GParamSpec *pspec); #define EPHY_BOOKMARK_PROPERTIES_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARK_PROPERTIES, EphyBookmarkPropertiesPrivate)) @@ -61,8 +60,6 @@ struct _EphyBookmarkPropertiesPrivate GtkWidget *title_entry; GtkWidget *location_entry; GtkWidget *topics_selector; - - EphyBookmarksBarModel *tb_model; }; enum @@ -143,9 +140,9 @@ ephy_bookmark_properties_set_bookmark (EphyBookmarkProperties *selector, static void ephy_bookmark_properties_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { EphyBookmarkProperties *selector = EPHY_BOOKMARK_PROPERTIES (object); @@ -153,8 +150,6 @@ ephy_bookmark_properties_set_property (GObject *object, { case PROP_BOOKMARKS: selector->priv->bookmarks = g_value_get_object (value); - selector->priv->tb_model = EPHY_BOOKMARKSBAR_MODEL - (ephy_bookmarks_get_toolbars_model (selector->priv->bookmarks)); break; case PROP_BOOKMARK: ephy_bookmark_properties_set_bookmark @@ -168,9 +163,9 @@ ephy_bookmark_properties_set_property (GObject *object, static void ephy_bookmark_properties_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { EphyBookmarkProperties *selector = EPHY_BOOKMARK_PROPERTIES (object); @@ -187,8 +182,8 @@ ephy_bookmark_properties_get_property (GObject *object, static void bookmark_properties_response_cb (GtkDialog *dialog, - int response_id, - gpointer data) + int response_id, + gpointer data) { switch (response_id) { @@ -213,8 +208,8 @@ update_entry (EphyBookmarkProperties *props, GtkWidget *entry, guint prop) g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, text); ephy_node_set_property (props->priv->bookmark, - prop, - &value); + prop, + &value); g_value_unset (&value); g_free (text); } @@ -245,29 +240,7 @@ location_entry_changed_cb (GtkWidget *entry, EphyBookmarkProperties *props) { ephy_bookmarks_set_address (props->priv->bookmarks, props->priv->bookmark, - gtk_entry_get_text (GTK_ENTRY (entry))); -} - -static void -toolbar_checkbox_changed_cb (GtkWidget *checkbox, EphyBookmarkProperties *props) -{ - gboolean state; - guint id; - - state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)); - - id = ephy_node_get_id (props->priv->bookmark); - - if (state) - { - ephy_bookmarksbar_model_add_bookmark - (props->priv->tb_model, FALSE, id); - } - else - { - ephy_bookmarksbar_model_remove_bookmark - (props->priv->tb_model, id); - } + gtk_entry_get_text (GTK_ENTRY (entry))); } static void @@ -306,11 +279,9 @@ static void build_ui (EphyBookmarkProperties *editor) { GtkWidget *table, *label, *entry, *topics_selector; - GtkWidget *checkbox, *scrolled_window; + GtkWidget *scrolled_window; char *str; const char *tmp; - gboolean state; - guint id; g_signal_connect (G_OBJECT (editor), "response", @@ -319,7 +290,7 @@ build_ui (EphyBookmarkProperties *editor) ephy_state_add_window (GTK_WIDGET(editor), "bookmark_properties", - 290, 280, FALSE, + 290, 280, FALSE, EPHY_STATE_WINDOW_SAVE_SIZE); update_window_title (editor); @@ -398,16 +369,6 @@ build_ui (EphyBookmarkProperties *editor) gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - checkbox = gtk_check_button_new_with_mnemonic (_("_Show in bookmarks bar")); - id = ephy_node_get_id (editor->priv->bookmark); - state = ephy_bookmarksbar_model_has_bookmark (editor->priv->tb_model, id); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), state); - g_signal_connect (checkbox, "toggled", - G_CALLBACK (toolbar_checkbox_changed_cb), editor); - gtk_table_attach (GTK_TABLE (table), checkbox, 0, 2, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (checkbox); - - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editor)->vbox), table, TRUE, TRUE, 0); gtk_dialog_add_button (GTK_DIALOG (editor), diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c index 24dbeedac..7608823a6 100644 --- a/src/bookmarks/ephy-bookmarks-editor.c +++ b/src/bookmarks/ephy-bookmarks-editor.c @@ -62,10 +62,10 @@ #include "ephy-gui.h" #include "ephy-stock-icons.h" #include "ephy-search-entry.h" -#include "ephy-bookmarksbar-model.h" #include "ephy-favicon-cache.h" #include "eel-gconf-extensions.h" #include "ephy-debug.h" +#include "egg-toolbars-model.h" static GtkTargetEntry topic_drag_dest_types [] = { @@ -76,9 +76,9 @@ static int n_topic_drag_dest_types = G_N_ELEMENTS (topic_drag_dest_types); static GtkTargetEntry bmk_drag_types [] = { - { EPHY_DND_URL_TYPE, 0, 0 }, - { EPHY_DND_URI_LIST_TYPE, 0, 1 }, - { EPHY_DND_TEXT_TYPE, 0, 2 } + { EPHY_DND_URL_TYPE, 0, 0 }, + { EPHY_DND_URI_LIST_TYPE, 0, 1 }, + { EPHY_DND_TEXT_TYPE, 0, 2 } }; static int n_bmk_drag_types = G_N_ELEMENTS (bmk_drag_types); @@ -93,9 +93,9 @@ static void ephy_bookmarks_editor_init (EphyBookmarksEditor *editor); static void ephy_bookmarks_editor_finalize (GObject *object); static void ephy_bookmarks_editor_dispose (GObject *object); static void ephy_bookmarks_editor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void ephy_bookmarks_editor_get_property (GObject *object, guint prop_id, GValue *value, @@ -106,10 +106,8 @@ static void cmd_open_bookmarks_in_tabs (GtkAction *action, EphyBookmarksEditor *editor); static void cmd_open_bookmarks_in_browser (GtkAction *action, EphyBookmarksEditor *editor); -static void cmd_show_in_bookmarks_bar (GtkAction *action, - EphyBookmarksEditor *editor); static void cmd_delete (GtkAction *action, - EphyBookmarksEditor *editor); + EphyBookmarksEditor *editor); static void cmd_bookmark_properties (GtkAction *action, EphyBookmarksEditor *editor); static void cmd_bookmarks_import (GtkAction *action, @@ -151,7 +149,6 @@ struct _EphyBookmarksEditorPrivate GtkUIManager *ui_merge; GtkActionGroup *action_group; int priority_col; - EphyBookmarksBarModel *tb_model; GtkTreeViewColumn *title_col; GtkTreeViewColumn *address_col; @@ -225,15 +222,6 @@ static GtkActionEntry ephy_bookmark_popup_entries [] = { }; static guint ephy_bookmark_popup_n_entries = G_N_ELEMENTS (ephy_bookmark_popup_entries); -static GtkToggleActionEntry ephy_bookmark_popup_toggle_entries [] = -{ - /* File Menu */ - { "ShowInBookmarksBar", NULL, N_("_Show in Bookmarks Bar"), NULL, - N_("Show the selected bookmark or topic in the bookmarks bar"), - G_CALLBACK (cmd_show_in_bookmarks_bar), FALSE } -}; -static guint ephy_bookmark_popup_n_toggle_entries = G_N_ELEMENTS (ephy_bookmark_popup_toggle_entries); - enum { VIEW_TITLE, @@ -260,14 +248,14 @@ entry_selection_changed_cb (GtkWidget *widget, GParamSpec *pspec, EphyBookmarksE static void add_entry_monitor (EphyBookmarksEditor *editor, GtkWidget *entry) { - g_signal_connect (G_OBJECT (entry), - "notify::selection-bound", - G_CALLBACK (entry_selection_changed_cb), - editor); - g_signal_connect (G_OBJECT (entry), - "notify::cursor-position", - G_CALLBACK (entry_selection_changed_cb), - editor); + g_signal_connect (G_OBJECT (entry), + "notify::selection-bound", + G_CALLBACK (entry_selection_changed_cb), + editor); + g_signal_connect (G_OBJECT (entry), + "notify::cursor-position", + G_CALLBACK (entry_selection_changed_cb), + editor); } static void @@ -288,7 +276,7 @@ cmd_add_topic (GtkAction *action, EphyNode *node; node = ephy_bookmarks_add_keyword (editor->priv->bookmarks, - _("Type a topic")); + _("Type a topic")); ephy_node_view_select_node (EPHY_NODE_VIEW (editor->priv->key_view), node); ephy_node_view_edit (EPHY_NODE_VIEW (editor->priv->key_view), TRUE); add_text_renderer_monitor (editor); @@ -334,65 +322,6 @@ get_target_window (EphyBookmarksEditor *editor) } static void -toolbar_items_changed_cb (EggToolbarsModel *model, - int toolbar_position, - int position, - EphyBookmarksEditor *editor) -{ - ephy_bookmarks_editor_update_menu (editor); -} - -static void -cmd_show_in_bookmarks_bar (GtkAction *action, - EphyBookmarksEditor *editor) -{ - EphyNode *node; - GList *selection; - gboolean state, topic; - guint id; - - if (ephy_node_view_is_target (EPHY_NODE_VIEW (editor->priv->bm_view))) - { - selection = ephy_node_view_get_selection - (EPHY_NODE_VIEW (editor->priv->bm_view)); - topic = FALSE; - } - else if (ephy_node_view_is_target (EPHY_NODE_VIEW (editor->priv->key_view))) - { - selection = ephy_node_view_get_selection - (EPHY_NODE_VIEW (editor->priv->key_view)); - topic = TRUE; - } - else - { - return; - } - - node = selection->data; - id = ephy_node_get_id (node); - state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - - if (state) - { - ephy_bookmarksbar_model_add_bookmark - (editor->priv->tb_model, topic, id); - } - else - { - g_signal_handlers_block_by_func - (editor->priv->tb_model, - G_CALLBACK (toolbar_items_changed_cb), editor); - ephy_bookmarksbar_model_remove_bookmark - (editor->priv->tb_model, id); - g_signal_handlers_unblock_by_func - (editor->priv->tb_model, - G_CALLBACK (toolbar_items_changed_cb), editor); - } - - g_list_free (selection); -} - -static void cmd_open_bookmarks_in_tabs (GtkAction *action, EphyBookmarksEditor *editor) { @@ -478,7 +407,7 @@ delete_topic_dialog_construct (GtkWindow *parent, gtk_window_group_add_window (GTK_WINDOW (parent)->group, GTK_WINDOW (dialog)); - return dialog; + return dialog; } static void @@ -863,7 +792,7 @@ cmd_bookmarks_import (GtkAction *action, gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); - store = GTK_LIST_STORE (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); + store = GTK_LIST_STORE (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); files = add_bookmarks_files (FIREFOX_BOOKMARKS_DIR_0, "bookmarks.html", 2); files = g_slist_concat (add_bookmarks_files (FIREFOX_BOOKMARKS_DIR_1, "bookmarks.html", 2), files); @@ -879,8 +808,8 @@ cmd_bookmarks_import (GtkAction *action, gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, _("File"), 1, NULL, -1); - sortmodel = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store)); - g_object_unref (store); + sortmodel = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store)); + g_object_unref (store); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sortmodel), 0, GTK_SORT_ASCENDING); @@ -1129,8 +1058,8 @@ ephy_bookmarks_editor_finalize (GObject *object) if (editor->priv->window) { g_object_remove_weak_pointer - (G_OBJECT(editor->priv->window), - (gpointer *)&editor->priv->window); + (G_OBJECT(editor->priv->window), + (gpointer *)&editor->priv->window); } G_OBJECT_CLASS (parent_class)->finalize (object); @@ -1138,7 +1067,7 @@ ephy_bookmarks_editor_finalize (GObject *object) static void ephy_bookmarks_editor_node_activated_cb (GtkWidget *view, - EphyNode *node, + EphyNode *node, EphyBookmarksEditor *editor) { const char *location; @@ -1161,8 +1090,8 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) gboolean key_selection, bmk_selection, single_bmk_selected; gboolean key_normal = FALSE; gboolean cut, copy, paste, select_all; - gboolean can_show_in_bookmarks_bar, show_in_bookmarks_bar = FALSE; gboolean mutable = TRUE; + GtkActionGroup *action_group; GtkAction *action; GList *selected; @@ -1210,11 +1139,6 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) { EphyNode *node = selected->data; EphyNodePriority priority; - guint id; - - id = ephy_node_get_id (node); - show_in_bookmarks_bar = ephy_bookmarksbar_model_has_bookmark - (editor->priv->tb_model, id); priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); @@ -1233,8 +1157,6 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) g_return_if_fail (node != NULL); id = ephy_node_get_id (node); - show_in_bookmarks_bar = ephy_bookmarksbar_model_has_bookmark - (editor->priv->tb_model, id); mutable = !ephy_node_get_property_boolean (node, EPHY_NODE_BMK_PROP_IMMUTABLE); g_list_free (selected); @@ -1263,8 +1185,6 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) delete = (bmk_focus && bmk_selection && mutable) || (key_selection && key_focus && key_normal); properties = bmk_focus && single_bmk_selected && mutable; - can_show_in_bookmarks_bar = (bmk_focus && single_bmk_selected && mutable) || - (key_selection && key_focus); action_group = editor->priv->action_group; action = gtk_action_group_get_action (action_group, "OpenInWindow"); @@ -1287,25 +1207,13 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) action = gtk_action_group_get_action (action_group, "Paste"); gtk_action_set_sensitive (action, paste); action = gtk_action_group_get_action (action_group, "SelectAll"); - gtk_action_set_sensitive (action, select_all); - action = gtk_action_group_get_action (action_group, "ShowInBookmarksBar"); - gtk_action_set_sensitive (action, can_show_in_bookmarks_bar); - - g_signal_handlers_block_by_func - (G_OBJECT (GTK_TOGGLE_ACTION (action)), - G_CALLBACK (cmd_show_in_bookmarks_bar), - editor); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_in_bookmarks_bar); - g_signal_handlers_unblock_by_func - (G_OBJECT (GTK_TOGGLE_ACTION (action)), - G_CALLBACK (cmd_show_in_bookmarks_bar), - editor); + g_object_set (action, "sensitive", select_all, NULL); } static gboolean view_focus_cb (EphyNodeView *view, - GdkEventFocus *event, - EphyBookmarksEditor *editor) + GdkEventFocus *event, + EphyBookmarksEditor *editor) { ephy_bookmarks_editor_update_menu (editor); @@ -1316,21 +1224,21 @@ static void add_focus_monitor (EphyBookmarksEditor *editor, GtkWidget *widget) { g_signal_connect (G_OBJECT (widget), - "focus_in_event", - G_CALLBACK (view_focus_cb), - editor); + "focus_in_event", + G_CALLBACK (view_focus_cb), + editor); g_signal_connect (G_OBJECT (widget), - "focus_out_event", - G_CALLBACK (view_focus_cb), - editor); + "focus_out_event", + G_CALLBACK (view_focus_cb), + editor); } static void remove_focus_monitor (EphyBookmarksEditor *editor, GtkWidget *widget) { g_signal_handlers_disconnect_by_func (G_OBJECT (widget), - G_CALLBACK (view_focus_cb), - editor); + G_CALLBACK (view_focus_cb), + editor); } static gboolean @@ -1381,13 +1289,13 @@ ephy_bookmarks_editor_dispose (GObject *object) static void bookmarks_filter (EphyBookmarksEditor *editor, - EphyNode *keyword) + EphyNode *keyword) { ephy_node_filter_empty (editor->priv->bookmarks_filter); ephy_node_filter_add_expression (editor->priv->bookmarks_filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_HAS_PARENT, - keyword), - 0); + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_HAS_PARENT, + keyword), + 0); ephy_node_filter_done_changing (editor->priv->bookmarks_filter); } @@ -1462,15 +1370,15 @@ search_entry_search_cb (GtkWidget *entry, const char *search_text, EphyBookmarks ephy_node_filter_empty (editor->priv->bookmarks_filter); ephy_node_filter_add_expression (editor->priv->bookmarks_filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, - EPHY_NODE_BMK_PROP_TITLE, - search_text), - 0); + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, + EPHY_NODE_BMK_PROP_TITLE, + search_text), + 0); ephy_node_filter_add_expression (editor->priv->bookmarks_filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, - EPHY_NODE_BMK_PROP_KEYWORDS, - search_text), - 0); + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, + EPHY_NODE_BMK_PROP_KEYWORDS, + search_text), + 0); ephy_node_filter_done_changing (editor->priv->bookmarks_filter); } @@ -1646,10 +1554,6 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) gtk_action_group_set_translation_domain (action_group, NULL); gtk_action_group_add_actions (action_group, ephy_bookmark_popup_entries, ephy_bookmark_popup_n_entries, editor); - gtk_action_group_add_toggle_actions (action_group, - ephy_bookmark_popup_toggle_entries, - ephy_bookmark_popup_n_toggle_entries, - editor); details_value = get_details_value (editor); gtk_action_group_add_radio_actions (action_group, @@ -1661,8 +1565,8 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) gtk_ui_manager_insert_action_group (ui_merge, action_group, 0); gtk_ui_manager_add_ui_from_file (ui_merge, - ephy_file ("epiphany-bookmark-editor-ui.xml"), - NULL); + ephy_file ("epiphany-bookmark-editor-ui.xml"), + NULL); gtk_window_add_accel_group (GTK_WINDOW (editor), gtk_ui_manager_get_accel_group (ui_merge)); gtk_ui_manager_ensure_update (ui_merge); @@ -1694,7 +1598,7 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) key_view = ephy_node_view_new (node, NULL); add_focus_monitor (editor, key_view); col_id = ephy_node_view_add_data_column (EPHY_NODE_VIEW (key_view), - G_TYPE_STRING, -1, + G_TYPE_STRING, -1, provide_keyword_uri, editor); ephy_node_view_add_column (EPHY_NODE_VIEW (key_view), _("Topics"), G_TYPE_STRING, @@ -1704,11 +1608,11 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) EPHY_NODE_VIEW_SEARCHABLE, NULL, NULL); ephy_node_view_enable_drag_source (EPHY_NODE_VIEW (key_view), topic_drag_types, - n_topic_drag_types, + n_topic_drag_types, col_id, -1); ephy_node_view_enable_drag_dest (EPHY_NODE_VIEW (key_view), - topic_drag_dest_types, - n_topic_drag_dest_types); + topic_drag_dest_types, + n_topic_drag_dest_types); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (key_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); g_signal_connect (G_OBJECT (selection), @@ -1777,7 +1681,7 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) 0, NULL, &(editor->priv->address_col)); ephy_node_view_enable_drag_source (EPHY_NODE_VIEW (bm_view), bmk_drag_types, - n_bmk_drag_types, + n_bmk_drag_types, url_col_id, title_col_id); ephy_node_view_set_sort (EPHY_NODE_VIEW (bm_view), G_TYPE_STRING, EPHY_NODE_BMK_PROP_TITLE, GTK_SORT_ASCENDING); @@ -1804,11 +1708,11 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) ephy_state_add_window (GTK_WIDGET(editor), "bookmarks_editor", - 450, 400, FALSE, + 450, 400, FALSE, EPHY_STATE_WINDOW_SAVE_SIZE | EPHY_STATE_WINDOW_SAVE_POSITION); ephy_state_add_paned (GTK_WIDGET (hpaned), "bookmarks_paned", - 130); + 130); set_columns_visibility (editor, details_value); } @@ -1820,15 +1724,15 @@ ephy_bookmarks_editor_set_parent (EphyBookmarksEditor *ebe, if (ebe->priv->window) { g_object_remove_weak_pointer - (G_OBJECT(ebe->priv->window), - (gpointer *)&ebe->priv->window); + (G_OBJECT(ebe->priv->window), + (gpointer *)&ebe->priv->window); } ebe->priv->window = window; g_object_add_weak_pointer - (G_OBJECT(ebe->priv->window), - (gpointer *)&ebe->priv->window); + (G_OBJECT(ebe->priv->window), + (gpointer *)&ebe->priv->window); } @@ -1851,9 +1755,9 @@ ephy_bookmarks_editor_new (EphyBookmarks *bookmarks) static void ephy_bookmarks_editor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { EphyBookmarksEditor *editor = EPHY_BOOKMARKS_EDITOR (object); @@ -1870,9 +1774,9 @@ ephy_bookmarks_editor_set_property (GObject *object, static void ephy_bookmarks_editor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { EphyBookmarksEditor *editor = EPHY_BOOKMARKS_EDITOR (object); @@ -1891,13 +1795,4 @@ static void ephy_bookmarks_editor_init (EphyBookmarksEditor *editor) { editor->priv = EPHY_BOOKMARKS_EDITOR_GET_PRIVATE (editor); - - editor->priv->tb_model = EPHY_BOOKMARKSBAR_MODEL - (ephy_bookmarks_get_toolbars_model - (ephy_shell_get_bookmarks (ephy_shell))); - - g_signal_connect (editor->priv->tb_model, "item_added", - G_CALLBACK (toolbar_items_changed_cb), editor); - g_signal_connect (editor->priv->tb_model, "item_removed", - G_CALLBACK (toolbar_items_changed_cb), editor); } diff --git a/src/bookmarks/ephy-bookmarks-menu.c b/src/bookmarks/ephy-bookmarks-menu.c index 8c54408bb..bbc223655 100644 --- a/src/bookmarks/ephy-bookmarks-menu.c +++ b/src/bookmarks/ephy-bookmarks-menu.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2003, 2004 Marco Pesenti Gritti * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2004 Peter Harvey * * 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 @@ -22,790 +23,213 @@ #include "config.h" #include "ephy-bookmarks-menu.h" +#include "ephy-bookmarks-ui.h" #include "ephy-bookmark-action.h" +#include "ephy-open-tabs-action.h" +#include "ephy-topic-action.h" +#include "ephy-nodes-cover.h" +#include "ephy-node-common.h" #include "ephy-link.h" #include "ephy-shell.h" -#include "ephy-node-common.h" +#include "ephy-string.h" #include "ephy-gui.h" #include "ephy-debug.h" -#include <glib/gprintf.h> -#include <glib/gi18n.h> -#include <gtk/gtkuimanager.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkmenuitem.h> #include <string.h> -#define EPHY_BOOKMARKS_MENU_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARKS_MENU, EphyBookmarksMenuPrivate)) - -struct _EphyBookmarksMenuPrivate -{ - GtkUIManager *manager; - char *path; - EphyBookmarks *bookmarks; - GtkActionGroup *bmk_actions; - GtkActionGroup *folder_actions; - GSList *removed_bmks; - guint ui_id; - guint update_tag; - gboolean needs_update; -}; - -/* 14 = strlen ("0000000000000000") - strlen ("%x") - * FIXME: for 32bit, 6 is sufficient -> use some #if magic? - */ -#define MAXLEN 14 - -/* this %x is bookmark node id */ -#define BMK_VERB_FORMAT "Bmk%x" -#define BMK_VERB_FORMAT_LENGTH strlen (BMK_VERB_FORMAT) + MAXLEN + 1 - -/* first %x is bookmark node id, second %x is g_str_hash of path */ -#define BMK_NAME_FORMAT "Bmk%x%x" -#define BMK_NAME_FORMAT_LENGTH strlen (BMK_NAME_FORMAT) + 2 * MAXLEN + 1 - -/* first %x is g_str_hash of folder name, 2nd %x is g_str_hash of path */ -#define FOLDER_VERB_FORMAT "Fld%x%x" -#define FOLDER_VERB_FORMAT_LENGTH strlen (FOLDER_VERB_FORMAT) + 2 * MAXLEN + 1 - -#define BMK_ACCEL_PATH_PREFIX "<Actions>/BmkActions/" - -#define GAZILLION 200 -#define UPDATE_DELAY 5000 /* ms */ -#define LABEL_WIDTH_CHARS 32 +#define MIN_MENU_SIZE 7 +#define MAX_MENU_SIZE 21 enum { - PROP_0, - PROP_PATH, - PROP_UI_MANAGER + BUILD_SUBDIVIS = 1 << 0, + BUILD_SUBMENUS = 1 << 1, + BUILD_CHILD_SUBDIVIS = 1 << 2, + BUILD_CHILD_SUBMENUS = 1 << 3 }; -static void ephy_bookmarks_menu_class_init (EphyBookmarksMenuClass *klass); -static void ephy_bookmarks_menu_init (EphyBookmarksMenu *menu); - -static GObjectClass *parent_class = NULL; - -GType -ephy_bookmarks_menu_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (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 - }; - static const GInterfaceInfo link_info = - { - NULL, - NULL, - NULL - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "EphyBookmarksMenu", - &our_info, 0); - g_type_add_interface_static (type, - EPHY_TYPE_LINK, - &link_info); - } - - return type; -} - -static void -connect_proxy_cb (GtkActionGroup *action_group, - GtkAction *action, - GtkWidget *proxy) -{ - if (GTK_IS_MENU_ITEM (proxy)) - { - GtkLabel *label; - - label = (GtkLabel *) ((GtkBin *) proxy)->child; - - gtk_label_set_use_underline (label, FALSE); - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_max_width_chars (label, LABEL_WIDTH_CHARS); - } -} - -static void -remove_action (gpointer idptr, - GtkActionGroup *action_group) -{ - GtkAction *action; - char verb[BMK_VERB_FORMAT_LENGTH]; - - g_snprintf (verb, sizeof (verb), BMK_VERB_FORMAT, GPOINTER_TO_UINT (idptr)); - action = gtk_action_group_get_action (action_group, verb); - g_return_if_fail (action != NULL); - - gtk_action_group_remove_action (action_group, action); -} - -static void -ephy_bookmarks_menu_clean (EphyBookmarksMenu *menu) -{ - EphyBookmarksMenuPrivate *p = menu->priv; - - START_PROFILER ("Cleaning bookmarks menu") - - if (p->ui_id != 0) - { - gtk_ui_manager_remove_ui (p->manager, p->ui_id); - gtk_ui_manager_ensure_update (p->manager); - p->ui_id = 0; - } - - if (p->bmk_actions != NULL && menu->priv->removed_bmks != NULL) - { - /* now we can remove the actions for removed bookmarks */ - g_slist_foreach (menu->priv->removed_bmks, (GFunc) remove_action, - menu->priv->bmk_actions); - g_slist_free (menu->priv->removed_bmks); - menu->priv->removed_bmks = NULL; - } - - if (p->folder_actions != NULL) - { - gtk_ui_manager_remove_action_group (p->manager, p->folder_actions); - g_object_unref (p->folder_actions); - } - - STOP_PROFILER ("Cleaning bookmarks menu") -} - -static void -add_action_for_bookmark (EphyBookmarksMenu *menu, - EphyNode *bmk) -{ - GtkAction *action; - char verb[BMK_VERB_FORMAT_LENGTH]; - char apath[strlen (BMK_ACCEL_PATH_PREFIX) + BMK_VERB_FORMAT_LENGTH]; - guint id; - - g_return_if_fail (bmk != NULL); - - id = ephy_node_get_id (bmk); - - g_snprintf (verb, sizeof (verb), BMK_VERB_FORMAT, id); - g_snprintf (apath, sizeof (apath), BMK_ACCEL_PATH_PREFIX "%s", verb); - - action = ephy_bookmark_action_new (verb, bmk); - - gtk_action_set_accel_path (action, apath); - - g_signal_connect_swapped (action, "open-link", - G_CALLBACK (ephy_link_open), menu); - - gtk_action_group_add_action (menu->priv->bmk_actions, action); - g_object_unref (action); -} - -static void -ensure_bookmark_actions (EphyBookmarksMenu *menu) -{ - EphyNode *bookmarks, *bmk; - GPtrArray *children; - int i; - - if (menu->priv->bmk_actions != NULL) return; - - START_PROFILER ("Adding bookmarks actions") - - menu->priv->bmk_actions = gtk_action_group_new ("BmkActions"); - gtk_ui_manager_insert_action_group (menu->priv->manager, - menu->priv->bmk_actions, -1); - - g_signal_connect (menu->priv->bmk_actions, "connect-proxy", - G_CALLBACK (connect_proxy_cb), NULL); - - bookmarks = ephy_bookmarks_get_bookmarks (menu->priv->bookmarks); - children = ephy_node_get_children (bookmarks); - for (i = 0; i < children->len; i++) - { - bmk = g_ptr_array_index (children, i); - - add_action_for_bookmark (menu, bmk); - } - - STOP_PROFILER ("Adding bookmarks actions") -} - -static int -sort_topics (gconstpointer a, gconstpointer b) -{ - EphyNode *node_a = (EphyNode *)a; - EphyNode *node_b = (EphyNode *)b; - const char *title1, *title2; - int retval; - - title1 = ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME); - title2 = ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME); - - if (title1 == NULL) - { - retval = -1; - } - else if (title2 == NULL) - { - retval = 1; - } - else - { - char *str_a, *str_b; - - str_a = g_utf8_casefold (title1, -1); - str_b = g_utf8_casefold (title2, -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; - const char *title1, *title2; - int retval; - - title1 = ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE); - title2 = ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE); - - if (title1 == NULL) - { - retval = -1; - } - else if (title2 == NULL) - { - retval = 1; - } - else - { - char *str_a, *str_b; - - str_a = g_utf8_casefold (title1, -1); - str_b = g_utf8_casefold (title2, -1); - retval = g_utf8_collate (str_a, str_b); - g_free (str_a); - g_free (str_b); - } - - return retval; -} - +/* Construct a block of bookmark actions, postfixing the names with a topic id + * to allow different. */ static void -create_menu (EphyBookmarksMenu *menu, - EphyNode *node, - const char *path) +append_bookmarks (GString *string, const GPtrArray *bookmarks, gint instance) { - GPtrArray *children; - EphyBookmarksMenuPrivate *p = menu->priv; - GList *node_list = NULL, *l; - guint phash; - int i; - - phash = g_str_hash (path); - - children = ephy_node_get_children (node); - for (i = 0; i < children->len; ++i) - { - node_list = g_list_prepend (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) - { - char verb[BMK_VERB_FORMAT_LENGTH]; - char name[BMK_NAME_FORMAT_LENGTH]; - guint id; - - id = ephy_node_get_id ((EphyNode *) l->data); - - g_snprintf (verb, sizeof (verb), BMK_VERB_FORMAT, id); - g_snprintf (name, sizeof (name), BMK_NAME_FORMAT, id, phash); - - gtk_ui_manager_add_ui (p->manager, p->ui_id, path, - name, verb, - GTK_UI_MANAGER_MENUITEM, FALSE); - } - g_list_free (node_list); -} - -#define FOLDER_ACCEL_PATH_PREFIX "<Actions>/FolderActions/" - -static char * -create_submenu (EphyBookmarksMenu *menu, - EphyNode *topic) -{ - EphyBookmarksMenuPrivate *p = menu->priv; - GtkAction *action; - char verb[FOLDER_VERB_FORMAT_LENGTH]; - char apath[strlen (FOLDER_ACCEL_PATH_PREFIX) + FOLDER_VERB_FORMAT_LENGTH]; - const char *title; - char *folder; - char **folders; - GString *path; - guint phash, fhash; - int i; - - title = ephy_node_get_property_string (topic, EPHY_NODE_KEYWORD_PROP_NAME); - g_return_val_if_fail (title != NULL, NULL); - - folders = g_strsplit (title, BOOKMARKS_HIERARCHY_SEP, -1); - - /* occurs if topic name was "" or BOOKMARKS_HIERARCHY_SEP */ - if (folders == NULL || folders[0] == NULL) - { - g_strfreev (folders); - return g_strdup (p->path); - } - - path = g_string_new (p->path); - for (i = 0; folders[i] != NULL; i++) - { - folder = folders[i]; - - /* happens for BOOKMARKS_HIERARCHY_SEP at start/end of title, - * or when occurring twice in succession. - * Treat as if it didn't occur/only occurred once. - */ - if (folders[i][0] == '\0') continue; - - phash = g_str_hash (path->str); - fhash = g_str_hash (folder); - g_snprintf (verb, sizeof (verb), FOLDER_VERB_FORMAT, fhash, phash); + char *name; + long i; - if (gtk_action_group_get_action (p->folder_actions, verb) == NULL) + for (i = 0; i < bookmarks->len; i++) + { + name = ephy_bookmark_action_name (g_ptr_array_index (bookmarks, i)); + if (name) { - g_snprintf (apath, sizeof (apath), - FOLDER_ACCEL_PATH_PREFIX "%s", verb); - - action = g_object_new (GTK_TYPE_ACTION, - "name", verb, - "label", folder, - "hide_if_empty", FALSE, - NULL); - gtk_action_set_accel_path (action, apath); - - gtk_action_group_add_action (p->folder_actions, action); - g_object_unref (action); - - gtk_ui_manager_add_ui (p->manager, p->ui_id, path->str, - verb, verb, - GTK_UI_MANAGER_MENU, FALSE); + g_string_append_printf (string, "<menuitem action=\"%s\" name=\"%s-%d\"/>", + name, name, instance); + g_free (name); } - - g_string_append (path, "/"); - g_string_append (path, verb); } - - g_strfreev (folders); - - return g_string_free (path, FALSE); } +/* Build a menu of the given bookmarks categorised by the given topics. + * Shows categorisation using subdivisions, submenus, or a mix of both. */ static void -ephy_bookmarks_menu_rebuild (EphyBookmarksMenu *menu) +append_menu (GString *string, const GPtrArray *topics, const GPtrArray *bookmarks, guint flags) { - EphyBookmarksMenuPrivate *p = menu->priv; - EphyNode *topics, *not_categorized, *node; - GPtrArray *children; - GList *node_list = NULL, *l; - char *path; - int i; - - if (menu->priv->needs_update == FALSE) - { - LOG ("No update required"); + GPtrArray *uncovered; + guint i; - return; - } - - LOG ("Rebuilding bookmarks menu"); - - ephy_bookmarks_menu_clean (menu); - - START_PROFILER ("Rebuilding bookmarks menu") - - ensure_bookmark_actions (menu); - p->folder_actions = gtk_action_group_new ("FolderActions"); - gtk_ui_manager_insert_action_group (p->manager, p->folder_actions, -1); - - g_signal_connect (p->folder_actions, "connect-proxy", - G_CALLBACK (connect_proxy_cb), NULL); - - p->ui_id = gtk_ui_manager_new_merge_id (p->manager); - - topics = ephy_bookmarks_get_keywords (p->bookmarks); - children = ephy_node_get_children (topics); - - 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) + gboolean use_subdivis = flags & BUILD_SUBDIVIS; + gboolean use_submenus = flags & BUILD_SUBMENUS; + + if (use_subdivis || use_submenus) + { + GPtrArray *subset, *covering, *subdivisions, *submenus; + GArray *sizes = 0; + EphyNode *topic; + gint size, total; + gboolean separate = FALSE; + char *name; + + /* Get the subtopics, uncovered bookmarks, and subtopic sizes. */ + sizes = g_array_sized_new (FALSE, FALSE, sizeof(int), topics->len); + uncovered = g_ptr_array_sized_new (bookmarks->len); + covering = ephy_nodes_get_covering (topics, bookmarks, 0, uncovered, sizes); + + /* Preallocate arrays for submenus, subdivisions, and bookmark subsets. */ + subdivisions = g_ptr_array_sized_new (topics->len); + submenus = g_ptr_array_sized_new (topics->len); + subset = g_ptr_array_sized_new (bookmarks->len); + + /* Get the total number of items in the menu. */ + total = uncovered->len; + for (i = 0; i < covering->len; i++) + total += g_array_index (sizes, int, i); + + /* Seperate covering into list of submenus and subdivisions */ + for (i = 0; i < covering->len; i++) { - node_list = g_list_prepend (node_list, kid); + topic = g_ptr_array_index (covering, i); + size = g_array_index (sizes, int, i); + + if (!use_submenus || (use_subdivis && (size < MIN_MENU_SIZE || total < MAX_MENU_SIZE))) + { + g_ptr_array_add (subdivisions, topic); + } + else + { + g_ptr_array_add (submenus, topic); + total = total - size + 1; + } } - } - - node_list = g_list_sort (node_list, (GCompareFunc) sort_topics); - - for (l = node_list; l != NULL; l = l->next) - { - node = (EphyNode *) l->data; - - path = create_submenu (menu, node); - create_menu (menu, node, path); - g_free (path); - } - - not_categorized = ephy_bookmarks_get_not_categorized (p->bookmarks); - - if (ephy_node_get_n_children (not_categorized) > 0) - { - create_menu (menu, not_categorized, p->path); - } - - g_list_free (node_list); - - STOP_PROFILER ("Rebuilding bookmarks menu") - - menu->priv->needs_update = FALSE; -} - -static gboolean -do_update_cb (EphyBookmarksMenu *menu) -{ - LOG ("do_update_cb"); - - ephy_bookmarks_menu_rebuild (menu); - menu->priv->update_tag = 0; - - /* don't run again */ - return FALSE; -} - -static void -ephy_bookmarks_menu_maybe_update (EphyBookmarksMenu *menu) -{ - EphyNode *bookmarks; - GPtrArray *children; - - menu->priv->needs_update = TRUE; - - /* FIXME: is there any way that we get here while the menu is popped up? - * if so, needs to do_update NOW - */ - - /* if there are only a few bookmarks, update soon */ - bookmarks = ephy_bookmarks_get_bookmarks (menu->priv->bookmarks); - children = ephy_node_get_children (bookmarks); - if (children->len < GAZILLION) - { - if (menu->priv->update_tag == 0) + + /* Sort the list of submenus and subdivisions. */ + g_ptr_array_sort (submenus, ephy_bookmarks_compare_topic_pointers); + g_ptr_array_sort (subdivisions, ephy_bookmarks_compare_topic_pointers); + + if (flags & BUILD_CHILD_SUBDIVIS) flags |= BUILD_SUBDIVIS; + if (flags & BUILD_CHILD_SUBMENUS) flags |= BUILD_SUBMENUS; + + /* Create each of the submenus. */ + for (i = 0; i < submenus->len; i++) { - menu->priv->update_tag = - g_timeout_add (UPDATE_DELAY, - (GSourceFunc) do_update_cb, menu); + topic = g_ptr_array_index (submenus, i); + ephy_nodes_get_covered (topic, bookmarks, subset); + + name = ephy_topic_action_name (topic); + if (name) + { + g_string_append_printf (string, "<menu name=\"%s\" action=\"%s\">", + name, name); + append_menu (string, topics, subset, flags); + g_string_append (string, "</menu>"); + separate = TRUE; + g_free (name); + } } - } - else if (menu->priv->update_tag != 0) - { - /* remove scheduled update, update on demand */ - g_source_remove (menu->priv->update_tag); - menu->priv->update_tag = 0; - } -} - -static void -ephy_bookmarks_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyBookmarksMenu *menu = EPHY_BOOKMARKS_MENU (object); - - switch (prop_id) - { - case PROP_PATH: - menu->priv->path = g_value_dup_string (value); - break; - case PROP_UI_MANAGER: - menu->priv->manager = g_value_get_object (value); - break; - } -} - -static void -ephy_bookmarks_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - /* no readable properties */ - g_return_if_reached (); -} - -static void -bookmarks_tree_changed_cb (EphyBookmarks *bookmarks, - EphyBookmarksMenu *menu) -{ - LOG ("bookmarks_tree_changed_cb"); - - ephy_bookmarks_menu_maybe_update (menu); -} - -static void -topics_added_cb (EphyNode *keywords, - EphyNode *bmk, - EphyBookmarksMenu *menu) -{ - LOG ("topics_added_cb"); - - ephy_bookmarks_menu_maybe_update (menu); -} - -static void -topics_removed_cb (EphyNode *keywords, - EphyNode *child, - guint old_index, - EphyBookmarksMenu *menu) -{ - LOG ("topics_removed_cb"); - - ephy_bookmarks_menu_maybe_update (menu); -} - -static void -topic_child_changed_cb (EphyNode *node, - EphyNode *child, - guint property_id, - EphyBookmarksMenu *menu) -{ - LOG ("topic_child_changed_cb id=%d property=%d", - ephy_node_get_id (child), property_id); - - if (property_id == EPHY_NODE_KEYWORD_PROP_NAME) - { - /* the title of the topic has changed, which may change the - * hierarchy. - */ - ephy_bookmarks_menu_maybe_update (menu); - } -} - -static void -bookmark_added_cb (EphyNode *bookmarks, - EphyNode *bmk, - EphyBookmarksMenu *menu) -{ - LOG ("bookmark_added_cb id=%d", ephy_node_get_id (bmk)); - if (menu->priv->bmk_actions != NULL) - { - /* If the new bookmark has the node ID of one scheduled to - * be removed, remove the old one first then add new one. - * This works since the action name depends only on the - * node ID. See bug #154805. - */ - GSList *l; - - l = g_slist_find (menu->priv->removed_bmks, - GUINT_TO_POINTER (ephy_node_get_id (bmk))); - if (l != NULL) + /* Create each of the subdivisions. */ + for (i = 0; i < subdivisions->len; i++) { - remove_action (l->data, menu->priv->bmk_actions); - - menu->priv->removed_bmks = g_slist_delete_link - (menu->priv->removed_bmks, l); + topic = g_ptr_array_index (subdivisions, i); + ephy_nodes_get_covered (topic, bookmarks, subset); + g_ptr_array_sort (subset, ephy_bookmarks_compare_bookmark_pointers); + + if (separate) g_string_append (string, "<separator/>"); + append_bookmarks (string, subset, i+1); + separate = TRUE; } - add_action_for_bookmark (menu, bmk); - - ephy_bookmarks_menu_maybe_update (menu); + g_array_free (sizes, TRUE); + g_ptr_array_free (covering, TRUE); + g_ptr_array_free (subdivisions, TRUE); + g_ptr_array_free (submenus, TRUE); + g_ptr_array_free (subset, TRUE); + + if (separate && uncovered->len) g_string_append (string, "<separator/>"); } -} - -static void -bookmark_removed_cb (EphyNode *bookmarks, - EphyNode *bmk, - guint old_index, - EphyBookmarksMenu *menu) -{ - LOG ("bookmark_removed_cb id=%d", ephy_node_get_id (bmk)); - - if (menu->priv->bmk_actions != NULL) + else { - /* we cannot remove the action here since the menu might still - * reference it. - */ - menu->priv->removed_bmks = - g_slist_prepend (menu->priv->removed_bmks, - GUINT_TO_POINTER (ephy_node_get_id (bmk))); - - ephy_bookmarks_menu_maybe_update (menu); + uncovered = g_ptr_array_sized_new (bookmarks->len); + for (i = 0; i < bookmarks->len; i++) + g_ptr_array_add (uncovered, g_ptr_array_index (bookmarks, i)); + g_ptr_array_sort (uncovered, ephy_bookmarks_compare_bookmark_pointers); } + + /* Create the final subdivision (uncovered bookmarks). */ + g_ptr_array_sort (uncovered, ephy_bookmarks_compare_bookmark_pointers); + append_bookmarks (string, uncovered, 0); + g_ptr_array_free (uncovered, TRUE); } -static void -activate_cb (GtkAction *action, - EphyBookmarksMenu *menu) -{ - LOG ("activate_cb"); - - ephy_bookmarks_menu_rebuild (menu); -} - -static void -ephy_bookmarks_menu_init (EphyBookmarksMenu *menu) -{ - menu->priv = EPHY_BOOKMARKS_MENU_GET_PRIVATE (menu); -} - -static GObject * -ephy_bookmarks_menu_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_params) +void +ephy_bookmarks_menu_build (GString *string, EphyNode *parent) { - EphyBookmarksMenu *menu; - GObject *object; - GtkAction *action; + GPtrArray *children, *topics; + EphyBookmarks *eb; EphyNode *node; + gint priority; + guint flags, id, i; + + eb = ephy_shell_get_bookmarks (ephy_shell); - object = parent_class->constructor (type, n_construct_properties, - construct_params); - - menu = EPHY_BOOKMARKS_MENU (object); - - g_assert (menu->priv->manager != NULL && menu->priv->path != NULL); - - menu->priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell); - g_signal_connect_object (menu->priv->bookmarks, "tree_changed", - G_CALLBACK (bookmarks_tree_changed_cb), - menu, 0); - - node = ephy_bookmarks_get_keywords (menu->priv->bookmarks); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, - (EphyNodeCallback) topics_added_cb, - G_OBJECT (menu)); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) topics_removed_cb, - G_OBJECT (menu)); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, - (EphyNodeCallback) topic_child_changed_cb, - G_OBJECT (menu)); - - node = ephy_bookmarks_get_bookmarks (menu->priv->bookmarks); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, - (EphyNodeCallback) bookmark_added_cb, - G_OBJECT (menu)); - ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) bookmark_removed_cb, - G_OBJECT (menu)); - - action = gtk_ui_manager_get_action (menu->priv->manager, - menu->priv->path); - g_signal_connect_object (action, "activate", - G_CALLBACK (activate_cb), menu, 0); - - ephy_bookmarks_menu_maybe_update (menu); - - return object; -} - -static void -ephy_bookmarks_menu_finalize (GObject *o) -{ - EphyBookmarksMenu *menu = EPHY_BOOKMARKS_MENU (o); - EphyBookmarksMenuPrivate *p = menu->priv; - - if (menu->priv->update_tag != 0) + children = ephy_node_get_children (ephy_bookmarks_get_keywords (eb)); + topics = g_ptr_array_sized_new (children->len); + for (i = 0; i < children->len; i++) { - g_source_remove (menu->priv->update_tag); + node = g_ptr_array_index (children, i); + priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (priority == EPHY_NODE_NORMAL_PRIORITY) + g_ptr_array_add (topics, node); } - g_slist_free (menu->priv->removed_bmks); + /* If no parent was supplied, use the default 'All' */ + node = parent ? parent : ephy_bookmarks_get_bookmarks(eb); + children = ephy_node_get_children (node); - if (p->bmk_actions != NULL) - { - g_object_unref (p->bmk_actions); - } + /* Determine what kind of menu we want. */ + id = ephy_node_get_id (node); + switch(id) + { + case FAVORITES_NODE_ID: + flags = 0; + break; + case BOOKMARKS_NODE_ID: + flags = BUILD_SUBMENUS | BUILD_CHILD_SUBDIVIS; + break; + default: + flags = BUILD_SUBMENUS | BUILD_SUBDIVIS | BUILD_CHILD_SUBDIVIS; + /* flags = BUILD_SUBDIVIS; */ + break; + } - if (p->folder_actions != NULL) + /* Build the menu, and return the merge_id */ + append_menu (string, topics, children, flags); + g_ptr_array_free (topics, TRUE); + + /* Add a "Open in tabs" menu item if this menu isn't the 'All' menu. */ + if (id != BOOKMARKS_NODE_ID) { - g_object_unref (p->folder_actions); + char *name = ephy_open_tabs_action_name (node); + g_string_append_printf + (string, "<separator/><menuitem action=\"%s\" name=\"OpenTabs\"/>", name); + g_free (name); } - - g_free (p->path); - - LOG ("EphyBookmarksMenu finalised %p", o);; - - G_OBJECT_CLASS (parent_class)->finalize (o); -} - -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->constructor = ephy_bookmarks_menu_constructor; - 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_PATH, - g_param_spec_string ("path", - "Path", - "Merge path", - NULL, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_UI_MANAGER, - g_param_spec_object ("ui-manager", - "UI Manager", - "UI Manager", - GTK_TYPE_UI_MANAGER, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof (EphyBookmarksMenuPrivate)); -} - -EphyBookmarksMenu * -ephy_bookmarks_menu_new (GtkUIManager *manager, - const char *path) -{ - return EPHY_BOOKMARKS_MENU (g_object_new (EPHY_TYPE_BOOKMARKS_MENU, - "ui-manager", manager, - "path", path, - NULL)); } diff --git a/src/bookmarks/ephy-bookmarks-menu.h b/src/bookmarks/ephy-bookmarks-menu.h index 82a828b50..813d90805 100644 --- a/src/bookmarks/ephy-bookmarks-menu.h +++ b/src/bookmarks/ephy-bookmarks-menu.h @@ -23,40 +23,11 @@ #ifndef EPHY_BOOKMARKS_MENU_H #define EPHY_BOOKMARKS_MENU_H -#include <glib-object.h> -#include <gtk/gtkuimanager.h> +#include "ephy-window.h" +#include "ephy-node.h" -G_BEGIN_DECLS +#include <gtk/gtk.h> -#define EPHY_TYPE_BOOKMARKS_MENU (ephy_bookmarks_menu_get_type()) -#define EPHY_BOOKMARKS_MENU(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_BOOKMARKS_MENU, EphyBookmarksMenu)) -#define EPHY_BOOKMARKS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_BOOKMARKS_MENU, EphyBookmarksMenuClass)) -#define EPHY_IS_BOOKMARKS_MENU(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_BOOKMARKS_MENU)) -#define EPHY_IS_BOOKMARKS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_BOOKMARKS_MENU)) -#define EPHY_BOOKMARKS_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_BOOKMARKS_MENU, EphyBookmarksMenuClass)) - -typedef struct _EphyBookmarksMenu EphyBookmarksMenu; -typedef struct _EphyBookmarksMenuPrivate EphyBookmarksMenuPrivate; -typedef struct _EphyBookmarksMenuClass EphyBookmarksMenuClass; - -struct _EphyBookmarksMenuClass -{ - GObjectClass parent_class; -}; - -struct _EphyBookmarksMenu -{ - GObject parent_object; - - /*< private >*/ - EphyBookmarksMenuPrivate *priv; -}; - -GType ephy_bookmarks_menu_get_type (void); - -EphyBookmarksMenu *ephy_bookmarks_menu_new (GtkUIManager *manager, - const char *path); - -G_END_DECLS +void ephy_bookmarks_menu_build (GString *string, EphyNode *parent); #endif diff --git a/src/bookmarks/ephy-bookmarks-ui.c b/src/bookmarks/ephy-bookmarks-ui.c new file mode 100644 index 000000000..0b97a8fa8 --- /dev/null +++ b/src/bookmarks/ephy-bookmarks-ui.c @@ -0,0 +1,552 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#include "config.h" + +#include "ephy-bookmarks.h" +#include "ephy-bookmarks-ui.h" +#include "ephy-bookmarks-menu.h" +#include "ephy-bookmark-action.h" +#include "ephy-topic-action.h" +#include "ephy-bookmark-action-group.h" +#include "ephy-topic-action-group.h" +#include "ephy-related-action.h" +#include "ephy-open-tabs-action.h" +#include "ephy-topic-factory-action.h" +#include "ephy-bookmark-factory-action.h" +#include "ephy-node-common.h" +#include "ephy-link.h" +#include "ephy-dnd.h" +#include "ephy-history.h" +#include "ephy-shell.h" +#include "ephy-string.h" +#include "ephy-debug.h" +#include "ephy-file-helpers.h" + +#include <string.h> +#include <glib/gi18n.h> + +#define BM_WINDOW_DATA_KEY "bookmarks-window-data" + +typedef struct +{ + guint bookmarks_menu; + guint favorites_menu; +} BookmarksWindowData; + + + +static GString * bookmarks_menu_string = 0; +static GString * favorites_menu_string = 0; + +static GtkAction * +find_action (GtkUIManager *manager, const char *name) +{ + GList *l = gtk_ui_manager_get_action_groups (manager); + GtkAction *action; + + while (l != NULL) + { + action = gtk_action_group_get_action (GTK_ACTION_GROUP (l->data), name); + if (action) return action; + l = l->next; + } + + return NULL; +} + +static void +activate_bookmarks_menu (GtkAction *action, EphyWindow *window) +{ + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + if (data && !data->bookmarks_menu) + { + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + gtk_ui_manager_ensure_update (manager); + + if (!bookmarks_menu_string->len) + { + g_string_append (bookmarks_menu_string, + "<ui><menubar><menu name=\"BookmarksMenu\" action=\"Bookmarks\">"); + ephy_bookmarks_menu_build (bookmarks_menu_string, 0); + g_string_append (bookmarks_menu_string, "</menu></menubar></ui>"); + } + + data->bookmarks_menu = gtk_ui_manager_add_ui_from_string + (manager, bookmarks_menu_string->str, bookmarks_menu_string->len, 0); + + gtk_ui_manager_ensure_update (manager); + } +} + +static void +activate_favorites_menu (GtkAction *action, EphyWindow *window) +{ + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + if (data && !data->favorites_menu) + { + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + gtk_ui_manager_ensure_update (manager); + + if (!favorites_menu_string->len) + { + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *favorites = ephy_bookmarks_get_favorites (eb); + + g_string_append (favorites_menu_string, + "<ui><menubar><menu name=\"GoMenu\" action=\"Go\">"); + ephy_bookmarks_menu_build (favorites_menu_string, favorites); + g_string_append (favorites_menu_string, "</menu></menubar></ui>"); + } + + data->favorites_menu = gtk_ui_manager_add_ui_from_string + (manager, favorites_menu_string->str, favorites_menu_string->len, 0); + + gtk_ui_manager_ensure_update (manager); + } +} + +static void +erase_bookmarks_menu (EphyWindow *window) +{ + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + + if (data != NULL && data->bookmarks_menu != 0) + { + gtk_ui_manager_remove_ui (manager, data->bookmarks_menu); + data->bookmarks_menu = 0; + } + g_string_truncate (bookmarks_menu_string, 0); +} + +static void +erase_favorites_menu (EphyWindow *window) +{ + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + + if (data != NULL && data->favorites_menu != 0) + { + gtk_ui_manager_remove_ui (manager, data->favorites_menu); + data->favorites_menu = 0; + } + g_string_truncate (favorites_menu_string, 0); +} + +static void +tree_changed_cb (EphyBookmarks *bookmarks, EphyWindow *window) +{ + erase_bookmarks_menu (window); +} + +static void +node_added_cb (EphyNode *parent, EphyNode *child, EphyWindow *window) +{ + erase_bookmarks_menu (window); + erase_favorites_menu (window); +} + +static void +node_changed_cb (EphyNode *parent, EphyNode *child, guint property_id, EphyWindow *window) +{ + if (property_id == EPHY_NODE_KEYWORD_PROP_NAME || property_id == EPHY_NODE_BMK_PROP_TITLE) + { + erase_bookmarks_menu (window); + erase_favorites_menu (window); + } +} + +static void +node_removed_cb (EphyNode *parent, EphyNode *child, guint index, EphyWindow *window) +{ + erase_bookmarks_menu (window); + erase_favorites_menu (window); +} + +void +ephy_bookmarks_ui_attach_window (EphyWindow *window) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *bookmarks = ephy_bookmarks_get_bookmarks (eb); + EphyNode *topics = ephy_bookmarks_get_keywords (eb); + EphyNode *favorites = ephy_bookmarks_get_favorites (eb); + + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + GtkActionGroup *actions; + GtkAction *action; + + g_return_if_fail (data == 0); + data = g_new0 (BookmarksWindowData, 1); + g_object_set_data_full (G_OBJECT (window), BM_WINDOW_DATA_KEY, data, g_free); + + actions = ephy_bookmark_group_new (bookmarks); + gtk_ui_manager_insert_action_group (manager, actions, 0); + g_signal_connect_swapped (G_OBJECT (actions), "open-link", + G_CALLBACK (ephy_link_open), G_OBJECT (window)); + g_object_unref (G_OBJECT (actions)); + + actions = ephy_topic_group_new (topics, manager); + gtk_ui_manager_insert_action_group (manager, actions, 0); + g_object_unref (G_OBJECT (actions)); + + actions = ephy_open_tabs_group_new (topics); + gtk_ui_manager_insert_action_group (manager, actions, 0); + g_signal_connect_swapped (G_OBJECT (actions), "open-link", + G_CALLBACK (ephy_link_open), G_OBJECT (window)); + g_object_unref (G_OBJECT (actions)); + + actions = gtk_action_group_new ("BookmarkToolbarActions"); + + action = ephy_topic_factory_action_new ("AddTopicToToolbar"); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + + action = ephy_bookmark_factory_action_new ("AddBookmarkToToolbar"); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + + action = ephy_related_action_new (EPHY_LINK (window), manager, "RelatedTopic"); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + + gtk_ui_manager_insert_action_group (manager, actions, 0); + g_object_unref (G_OBJECT (actions)); + + + ephy_node_signal_connect_object (bookmarks, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + ephy_node_signal_connect_object (topics, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + ephy_node_signal_connect_object (favorites, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + + ephy_node_signal_connect_object (bookmarks, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + ephy_node_signal_connect_object (topics, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + ephy_node_signal_connect_object (favorites, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + + ephy_node_signal_connect_object (bookmarks, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + G_OBJECT (window)); + ephy_node_signal_connect_object (topics, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + G_OBJECT (window)); + + g_signal_connect_object (G_OBJECT (eb), "tree_changed", + G_CALLBACK (tree_changed_cb), + G_OBJECT (window), 0); + + /* Build menus on demand. */ + if (!favorites_menu_string) favorites_menu_string = g_string_new (""); + if (!bookmarks_menu_string) bookmarks_menu_string = g_string_new (""); + action = find_action (manager, "Bookmarks"); + g_signal_connect_object (G_OBJECT (action), "activate", + G_CALLBACK (activate_bookmarks_menu), + G_OBJECT (window), 0); + action = find_action (manager, "Go"); + g_signal_connect_object (G_OBJECT (action), "activate", + G_CALLBACK (activate_favorites_menu), + G_OBJECT (window), 0); +} + +void +ephy_bookmarks_ui_detach_window (EphyWindow *window) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *bookmarks = ephy_bookmarks_get_bookmarks (eb); + EphyNode *topics = ephy_bookmarks_get_keywords (eb); + EphyNode *favorites = ephy_bookmarks_get_favorites (eb); + + BookmarksWindowData *data = g_object_get_data (G_OBJECT (window), BM_WINDOW_DATA_KEY); + GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); + GtkAction *action; + + g_return_if_fail (data != 0); + if (data->bookmarks_menu) gtk_ui_manager_remove_ui (manager, data->bookmarks_menu); + if (data->favorites_menu) gtk_ui_manager_remove_ui (manager, data->favorites_menu); + g_object_set_data (G_OBJECT (window), BM_WINDOW_DATA_KEY, 0); + + ephy_node_signal_disconnect_object (bookmarks, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + ephy_node_signal_disconnect_object (topics, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + ephy_node_signal_disconnect_object (favorites, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + G_OBJECT (window)); + + ephy_node_signal_disconnect_object (bookmarks, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + ephy_node_signal_disconnect_object (topics, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + ephy_node_signal_disconnect_object (favorites, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + G_OBJECT (window)); + + ephy_node_signal_disconnect_object (bookmarks, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + G_OBJECT (window)); + ephy_node_signal_disconnect_object (topics, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + G_OBJECT (window)); + + g_signal_handlers_disconnect_by_func + (G_OBJECT (eb), G_CALLBACK (tree_changed_cb), G_OBJECT (window)); + + action = find_action (manager, "Bookmarks"); + g_signal_handlers_disconnect_by_func + (G_OBJECT (action), G_CALLBACK (activate_bookmarks_menu), G_OBJECT (window)); + + action = find_action (manager, "Go"); + g_signal_handlers_disconnect_by_func + (G_OBJECT (action), G_CALLBACK (activate_favorites_menu), G_OBJECT (window)); +} + +static void +toolbar_node_removed_cb (EphyNode *parent, EphyNode *child, guint index, EggToolbarsModel *model) +{ + gint i, j; + char *nid = NULL; + const char *id; + + switch (ephy_node_get_id (parent)) + { + case BOOKMARKS_NODE_ID: + nid = ephy_bookmark_action_name (child); + break; + case KEYWORDS_NODE_ID: + nid = ephy_topic_action_name (child); + break; + default: + return; + } + + for (i=egg_toolbars_model_n_toolbars(model)-1; i>=0; i--) + for (j=egg_toolbars_model_n_items(model, i)-1; j>=0; j--) + { + id = egg_toolbars_model_item_nth (model, i, j); + if (!strcmp (id, nid)) + { + egg_toolbars_model_remove_item (model, i, j); + } + } + + free (nid); +} + +/* Below this line we have functions relating to toolbar code */ + +static EggToolbarsItemType bookmark_type; +static EggToolbarsItemType topic_type; +static EphyBookmarks *eb; + +static gboolean +topic_has_data (EggToolbarsItemType *type, + const char *name) +{ + EphyNode *node, *topics; + guint node_id; + + if (sscanf (name, "OpenTopic%u", &node_id) != 1 || + sscanf (name, "Tpc%u", &node_id) != 1) return FALSE; + node = ephy_bookmarks_get_from_id (eb, node_id); + if (!node) return FALSE; + topics = ephy_bookmarks_get_keywords (eb); + return ephy_node_has_child (topics, node); +} + +static char * +topic_get_data (EggToolbarsItemType *type, + const char *name) +{ + EphyNode *node; + guint node_id; + + if (sscanf (name, "OpenTopic%u", &node_id) != 1 || + sscanf (name, "Tpc%u", &node_id) != 1) return NULL; + node = ephy_bookmarks_get_from_id (eb, node_id); + if (!node) return NULL; + return ephy_bookmarks_get_topic_uri (eb, node); +} + +static char * +topic_get_name (EggToolbarsItemType *type, + const char *name) +{ + EphyNode *topic = ephy_bookmarks_find_keyword (eb, name, FALSE); + if (topic == NULL) return NULL; + return ephy_topic_action_name (topic); +} + + +static gboolean +bookmark_has_data (EggToolbarsItemType *type, + const char *name) +{ + EphyNode *node; + guint node_id; + + if (sscanf (name, "OpenBmk%u", &node_id) != 1 || + sscanf (name, "Bmk%u", &node_id) != 1) return FALSE; + node = ephy_bookmarks_get_from_id (eb, node_id); + if (!node) return FALSE; + + return (ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION) != NULL); +} + +static char * +bookmark_get_data (EggToolbarsItemType *type, + const char *name) +{ + EphyNode *node; + guint node_id; + + if (sscanf (name, "OpenBmk%u", &node_id) != 1 || + sscanf (name, "Bmk%u", &node_id) != 1) return NULL; + node = ephy_bookmarks_get_from_id (eb, node_id); + if (!node) return NULL; + + return g_strdup (ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION)); +} + +static char * +bookmark_get_name (EggToolbarsItemType *type, + const char *data) +{ + EphyNode *node; + gchar **netscape_url; + + netscape_url = g_strsplit (data, "\n", 2); + if (!netscape_url || !netscape_url[0]) + { + g_strfreev (netscape_url); + return NULL; + } + + node = ephy_bookmarks_find_bookmark (eb, netscape_url[0]); + g_strfreev (netscape_url); + + if (!node) return NULL; + return ephy_bookmark_action_name (node); +} + +static char * +bookmark_new_name (EggToolbarsItemType *type, + const char *data) +{ + EphyHistory *gh; + EphyNode *node; + gchar **netscape_url; + const char *icon; + const char *title; + + netscape_url = g_strsplit (data, "\n", 2); + if (!netscape_url || !netscape_url[0]) + { + g_strfreev (netscape_url); + return NULL; + } + + title = netscape_url[1]; + if (title == NULL || title[0] == '\0') + { + title = _("Untitled"); + } + + node = ephy_bookmarks_add (eb, title, netscape_url[0]); + + if (node != NULL) + { + gh = EPHY_HISTORY (ephy_embed_shell_get_global_history (embed_shell)); + icon = ephy_history_get_icon (gh, netscape_url[0]); + + if (icon) + { + ephy_bookmarks_set_icon (eb, netscape_url[0], icon); + } + } + + g_strfreev (netscape_url); + + return ephy_bookmark_action_name (node); +} + +void +ephy_bookmarks_ui_attach_toolbar_model (EggToolbarsModel *model) +{ + eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *bookmarks = ephy_bookmarks_get_bookmarks (eb); + EphyNode *topics = ephy_bookmarks_get_keywords (eb); + GList *types = egg_toolbars_model_get_types (model); + + topic_type.type = gdk_atom_intern (EPHY_DND_TOPIC_TYPE, TRUE); + topic_type.has_data = topic_has_data; + topic_type.get_data = topic_get_data; + topic_type.new_name = NULL; + topic_type.get_name = topic_get_name; + + bookmark_type.type = gdk_atom_intern (EPHY_DND_URL_TYPE, TRUE); + bookmark_type.has_data = bookmark_has_data; + bookmark_type.get_data = bookmark_get_data; + bookmark_type.new_name = bookmark_new_name; + bookmark_type.get_name = bookmark_get_name; + + types = g_list_prepend (types, &bookmark_type); + types = g_list_prepend (types, &topic_type); + egg_toolbars_model_set_types (model, types); + + ephy_node_signal_connect_object (bookmarks, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)toolbar_node_removed_cb, + G_OBJECT (model)); + ephy_node_signal_connect_object (topics, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)toolbar_node_removed_cb, + G_OBJECT (model)); + + egg_toolbars_model_set_n_avail (model, "AddTopicToToolbar", G_MAXINT); + egg_toolbars_model_set_n_avail (model, "AddBookmarkToToolbar", G_MAXINT); + egg_toolbars_model_set_n_avail (model, "RelatedTopic", 1); +} + + +void +ephy_bookmarks_ui_detach_toolbar_model (EggToolbarsModel *model) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *bookmarks = ephy_bookmarks_get_bookmarks (eb); + EphyNode *topics = ephy_bookmarks_get_keywords (eb); + + ephy_node_signal_disconnect_object (bookmarks, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)toolbar_node_removed_cb, + G_OBJECT (model)); + ephy_node_signal_disconnect_object (topics, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)toolbar_node_removed_cb, + G_OBJECT (model)); +} diff --git a/src/bookmarks/ephy-bookmarks-ui.h b/src/bookmarks/ephy-bookmarks-ui.h new file mode 100644 index 000000000..084b37eea --- /dev/null +++ b/src/bookmarks/ephy-bookmarks-ui.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#ifndef EPHY_BOOKMARKS_UI_H +#define EPHY_BOOKMARKS_UI_H + +#include "ephy-window.h" +#include "egg-toolbars-model.h" + +#include <gtk/gtk.h> + +void ephy_bookmarks_ui_attach_window (EphyWindow *window); +void ephy_bookmarks_ui_detach_window (EphyWindow *window); + +void ephy_bookmarks_ui_attach_toolbar_model (EggToolbarsModel *model); +void ephy_bookmarks_ui_detach_toolbar_model (EggToolbarsModel *model); + +#endif diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c index c6435e40d..4e661a497 100644 --- a/src/bookmarks/ephy-bookmarks.c +++ b/src/bookmarks/ephy-bookmarks.c @@ -30,7 +30,6 @@ #include "ephy-debug.h" #include "ephy-tree-model-node.h" #include "ephy-node-common.h" -#include "ephy-bookmarksbar-model.h" #include "ephy-bookmarks-export.h" #include "ephy-bookmarks-import.h" #include "ephy-bookmark-properties.h" @@ -58,7 +57,6 @@ struct _EphyBookmarksPrivate { - EphyBookmarksBarModel *toolbars_model; gboolean init_defaults; gboolean dirty; guint save_timeout_id; @@ -110,12 +108,6 @@ static const char *default_topics [] = }; static int n_default_topics = G_N_ELEMENTS (default_topics); -enum -{ - PROP_0, - PROP_TOOLBARS_MODEL -}; - /* Signals */ enum { @@ -136,33 +128,33 @@ static GObjectClass *parent_class = NULL; GType ephy_bookmarks_get_type (void) { - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo our_info = - { - sizeof (EphyBookmarksClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_bookmarks_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphyBookmarks), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_bookmarks_init - }; + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyBookmarksClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_bookmarks_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyBookmarks), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_bookmarks_init + }; volatile GType flags_type; /* work around gcc's optimiser */ /* make sure the flags type is known */ flags_type = EPHY_TYPE_BOOKMARK_PROPERTY; - type = g_type_register_static (G_TYPE_OBJECT, + type = g_type_register_static (G_TYPE_OBJECT, "EphyBookmarks", &our_info, 0); - } + } - return type; + return type; } static void @@ -180,126 +172,18 @@ ephy_bookmarks_init_defaults (EphyBookmarks *eb) EphyNode *bmk; bmk = ephy_bookmarks_add (eb, _(default_bookmarks[i].title), - _(default_bookmarks[i].location)); - ephy_bookmarksbar_model_add_bookmark (eb->priv->toolbars_model, FALSE, - ephy_node_get_id (bmk)); - } -} - -static char * -get_item_type_forward_cb (EggToolbarsModel *model, - GdkAtom type, - EggToolbarsModel *bookmarksbar_model) -{ - char *retval; - - g_signal_emit_by_name (bookmarksbar_model, "get_item_type", - type, &retval); - - return retval; -} - -static char * -get_item_id_forward_cb (EggToolbarsModel *model, - const char *type, - const char *name, - EggToolbarsModel *bookmarksbar_model) -{ - char *retval; - - g_signal_emit_by_name (bookmarksbar_model, "get_item_id", - type, name, &retval); - - return retval; -} - -static char * -get_item_data_forward_cb (EggToolbarsModel *model, - const char *type, - const char *id, - EggToolbarsModel *bookmarksbar_model) -{ - char *retval; - - g_signal_emit_by_name (bookmarksbar_model, "get_item_data", - type, id, &retval); - - return retval; -} - -GObject * -ephy_bookmarks_get_toolbars_model (EphyBookmarks *eb) -{ - g_return_val_if_fail (EPHY_IS_BOOKMARKS (eb), NULL); - - LOG ("ephy_bookmarks_get_toolbars_model"); - - if (eb->priv->toolbars_model == NULL) - { - GObject *toolbars_model; - - eb->priv->toolbars_model = EPHY_BOOKMARKSBAR_MODEL - (ephy_bookmarksbar_model_new (eb)); - - /* forward those signals, so that bookmarks can also be on the main model */ - toolbars_model = ephy_shell_get_toolbars_model (ephy_shell, FALSE); - - g_signal_connect_after (toolbars_model, "get_item_type", - G_CALLBACK (get_item_type_forward_cb), - eb->priv->toolbars_model); - g_signal_connect_after (toolbars_model, "get_item_id", - G_CALLBACK (get_item_id_forward_cb), - eb->priv->toolbars_model); - g_signal_connect_after (toolbars_model, "get_item_data", - G_CALLBACK (get_item_data_forward_cb), - eb->priv->toolbars_model); - - if (eb->priv->init_defaults) - { - ephy_bookmarks_init_defaults (eb); - } + _(default_bookmarks[i].location)); } - - return G_OBJECT (eb->priv->toolbars_model); } static void -ephy_bookmarks_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - /* no writable properties */ - g_assert_not_reached (); -} - -static void -ephy_bookmarks_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EphyBookmarks *eb = EPHY_BOOKMARKS (object); - - switch (prop_id) - { - case PROP_TOOLBARS_MODEL: - g_value_set_object (value, ephy_bookmarks_get_toolbars_model (eb)); - break; - } -} - - -static void ephy_bookmarks_class_init (EphyBookmarksClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); + parent_class = g_type_class_peek_parent (klass); - object_class->finalize = ephy_bookmarks_finalize; - object_class->set_property = ephy_bookmarks_set_property; - object_class->get_property = ephy_bookmarks_get_property; + object_class->finalize = ephy_bookmarks_finalize; klass->resolve_address = impl_resolve_address; @@ -325,14 +209,6 @@ ephy_bookmarks_class_init (EphyBookmarksClass *klass) G_TYPE_STRING, G_TYPE_STRING); - g_object_class_install_property (object_class, - PROP_TOOLBARS_MODEL, - g_param_spec_object ("toolbars-model", - "Toolbars model", - "Toolbars model", - EPHY_TYPE_BOOKMARKSBAR_MODEL, - G_PARAM_READABLE)); - g_type_class_add_private (object_class, sizeof(EphyBookmarksPrivate)); } @@ -408,7 +284,7 @@ ephy_bookmarks_save_delayed (EphyBookmarks *bookmarks, int delay) { bookmarks->priv->save_timeout_id = g_timeout_add (BOOKMARKS_SAVE_DELAY, - (GSourceFunc) save_bookmarks_delayed, + (GSourceFunc) save_bookmarks_delayed, bookmarks); } else @@ -485,7 +361,7 @@ add_to_favorites (EphyBookmarks *eb, EphyNode *node, EphyHistory *eh) if (eb->priv->lower_fav && full_menu) { ephy_node_remove_child (eb->priv->favorites, - eb->priv->lower_fav); + eb->priv->lower_fav); } ephy_node_add_child (eb->priv->favorites, node); @@ -692,7 +568,7 @@ update_bookmark_keywords (EphyBookmarks *eb, EphyNode *bookmark) g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, case_normalized_keywords); ephy_node_set_property (bookmark, EPHY_NODE_BMK_PROP_KEYWORDS, - &value); + &value); g_value_unset (&value); g_string_free (list, TRUE); @@ -998,30 +874,30 @@ ephy_bookmarks_init (EphyBookmarks *eb) /* Translators: this topic contains all bookmarks */ g_value_set_string (&value, Q_("bookmarks|All")); ephy_node_set_property (eb->priv->bookmarks, - EPHY_NODE_KEYWORD_PROP_NAME, - &value); + EPHY_NODE_KEYWORD_PROP_NAME, + &value); g_value_unset (&value); ephy_node_signal_connect_object (eb->priv->bookmarks, - EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) bookmarks_removed_cb, - G_OBJECT (eb)); + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) bookmarks_removed_cb, + G_OBJECT (eb)); ephy_node_signal_connect_object (eb->priv->bookmarks, - EPHY_NODE_CHILD_CHANGED, - (EphyNodeCallback) bookmarks_changed_cb, - G_OBJECT (eb)); + EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback) bookmarks_changed_cb, + G_OBJECT (eb)); /* Keywords */ eb->priv->keywords = ephy_node_new_with_id (db, KEYWORDS_NODE_ID); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, EPHY_NODE_ALL_PRIORITY); ephy_node_set_property (eb->priv->bookmarks, - EPHY_NODE_KEYWORD_PROP_PRIORITY, - &value); + EPHY_NODE_KEYWORD_PROP_PRIORITY, + &value); g_value_unset (&value); ephy_node_signal_connect_object (eb->priv->keywords, - EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) topics_removed_cb, - G_OBJECT (eb)); + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) topics_removed_cb, + G_OBJECT (eb)); ephy_node_add_child (eb->priv->keywords, eb->priv->bookmarks); @@ -1034,8 +910,8 @@ ephy_bookmarks_init (EphyBookmarks *eb) /* Translators: this topic contains the most used bookmarks */ g_value_set_string (&value, Q_("bookmarks|Most Visited")); ephy_node_set_property (eb->priv->favorites, - EPHY_NODE_KEYWORD_PROP_NAME, - &value); + EPHY_NODE_KEYWORD_PROP_NAME, + &value); g_value_unset (&value); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, EPHY_NODE_SPECIAL_PRIORITY); @@ -1053,8 +929,8 @@ ephy_bookmarks_init (EphyBookmarks *eb) /* Translators: this topic contains the not categorized bookmarks */ g_value_set_string (&value, Q_("bookmarks|Not Categorized")); ephy_node_set_property (eb->priv->notcategorized, - EPHY_NODE_KEYWORD_PROP_NAME, - &value); + EPHY_NODE_KEYWORD_PROP_NAME, + &value); g_value_unset (&value); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, EPHY_NODE_SPECIAL_PRIORITY); @@ -1120,6 +996,11 @@ ephy_bookmarks_init (EphyBookmarks *eb) eb->priv->init_defaults = TRUE; } } + + if (eb->priv->init_defaults) + { + ephy_bookmarks_init_defaults (eb); + } eb->priv->disable_bookmark_editing_notifier_id = eel_gconf_notification_add (CONF_LOCKDOWN_DISABLE_BOOKMARK_EDITING, @@ -1150,13 +1031,6 @@ ephy_bookmarks_finalize (GObject *object) ephy_bookmarks_save (eb); - /* have to do this before unreffing the nodes */ - LOG ("Unref bookmarks toolbars model"); - if (eb->priv->toolbars_model != NULL) - { - g_object_unref (eb->priv->toolbars_model); - } - ephy_node_unref (eb->priv->bookmarks); ephy_node_unref (eb->priv->keywords); ephy_node_unref (eb->priv->favorites); @@ -1236,13 +1110,13 @@ ephy_bookmarks_add (EphyBookmarks *eb, g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, title); ephy_node_set_property (bm, EPHY_NODE_BMK_PROP_TITLE, - &value); + &value); g_value_unset (&value); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, url); ephy_node_set_property (bm, EPHY_NODE_BMK_PROP_LOCATION, - &value); + &value); g_value_unset (&value); update_has_smart_address (eb, bm, url); @@ -1266,7 +1140,7 @@ ephy_bookmarks_set_address (EphyBookmarks *eb, g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, address); ephy_node_set_property (bookmark, EPHY_NODE_BMK_PROP_LOCATION, - &value); + &value); g_value_unset (&value); update_has_smart_address (eb, bookmark, address); @@ -1318,7 +1192,7 @@ ephy_bookmarks_set_icon (EphyBookmarks *eb, g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, icon); ephy_node_set_property (node, EPHY_NODE_BMK_PROP_ICON, - &value); + &value); g_value_unset (&value); } @@ -1468,13 +1342,13 @@ ephy_bookmarks_add_keyword (EphyBookmarks *eb, g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, name); ephy_node_set_property (key, EPHY_NODE_KEYWORD_PROP_NAME, - &value); + &value); g_value_unset (&value); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, EPHY_NODE_NORMAL_PRIORITY); ephy_node_set_property (key, EPHY_NODE_KEYWORD_PROP_PRIORITY, - &value); + &value); g_value_unset (&value); ephy_node_add_child (eb->priv->keywords, key); @@ -1504,7 +1378,7 @@ bookmark_destroyed_cb (EphyNode *bookmark, GtkWidget * ephy_bookmarks_show_bookmark_properties (EphyBookmarks *bookmarks, EphyNode *bookmark, - GtkWidget *parent) + GtkWidget *parent) { GtkWidget *dialog = NULL; @@ -1734,3 +1608,60 @@ ephy_bookmarks_get_from_id (EphyBookmarks *eb, long id) { return ephy_node_db_get_node_from_id (eb->priv->db, id); } + +int +ephy_bookmarks_compare_topics (gconstpointer a, gconstpointer b) +{ + EphyNode *node_a = (EphyNode *)a; + EphyNode *node_b = (EphyNode *)b; + const char *title1, *title2; + int priority1, priority2; + + priority1 = ephy_node_get_property_int (node_a, EPHY_NODE_KEYWORD_PROP_PRIORITY); + priority2 = ephy_node_get_property_int (node_b, EPHY_NODE_KEYWORD_PROP_PRIORITY); + + if (priority1 > priority2) return 1; + if (priority1 < priority2) return -1; + + title1 = ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME); + title2 = ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME); + + if (title1 == title2) return 0; + if (title1 == NULL) return -1; + if (title2 == NULL) return 1; + return g_utf8_collate (title1, title2); +} + +int +ephy_bookmarks_compare_topic_pointers (gconstpointer a, gconstpointer b) +{ + EphyNode *node_a = *(EphyNode **)a; + EphyNode *node_b = *(EphyNode **)b; + + return ephy_bookmarks_compare_topics (node_a, node_b); +} + +int +ephy_bookmarks_compare_bookmarks (gconstpointer a, gconstpointer b) +{ + EphyNode *node_a = (EphyNode *)a; + EphyNode *node_b = (EphyNode *)b; + const char *title1, *title2; + + title1 = ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE); + title2 = ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE); + + if (title1 == title2) return 0; + if (title1 == NULL) return -1; + if (title2 == NULL) return 1; + return g_utf8_collate (title1, title2); +} + +int +ephy_bookmarks_compare_bookmark_pointers (gconstpointer a, gconstpointer b) +{ + EphyNode *node_a = *(EphyNode **)a; + EphyNode *node_b = *(EphyNode **)b; + + return ephy_bookmarks_compare_bookmarks (node_a, node_b); +} diff --git a/src/bookmarks/ephy-bookmarks.h b/src/bookmarks/ephy-bookmarks.h index cae6b82ba..3322cd3b7 100644 --- a/src/bookmarks/ephy-bookmarks.h +++ b/src/bookmarks/ephy-bookmarks.h @@ -78,8 +78,6 @@ EphyBookmarks *ephy_bookmarks_new (void); EphyNode *ephy_bookmarks_get_from_id (EphyBookmarks *eb, long id); -GObject *ephy_bookmarks_get_toolbars_model (EphyBookmarks *eb); - /* Bookmarks */ EphyNode *ephy_bookmarks_add (EphyBookmarks *eb, @@ -151,6 +149,12 @@ EphyNode *ephy_bookmarks_get_smart_bookmarks (EphyBookmarks *eb); EphyNode *ephy_bookmarks_get_local (EphyBookmarks *eb); +/* Comparison functions, useful for sorting lists and arrays. */ +int ephy_bookmarks_compare_topics (gconstpointer a, gconstpointer b); +int ephy_bookmarks_compare_topic_pointers (gconstpointer a, gconstpointer b); +int ephy_bookmarks_compare_bookmarks (gconstpointer a, gconstpointer b); +int ephy_bookmarks_compare_bookmark_pointers (gconstpointer a, gconstpointer b); + G_END_DECLS #endif diff --git a/src/bookmarks/ephy-bookmarksbar-model.c b/src/bookmarks/ephy-bookmarksbar-model.c deleted file mode 100755 index 13928950e..000000000 --- a/src/bookmarks/ephy-bookmarksbar-model.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (C) 2003-2004 Marco Pesenti Gritti - * Copyright (C) 2003-2004 Christian Persch - * - * 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. - * - * $Id$ - */ - -#include "config.h" - -#include "ephy-bookmarksbar-model.h" -#include "ephy-bookmarks.h" -#include "ephy-dnd.h" -#include "ephy-node-common.h" -#include "ephy-file-helpers.h" -#include "ephy-history.h" -#include "ephy-shell.h" -#include "ephy-string.h" -#include "ephy-debug.h" - -#include <string.h> -#include <glib/gi18n.h> - -#define EPHY_BOOKMARKSBARS_XML_FILE "epiphany-bookmarksbar.xml" -#define EPHY_BOOKMARKSBARS_XML_VERSION "1.0" - -enum -{ - PROP_0, - PROP_BOOKMARKS -}; - -enum -{ - URL, - NAME -}; - -#define EPHY_BOOKMARKSBAR_MODEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARKSBAR_MODEL, EphyBookmarksBarModelPrivate)) - -struct _EphyBookmarksBarModelPrivate -{ - EphyBookmarks *bookmarks; - char *xml_file; - guint timeout; -}; - -static void ephy_bookmarksbar_model_class_init (EphyBookmarksBarModelClass *klass); -static void ephy_bookmarksbar_model_init (EphyBookmarksBarModel *t); - -static GObjectClass *parent_class = NULL; - -GType -ephy_bookmarksbar_model_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo our_info = { - sizeof (EphyBookmarksBarModelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_bookmarksbar_model_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphyBookmarksBarModel), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_bookmarksbar_model_init - }; - - type = g_type_register_static (EGG_TYPE_TOOLBARS_MODEL, - "EphyBookmarksBarModel", - &our_info, 0); - } - - return type; -} - -static gboolean -get_toolbar_and_item_pos (EphyBookmarksBarModel *model, - const char *name, - int *toolbar, - int *position) -{ - EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); - int n_toolbars, n_items; - int t,i; - - n_toolbars = egg_toolbars_model_n_toolbars (eggmodel); - - for (t = 0; t < n_toolbars; t++) - { - n_items = egg_toolbars_model_n_items (eggmodel, t); - - for (i = 0; i < n_items; i++) - { - const char *i_name; - gboolean is_separator; - - egg_toolbars_model_item_nth (EGG_TOOLBARS_MODEL (model), - t , i, &is_separator, &i_name, NULL); - g_return_val_if_fail (i_name != NULL, FALSE); - - if (strcmp (i_name, name) == 0) - { - if (toolbar) *toolbar = t; - if (position) *position = i; - - return TRUE; - } - } - } - - return FALSE; -} - -static int -get_toolbar_pos (EphyBookmarksBarModel *model, - const char *name) -{ - EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); - int i, n_toolbars; - - n_toolbars = egg_toolbars_model_n_toolbars (eggmodel); - - for (i = 0; i < n_toolbars; i++) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (eggmodel, i); - if (strcmp (name, t_name) == 0) - { - return i; - } - } - - return -1; -} - -char * -ephy_bookmarksbar_model_get_action_name (EphyBookmarksBarModel *model, - long id) -{ - return g_strdup_printf ("GoBookmark-%ld", id); -} - -EphyNode * -ephy_bookmarksbar_model_get_node (EphyBookmarksBarModel *model, - const char *action_name) -{ - EphyBookmarks *bookmarks = EPHY_BOOKMARKSBAR_MODEL (model)->priv->bookmarks; - unsigned long node_id; - - if (!ephy_string_to_int (action_name + strlen ("GoBookmark-"), &node_id)) - { - return NULL; - } - - return ephy_bookmarks_get_from_id (bookmarks, node_id); -} - -void -ephy_bookmarksbar_model_add_bookmark (EphyBookmarksBarModel *model, - gboolean topic, - long id) -{ - char *name; - int toolbar_position; - - toolbar_position = get_toolbar_pos (model, "BookmarksBar"); - g_return_if_fail (toolbar_position != -1); - - name = ephy_bookmarksbar_model_get_action_name (model, id); - egg_toolbars_model_add_item (EGG_TOOLBARS_MODEL (model), - toolbar_position, -1, name, - topic ? EPHY_DND_TOPIC_TYPE : - EPHY_DND_URL_TYPE); - g_free (name); -} - -void -ephy_bookmarksbar_model_remove_bookmark (EphyBookmarksBarModel *model, - long id) -{ - char *action_name; - int toolbar, position; - - action_name = ephy_bookmarksbar_model_get_action_name (model, id); - g_return_if_fail (action_name != NULL); - - while (get_toolbar_and_item_pos (model, action_name, &toolbar, &position)) - { - egg_toolbars_model_remove_item (EGG_TOOLBARS_MODEL (model), - toolbar, position); - } - - g_free (action_name); -} - -gboolean -ephy_bookmarksbar_model_has_bookmark (EphyBookmarksBarModel *model, - long id) -{ - char *action_name; - gboolean found; - int toolbar, pos; - - action_name = ephy_bookmarksbar_model_get_action_name (model, id); - g_return_val_if_fail (action_name != NULL, FALSE); - - found = get_toolbar_and_item_pos (model, action_name, &toolbar, &pos); - - g_free (action_name); - - return found; -} - -static gboolean -save_changes_idle (EphyBookmarksBarModel *model) -{ - LOG ("Saving bookmarks toolbars model"); - - egg_toolbars_model_save - (EGG_TOOLBARS_MODEL (model), - model->priv->xml_file, - EPHY_BOOKMARKSBARS_XML_VERSION); - - model->priv->timeout = 0; - - /* don't run again */ - return FALSE; -} - -static void -save_changes (EphyBookmarksBarModel *model) -{ - if (model->priv->timeout == 0) - { - model->priv->timeout = - g_idle_add ((GSourceFunc) save_changes_idle, model); - } -} - -static void -update_flags_and_save_changes (EphyBookmarksBarModel *model) -{ - EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); - int i, n_toolbars; - int flag = 0; - - n_toolbars = egg_toolbars_model_n_toolbars (eggmodel); - - if (n_toolbars <= 1) - { - flag = EGG_TB_MODEL_NOT_REMOVABLE; - } - - for (i = 0; i < n_toolbars; i++) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (eggmodel, i); - g_return_if_fail (t_name != NULL); - - egg_toolbars_model_set_flags (eggmodel, i, flag); - } - - save_changes (model); -} - -static void -item_added_cb (EphyBookmarksBarModel *model, - int toolbar_position, - int position) -{ - save_changes (model); -} - -static char * -impl_get_item_type (EggToolbarsModel *model, - GdkAtom type) -{ - if (gdk_atom_intern (EPHY_DND_TOPIC_TYPE, FALSE) == type) - { - return g_strdup (EPHY_DND_TOPIC_TYPE); - } - else if (gdk_atom_intern (EPHY_DND_URL_TYPE, FALSE) == type) - { - return g_strdup (EPHY_DND_URL_TYPE); - } - - return EGG_TOOLBARS_MODEL_CLASS (parent_class)->get_item_type (model, type); -} - -static char * -impl_get_item_id (EggToolbarsModel *eggmodel, - const char *type, - const char *name) -{ - EphyBookmarksBarModel *model = EPHY_BOOKMARKSBAR_MODEL (eggmodel); - EphyBookmarks *bookmarks = model->priv->bookmarks; - - if (strcmp (type, EPHY_DND_TOPIC_TYPE) == 0) - { - EphyNode *topic; - - topic = ephy_bookmarks_find_keyword (bookmarks, name, FALSE); - if (topic == NULL) return NULL; - - return ephy_bookmarksbar_model_get_action_name - (model, ephy_node_get_id (topic)); - } - else if (strcmp (type, EPHY_DND_URL_TYPE) == 0) - { - EphyNode *node = NULL; - gchar **netscape_url; - - netscape_url = g_strsplit (name, "\n", 2); - if (!netscape_url || !netscape_url[URL]) { - g_strfreev (netscape_url); - return NULL; - } - - node = ephy_bookmarks_find_bookmark (bookmarks, netscape_url[URL]); - - if (!node) - { - /* Create the bookmark, it does not exist */ - EphyHistory *gh; - const char *icon; - const char *title; - - title = netscape_url[NAME]; - if (title == NULL || *title == '\0') - { - title = _("Untitled"); - } - - node = ephy_bookmarks_add (bookmarks, title, netscape_url[URL]); - - if (node != NULL) - { - gh = EPHY_HISTORY (ephy_embed_shell_get_global_history (embed_shell)); - icon = ephy_history_get_icon (gh, netscape_url[URL]); - - if (icon) - { - ephy_bookmarks_set_icon (bookmarks, netscape_url[URL], icon); - } - } - } - - g_strfreev (netscape_url); - - if (node == NULL) return NULL; - - return ephy_bookmarksbar_model_get_action_name - (model, ephy_node_get_id (node)); - } - - return EGG_TOOLBARS_MODEL_CLASS (parent_class)->get_item_id (eggmodel, type, name); -} - -static char * -impl_get_item_data (EggToolbarsModel *eggmodel, - const char *type, - const char *id) -{ - EphyBookmarksBarModel *model = EPHY_BOOKMARKSBAR_MODEL (eggmodel); - EphyNode *node; - - if (strcmp (type, EPHY_DND_TOPIC_TYPE) == 0) - { - char *uri; - - node = ephy_bookmarksbar_model_get_node (model, id); - g_return_val_if_fail (node != NULL, NULL); - - uri = ephy_bookmarks_get_topic_uri - (model->priv->bookmarks, node); - - return uri; - } - else if (strcmp (type, EPHY_DND_URL_TYPE) == 0) - { - const char *name; - - node = ephy_bookmarksbar_model_get_node (model, id); - g_return_val_if_fail (node != NULL, NULL); - - name = ephy_node_get_property_string - (node, EPHY_NODE_BMK_PROP_LOCATION); - - return g_strdup (name); - } - - return EGG_TOOLBARS_MODEL_CLASS (parent_class)->get_item_data (eggmodel, type, id); -} - -static void -load_toolbars (EphyBookmarksBarModel *model) -{ - EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); - gboolean success = FALSE; - - success = egg_toolbars_model_load (eggmodel, model->priv->xml_file); - LOG ("Loading the toolbars was %ssuccessful", success ? "" : "un"); - - /* Try migration first: load the old layout, and remove every toolbar - * except the BookmarksBar toolbar - */ - if (success == FALSE) - { - char *old_xml; - int i, n_toolbars; - - old_xml = g_build_filename (ephy_dot_dir (), - "epiphany-toolbars.xml", - NULL); - success = egg_toolbars_model_load (eggmodel, old_xml); - g_free (old_xml); - - if (success) - { - n_toolbars = egg_toolbars_model_n_toolbars (eggmodel); - - for (i = n_toolbars - 1; i >= 0; i--) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (eggmodel, i); - g_return_if_fail (t_name != NULL); - - if (strcmp (t_name, "BookmarksBar") != 0) - { - egg_toolbars_model_remove_toolbar (eggmodel, i); - } - } - } - - LOG ("Migration was %ssuccessful", success ? "" : "un"); - } - - /* Load default set */ - if (success == FALSE) - { - egg_toolbars_model_load - (eggmodel, ephy_file ("epiphany-bookmarksbar.xml")); - LOG ("Loading the default toolbars was %ssuccessful", success ? "" : "un"); - } - - /* Ensure that we have a BookmarksBar */ - if (get_toolbar_pos (model, "BookmarksBar") == -1) - { - egg_toolbars_model_add_toolbar - (eggmodel, -1, "BookmarksBar"); - } -} - -static void -ephy_bookmarksbar_model_init (EphyBookmarksBarModel *model) -{ - model->priv = EPHY_BOOKMARKSBAR_MODEL_GET_PRIVATE (model); - - LOG ("EphyBookmarksBarModel initialising"); - - model->priv->xml_file = g_build_filename (ephy_dot_dir (), - EPHY_BOOKMARKSBARS_XML_FILE, - NULL); - - g_signal_connect_after (model, "item_added", - G_CALLBACK (item_added_cb), NULL); - g_signal_connect_after (model, "item_removed", - G_CALLBACK (save_changes), NULL); - g_signal_connect_after (model, "toolbar_added", - G_CALLBACK (update_flags_and_save_changes), NULL); - g_signal_connect_after (model, "toolbar_removed", - G_CALLBACK (update_flags_and_save_changes), NULL); -} - -static void -ephy_bookmarksbar_model_dispose (GObject *object) -{ - EphyBookmarksBarModel *model = EPHY_BOOKMARKSBAR_MODEL (object); - - LOG ("EphyBookmarksBarModel disposing"); - - if (model->priv->timeout != 0) - { - g_source_remove (model->priv->timeout); - model->priv->timeout = 0; - } - - save_changes_idle (model); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -ephy_bookmarksbar_model_finalize (GObject *object) -{ - EphyBookmarksBarModel *model = EPHY_BOOKMARKSBAR_MODEL (object); - - g_free (model->priv->xml_file); - - LOG ("EphyBookmarksBarModel finalised"); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -ephy_bookmarksbar_model_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyBookmarksBarModel *model = EPHY_BOOKMARKSBAR_MODEL (object); - - switch (prop_id) - { - case PROP_BOOKMARKS: - /* we're owned by bookmarks, so don't g_object_ref() here */ - model->priv->bookmarks = g_value_get_object (value); - load_toolbars (model); - break; - } -} - -static void -ephy_bookmarksbar_model_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - /* no readable properties */ - g_assert_not_reached (); -} - -static void -ephy_bookmarksbar_model_class_init (EphyBookmarksBarModelClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - EggToolbarsModelClass *eggclass = EGG_TOOLBARS_MODEL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = ephy_bookmarksbar_model_dispose; - object_class->finalize = ephy_bookmarksbar_model_finalize; - object_class->set_property = ephy_bookmarksbar_model_set_property; - object_class->get_property = ephy_bookmarksbar_model_get_property; - - eggclass->get_item_type = impl_get_item_type; - eggclass->get_item_id = impl_get_item_id; - eggclass->get_item_data = impl_get_item_data; - - g_object_class_install_property (object_class, - PROP_BOOKMARKS, - g_param_spec_object ("bookmarks", - "Bookmarks", - "Bookmarks", - EPHY_TYPE_BOOKMARKS, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof (EphyBookmarksBarModelPrivate)); -} - -EggToolbarsModel * -ephy_bookmarksbar_model_new (EphyBookmarks *bookmarks) -{ - return EGG_TOOLBARS_MODEL (g_object_new (EPHY_TYPE_BOOKMARKSBAR_MODEL, - "bookmarks", bookmarks, - NULL)); -} diff --git a/src/bookmarks/ephy-bookmarksbar-model.h b/src/bookmarks/ephy-bookmarksbar-model.h deleted file mode 100755 index 1849e20c9..000000000 --- a/src/bookmarks/ephy-bookmarksbar-model.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2003-2004 Marco Pesenti Gritti - * Copyright (C) 2003-2004 Christian Persch - * - * 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. - * - * $Id$ - */ - -#ifndef EPHY_BOOKMARKSBAR_MODEL_H -#define EPHY_BOOKMARKSBAR_MODEL_H - -#include "egg-toolbars-model.h" -#include "ephy-bookmarks.h" - -G_BEGIN_DECLS - -#define EPHY_TYPE_BOOKMARKSBAR_MODEL (ephy_bookmarksbar_model_get_type ()) -#define EPHY_BOOKMARKSBAR_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_BOOKMARKSBAR_MODEL, EphyBookmarksBarModel)) -#define EPHY_BOOKMARKSBAR_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_BOOKMARKSBAR_MODEL, EphyBookmarksBarModelClass)) -#define EPHY_IS_BOOKMARKSBAR_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_BOOKMARKSBAR_MODEL)) -#define EPHY_IS_BOOKMARKSBAR_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_BOOKMARKSBAR_MODEL)) -#define EPHY_BOOKMARKSBAR_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_BOOKMARKSBAR_MODEL, EphyBookmarksBarModelClass)) - -typedef struct _EphyBookmarksBarModelClass EphyBookmarksBarModelClass; -typedef struct _EphyBookmarksBarModel EphyBookmarksBarModel; -typedef struct _EphyBookmarksBarModelPrivate EphyBookmarksBarModelPrivate; - -struct _EphyBookmarksBarModel -{ - EggToolbarsModel parent_object; - - /*< private >*/ - EphyBookmarksBarModelPrivate *priv; -}; - -struct _EphyBookmarksBarModelClass -{ - EggToolbarsModelClass parent_class; -}; - -GType ephy_bookmarksbar_model_get_type (void); - -EggToolbarsModel *ephy_bookmarksbar_model_new (EphyBookmarks *bookmarks); - -char *ephy_bookmarksbar_model_get_action_name (EphyBookmarksBarModel *model, - long id); - -EphyNode *ephy_bookmarksbar_model_get_node (EphyBookmarksBarModel *model, - const char *action_name); - -void ephy_bookmarksbar_model_add_bookmark (EphyBookmarksBarModel *model, - gboolean topic, - long id); - -void ephy_bookmarksbar_model_remove_bookmark (EphyBookmarksBarModel *model, - long id); - -gboolean ephy_bookmarksbar_model_has_bookmark (EphyBookmarksBarModel *model, - long id); - -G_END_DECLS - -#endif diff --git a/src/bookmarks/ephy-bookmarksbar.c b/src/bookmarks/ephy-bookmarksbar.c deleted file mode 100644 index d34dcf86c..000000000 --- a/src/bookmarks/ephy-bookmarksbar.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jorn Baayen - * Copyright (C) 2003-2004 Marco Pesenti Gritti - * Copyright (C) 2003-2004 Christian Persch - * - * 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. - * - * $Id$ - */ - -#include "config.h" - -#include "ephy-bookmarksbar.h" -#include "ephy-bookmarksbar-model.h" -#include "ephy-bookmarks.h" -#include "ephy-shell.h" -#include "ephy-topic-action.h" -#include "ephy-link.h" -#include "ephy-bookmark-action.h" -#include "ephy-new-bookmark.h" -#include "ephy-stock-icons.h" -#include "ephy-dnd.h" -#include "ephy-debug.h" - -#include <gtk/gtkuimanager.h> -#include <gtk/gtktoolbar.h> -#include <glib/gi18n.h> -#include <string.h> - -static GtkTargetEntry drag_targets[] = -{ - { EPHY_DND_TOPIC_TYPE, 0, 0 }, - { EPHY_DND_URL_TYPE, 0, 1 } -}; -static int n_drag_targets = G_N_ELEMENTS (drag_targets); - -enum -{ - PROP_0, - PROP_BOOKMARKS, - PROP_WINDOW -}; - -static GObjectClass *parent_class = NULL; - -#define EPHY_BOOKMARKSBAR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARKSBAR, EphyBookmarksBarPrivate)) - -struct _EphyBookmarksBarPrivate -{ - EphyWindow *window; - GtkActionGroup *action_group; - EphyBookmarks *bookmarks; - EggToolbarsModel *toolbars_model; -}; - -static void ephy_bookmarksbar_class_init (EphyBookmarksBarClass *klass); -static void ephy_bookmarksbar_init (EphyBookmarksBar *toolbar); - -GType -ephy_bookmarksbar_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo our_info = - { - sizeof (EphyBookmarksBarClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_bookmarksbar_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphyBookmarksBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_bookmarksbar_init - }; - - static const GInterfaceInfo link_info = - { - NULL, - NULL, - NULL - }; - - type = g_type_register_static (EGG_TYPE_EDITABLE_TOOLBAR, - "EphyBookmarksBar", - &our_info, 0); - g_type_add_interface_static (type, - EPHY_TYPE_LINK, - &link_info); - } - - return type; -} - -static gboolean -remove_action_from_model (EggToolbarsModel *model, const char *name) -{ - int n_toolbars, n_items, t, i; - - n_toolbars = egg_toolbars_model_n_toolbars (model); - - for (t = 0; t < n_toolbars; t++) - { - n_items = egg_toolbars_model_n_items (model, t); - - for (i = 0; i < n_items; i++) - { - const char *i_name; - gboolean is_separator; - - egg_toolbars_model_item_nth (model, t , i, &is_separator, - &i_name, NULL); - g_return_val_if_fail (i_name != NULL, FALSE); - - if (strcmp (i_name, name) == 0) - { - egg_toolbars_model_remove_item (model, t, i); - - if (!remove_action_from_model (model, name)) - { - return FALSE; - } - } - } - } - - return FALSE; -} - -static void -bookmark_destroy_cb (EphyNode *node, - EphyBookmarksBar *toolbar) -{ - EggToolbarsModel *model; - GtkAction *action; - char *name; - long id; - - - model = toolbar->priv->toolbars_model; - id = ephy_node_get_id (node); - name = ephy_bookmarksbar_model_get_action_name - (EPHY_BOOKMARKSBAR_MODEL (model), id); - remove_action_from_model (model, name); - - model = EGG_TOOLBARS_MODEL (ephy_shell_get_toolbars_model - (ephy_shell, FALSE)); - remove_action_from_model (model, name); - - action = gtk_action_group_get_action (toolbar->priv->action_group, name); - if (action) - { - gtk_action_group_remove_action (toolbar->priv->action_group, action); - } - - g_free (name); -} - -static void -ephy_bookmarksbar_action_request (EggEditableToolbar *eggtoolbar, - const char *name) -{ - EphyBookmarksBar *toolbar = EPHY_BOOKMARKSBAR (eggtoolbar); - GtkAction *action = NULL; - EphyNode *bmks, *topics; - - bmks = ephy_bookmarks_get_bookmarks (toolbar->priv->bookmarks); - topics = ephy_bookmarks_get_keywords (toolbar->priv->bookmarks); - - LOG ("Action request for action '%s'", name); - - if (g_str_has_prefix (name, "GoBookmark-")) - { - EphyNode *node; - - node = ephy_bookmarksbar_model_get_node - (EPHY_BOOKMARKSBAR_MODEL (toolbar->priv->toolbars_model), - name); - g_return_if_fail (node != NULL); - - if (ephy_node_has_child (topics, node)) - { - action = ephy_topic_action_new (name, node); - } - else if (ephy_node_has_child (bmks, node)) - { - action = ephy_bookmark_action_new (name, node); - } - - g_return_if_fail (action != NULL); - - g_signal_connect_swapped (action, "open-link", - G_CALLBACK (ephy_link_open), toolbar); - - gtk_action_group_add_action (toolbar->priv->action_group, action); - g_object_unref (action); - - ephy_node_signal_connect_object (node, - EPHY_NODE_DESTROY, - (EphyNodeCallback) bookmark_destroy_cb, - G_OBJECT (toolbar)); - } - - if (EGG_EDITABLE_TOOLBAR_CLASS (parent_class)->action_request) - { - EGG_EDITABLE_TOOLBAR_CLASS (parent_class)->action_request (eggtoolbar, name); - } -} - -static void -toolbar_added_cb (EggToolbarsModel *model, - int position, - EggEditableToolbar *toolbar) -{ - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (model, position); - g_return_if_fail (t_name != NULL); - - egg_editable_toolbar_set_drag_dest - (toolbar, drag_targets, n_drag_targets, t_name); -} - -static void -ephy_bookmarksbar_set_window (EphyBookmarksBar *toolbar, - EphyWindow *window) -{ - EggEditableToolbar *eggtoolbar = EGG_EDITABLE_TOOLBAR (toolbar); - EggToolbarsModel *model = toolbar->priv->toolbars_model; - GtkUIManager *manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window)); - int i, n_toolbars; - - g_return_if_fail (toolbar->priv->window == NULL); - g_return_if_fail (model != NULL); - - toolbar->priv->window = window; - - toolbar->priv->action_group = - gtk_action_group_new ("BookmarksToolbarActions"); - - gtk_ui_manager_insert_action_group (manager, - toolbar->priv->action_group, -1); - - g_object_set (G_OBJECT (toolbar), - "ui-manager", manager, - "model", model, - NULL); - - g_signal_connect_after (model, "toolbar_added", - G_CALLBACK (toolbar_added_cb), toolbar); - - /* now that the toolbar has been constructed, set drag dests */ - n_toolbars = egg_toolbars_model_n_toolbars (model); - for (i = 0; i < n_toolbars; i++) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (model, i); - g_return_if_fail (t_name != NULL); - - egg_editable_toolbar_set_drag_dest - (eggtoolbar, drag_targets, n_drag_targets, t_name); - } -} - -static void -ephy_bookmarksbar_init (EphyBookmarksBar *toolbar) -{ - toolbar->priv = EPHY_BOOKMARKSBAR_GET_PRIVATE (toolbar); -} - -static void -ephy_bookmarksbar_finalize (GObject *object) -{ - EphyBookmarksBar *toolbar = EPHY_BOOKMARKSBAR (object); - - g_object_unref (toolbar->priv->action_group); - - g_signal_handlers_disconnect_by_func - (toolbar->priv->toolbars_model, - G_CALLBACK (toolbar_added_cb), - toolbar); - - LOG ("EphyBookmarksBar %p finalised", object); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -ephy_bookmarksbar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyBookmarksBar *toolbar = EPHY_BOOKMARKSBAR (object); - - switch (prop_id) - { - case PROP_BOOKMARKS: - toolbar->priv->bookmarks = g_value_get_object (value); - toolbar->priv->toolbars_model = - EGG_TOOLBARS_MODEL (ephy_bookmarks_get_toolbars_model (toolbar->priv->bookmarks)); - break; - case PROP_WINDOW: - ephy_bookmarksbar_set_window (toolbar, g_value_get_object (value)); - break; - } -} - -static void -ephy_bookmarksbar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - /* no readable properties */ - g_assert_not_reached (); -} - -static void -ephy_bookmarksbar_class_init (EphyBookmarksBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - EggEditableToolbarClass *eet_class = EGG_EDITABLE_TOOLBAR_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_bookmarksbar_finalize; - object_class->set_property = ephy_bookmarksbar_set_property; - object_class->get_property = ephy_bookmarksbar_get_property; - - eet_class->action_request = ephy_bookmarksbar_action_request; - - g_object_class_install_property (object_class, - PROP_WINDOW, - g_param_spec_object ("window", - "Window", - "Parent window", - EPHY_TYPE_WINDOW, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_BOOKMARKS, - g_param_spec_object ("bookmarks", - "Bookmarks", - "Bookmarks Model", - EPHY_TYPE_BOOKMARKS, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof(EphyBookmarksBarPrivate)); -} - -GtkWidget * -ephy_bookmarksbar_new (EphyWindow *window) -{ - EphyBookmarks *bookmarks; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - - return GTK_WIDGET (g_object_new (EPHY_TYPE_BOOKMARKSBAR, - "bookmarks", bookmarks, - "window", window, - NULL)); -} diff --git a/src/bookmarks/ephy-bookmarksbar.h b/src/bookmarks/ephy-bookmarksbar.h deleted file mode 100644 index b715f8ecb..000000000 --- a/src/bookmarks/ephy-bookmarksbar.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2002 Jorn Baayen - * Copyright (C) 2003-2004 Marco Pesenti Gritti - * Copyright (C) 2003-2004 Christian Persch - * - * 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. - * - * $Id$ - */ - -#ifndef EPHY_BOOKMARKSBAR_H -#define EPHY_BOOKMARKSBAR_H - -#include "egg-editable-toolbar.h" -#include "ephy-window.h" - -#include <glib-object.h> -#include <glib.h> - -G_BEGIN_DECLS - -#define EPHY_TYPE_BOOKMARKSBAR (ephy_bookmarksbar_get_type ()) -#define EPHY_BOOKMARKSBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_BOOKMARKSBAR, EphyBookmarksBar)) -#define EPHY_BOOKMARKSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_BOOKMARKSBAR, EphyBookmarksBarClass)) -#define EPHY_IS_BOOKMARKSBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_BOOKMARKSBAR)) -#define EPHY_IS_BOOKMARKSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_BOOKMARKSBAR)) -#define EPHY_BOOKMARKSBAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_BOOKMARKSBAR, EphyBookmarksBarClass)) - -typedef struct _EphyBookmarksBar EphyBookmarksBar; -typedef struct _EphyBookmarksBarClass EphyBookmarksBarClass; -typedef struct _EphyBookmarksBarPrivate EphyBookmarksBarPrivate; - -struct _EphyBookmarksBar -{ - EggEditableToolbar parent_object; - - /*< private >*/ - EphyBookmarksBarPrivate *priv; -}; - -struct _EphyBookmarksBarClass -{ - EggEditableToolbarClass parent_class; -}; - -GType ephy_bookmarksbar_get_type (void); - -GtkWidget *ephy_bookmarksbar_new (EphyWindow *window); - -G_END_DECLS - -#endif diff --git a/src/bookmarks/ephy-favorites-menu.c b/src/bookmarks/ephy-favorites-menu.c deleted file mode 100644 index d6f93d6c8..000000000 --- a/src/bookmarks/ephy-favorites-menu.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2002 Ricardo Fernández Pascual - * Copyright (C) 2003, 2004 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch - * - * 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. - * - * $Id$ - */ - -#include "config.h" - -#include "ephy-favorites-menu.h" -#include "ephy-bookmark-action.h" -#include "ephy-link.h" -#include "ephy-shell.h" -#include "ephy-debug.h" - -#include <gtk/gtkmenuitem.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkuimanager.h> -#include <glib/gprintf.h> - -#define LABEL_WIDTH_CHARS 32 - -#define EPHY_FAVORITES_MENU_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_FAVORITES_MENU, EphyFavoritesMenuPrivate)) - -struct _EphyFavoritesMenuPrivate -{ - EphyWindow *window; - EphyBookmarks *bookmarks; - GtkActionGroup *action_group; - guint ui_id; - guint update_tag; -}; - -static void ephy_favorites_menu_class_init (EphyFavoritesMenuClass *klass); -static void ephy_favorites_menu_init (EphyFavoritesMenu *menu); -static void ephy_favorites_menu_finalize (GObject *o); - -enum -{ - PROP_0, - PROP_WINDOW -}; - -static gpointer parent_class; - -GType -ephy_favorites_menu_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo our_info = - { - sizeof (EphyFavoritesMenuClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_favorites_menu_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphyFavoritesMenu), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_favorites_menu_init - }; - static const GInterfaceInfo link_info = - { - NULL, - NULL, - NULL - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "EphyFavoritesMenu", - &our_info, 0); - g_type_add_interface_static (type, - EPHY_TYPE_LINK, - &link_info); - } - - return type; -} - -static void -ephy_favorites_menu_clean (EphyFavoritesMenu *menu) -{ - EphyFavoritesMenuPrivate *p = menu->priv; - GtkUIManager *merge = GTK_UI_MANAGER (ephy_window_get_ui_manager (p->window)); - - if (p->ui_id > 0) - { - gtk_ui_manager_remove_ui (merge, p->ui_id); - gtk_ui_manager_ensure_update (merge); - p->ui_id = 0; - } - - if (p->action_group != NULL) - { - gtk_ui_manager_remove_action_group (merge, p->action_group); - g_object_unref (p->action_group); - } -} - -static void -connect_proxy_cb (GtkActionGroup *action_group, - GtkAction *action, - GtkWidget *proxy) -{ - if (GTK_IS_MENU_ITEM (proxy)) - { - GtkLabel *label; - - label = (GtkLabel *) ((GtkBin *) proxy)->child; - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_max_width_chars (label, LABEL_WIDTH_CHARS); - } -} - -static void -ephy_favorites_menu_rebuild (EphyFavoritesMenu *menu) -{ - EphyFavoritesMenuPrivate *p = menu->priv; - gint i; - EphyNode *fav; - GPtrArray *children; - GtkUIManager *merge = GTK_UI_MANAGER (ephy_window_get_ui_manager (p->window)); - - LOG ("Rebuilding favorites menu"); - - START_PROFILER ("Rebuild favorites menu") - - ephy_favorites_menu_clean (menu); - - fav = ephy_bookmarks_get_favorites (p->bookmarks); - children = ephy_node_get_children (fav); - - p->action_group = gtk_action_group_new ("FavoritesActions"); - gtk_ui_manager_insert_action_group (merge, p->action_group, -1); - g_signal_connect (p->action_group, "connect-proxy", - G_CALLBACK (connect_proxy_cb), NULL); - - p->ui_id = gtk_ui_manager_new_merge_id (merge); - - for (i = 0; i < children->len; i++) - { - char verb[20]; - char name[20]; - char accel_path[48]; - EphyNode *node; - GtkAction *action; - - g_snprintf (verb, sizeof (verb),"GoFav%d", i); - g_snprintf (name, sizeof (name), "GoFav%dMenu", i); - g_snprintf (accel_path, sizeof (accel_path), - "<Actions>/FavoritesActions/%s", verb); - - node = g_ptr_array_index (children, i); - - action = ephy_bookmark_action_new (verb, node); - gtk_action_set_accel_path (action, accel_path); - gtk_action_group_add_action (p->action_group, action); - g_object_unref (action); - g_signal_connect_swapped (action, "open-link", - G_CALLBACK (ephy_link_open), menu); - - gtk_ui_manager_add_ui (merge, p->ui_id, - "/menubar/GoMenu", - name, verb, - GTK_UI_MANAGER_MENUITEM, FALSE); - } - - STOP_PROFILER ("Rebuild favorites menu") -} - -static void -ephy_favorites_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyFavoritesMenu *menu = EPHY_FAVORITES_MENU (object); - - switch (prop_id) - { - case PROP_WINDOW: - menu->priv->window = g_value_get_object (value); - ephy_favorites_menu_rebuild (menu); - break; - } -} - -static void -ephy_favorites_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EphyFavoritesMenu *menu = EPHY_FAVORITES_MENU (object); - - switch (prop_id) - { - case PROP_WINDOW: - g_value_set_object (value, menu->priv->window); - break; - } -} - - -static void -ephy_favorites_menu_class_init (EphyFavoritesMenuClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_favorites_menu_finalize; - object_class->set_property = ephy_favorites_menu_set_property; - object_class->get_property = ephy_favorites_menu_get_property; - - g_object_class_install_property (object_class, - PROP_WINDOW, - g_param_spec_object ("window", - "Window", - "Parent window", - EPHY_TYPE_WINDOW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof(EphyFavoritesMenuPrivate)); -} - -static gboolean -do_updates (EphyFavoritesMenu *menu) -{ - ephy_favorites_menu_rebuild (menu); - - menu->priv->update_tag = 0; - - /* don't run again */ - return FALSE; -} - -static void -fav_removed_cb (EphyNode *node, - EphyNode *child, - guint old_index, - EphyFavoritesMenu *menu) -{ - if (menu->priv->update_tag == 0) - { - menu->priv->update_tag = g_idle_add((GSourceFunc)do_updates, menu); - } -} - -static void -fav_added_cb (EphyNode *node, - EphyNode *child, - EphyFavoritesMenu *menu) -{ - if (menu->priv->update_tag == 0) - { - menu->priv->update_tag = g_idle_add((GSourceFunc)do_updates, menu); - } -} - -static void -ephy_favorites_menu_init (EphyFavoritesMenu *menu) -{ - EphyFavoritesMenuPrivate *p = EPHY_FAVORITES_MENU_GET_PRIVATE (menu); - EphyNode *fav; - menu->priv = p; - - menu->priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell); - - fav = ephy_bookmarks_get_favorites (menu->priv->bookmarks); - ephy_node_signal_connect_object (fav, - EPHY_NODE_CHILD_REMOVED, - (EphyNodeCallback) fav_removed_cb, - G_OBJECT (menu)); - ephy_node_signal_connect_object (fav, - EPHY_NODE_CHILD_ADDED, - (EphyNodeCallback) fav_added_cb, - G_OBJECT (menu)); -} - -static void -ephy_favorites_menu_finalize (GObject *o) -{ - EphyFavoritesMenu *menu = EPHY_FAVORITES_MENU (o); - - if (menu->priv->action_group != NULL) - { - g_object_unref (menu->priv->action_group); - } - - G_OBJECT_CLASS (parent_class)->finalize (o); -} - -EphyFavoritesMenu * -ephy_favorites_menu_new (EphyWindow *window) -{ - return g_object_new (EPHY_TYPE_FAVORITES_MENU, - "window", window, - NULL); -} diff --git a/src/bookmarks/ephy-favorites-menu.h b/src/bookmarks/ephy-favorites-menu.h deleted file mode 100644 index c399218b9..000000000 --- a/src/bookmarks/ephy-favorites-menu.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2002 Ricardo Fernández Pascual - * Copyright (C) 2003 Marco Pesenti Gritti - * - * 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. - * - * $Id$ - */ - -#ifndef EPHY_FAVORITES_MENU_H -#define EPHY_FAVORITES_MENU_H - -#include "ephy-window.h" - -G_BEGIN_DECLS - -#define EPHY_TYPE_FAVORITES_MENU (ephy_favorites_menu_get_type()) -#define EPHY_FAVORITES_MENU(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_FAVORITES_MENU, EphyFavoritesMenu)) -#define EPHY_FAVORITES_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_FAVORITES_MENU, EphyFavoritesMenuClass)) -#define EPHY_IS_FAVORITES_MENU(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_FAVORITES_MENU)) -#define EPHY_IS_FAVORITES_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_FAVORITES_MENU)) -#define EPHY_FAVORITES_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_FAVORITES_MENU, EphyFavoritesMenuClass)) - -typedef struct _EphyFavoritesMenu EphyFavoritesMenu; -typedef struct _EphyFavoritesMenuClass EphyFavoritesMenuClass; -typedef struct _EphyFavoritesMenuPrivate EphyFavoritesMenuPrivate; - -struct _EphyFavoritesMenuClass -{ - GObjectClass parent_class; -}; - -struct _EphyFavoritesMenu -{ - GObject parent_object; - - /*< private >*/ - EphyFavoritesMenuPrivate *priv; -}; - -GType ephy_favorites_menu_get_type (void); - -EphyFavoritesMenu *ephy_favorites_menu_new (EphyWindow *window); - -G_END_DECLS - -#endif diff --git a/src/bookmarks/ephy-new-bookmark.c b/src/bookmarks/ephy-new-bookmark.c index 46c05b216..c1e2f2a83 100644 --- a/src/bookmarks/ephy-new-bookmark.c +++ b/src/bookmarks/ephy-new-bookmark.c @@ -46,9 +46,9 @@ static void ephy_new_bookmark_class_init (EphyNewBookmarkClass *klass); static void ephy_new_bookmark_init (EphyNewBookmark *editor); static void ephy_new_bookmark_finalize (GObject *object); static void ephy_new_bookmark_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void ephy_new_bookmark_get_property (GObject *object, guint prop_id, GValue *value, @@ -164,7 +164,7 @@ ephy_new_bookmark_add (EphyNewBookmark *new_bookmark) title = gtk_editable_get_chars (GTK_EDITABLE (new_bookmark->priv->title_entry), 0, -1); node = ephy_bookmarks_add (new_bookmark->priv->bookmarks, title, - new_bookmark->priv->location); + new_bookmark->priv->location); new_bookmark->priv->id = ephy_node_get_id (node); ephy_topics_selector_apply (selector, node); @@ -260,6 +260,17 @@ build_editing_table (EphyNewBookmark *editor) gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + label = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0); + + label = gtk_label_new (_("Each \xE2\x80\xA2 highlights a topic to consider, derived from your current selections and existing bookmarks.")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 0, 0); + return table; } @@ -268,7 +279,7 @@ ephy_new_bookmark_construct (EphyNewBookmark *editor) { ephy_state_add_window (GTK_WIDGET(editor), "new_bookmark", - 280, 240, FALSE, + 280, 240, FALSE, EPHY_STATE_WINDOW_SAVE_SIZE); gtk_window_set_title (GTK_WINDOW (editor), @@ -414,9 +425,9 @@ ephy_new_bookmark_new (EphyBookmarks *bookmarks, static void ephy_new_bookmark_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { EphyNewBookmark *editor = EPHY_NEW_BOOKMARK (object); @@ -437,9 +448,9 @@ ephy_new_bookmark_set_property (GObject *object, static void ephy_new_bookmark_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { EphyNewBookmark *editor = EPHY_NEW_BOOKMARK (object); diff --git a/src/bookmarks/ephy-nodes-cover.c b/src/bookmarks/ephy-nodes-cover.c new file mode 100644 index 000000000..dfe461ee3 --- /dev/null +++ b/src/bookmarks/ephy-nodes-cover.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2004 Peter Harvey <pah06@uow.edu.au> + * + * 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. + * + */ + +#include "config.h" + +#include "ephy-nodes-cover.h" + +/* Count the number of node entries which are children of parent. */ +gint +ephy_nodes_count_covered (EphyNode *parent, const GPtrArray *children) +{ + guint i, len = 0; + EphyNode *child; + + for(i = 0; i < children->len; i++) + { + child = g_ptr_array_index (children, i); + if (ephy_node_has_child (parent, child)) + { + len++; + } + } + return len; +} + +/* Removes from the array of children those which are children of the given parent. */ +gint +ephy_nodes_remove_covered (EphyNode *parent, GPtrArray *children) +{ + guint i, len = children->len; + EphyNode *child; + + for(i = 0; i < children->len; i++) + { + child = g_ptr_array_index (children, i); + if (ephy_node_has_child (parent, child)) + { + g_ptr_array_remove_index_fast (children, i); + i--; + } + } + return len - children->len; +} + +/* Removes from the array of children those which are children of the given parent. */ +gint +ephy_nodes_remove_not_covered (EphyNode *parent, GPtrArray *children) +{ + guint i, len = children->len; + EphyNode *child; + + for(i = 0; i < children->len; i++) + { + child = g_ptr_array_index (children, i); + if (!ephy_node_has_child (parent, child)) + { + g_ptr_array_remove_index_fast (children, i); + i--; + } + } + return len - children->len; +} + +/* Returns the subset of children which are childs of the given parent. + * Stores the result in the given _covered array if non-null. */ +GPtrArray * +ephy_nodes_get_covered (EphyNode *parent, const GPtrArray *children, GPtrArray *_covered) +{ + GPtrArray *covered = _covered?_covered:g_ptr_array_sized_new (children->len); + EphyNode *child; + guint i; + + covered->len = 0; + for (i = 0; i < children->len; i++) + { + child = g_ptr_array_index (children, i); + if (ephy_node_has_child (parent, child)) + { + g_ptr_array_add (covered, child); + } + } + + return covered; +} + +/* Returns true if the parent covers all the children. */ +gboolean +ephy_nodes_covered (EphyNode *parent, const GPtrArray *children) +{ + EphyNode *child; + guint i; + + for (i = 0; i < children->len; i++) + { + child = g_ptr_array_index (children, i); + if (!ephy_node_has_child (parent, child)) + { + return FALSE; + } + } + + return TRUE; +} + +/* Returns the subset of parents which provide a covering of children. + * Arguments other than parents and children arguments are only used if non-null. + * Uses the _covering array to store the subset of parents. + * Uses the _uncovered array to store those children which couldn't be covered. + * Uses the _sizes array to store the number of children covered by each parent. */ +GPtrArray * +ephy_nodes_get_covering (const GPtrArray *parents, const GPtrArray *children, + GPtrArray *_covering, GPtrArray *_uncovered, GArray *_sizes) +{ + GPtrArray *uncovered = _uncovered?_uncovered:g_ptr_array_sized_new (children->len); + GPtrArray *covering = _covering?_covering:g_ptr_array_sized_new (parents->len); + GArray *sizes = _sizes; + + /* Create arrays to store the number of children each parent has which + * are currently not covered, and the number of children it has total. */ + int *count_u = g_malloc (sizeof(int) * parents->len); + int *count_c = g_malloc (sizeof(int) * parents->len); + + EphyNode *parent; + guint i, p; + + /* Empty all the returning arrays. */ + uncovered->len = 0; + covering->len = 0; + if (sizes) sizes->len = 0; + + /* Initialise the array of uncovered bookmarks. */ + for (i = 0; i < children->len; i++) + { + g_ptr_array_add (uncovered, g_ptr_array_index (children, i)); + } + + /* Initialise the count_u and count_c arrays. + * NB: count_u[0] is set to 0 if the parent node + covers the entire set of children. */ + for (i = 0, p = 0; i < parents->len; i++) + { + parent = g_ptr_array_index (parents, i); + count_c[i] = ephy_nodes_count_covered (parent, children); + count_u[i] = (count_c[i]<children->len) ? count_c[i] : 0; + if (count_u[i] > count_u[p]) p = i; + } + + /* While there are more suitable topics... */ + while (count_u[p]) + { + /* Update the arrays of uncovered bookmarks and covering topics. */ + parent = g_ptr_array_index (parents, p); + ephy_nodes_remove_covered (parent, uncovered); + g_ptr_array_add (covering, parent); + if (sizes) g_array_append_val (sizes, count_c[p]); + + /* Find the next most suitable topic. */ + count_u[p] = 0; + for (i = 0; i < parents->len; i++) + { + /* Lazy update the count_u[i] array. */ + if (count_u[i] > count_u[p] || (count_u[i] == count_u[p] && count_c[i] < count_c[p])) + { + parent = g_ptr_array_index (parents, i); + count_u[i] = ephy_nodes_count_covered (parent, uncovered); + } + + if (count_u[i] > count_u[p] || (count_u[i] == count_u[p] && count_c[i] < count_c[p])) + { + p = i; + } + } + } + + if (_uncovered != uncovered) g_ptr_array_free (uncovered, TRUE); + g_free (count_u); + g_free (count_c); + + return covering; +} diff --git a/src/bookmarks/ephy-nodes-cover.h b/src/bookmarks/ephy-nodes-cover.h new file mode 100644 index 000000000..10d9a4edd --- /dev/null +++ b/src/bookmarks/ephy-nodes-cover.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2004 Peter Harvey <pah06@uow.edu.au> + * + * 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. + */ + +#ifndef EPHY_NODES_COVER_H +#define EPHY_NODES_COVER_H + +#include "ephy-bookmarks.h" + +G_BEGIN_DECLS + +gint ephy_nodes_remove_covered (EphyNode *parent, GPtrArray *children); + +gint ephy_nodes_remove_not_covered (EphyNode *parent, GPtrArray *children); + +gint ephy_nodes_count_covered (EphyNode *parent, const GPtrArray *children); + +gboolean ephy_nodes_covered (EphyNode *parent, const GPtrArray *children); + +GPtrArray * ephy_nodes_get_covered (EphyNode *parent, const GPtrArray *children, GPtrArray *_covered); + +GPtrArray * ephy_nodes_get_covering (const GPtrArray *parents, const GPtrArray *children, + GPtrArray *_covering, GPtrArray *_uncovered, GArray *_sizes); + +G_END_DECLS + +#endif /* EPHY_NODES_COVER_H */ diff --git a/src/bookmarks/ephy-open-tabs-action.c b/src/bookmarks/ephy-open-tabs-action.c new file mode 100644 index 000000000..482ec84d1 --- /dev/null +++ b/src/bookmarks/ephy-open-tabs-action.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2004 Peter Harvey <pah06@uow.edu.au> + * + * 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gtk/gtktoolitem.h> +#include <glib/gi18n.h> +#include <libgnomevfs/gnome-vfs-uri.h> +#include <string.h> + +#include "ephy-open-tabs-action.h" +#include "ephy-bookmarks.h" +#include "ephy-node-common.h" +#include "ephy-link-action.h" +#include "ephy-link.h" + +static void +activate_cb (GtkAction *action, gpointer dummy) +{ + EphyLink *link = g_object_get_data (G_OBJECT (action), "ephy-link"); + EphyNode *node = g_object_get_data (G_OBJECT (action), "ephy-node"); + GPtrArray *children = ephy_node_get_children (node); + EphyTab *tab = 0; + + gint i; + const char *url; + + for (i = 0; i < children->len; i++) + { + node = g_ptr_array_index (children, i); + url = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION); + tab = ephy_link_open (link, url, tab, EPHY_LINK_NEW_TAB); + } +} + +static void +node_added_cb (EphyNode *parent, EphyNode *child, GObject *object) +{ + GtkActionGroup *actions = GTK_ACTION_GROUP (object); + GtkAction *action; + char *name, *accel; + + name = ephy_open_tabs_action_name (child); + g_return_if_fail (name); + + action = gtk_action_new (name, _("Open in New _Tabs"), "Open this topic in tabs", NULL); + + g_object_set_data (G_OBJECT (action), "ephy-node", child); + g_object_set_data (G_OBJECT (action), "ephy-link", EPHY_LINK (object)); + + g_signal_connect (G_OBJECT (action), "activate", + G_CALLBACK (activate_cb), NULL); + + accel = g_strjoin ("/", "<Actions>", + gtk_action_group_get_name (actions), + name, + NULL); + gtk_action_set_accel_path (action, accel); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + g_free (accel); +} + +static void +node_removed_cb (EphyNode *parent, EphyNode *child, guint index, GObject *object) +{ + char *name = ephy_open_tabs_action_name (child); + if (name) + { + GtkActionGroup *actions = GTK_ACTION_GROUP (object); + GtkAction *action = gtk_action_group_get_action (actions, name); + if (action) gtk_action_group_remove_action (actions, action); + g_free (name); + } +} + +GtkActionGroup * +ephy_open_tabs_group_new (EphyNode *node) +{ + GPtrArray *children = ephy_node_get_children (node); + GObject *actions = G_OBJECT (ephy_link_action_group_new ("OpenTabsActions")); + gint i; + + for (i = 0; i < children->len; i++) + node_added_cb (node, g_ptr_array_index (children, i), actions); + + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + actions); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + actions); + + return GTK_ACTION_GROUP (actions); +} + +char * +ephy_open_tabs_action_name (EphyNode *node) +{ + return g_strdup_printf("OpenTabs%u", ephy_node_get_id (node)); +} diff --git a/src/bookmarks/ephy-open-tabs-action.h b/src/bookmarks/ephy-open-tabs-action.h new file mode 100644 index 000000000..8ab83c070 --- /dev/null +++ b/src/bookmarks/ephy-open-tabs-action.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2003 Peter Harvey + * + * 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. + */ + +#ifndef EPHY_OPEN_TABS_ACTION_H +#define EPHY_OPEN_TABS_ACTION_H + +#include <gtk/gtkactiongroup.h> + +#include "ephy-node.h" + +char * ephy_open_tabs_action_name (EphyNode *node); + +GtkActionGroup * ephy_open_tabs_group_new (EphyNode *node); + +#endif diff --git a/src/bookmarks/ephy-related-action.c b/src/bookmarks/ephy-related-action.c new file mode 100644 index 000000000..00c3327b5 --- /dev/null +++ b/src/bookmarks/ephy-related-action.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> +#include <glib/gi18n.h> + +#include "ephy-window.h" +#include "ephy-bookmarks.h" +#include "ephy-shell.h" +#include "ephy-node-common.h" +#include "ephy-stock-icons.h" +#include "ephy-related-action.h" + +static void +node_changed (EphyNode *node, guint propertyid, GObject *object) +{ + ephy_topic_action_updated (EPHY_TOPIC_ACTION (object)); +} + +static void +node_destroyed (EphyNode *node, GObject *object) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + + ephy_topic_action_set_topic (EPHY_TOPIC_ACTION (object), + ephy_bookmarks_get_favorites (eb)); + ephy_node_signal_connect_object (node, EPHY_NODE_CHANGED, + (EphyNodeCallback) node_changed, + object); + ephy_node_signal_connect_object (node, EPHY_NODE_DESTROY, + (EphyNodeCallback) node_destroyed, + object); +} + +static EphyTab * +open_link (EphyLink *link, + const char *address, + EphyTab *tab, + EphyLinkFlags flags) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *bookmark = ephy_bookmarks_find_bookmark (eb, address); + EphyNode *topic, *chosen = NULL; + + if (bookmark != NULL) + { + GPtrArray *topics; + gint i, tmp, best = 0; + + topic = ephy_topic_action_get_topic (EPHY_TOPIC_ACTION (link)); + tmp = ephy_node_get_property_int (topic, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (tmp == EPHY_NODE_NORMAL_PRIORITY && + ephy_node_has_child (topic, bookmark)) + { + return NULL; + } + ephy_node_signal_disconnect_object (topic, EPHY_NODE_CHANGED, + (EphyNodeCallback) node_changed, + G_OBJECT (link)); + ephy_node_signal_disconnect_object (topic, EPHY_NODE_DESTROY, + (EphyNodeCallback) node_destroyed, + G_OBJECT (link)); + + topics = ephy_node_get_children (ephy_bookmarks_get_keywords (eb)); + for (i = 0; i < topics->len; i++) + { + topic = g_ptr_array_index (topics, i); + tmp = ephy_node_get_property_int (topic, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (tmp == EPHY_NODE_NORMAL_PRIORITY && + ephy_node_has_child (topic, bookmark)) + { + tmp = ephy_node_get_n_children (topic); + if (chosen == NULL || (tmp >= 10 && tmp <= best)) + { + chosen = topic; + best = tmp; + } + } + } + + if (chosen == NULL) chosen = ephy_bookmarks_get_favorites (eb); + + ephy_topic_action_set_topic (EPHY_TOPIC_ACTION (link), chosen); + ephy_node_signal_connect_object (chosen, EPHY_NODE_CHANGED, + (EphyNodeCallback) node_changed, + G_OBJECT (link)); + ephy_node_signal_connect_object (chosen, EPHY_NODE_DESTROY, + (EphyNodeCallback) node_destroyed, + G_OBJECT (link)); + } + + return NULL; +} + +static void +iface_init (EphyLinkIface *iface) +{ + iface->open_link = open_link; +} + +GType +ephy_related_action_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyRelatedActionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, + NULL, /* class_data */ + sizeof (EphyRelatedAction), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + static const GInterfaceInfo link_info = + { + (GInterfaceInitFunc) iface_init, + NULL, + NULL + }; + + type = g_type_register_static (EPHY_TYPE_TOPIC_ACTION, + "EphyRelatedAction", + &our_info, 0); + g_type_add_interface_static (type, + EPHY_TYPE_LINK, + &link_info); + } + + return type; +} + +GtkAction * +ephy_related_action_new (EphyLink *link, GtkUIManager *manager, char * name) +{ + EphyBookmarks *eb = ephy_shell_get_bookmarks (ephy_shell); + EphyNode *favorites = ephy_bookmarks_get_favorites (eb); + + EphyRelatedAction *action = + EPHY_RELATED_ACTION (g_object_new (EPHY_TYPE_RELATED_ACTION, + "name", name, + "topic", favorites, + "short_label", _("Related"), + "stock-id", GTK_STOCK_INDEX, + "manager", manager, + NULL)); + + g_signal_connect_object (G_OBJECT (link), "open-link", + G_CALLBACK (ephy_link_open), action, + G_CONNECT_SWAPPED); + + return GTK_ACTION (action); +} + diff --git a/src/bookmarks/ephy-related-action.h b/src/bookmarks/ephy-related-action.h new file mode 100644 index 000000000..adf9139e0 --- /dev/null +++ b/src/bookmarks/ephy-related-action.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2003, 2004 Marco Pesenti Gritti + * Copyright (C) 2003, 2004 Christian Persch + * + * 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. + * + * $Id$ + */ + +#ifndef EPHY_RELATED_ACTION_H +#define EPHY_RELATED_ACTION_H + +#include "ephy-link.h" +#include "ephy-topic-action.h" + +#include <gtk/gtkactiongroup.h> +#include <gtk/gtkuimanager.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_RELATED_ACTION (ephy_related_action_get_type ()) +#define EPHY_RELATED_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_RELATED_ACTION, EphyRelatedAction)) +#define EPHY_RELATED_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_RELATED_ACTION, EphyRelatedActionClass)) +#define EPHY_IS_RELATED_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_RELATED_ACTION)) +#define EPHY_IS_RELATED_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_RELATED_ACTION)) +#define EPHY_RELATED_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_RELATED_ACTION, EphyRelatedActionClass)) + +typedef struct _EphyRelatedAction EphyRelatedAction; +typedef struct _EphyRelatedActionClass EphyRelatedActionClass; + +struct _EphyRelatedAction +{ + EphyTopicAction parent_instance; +}; + +struct _EphyRelatedActionClass +{ + EphyTopicActionClass parent_class; +}; + +GType ephy_related_action_get_type (void); + +GtkAction * ephy_related_action_new (EphyLink *link, GtkUIManager *manager, char *name); + +G_END_DECLS + +#endif diff --git a/src/bookmarks/ephy-topic-action-group.c b/src/bookmarks/ephy-topic-action-group.c new file mode 100644 index 000000000..c7ecd7105 --- /dev/null +++ b/src/bookmarks/ephy-topic-action-group.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#include "config.h" + +#include "ephy-topic-action-group.h" +#include "ephy-topic-action.h" +#include "ephy-node.h" +#include "ephy-node-common.h" +#include "ephy-bookmarks.h" +#include "ephy-debug.h" + +#include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> +#include <string.h> + + +static void +node_changed_cb (EphyNode *parent, + EphyNode *child, + guint property_id, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_topic_action_name (child); + g_return_if_fail (name != NULL); + action = gtk_action_group_get_action (actions, name); + + if (property_id == EPHY_NODE_KEYWORD_PROP_NAME) + { + ephy_topic_action_updated (EPHY_TOPIC_ACTION (action)); + } + + g_free (name); +} + +static void +node_added_cb (EphyNode *parent, + EphyNode *child, + GtkActionGroup *actions) +{ + GtkUIManager *manager; + GtkAction *action; + char *name, *accel; + + manager = g_object_get_data ((GObject *)actions, "ui-manager"); + name = ephy_topic_action_name (child); + action = ephy_topic_action_new (child, manager, name); + accel = g_strjoin ("/", "<Actions>", + gtk_action_group_get_name (actions), + name, NULL); + gtk_action_set_accel_path (action, accel); + gtk_action_group_add_action (actions, action); + g_object_unref (action); + g_free (accel); + + ephy_topic_action_updated (EPHY_TOPIC_ACTION (action)); +} + +static void +node_removed_cb (EphyNode *parent, + EphyNode *child, guint index, + GtkActionGroup *actions) +{ + GtkAction *action; + char *name; + + name = ephy_topic_action_name (child); + g_return_if_fail (name != NULL); + action = gtk_action_group_get_action (actions, name); + + if (action) + { + gtk_action_group_remove_action (actions, action); + } + + g_free (name); +} + +GtkActionGroup * +ephy_topic_group_new (EphyNode *node, + GtkUIManager *manager) +{ + GPtrArray *children = ephy_node_get_children (node); + GObject *actions = (GObject *) gtk_action_group_new ("TopicActions"); + gint i; + + g_object_set_data (G_OBJECT (actions), "ui-manager", manager); + + for (i = 0; i < children->len; i++) + { + node_added_cb (node, g_ptr_array_index (children, i), (GtkActionGroup *)actions); + } + + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)node_added_cb, + actions); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)node_removed_cb, + actions); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)node_changed_cb, + actions); + + return GTK_ACTION_GROUP (actions); +} diff --git a/src/bookmarks/ephy-topic-action-group.h b/src/bookmarks/ephy-topic-action-group.h new file mode 100644 index 000000000..d1640b1c8 --- /dev/null +++ b/src/bookmarks/ephy-topic-action-group.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005 Peter Harvey + * + * 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. + */ + +#ifndef EPHY_TOPIC_ACTION_GROUP_H +#define EPHY_TOPIC_ACTION_GROUP_H + +#include "ephy-link-action.h" +#include "ephy-node.h" + +#include <gtk/gtkactiongroup.h> +#include <gtk/gtkuimanager.h> + +G_BEGIN_DECLS + +GtkActionGroup * ephy_topic_group_new (EphyNode *node, GtkUIManager *manager); + +G_END_DECLS + +#endif diff --git a/src/bookmarks/ephy-topic-action.c b/src/bookmarks/ephy-topic-action.c index 4885d2af6..3e0607509 100644 --- a/src/bookmarks/ephy-topic-action.c +++ b/src/bookmarks/ephy-topic-action.c @@ -22,28 +22,27 @@ #include "config.h" #include "ephy-topic-action.h" +#include "ephy-node.h" #include "ephy-node-common.h" +#include "ephy-nodes-cover.h" #include "ephy-bookmarks.h" -#include "ephy-bookmarksbar.h" -#include "ephy-link.h" -#include "ephy-favicon-cache.h" -#include "ephy-shell.h" -#include "ephy-dnd.h" +#include "ephy-bookmarks-ui.h" +#include "ephy-bookmarks-menu.h" #include "ephy-gui.h" #include "ephy-debug.h" #include <glib/gi18n.h> #include <gtk/gtkwidget.h> -#include <gtk/gtkarrow.h> #include <gtk/gtkhbox.h> #include <gtk/gtklabel.h> #include <gtk/gtkbutton.h> -#include <gtk/gtktogglebutton.h> #include <gtk/gtkstock.h> #include <gtk/gtkimage.h> #include <gtk/gtkmenuitem.h> #include <gtk/gtkimagemenuitem.h> #include <gtk/gtkseparatormenuitem.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkarrow.h> #include <gtk/gtkmain.h> #include <libgnomevfs/gnome-vfs-uri.h> #include <string.h> @@ -54,26 +53,18 @@ #define EPHY_TOPIC_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_TOPIC_ACTION, EphyTopicActionPrivate)) -static GtkTargetEntry drag_targets[] = -{ - { EPHY_DND_TOPIC_TYPE, 0, 0 } -}; -static int n_drag_targets = G_N_ELEMENTS (drag_targets); - struct _EphyTopicActionPrivate { - EphyNode *topic_node; - - guint motion_handler; - guint release_handler; - gint drag_x; - gint drag_y; + EphyNode *node; + GtkUIManager *manager; + guint merge_id; }; enum { PROP_0, - PROP_TOPIC + PROP_TOPIC, + PROP_MANAGER }; static void ephy_topic_action_class_init (EphyTopicActionClass *class); @@ -101,7 +92,7 @@ ephy_topic_action_get_type (void) (GInstanceInitFunc) ephy_topic_action_init, }; - type = g_type_register_static (EPHY_TYPE_LINK_ACTION, + type = g_type_register_static (GTK_TYPE_ACTION, "EphyTopicAction", &type_info, 0); } @@ -120,16 +111,11 @@ create_tool_item (GtkAction *action) item = (* GTK_ACTION_CLASS (parent_class)->create_tool_item) (action); - hbox = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox); - gtk_container_add (GTK_CONTAINER (item), hbox); - button = gtk_toggle_button_new (); - gtk_widget_add_events (GTK_WIDGET (button), GDK_BUTTON1_MOTION_MASK); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE); gtk_widget_show (button); - gtk_container_add (GTK_CONTAINER (hbox), button); + gtk_container_add (GTK_CONTAINER (item), button); g_object_set_data (G_OBJECT (item), "button", button); arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); @@ -151,560 +137,122 @@ create_tool_item (GtkAction *action) } static void -menu_deactivate_cb (GtkMenuShell *ms, GtkWidget *button) -{ - g_object_set_data (G_OBJECT (button), "popup", NULL); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); - gtk_button_released (GTK_BUTTON (button)); -} - -static void -menu_activate_cb (GtkWidget *item, GtkAction *action) +ephy_topic_action_sync_label (GtkAction *action, GParamSpec *pspec, GtkWidget *proxy) { - EphyBookmarks *bookmarks; - EphyNode *node; - const char *location; - char *address; - - node = g_object_get_data (G_OBJECT (item), "node"); - location = ephy_node_get_property_string - (node, EPHY_NODE_BMK_PROP_LOCATION); - g_return_if_fail (location != NULL); - - bookmarks = ephy_shell_get_bookmarks (ephy_shell_get_default ()); - address = ephy_bookmarks_resolve_address (bookmarks, location, NULL); - g_return_if_fail (address != NULL); - - ephy_link_open (EPHY_LINK (action), address, NULL, - ephy_gui_is_middle_click () ? EPHY_LINK_NEW_TAB : 0); - - g_free (address); -} + GtkWidget *label = NULL; + GValue value = { 0, }; + const char *label_text; -static void -ephy_topic_action_sync_label (GtkAction *gaction, - GParamSpec *pspec, - GtkWidget *proxy) -{ - EphyTopicAction *action = EPHY_TOPIC_ACTION (gaction); + g_value_init (&value, G_TYPE_STRING); + g_object_get_property (G_OBJECT (action), "label", &value); - g_return_if_fail (EPHY_IS_NODE (action->priv->topic_node)); + label_text = g_value_get_string (&value); - /* note that we cannot use ellipsizing label with defined width, - * since that makes the label exactly that wide, even if the - * text takes less space. So we have to shorten the string. - */ if (GTK_IS_TOOL_ITEM (proxy)) { - GtkWidget *label = NULL; - char *title, *separator; - - label = g_object_get_data (G_OBJECT (proxy), "label"); - g_return_if_fail (label != NULL); - - g_object_get (G_OBJECT (action), "label", &title, NULL); - g_return_if_fail (label != NULL); - - /* In case this is a multi-hierarchy topic, we only want to - * display the leaf name. See bug #310963. - */ - separator = g_strrstr (title, BOOKMARKS_HIERARCHY_SEP); - - gtk_label_set_label (GTK_LABEL (label), - separator != NULL ? separator + strlen(BOOKMARKS_HIERARCHY_SEP) : title); - - g_free (title); - } -} - -static int -sort_bookmarks (gconstpointer a, gconstpointer b) -{ - EphyNode *node_a = (EphyNode *)a; - EphyNode *node_b = (EphyNode *)b; - const char *title1, *title2; - int retval; - - title1 = ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE); - title2 = ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE); - - if (title1 == NULL) - { - retval = -1; + label = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "label")); } - else if (title2 == NULL) + else if (GTK_IS_MENU_ITEM (proxy)) { - retval = 1; + label = GTK_BIN (proxy)->child; } else { - char *str_a, *str_b; - - str_a = g_utf8_casefold (title1, -1); - str_b = g_utf8_casefold (title2, -1); - retval = g_utf8_collate (str_a, str_b); - g_free (str_a); - g_free (str_b); - } - - return retval; -} - -static gboolean -can_open_in_tabs (EphyNode *node) -{ - GPtrArray *children; - int priority; - - priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); - children = ephy_node_get_children (node); - - return (priority != EPHY_NODE_ALL_PRIORITY) && (children->len > 1); -} - -static void -append_bookmarks_menu (EphyTopicAction *action, GtkWidget *menu, EphyNode *node, gboolean show_empty) -{ - EphyFaviconCache *cache; - GtkWidget *item; - GtkLabel *label; - GPtrArray *children; - - cache = EPHY_FAVICON_CACHE - (ephy_embed_shell_get_favicon_cache (EPHY_EMBED_SHELL (ephy_shell))); - - children = ephy_node_get_children (node); - - if (children->len < 1 && show_empty) - { - /* This is the adjective, not the verb */ - item = gtk_menu_item_new_with_label (_("Empty")); - gtk_widget_set_sensitive (item, FALSE); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - + g_warning ("Unknown widget"); return; } - else - { - GList *node_list = NULL, *l; - int i; - - for (i = 0; i < children->len; ++i) - { - node_list = g_list_prepend (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) - { - EphyNode *kid = (EphyNode*) l->data; - const char *icon_location; - const char *title; - - icon_location = ephy_node_get_property_string - (kid, EPHY_NODE_BMK_PROP_ICON); - title = ephy_node_get_property_string - (kid, EPHY_NODE_BMK_PROP_TITLE); - if (title == NULL) continue; - item = gtk_image_menu_item_new_with_label (title); - label = (GtkLabel *) ((GtkBin *) item)->child; - gtk_label_set_max_width_chars (label, LABEL_WIDTH_CHARS); - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_use_underline (label, FALSE); + g_return_if_fail (label != NULL); - if (icon_location) - { - GdkPixbuf *icon; - GtkWidget *image; - - icon = ephy_favicon_cache_get (cache, icon_location); - if (icon != NULL) - { - image = gtk_image_new_from_pixbuf (icon); - gtk_widget_show (image); - gtk_image_menu_item_set_image - (GTK_IMAGE_MENU_ITEM (item), image); - g_object_unref (icon); - } - } - - g_object_set_data (G_OBJECT (item), "node", kid); - g_signal_connect (item, "activate", - G_CALLBACK (menu_activate_cb), action); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - } - - g_list_free (node_list); + if (label_text) + { + gtk_label_set_label (GTK_LABEL (label), label_text); } + + g_value_unset (&value); } -#define TOPIC_NODE_DATA_KEY "TopicNode" - -static void -open_in_tabs_activate_cb (GtkWidget *item, EphyTopicAction *action) +static GtkWidget * +get_popup (EphyTopicAction *action) { - EphyBookmarks *bookmarks; - EphyNode *node; - GPtrArray *children; - EphyTab *tab = NULL; - GList *node_list = NULL, *l; - int i; - - node = g_object_get_data (G_OBJECT (item), TOPIC_NODE_DATA_KEY); - g_return_if_fail (node != NULL); - - children = ephy_node_get_children (node); - for (i = 0; i < children->len; ++i) - { - node_list = g_list_prepend (node_list, - g_ptr_array_index (children, i)); - } - - node_list = g_list_sort (node_list, (GCompareFunc) sort_bookmarks); - - bookmarks = ephy_shell_get_bookmarks (ephy_shell_get_default ()); + char path[40]; - for (l = node_list; l != NULL; l = l->next) + g_snprintf (path, sizeof (path), "/PopupTopic%ld", + (long int) ephy_node_get_id (action->priv->node)); + + if (action->priv->merge_id == 0) { - EphyNode *child = (EphyNode *) l->data; - const char *location; - char *address; - - location = ephy_node_get_property_string - (child, EPHY_NODE_BMK_PROP_LOCATION); - g_return_if_fail (location != NULL); - - address = ephy_bookmarks_resolve_address (bookmarks, location, NULL); - g_return_if_fail (address != NULL); - - tab = ephy_link_open (EPHY_LINK (action), address, tab, - tab ? EPHY_LINK_NEW_TAB : EPHY_LINK_NEW_WINDOW); - g_free (address); + GString *popup_menu_string = g_string_new (""); + g_string_append_printf (popup_menu_string, "<ui><popup name=\"%s\">", path+1); + ephy_bookmarks_menu_build (popup_menu_string, action->priv->node); + g_string_append (popup_menu_string, "</popup></ui>"); + + action->priv->merge_id = gtk_ui_manager_add_ui_from_string + (action->priv->manager, popup_menu_string->str, popup_menu_string->len, 0); + + g_string_free (popup_menu_string, TRUE); } - - g_list_free (node_list); + + return gtk_ui_manager_get_widget (action->priv->manager, path); } -static int -get_item_position (GtkWidget *widget, gboolean *last) +static void +erase_popup (EphyTopicAction *action) { - GtkWidget *item, *toolbar; - int index; - - item = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - g_return_val_if_fail (item != NULL, -1); - - toolbar = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR); - g_return_val_if_fail (toolbar != NULL, -1); - - index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (item)); - if (last) + if (action->priv->merge_id != 0) { - int n_items; - - n_items = gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar)); - *last = (index == n_items - 1); + gtk_ui_manager_remove_ui (action->priv->manager, action->priv->merge_id); + action->priv->merge_id = 0; } - - return index; } static void -remove_from_model (GtkWidget *widget) +child_added_cb (EphyNode *node, EphyNode *child, GObject *object) { - EphyBookmarks *bookmarks; - EggToolbarsModel *model; - int pos; - - pos = get_item_position (widget, NULL); - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - model = EGG_TOOLBARS_MODEL (ephy_bookmarks_get_toolbars_model (bookmarks)); - - egg_toolbars_model_remove_item (model, 0, pos); + EphyTopicAction *action = EPHY_TOPIC_ACTION (object); + erase_popup (action); } static void -move_in_model (GtkWidget *widget, int direction) +child_changed_cb (EphyNode *node, EphyNode *child, guint property, GObject *object) { - EphyBookmarks *bookmarks; - EggToolbarsModel *model; - int pos, new_pos; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - model = EGG_TOOLBARS_MODEL (ephy_bookmarks_get_toolbars_model (bookmarks)); - - pos = get_item_position (widget, NULL); - new_pos = MAX (0, pos + direction); - - egg_toolbars_model_move_item (model, 0, pos, 0, new_pos); + EphyTopicAction *action = EPHY_TOPIC_ACTION (object); + erase_popup (action); } static void -remove_activate_cb (GtkWidget *menu, GtkWidget *proxy) +child_removed_cb (EphyNode *node, EphyNode *child, guint index, GObject *object) { - remove_from_model (proxy); + EphyTopicAction *action = EPHY_TOPIC_ACTION (object); + erase_popup (action); } static void -move_left_activate_cb (GtkWidget *menu, GtkWidget *proxy) +menu_destroy_cb (GtkWidget *menuitem, + gpointer user_data) { - move_in_model (proxy, -1); + /* Save the submenu from similar destruction, + * because it doesn't rightly belong to this menuitem. */ + gtk_menu_item_remove_submenu (GTK_MENU_ITEM (menuitem)); } static void -move_right_activate_cb (GtkWidget *menu, GtkWidget *proxy) -{ - move_in_model (proxy, +1); -} - -static GtkWidget * -add_open_in_tabs_menu (EphyTopicAction *action, - GtkWidget *menu, - EphyNode *node) -{ - GtkWidget *item; - const char *label; - - label = ngettext ("Open in New _Tab", - "Open in New _Tabs", - ephy_node_get_n_children (node)); - - item = gtk_menu_item_new_with_mnemonic (label); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - g_object_set_data (G_OBJECT (item), TOPIC_NODE_DATA_KEY, node); - - g_signal_connect (item, "activate", - G_CALLBACK (open_in_tabs_activate_cb), action); - - return item; -} - -static GtkWidget * -build_bookmarks_menu (EphyTopicAction *action, EphyNode *node) -{ - GtkWidget *menu; - - menu = gtk_menu_new (); - - append_bookmarks_menu (action, menu, node, TRUE); - - if (can_open_in_tabs (node)) - { - GtkWidget *item; - - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - add_open_in_tabs_menu (action, menu, node); - } - - return menu; -} - -static int -sort_topics (gconstpointer a, gconstpointer b) -{ - EphyNode *node_a = (EphyNode *)a; - EphyNode *node_b = (EphyNode *)b; - const char *title1, *title2; - int retval; - - title1 = ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME); - title2 = ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME); - - if (title1 == NULL) - { - retval = -1; - } - else if (title2 == NULL) - { - retval = 1; - } - else - { - char *str_a, *str_b; - - str_a = g_utf8_casefold (title1, -1); - str_b = g_utf8_casefold (title2, -1); - retval = g_utf8_collate (str_a, str_b); - g_free (str_a); - g_free (str_b); - } - - return retval; -} - -static GtkWidget * -build_topics_menu (EphyTopicAction *action) -{ - GtkWidget *menu, *item; - GPtrArray *children; - int i; - EphyBookmarks *bookmarks; - EphyNode *all, *uncategorized, *node; - EphyNodePriority priority; - GList *node_list = NULL, *l = NULL; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - all = ephy_bookmarks_get_bookmarks (bookmarks); - node = ephy_bookmarks_get_keywords (bookmarks); - - menu = gtk_menu_new (); - - children = ephy_node_get_children (node); - - for (i = 0; i < children->len; ++i) - { - EphyNode *kid; - - 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_prepend (node_list, kid); - } - } - - node_list = g_list_sort (node_list, (GCompareFunc)sort_topics); - - for (l = g_list_first (node_list); l != NULL; l = g_list_next (l)) - { - EphyNode *kid; - const char *title; - GtkWidget *bmk_menu; - GtkLabel *label; - - kid = (EphyNode*)l->data; - if (kid == all) continue; - - title = ephy_node_get_property_string - (kid, EPHY_NODE_KEYWORD_PROP_NAME); - - item = gtk_image_menu_item_new_with_label (title); - label = (GtkLabel *) ((GtkBin *) item)->child; - gtk_label_set_max_width_chars (label, MENUITEM_WIDTH_CHARS); - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - bmk_menu = build_bookmarks_menu (action, kid); - gtk_widget_show (bmk_menu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), bmk_menu); - } - g_list_free (node_list); - - uncategorized = ephy_bookmarks_get_not_categorized (bookmarks); - append_bookmarks_menu (action, menu, uncategorized, FALSE); - - return menu; -} - -static GtkWidget * -build_menu (EphyTopicAction *action) +menu_init_cb (GtkWidget *menuitem, + EphyTopicAction *action) { - if (ephy_node_get_id (action->priv->topic_node) == BOOKMARKS_NODE_ID) - { - return build_topics_menu (action); - } - else + if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem)) == NULL) { - return build_bookmarks_menu (action, action->priv->topic_node); + GtkWidget *popup = get_popup (action); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), popup); + g_signal_connect (menuitem, "destroy", G_CALLBACK (menu_destroy_cb), NULL); } } static void -drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, - GtkSelectionData *selection_data, guint info, - guint32 time, EphyTopicAction *action) -{ - EphyBookmarks *bookmarks; - char *uri; - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - g_return_if_fail (bookmarks != NULL); - - uri = ephy_bookmarks_get_topic_uri (bookmarks, action->priv->topic_node); - g_return_if_fail (uri != NULL); - - gtk_selection_data_set (selection_data, selection_data->target, 8, - (unsigned char *) uri, strlen (uri)); - - g_free (uri); -} - -static void -drag_data_delete_cb (GtkWidget *widget, GdkDragContext *context, - EphyTopicAction *action) -{ - remove_from_model (widget); -} - -static void -stop_drag_check (EphyTopicAction *action, GtkWidget *widget) -{ - if (action->priv->motion_handler) - { - g_signal_handler_disconnect (widget, action->priv->motion_handler); - action->priv->motion_handler = 0; - - g_signal_handler_disconnect (widget, action->priv->release_handler); - action->priv->release_handler = 0; - } -} - -static gboolean -check_horizontal_threshold (GtkWidget *widget, gint start_x, gint start_y, - gint current_x, gint current_y) -{ - gint drag_threshold; - - g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); - - g_object_get (gtk_widget_get_settings (widget), - "gtk-dnd-drag-threshold", &drag_threshold, - NULL); - - return (ABS (current_x - start_x) > drag_threshold && - ABS (current_y - start_y) < drag_threshold); -} - -static gboolean -drag_motion_cb (GtkWidget *widget, GdkEventMotion *event, EphyTopicAction *action) +button_deactivate_cb (GtkMenuShell *ms, GtkWidget *button) { - GtkWidget *button, *event_widget; - - event_widget = gtk_get_event_widget ((GdkEvent*) event); - button = GTK_WIDGET (g_object_get_data (G_OBJECT (widget), "button")); - - if (!gtk_widget_is_ancestor (event_widget, widget) && - check_horizontal_threshold (widget, action->priv->drag_x, - action->priv->drag_y, event->x, event->y)) - { - GtkTargetList *target_list; - - target_list = gtk_target_list_new (drag_targets, n_drag_targets); - - stop_drag_check (action, widget); - gtk_menu_popdown (GTK_MENU (widget)); - gtk_drag_begin (button, target_list, GDK_ACTION_MOVE | - GDK_ACTION_COPY, 1, (GdkEvent*)event); - - gtk_target_list_unref (target_list); - } - - return TRUE; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); + gtk_button_released (GTK_BUTTON (button)); } static void @@ -713,196 +261,43 @@ button_toggled_cb (GtkWidget *button, { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { - GtkWidget *menu; - GdkEvent *event; - guint32 event_time = 0; - guint event_button = 0; - - menu = build_menu (action); - g_signal_connect_object (menu, "deactivate", - G_CALLBACK (menu_deactivate_cb), button, 0); - - event = gtk_get_current_event (); - if (event != NULL) - { - if (event->type == GDK_BUTTON_PRESS) - { - event_button = ((GdkEventButton *) event)->button; - event_time = ((GdkEventButton *) event)->time; - } - - gdk_event_free (event); - } - - if (event_button == 0) - { - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - ephy_gui_menu_position_under_widget, - button, 0 , gtk_get_current_event_time ()); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); - } - else - { - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - ephy_gui_menu_position_under_widget, - button, event_button, event_time); - } - - g_object_set_data (G_OBJECT (button), "popup", menu); - } -} - -static GtkWidget * -create_menu_item (GtkAction *action) -{ - GtkWidget *menu, *menu_item; - GValue value = { 0, }; - const char *title; - - g_value_init (&value, G_TYPE_STRING); - g_object_get_property (G_OBJECT (action), "label", &value); - - title = g_value_get_string (&value); - - menu_item = gtk_menu_item_new_with_label (title); - - g_value_unset (&value); - - menu = build_menu (EPHY_TOPIC_ACTION (action)); - gtk_widget_show (menu); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu); - - return menu_item; -} - -static void -show_context_menu (EphyTopicAction *action, - GtkWidget *proxy, - GdkEventButton *event, - GtkMenuPositionFunc func) -{ - GtkWidget *menu, *item, *image; - gboolean last; - - menu = gtk_menu_new (); - - item = add_open_in_tabs_menu (action, menu, action->priv->topic_node); - gtk_widget_set_sensitive (item, can_open_in_tabs (action->priv->topic_node)); - - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove from Toolbar")); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (remove_activate_cb), proxy); - - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_menu_item_new_with_mnemonic (_("Move _Left")); - gtk_widget_set_sensitive (item, get_item_position (proxy, NULL) > 0); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (move_left_activate_cb), proxy); - - item = gtk_menu_item_new_with_mnemonic (_("Move Ri_ght")); - get_item_position (proxy, &last); - gtk_widget_set_sensitive (item, !last); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (move_right_activate_cb), proxy); - - if (event != NULL) - { - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, func, proxy, - event->button, event->time); - } - else - { - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, func, proxy, 0, - gtk_get_current_event_time ()); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); + GtkWidget *popup = get_popup (action); + g_signal_connect_object (popup, "deactivate", + G_CALLBACK (button_deactivate_cb), button, 0); + gtk_menu_popup (GTK_MENU (popup), NULL, NULL, + ephy_gui_menu_position_under_widget, + button, 1, gtk_get_current_event_time ()); } } static gboolean -popup_menu_cb (GtkWidget *widget, EphyTopicAction *action) -{ - if (gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) - { - show_context_menu (action, widget, NULL, - ephy_gui_menu_position_under_widget); - return TRUE; - } - - return FALSE; -} - -static gboolean -button_release_cb (GtkWidget *widget, +button_release_cb (GtkWidget *button, GdkEventButton *event, EphyTopicAction *action) { if (event->button == 1) { - stop_drag_check (action, widget); - - if (GTK_IS_TOGGLE_BUTTON (widget)) - { - gtk_toggle_button_set_active - (GTK_TOGGLE_BUTTON (widget), FALSE); - } + gtk_toggle_button_set_active + (GTK_TOGGLE_BUTTON (button), FALSE); } return FALSE; } static gboolean -button_press_cb (GtkWidget *widget, +button_press_cb (GtkWidget *button, GdkEventButton *event, EphyTopicAction *action) { - if (event->button == 1 && - gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) + if (event->button == 1) { - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { - GtkWidget *menu; - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - menu = g_object_get_data (G_OBJECT (widget), "popup"); - g_return_val_if_fail (menu != NULL, FALSE); - - g_object_set_data (G_OBJECT (menu), "button", widget); - - action->priv->drag_x = event->x; - action->priv->drag_y = event->y; - action->priv->motion_handler = g_signal_connect - (menu, "motion_notify_event", - G_CALLBACK (drag_motion_cb), action); - action->priv->release_handler = g_signal_connect - (menu, "button_release_event", - G_CALLBACK (button_release_cb), action); - + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + button_toggled_cb (button, action); return TRUE; } } - else if (event->button == 3 && - gtk_widget_get_ancestor (widget, EPHY_TYPE_BOOKMARKSBAR)) - { - show_context_menu (action, widget, event, NULL); - return TRUE; - } return FALSE; } @@ -910,113 +305,140 @@ button_press_cb (GtkWidget *widget, static void connect_proxy (GtkAction *action, GtkWidget *proxy) { - GtkWidget *button; - - LOG ("connect_proxy action %p, proxy %p", action, proxy); - (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy); + + ephy_topic_action_sync_label (action, NULL, proxy); + g_signal_connect_object (action, "notify::label", + G_CALLBACK (ephy_topic_action_sync_label), proxy, 0); if (GTK_IS_TOOL_ITEM (proxy)) { - ephy_topic_action_sync_label (action, NULL, proxy); - g_signal_connect_object (action, "notify::label", - G_CALLBACK (ephy_topic_action_sync_label), proxy, 0); - - button = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "button")); + GtkWidget *button = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "button")); g_signal_connect (button, "toggled", G_CALLBACK (button_toggled_cb), action); - g_signal_connect (button, "popup_menu", - G_CALLBACK (popup_menu_cb), action); g_signal_connect (button, "button-press-event", G_CALLBACK (button_press_cb), action); g_signal_connect (button, "button-release-event", G_CALLBACK (button_release_cb), action); - g_signal_connect (button, "drag_data_get", - G_CALLBACK (drag_data_get_cb), action); - g_signal_connect (button, "drag_data_delete", - G_CALLBACK (drag_data_delete_cb), action); } else if (GTK_IS_MENU_ITEM (proxy)) { - GtkLabel *label; - - label = (GtkLabel *) ((GtkBin *) proxy)->child; - - gtk_label_set_use_underline (label, FALSE); - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_max_width_chars (label, LABEL_WIDTH_CHARS); + g_signal_connect (proxy, "map", G_CALLBACK (menu_init_cb), action); } } -static void -topic_changed_cb (EphyNode *node, - guint property_id, - EphyTopicAction *action) +void +ephy_topic_action_updated (EphyTopicAction *action) { - if (property_id == EPHY_NODE_KEYWORD_PROP_NAME) + GValue value = { 0, }; + const char *title; + int priority; + + g_return_if_fail (action->priv->node != NULL); + + priority = ephy_node_get_property_int + (action->priv->node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + + if (priority == EPHY_NODE_ALL_PRIORITY) { - GValue value = { 0, }; - const char *title; - int priority; - - priority = ephy_node_get_property_int - (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); - - if (priority == EPHY_NODE_ALL_PRIORITY) - { - title = _("Bookmarks"); - } - else - { - title = ephy_node_get_property_string - (node, EPHY_NODE_KEYWORD_PROP_NAME); - } - - g_value_init(&value, G_TYPE_STRING); - g_value_set_static_string (&value, title); - g_object_set_property (G_OBJECT (action), "label", &value); - g_value_unset (&value); + title = _("Bookmarks"); + } + else + { + title = ephy_node_get_property_string + (action->priv->node, EPHY_NODE_KEYWORD_PROP_NAME); } + + g_value_init(&value, G_TYPE_STRING); + g_value_set_static_string (&value, title); + g_object_set_property (G_OBJECT (action), "label", &value); + g_object_set_property (G_OBJECT (action), "tooltip", &value); + g_value_unset (&value); } -static void +EphyNode * +ephy_topic_action_get_topic (EphyTopicAction *action) +{ + return action->priv->node; +} + +void ephy_topic_action_set_topic (EphyTopicAction *action, EphyNode *node) { - action->priv->topic_node = node; + g_return_if_fail (node != NULL); + + if (action->priv->node == node) return; + + if (action->priv->node != NULL) + { + ephy_node_signal_disconnect_object + (action->priv->node, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)child_added_cb, G_OBJECT (action)); + ephy_node_signal_disconnect_object + (action->priv->node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)child_changed_cb, G_OBJECT (action)); + ephy_node_signal_disconnect_object + (action->priv->node, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)child_removed_cb, G_OBJECT (action)); + } - topic_changed_cb (node, EPHY_NODE_KEYWORD_PROP_NAME, action); - ephy_node_signal_connect_object (node, EPHY_NODE_CHANGED, - (EphyNodeCallback) topic_changed_cb, - G_OBJECT (action)); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)child_added_cb, + G_OBJECT (action)); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)child_changed_cb, + G_OBJECT (action)); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)child_removed_cb, + G_OBJECT (action)); + + action->priv->node = node; + + erase_popup (action); + + g_object_freeze_notify (G_OBJECT (action)); + g_object_notify (G_OBJECT (action), "topic"); + ephy_topic_action_updated (action); + g_object_thaw_notify (G_OBJECT (action)); } static void ephy_topic_action_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - EphyTopicAction *topic; - - topic = EPHY_TOPIC_ACTION (object); + EphyTopicAction *action = EPHY_TOPIC_ACTION (object); switch (prop_id) { case PROP_TOPIC: - ephy_topic_action_set_topic (topic, g_value_get_pointer (value)); + ephy_topic_action_set_topic (action, g_value_get_pointer (value)); + break; + case PROP_MANAGER: + action->priv->manager = g_value_get_object (value); break; } } static void ephy_topic_action_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - /* no readable properties */ - g_return_if_reached (); + EphyTopicAction *action = EPHY_TOPIC_ACTION (object); + + switch (prop_id) + { + case PROP_TOPIC: + g_value_set_pointer (value, action->priv->node); + break; + case PROP_MANAGER: + g_value_set_object (value, action->priv->manager); + break; + } } static void @@ -1029,21 +451,28 @@ ephy_topic_action_class_init (EphyTopicActionClass *class) action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM; action_class->create_tool_item = create_tool_item; - action_class->create_menu_item = create_menu_item; action_class->connect_proxy = connect_proxy; object_class->set_property = ephy_topic_action_set_property; object_class->get_property = ephy_topic_action_get_property; - g_object_class_install_property - (object_class, - PROP_TOPIC, - g_param_spec_pointer ("topic", - "Topic", - "Topic", - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); - + g_object_class_install_property (object_class, + PROP_TOPIC, + g_param_spec_pointer ("topic", + "Topic", + "Topic", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_MANAGER, + g_param_spec_object ("manager", + "Manager", + "UI Manager", + GTK_TYPE_UI_MANAGER, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_type_class_add_private (object_class, sizeof(EphyTopicActionPrivate)); } @@ -1051,14 +480,27 @@ static void ephy_topic_action_init (EphyTopicAction *action) { action->priv = EPHY_TOPIC_ACTION_GET_PRIVATE (action); + + action->priv->merge_id = 0; + action->priv->node = NULL; + action->priv->manager = NULL; +} + +char * +ephy_topic_action_name (EphyNode *node) +{ + return g_strdup_printf("Tpc%u", ephy_node_get_id (node)); } GtkAction * -ephy_topic_action_new (const char *name, - EphyNode *node) +ephy_topic_action_new (EphyNode *node, GtkUIManager *manager, char *name) { - return g_object_new (EPHY_TYPE_TOPIC_ACTION, - "name", name, - "topic", node, - NULL); + if(!name) name = ephy_topic_action_name (node); + g_return_val_if_fail (name, NULL); + + return GTK_ACTION (g_object_new (EPHY_TYPE_TOPIC_ACTION, + "name", name, + "topic", node, + "manager", manager, + NULL)); } diff --git a/src/bookmarks/ephy-topic-action.h b/src/bookmarks/ephy-topic-action.h index 7c39e2e19..f6be79b4c 100644 --- a/src/bookmarks/ephy-topic-action.h +++ b/src/bookmarks/ephy-topic-action.h @@ -25,22 +25,25 @@ #include "ephy-link-action.h" #include "ephy-node.h" +#include <gtk/gtkactiongroup.h> +#include <gtk/gtkuimanager.h> + G_BEGIN_DECLS -#define EPHY_TYPE_TOPIC_ACTION (ephy_topic_action_get_type ()) -#define EPHY_TOPIC_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_TOPIC_ACTION, EphyTopicAction)) -#define EPHY_TOPIC_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_TOPIC_ACTION, EphyTopicActionClass)) -#define EPHY_IS_TOPIC_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_TOPIC_ACTION)) -#define EPHY_IS_TOPIC_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_TOPIC_ACTION)) -#define EPHY_TOPIC_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TOPIC_ACTION, EphyTopicActionClass)) +#define EPHY_TYPE_TOPIC_ACTION (ephy_topic_action_get_type ()) +#define EPHY_TOPIC_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_TOPIC_ACTION, EphyTopicAction)) +#define EPHY_TOPIC_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_TOPIC_ACTION, EphyTopicActionClass)) +#define EPHY_IS_TOPIC_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_TOPIC_ACTION)) +#define EPHY_IS_TOPIC_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_TOPIC_ACTION)) +#define EPHY_TOPIC_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TOPIC_ACTION, EphyTopicActionClass)) -typedef struct _EphyTopicAction EphyTopicAction; -typedef struct _EphyTopicActionPrivate EphyTopicActionPrivate; -typedef struct _EphyTopicActionClass EphyTopicActionClass; +typedef struct _EphyTopicAction EphyTopicAction; +typedef struct _EphyTopicActionPrivate EphyTopicActionPrivate; +typedef struct _EphyTopicActionClass EphyTopicActionClass; struct _EphyTopicAction { - EphyLinkAction parent_instance; + GtkAction parent_instance; /*< private >*/ EphyTopicActionPrivate *priv; @@ -51,10 +54,19 @@ struct _EphyTopicActionClass EphyLinkActionClass parent_class; }; -GType ephy_topic_action_get_type (void); -GtkAction *ephy_topic_action_new (const char *name, - EphyNode *node); +GType ephy_topic_action_get_type (void); + +char * ephy_topic_action_name (EphyNode *node); + +GtkAction * ephy_topic_action_new (EphyNode *node, GtkUIManager *manager, char *name); + + +void ephy_topic_action_set_topic (EphyTopicAction *action, EphyNode *node); + +EphyNode * ephy_topic_action_get_topic (EphyTopicAction *action); + +void ephy_topic_action_updated (EphyTopicAction *action); G_END_DECLS diff --git a/src/bookmarks/ephy-topic-factory-action.c b/src/bookmarks/ephy-topic-factory-action.c new file mode 100644 index 000000000..909d02abb --- /dev/null +++ b/src/bookmarks/ephy-topic-factory-action.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2004 Peter Harvey + * + * 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 <gtk/gtktoolitem.h> +#include <glib/gi18n.h> + +#include "ephy-topic-factory-action.h" +#include "ephy-topic-action.h" +#include "ephy-shell.h" +#include "ephy-stock-icons.h" +#include "egg-editable-toolbar.h" + +static void ephy_topic_factory_action_class_init (EphyTopicFactoryActionClass *class); + +#define EPHY_TOPIC_FACTORY_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_TOPIC_FACTORY_ACTION, EphyTopicActionPrivate)) +#define EGG_TOOLBARS_MODEL_DATA "ephy-topic-factory-menu" + +static GObjectClass *parent_class = NULL; + +GType +ephy_topic_factory_action_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo type_info = + { + sizeof (EphyTopicFactoryActionClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) ephy_topic_factory_action_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (EphyTopicFactoryAction), + 0, /* n_preallocs */ + NULL + }; + + type = g_type_register_static (GTK_TYPE_ACTION, + "EphyTopicFactoryAction", + &type_info, 0); + } + return type; +} + +static int +sort_topics (gconstpointer a, gconstpointer b) +{ + EphyNode *node_a = *(EphyNode **)a; + EphyNode *node_b = *(EphyNode **)b; + const char *title1, *title2; + int priority1, priority2; + + priority1 = ephy_node_get_property_int (node_a, EPHY_NODE_KEYWORD_PROP_PRIORITY); + priority2 = ephy_node_get_property_int (node_b, EPHY_NODE_KEYWORD_PROP_PRIORITY); + + if (priority1 > priority2) + { + return 1; + } + else if (priority1 < priority2) + { + return -1; + } + else + { + title1 = ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME); + title2 = ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME); + + if (title1 == NULL) + { + return -1; + } + else if (title2 == NULL) + { + return 1; + } + else + { + return g_utf8_collate (title1, title2); + } + } + + return 0; +} + +static void +activate_item_cb (GtkWidget *menuitem, GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item; + EggToolbarsModel *model; + GList *children; + gint index, pos; + char *id; + + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_if_fail (item); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_if_fail (toolbar); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_if_fail (etoolbar); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_if_fail (model); + + children = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + pos = g_list_index (children, toolbar->parent); + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + g_list_free (children); + + id = g_object_get_data (G_OBJECT (menuitem), "ephy-action"); + egg_toolbars_model_add_item (model, pos, index, id); +} + +static GtkWidget * +build_menu (GtkWidget *placeholder, EggToolbarsModel *model) +{ + GtkWidget *menu, *item; + + EphyBookmarks *eb; + EphyNode *node; + GPtrArray *children, *topics; + + const char *name, *action; + gint i, priority = -1, ptmp; + + /* Get a sorted list of topics. */ + eb = ephy_shell_get_bookmarks (ephy_shell); + node = ephy_bookmarks_get_keywords (eb); + children = ephy_node_get_children (node); + topics = g_ptr_array_sized_new (children->len); + for (i = 0; i < children->len; i++) + g_ptr_array_add (topics, g_ptr_array_index (children, i)); + g_ptr_array_sort (topics, (GCompareFunc)sort_topics); + + menu = gtk_menu_new (); + for (i = 0; i < topics->len; i++) + { + node = g_ptr_array_index (topics, i); + + action = ephy_topic_action_name (node); + if (egg_toolbars_model_get_n_avail (model, action) < 0) + continue; + + ptmp = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (ptmp != priority && priority >= 0) + { + item = gtk_separator_menu_item_new (); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + } + priority = ptmp; + + name = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); + item = gtk_menu_item_new_with_label (name); + + g_object_set_data_full (G_OBJECT (item), "ephy-action", (gpointer) action, g_free); + g_signal_connect (item, "activate", G_CALLBACK (activate_item_cb), placeholder); + gtk_widget_show (item); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + } + g_ptr_array_free (topics, TRUE); + + return menu; +} + +static void +remove_placeholder_cb (GtkMenuShell *menushell, GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item; + EggToolbarsModel *model; + GList *children; + gint index, pos; + + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_if_fail (item); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_if_fail (toolbar); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_if_fail (etoolbar); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_if_fail (model); + + g_object_set_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA, NULL); + + children = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + pos = g_list_index (children, toolbar->parent); + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + g_list_free (children); + + egg_toolbars_model_remove_item (model, pos, index); +} + +static gboolean +activate_placeholder_cb (GtkWidget *placeholder) +{ + GtkWidget *toolbar, *etoolbar, *item, *menu; + EggToolbarsModel *model; + gint index; + + /* Get our position on a toolbar. */ + item = gtk_widget_get_ancestor (placeholder, GTK_TYPE_TOOL_ITEM); + g_return_val_if_fail (item, FALSE); + toolbar = gtk_widget_get_ancestor (item, GTK_TYPE_TOOLBAR); + g_return_val_if_fail (toolbar, FALSE); + etoolbar = gtk_widget_get_ancestor (toolbar, EGG_TYPE_EDITABLE_TOOLBAR); + g_return_val_if_fail (etoolbar, FALSE); + model = egg_editable_toolbar_get_model (EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_val_if_fail (model, FALSE); + + /* If we are not yet on the toolbar, abort. */ + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item)); + if (index < 0 || index >= gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar))) + return FALSE; + + /* If there is already a popup menu, abort. */ + menu = g_object_get_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA); + if (menu != NULL) return FALSE; + + /* Create the menu and store it's pointer to ensure noone else creates a menu. */ + menu = build_menu (placeholder, model); + g_object_set_data (G_OBJECT (model), EGG_TOOLBARS_MODEL_DATA, menu); + + g_signal_connect (menu, "selection-done", + G_CALLBACK (remove_placeholder_cb), placeholder); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, + gtk_get_current_event_time ()); + + return FALSE; +} + +static void +clicked_placeholder_cb (GtkWidget *placeholder, GdkEventButton *event, gpointer user) +{ + activate_placeholder_cb (placeholder); +} + +static void +realize_placeholder_cb (GtkWidget *placeholder, gpointer user) +{ + g_idle_add ((GSourceFunc) activate_placeholder_cb, placeholder); +} + +static GtkWidget * +create_tool_item (GtkAction *action) +{ + GtkWidget *item = GTK_WIDGET (gtk_tool_item_new ()); + GtkWidget *widget = gtk_button_new_with_label (" ? "); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + + gtk_container_add (GTK_CONTAINER (item), widget); + gtk_widget_show (widget); + + return item; +} + +static void +connect_proxy (GtkAction *action, GtkWidget *proxy) +{ + GtkWidget *widget; + + (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy); + + g_return_if_fail (GTK_IS_TOOL_ITEM (proxy)); + + widget = gtk_bin_get_child (GTK_BIN (proxy)); + + g_signal_connect (G_OBJECT (widget), "realize", + G_CALLBACK (realize_placeholder_cb), + G_OBJECT (action)); + g_signal_connect (G_OBJECT (widget), "clicked", + G_CALLBACK (clicked_placeholder_cb), + G_OBJECT (action)); +} + +static void +ephy_topic_factory_action_class_init (EphyTopicFactoryActionClass *class) +{ + GtkActionClass *action_class = GTK_ACTION_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM; + action_class->connect_proxy = connect_proxy; + action_class->create_tool_item = create_tool_item; +} + +GtkAction * +ephy_topic_factory_action_new (const char *name) +{ + return GTK_ACTION (g_object_new (EPHY_TYPE_TOPIC_FACTORY_ACTION, + "name", name, + "label", _("Quick Topic"), + "stock-id", GTK_STOCK_ADD, + NULL)); +} diff --git a/src/bookmarks/ephy-topic-factory-action.h b/src/bookmarks/ephy-topic-factory-action.h new file mode 100644 index 000000000..70b40e676 --- /dev/null +++ b/src/bookmarks/ephy-topic-factory-action.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004 Peter Harvey + * + * 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. + * + * $Id$ + */ + +#ifndef EPHY_TOPIC_FACTORY_ACTION_H +#define EPHY_TOPIC_FACTORY_ACTION_H + +#include "ephy-node.h" +#include "ephy-window.h" + +#include <gtk/gtk.h> +#include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> + +#define EPHY_TYPE_TOPIC_FACTORY_ACTION (ephy_topic_factory_action_get_type ()) +#define EPHY_TOPIC_FACTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_TOPIC_FACTORY_ACTION, EphyTopicFactoryAction)) +#define EPHY_TOPIC_FACTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_TOPIC_FACTORY_ACTION, EphyTopicFactoryActionClass)) +#define EPHY_IS_TOPIC_FACTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_TOPIC_FACTORY_ACTION)) +#define EPHY_IS_TOPIC_FACTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_TOPIC_FACTORY_ACTION)) +#define EPHY_TOPIC_FACTORY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TOPIC_FACTORY_ACTION, EphyTopicFactoryActionClass)) + +typedef struct _EphyTopicFactoryAction EphyTopicFactoryAction; +typedef struct _EphyTopicFactoryActionClass EphyTopicFactoryActionClass; + +struct _EphyTopicFactoryAction +{ + GtkAction parent; +}; + +struct _EphyTopicFactoryActionClass +{ + GtkActionClass parent_class; +}; + +GType ephy_topic_factory_action_get_type (void); + +GtkAction * ephy_topic_factory_action_new (const char *name); + +#endif diff --git a/src/ephy-link-action.c b/src/ephy-link-action.c index 5eca8a65b..d4667090f 100644 --- a/src/ephy-link-action.c +++ b/src/ephy-link-action.c @@ -178,3 +178,47 @@ ephy_link_action_get_type (void) return type; } + +GType +ephy_link_action_group_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyLinkActionGroupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, + NULL, /* class_data */ + sizeof (EphyLinkActionGroup), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + static const GInterfaceInfo link_info = + { + NULL, + NULL, + NULL + }; + + type = g_type_register_static (GTK_TYPE_ACTION_GROUP, + "EphyLinkActionGroup", + &our_info, 0); + g_type_add_interface_static (type, + EPHY_TYPE_LINK, + &link_info); + } + + return type; +} + +EphyLinkActionGroup * +ephy_link_action_group_new (char * name) +{ + return EPHY_LINK_ACTION_GROUP (g_object_new (EPHY_TYPE_LINK_ACTION_GROUP, + "name", "BookmarkActions", NULL)); +} diff --git a/src/ephy-link-action.h b/src/ephy-link-action.h index 046fed715..7dbc5794c 100644 --- a/src/ephy-link-action.h +++ b/src/ephy-link-action.h @@ -22,18 +22,29 @@ #define EPHY_LINK_ACTION_H #include <gtk/gtkaction.h> +#include <gtk/gtkactiongroup.h> G_BEGIN_DECLS -#define EPHY_TYPE_LINK_ACTION (ephy_link_action_get_type ()) -#define EPHY_LINK_ACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_LINK_ACTION, EphyLinkAction)) -#define EPHY_LINK_ACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_LINK_ACTION, EphyLinkActionClass)) -#define EPHY_IS_LINK_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_LINK_ACTION)) -#define EPHY_IS_LINK_ACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_LINK_ACTION)) -#define EPHY_LINK_ACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_LINK_ACTION, EphyLinkActionClass)) +#define EPHY_TYPE_LINK_ACTION (ephy_link_action_get_type ()) +#define EPHY_LINK_ACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_LINK_ACTION, EphyLinkAction)) +#define EPHY_LINK_ACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_LINK_ACTION, EphyLinkActionClass)) +#define EPHY_IS_LINK_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_LINK_ACTION)) +#define EPHY_IS_LINK_ACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_LINK_ACTION)) +#define EPHY_LINK_ACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_LINK_ACTION, EphyLinkActionClass)) -typedef struct _EphyLinkAction EphyLinkAction; -typedef struct _EphyLinkActionClass EphyLinkActionClass; +#define EPHY_TYPE_LINK_ACTION_GROUP (ephy_link_action_group_get_type ()) +#define EPHY_LINK_ACTION_GROUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_LINK_ACTION_GROUP, EphyLinkActionGroup)) +#define EPHY_LINK_ACTION_GROUP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_LINK_ACTION_GROUP, EphyLinkActionGroupClass)) +#define EPHY_IS_LINK_ACTION_GROUP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_LINK_ACTION_GROUP)) +#define EPHY_IS_LINK_ACTION_GROUP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_LINK_ACTION_GROUP)) +#define EPHY_LINK_ACTION_GROUP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_LINK_ACTION_GROUP, EphyLinkActionGroupClass)) + +typedef struct _EphyLinkAction EphyLinkAction; +typedef struct _EphyLinkActionClass EphyLinkActionClass; + +typedef struct _EphyLinkActionGroup EphyLinkActionGroup; +typedef struct _EphyLinkActionGroupClass EphyLinkActionGroupClass; struct _EphyLinkAction { @@ -45,8 +56,22 @@ struct _EphyLinkActionClass GtkActionClass parent_class; }; +struct _EphyLinkActionGroup +{ + GtkActionGroup parent_instance; +}; + +struct _EphyLinkActionGroupClass +{ + GtkActionGroupClass parent_class; +}; + GType ephy_link_action_get_type (void); +GType ephy_link_action_group_get_type (void); + +EphyLinkActionGroup * ephy_link_action_group_new (char *name); + G_END_DECLS #endif diff --git a/src/ephy-lockdown.c b/src/ephy-lockdown.c index 1d2a9def7..2495a7b46 100644 --- a/src/ephy-lockdown.c +++ b/src/ephy-lockdown.c @@ -65,22 +65,22 @@ static GObjectClass *parent_class = NULL; static int find_name (GtkActionGroup *action_group, - const char *name) + const char *name) { - return strcmp (gtk_action_group_get_name (action_group), name); + return strcmp (gtk_action_group_get_name (action_group), name); } static GtkActionGroup * find_action_group (GtkUIManager *manager, const char *name) { - GList *list, *element; + GList *list, *element; - list = gtk_ui_manager_get_action_groups (manager); - element = g_list_find_custom (list, name, (GCompareFunc) find_name); - g_return_val_if_fail (element != NULL, NULL); + list = gtk_ui_manager_get_action_groups (manager); + element = g_list_find_custom (list, name, (GCompareFunc) find_name); + g_return_val_if_fail (element != NULL, NULL); - return GTK_ACTION_GROUP (element->data); + return GTK_ACTION_GROUP (element->data); } static void @@ -149,10 +149,6 @@ update_window (EphyWindow *window, action = gtk_action_group_get_action (action_group, "ViewToolbar"); ephy_action_change_sensitivity_flags (action, LOCKDOWN_FLAG, !writable); - writable = eel_gconf_key_is_writable (CONF_WINDOWS_SHOW_BOOKMARKS_BAR); - action = gtk_action_group_get_action (action_group, "ViewBookmarksBar"); - ephy_action_change_sensitivity_flags (action, LOCKDOWN_FLAG, !writable); - writable = eel_gconf_key_is_writable (CONF_WINDOWS_SHOW_STATUSBAR); action = gtk_action_group_get_action (action_group, "ViewStatusbar"); ephy_action_change_sensitivity_flags (action, LOCKDOWN_FLAG, !writable); diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c index 63e4a92c1..ae572da81 100644 --- a/src/ephy-notebook.c +++ b/src/ephy-notebook.c @@ -59,7 +59,7 @@ #define INSANE_NUMBER_OF_URLS 20 /* Until https://bugzilla.mozilla.org/show_bug.cgi?id=296002 is fixed */ -#define KEEP_TAB_IN_SAME_TOPLEVEL +//#define KEEP_TAB_IN_SAME_TOPLEVEL #define EPHY_NOTEBOOK_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_NOTEBOOK, EphyNotebookPrivate)) @@ -85,7 +85,7 @@ static void ephy_notebook_init (EphyNotebook *notebook); static void ephy_notebook_class_init (EphyNotebookClass *klass); static void ephy_notebook_finalize (GObject *object); static void move_tab_to_another_notebook (EphyNotebook *src, - EphyNotebook *dest, + EphyNotebook *dest, GdkEventMotion *event, int dest_position); static void move_tab (EphyNotebook *notebook, @@ -96,8 +96,8 @@ static GdkCursor *cursor = NULL; static const GtkTargetEntry url_drag_types [] = { - { EPHY_DND_URI_LIST_TYPE, 0, 0 }, - { EPHY_DND_URL_TYPE, 0, 1 } + { EPHY_DND_URI_LIST_TYPE, 0, 0 }, + { EPHY_DND_URL_TYPE, 0, 1 } }; enum @@ -722,7 +722,6 @@ move_tab_to_another_notebook (EphyNotebook *src, tab = EPHY_TAB (gtk_notebook_get_nth_page (GTK_NOTEBOOK (src), cur_page)); /* stop drag in origin window */ - */ drag_stop (src, event->time); ephy_notebook_move_tab (src, dest, tab, dest_position); @@ -804,9 +803,9 @@ ephy_notebook_new (void) static void ephy_notebook_switch_page_cb (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - gpointer data) + GtkNotebookPage *page, + guint page_num, + gpointer data) { EphyNotebook *nb = EPHY_NOTEBOOK (notebook); GtkWidget *child; @@ -929,17 +928,17 @@ ephy_notebook_init (EphyNotebook *notebook) gtk_widget_add_events (GTK_WIDGET (notebook), GDK_BUTTON1_MOTION_MASK); g_signal_connect_after (G_OBJECT (notebook), "switch_page", - G_CALLBACK (ephy_notebook_switch_page_cb), - NULL); + G_CALLBACK (ephy_notebook_switch_page_cb), + NULL); /* Set up drag-and-drop target */ g_signal_connect (G_OBJECT(notebook), "drag_data_received", G_CALLBACK(notebook_drag_data_received_cb), NULL); - gtk_drag_dest_set (GTK_WIDGET(notebook), GTK_DEST_DEFAULT_MOTION | + gtk_drag_dest_set (GTK_WIDGET(notebook), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, - url_drag_types, G_N_ELEMENTS (url_drag_types), - GDK_ACTION_MOVE | GDK_ACTION_COPY); + url_drag_types, G_N_ELEMENTS (url_drag_types), + GDK_ACTION_MOVE | GDK_ACTION_COPY); notebook->priv->tabs_vis_notifier_id = eel_gconf_notification_add (CONF_ALWAYS_SHOW_TABS_BAR, @@ -1040,7 +1039,7 @@ tab_label_style_set_cb (GtkWidget *hbox, context = gtk_widget_get_pango_context (hbox); metrics = pango_context_get_metrics (context, - hbox->style->font_desc, + hbox->style->font_desc, pango_context_get_language (context)); char_width = pango_font_metrics_get_approximate_digit_width (metrics); @@ -1087,8 +1086,8 @@ build_tab_label (EphyNotebook *nb, EphyTab *tab) _("Close tab"), NULL); g_signal_connect (G_OBJECT (close_button), "clicked", - G_CALLBACK (close_button_clicked_cb), - tab); + G_CALLBACK (close_button_clicked_cb), + tab); /* setup load feedback */ spinner = ephy_spinner_new (); @@ -1100,11 +1099,11 @@ build_tab_label (EphyNotebook *nb, EphyTab *tab) gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0); /* setup label */ - label = gtk_label_new (""); + label = gtk_label_new (""); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_misc_set_padding (GTK_MISC (label), 0, 0); + gtk_misc_set_padding (GTK_MISC (label), 0, 0); gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0); /* Set minimal size */ @@ -1165,9 +1164,9 @@ ephy_notebook_add_tab (EphyNotebook *nb, sync_load_status (tab, NULL, label); g_signal_connect_object (tab, "notify::icon", - G_CALLBACK (sync_icon), label, 0); + G_CALLBACK (sync_icon), label, 0); g_signal_connect_object (tab, "notify::title", - G_CALLBACK (sync_label), label, 0); + G_CALLBACK (sync_label), label, 0); g_signal_connect_object (tab, "notify::load-status", G_CALLBACK (sync_load_status), label, 0); diff --git a/src/ephy-shell.c b/src/ephy-shell.c index d1144f816..c7dc315c5 100644 --- a/src/ephy-shell.c +++ b/src/ephy-shell.c @@ -30,6 +30,7 @@ #include "ephy-file-helpers.h" #include "ephy-favicon-cache.h" #include "ephy-window.h" +#include "ephy-bookmarks-ui.h" #include "ephy-bookmarks-import.h" #include "ephy-bookmarks-editor.h" #include "ephy-history-window.h" @@ -938,19 +939,10 @@ ephy_shell_get_toolbars_model (EphyShell *shell, gboolean fullscreen) { if (shell->priv->toolbars_model == NULL) { - EphyBookmarks *bookmarks; - GObject *bookmarksbar_model; - shell->priv->toolbars_model = ephy_toolbars_model_new (); - - /* get the bookmarks toolbars model. we have to do this - * before loading the toolbars model from disk, since - * this will connect the get_item_* signals - */ - bookmarks = ephy_shell_get_bookmarks (shell); - bookmarksbar_model = ephy_bookmarks_get_toolbars_model (bookmarks); - - /* ok, now we can load the model */ + + ephy_bookmarks_ui_attach_toolbar_model (shell->priv->toolbars_model); + ephy_toolbars_model_load (EPHY_TOOLBARS_MODEL (shell->priv->toolbars_model)); } diff --git a/src/ephy-toolbar-editor.c b/src/ephy-toolbar-editor.c index a8179dd42..7726e4b62 100644 --- a/src/ephy-toolbar-editor.c +++ b/src/ephy-toolbar-editor.c @@ -167,7 +167,7 @@ ephy_toolbar_editor_constructor (GType type, GObjectConstructParam *construct_params) { - GObject *object; + GObject *object; EphyToolbarEditorPrivate *priv; GtkWidget *dialog, *editor, *toolbar, *vbox, *hbox, *label, *combo; GtkUIManager *manager; @@ -180,13 +180,13 @@ ephy_toolbar_editor_constructor (GType type, char *pref; int i; - object = parent_class->constructor (type, n_construct_properties, + object = parent_class->constructor (type, n_construct_properties, construct_params); #ifdef ENABLE_NLS - /* Initialize the control centre domain */ - bindtextdomain (CONTROL_CENTRE_DOMAIN, GNOMELOCALEDIR); - bind_textdomain_codeset(CONTROL_CENTRE_DOMAIN, "UTF-8"); + /* Initialize the control centre domain */ + bindtextdomain (CONTROL_CENTRE_DOMAIN, GNOMELOCALEDIR); + bind_textdomain_codeset(CONTROL_CENTRE_DOMAIN, "UTF-8"); #endif dialog = GTK_WIDGET (object); @@ -199,14 +199,12 @@ ephy_toolbar_editor_constructor (GType type, gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_title (GTK_WINDOW (dialog), _("Toolbar Editor")); - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (priv->window)); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (priv->window)); gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser"); manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (priv->window)); editor = egg_toolbar_editor_new (manager, priv->model); - egg_toolbar_editor_load_actions (EGG_TOOLBAR_EDITOR (editor), - ephy_file ("epiphany-toolbar.xml")); gtk_container_set_border_width (GTK_CONTAINER (EGG_TOOLBAR_EDITOR (editor)), 5); gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5); gtk_box_pack_start (GTK_BOX (vbox), editor, TRUE, TRUE, 0); @@ -294,13 +292,11 @@ ephy_toolbar_editor_constructor (GType type, gtk_widget_show (editor); ephy_state_add_window (dialog, "toolbar_editor", - 500, 330, FALSE, + 500, 330, FALSE, EPHY_STATE_WINDOW_SAVE_SIZE); gtk_widget_show (dialog); egg_editable_toolbar_set_edit_mode (EGG_EDITABLE_TOOLBAR (toolbar), TRUE); - egg_editable_toolbar_set_edit_mode - (EGG_EDITABLE_TOOLBAR (ephy_window_get_bookmarksbar (priv->window)), TRUE); return object; } @@ -313,8 +309,6 @@ ephy_toolbar_editor_finalize (GObject *object) egg_editable_toolbar_set_edit_mode (EGG_EDITABLE_TOOLBAR (ephy_window_get_toolbar (priv->window)), FALSE); - egg_editable_toolbar_set_edit_mode (EGG_EDITABLE_TOOLBAR - (ephy_window_get_bookmarksbar (priv->window)), FALSE); g_object_set_data (G_OBJECT (priv->window), DATA_KEY, NULL); @@ -337,14 +331,14 @@ ephy_toolbar_editor_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EphyToolbarEditorPrivate *priv = EPHY_TOOLBAR_EDITOR (object)->priv; + EphyToolbarEditorPrivate *priv = EPHY_TOOLBAR_EDITOR (object)->priv; - switch (prop_id) - { + switch (prop_id) + { case PROP_WINDOW: priv->window = g_value_get_object (value); break; - } + } } static void @@ -363,10 +357,10 @@ ephy_toolbar_editor_class_init (EphyToolbarEditorClass *klass) dialog_class->response = ephy_toolbar_editor_response; g_object_class_install_property (object_class, - PROP_WINDOW, - g_param_spec_object ("window", - "Window", - "Parent window", + PROP_WINDOW, + g_param_spec_object ("window", + "Window", + "Parent window", EPHY_TYPE_WINDOW, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); diff --git a/src/ephy-toolbar.c b/src/ephy-toolbar.c index eb31c1ed3..26af93311 100755 --- a/src/ephy-toolbar.c +++ b/src/ephy-toolbar.c @@ -167,20 +167,6 @@ fixed_toolbar_reconfigured_cb (GtkToolItem *item, ephy_spinner_set_size (spinner, size); } -static void -toolbar_added_cb (EggToolbarsModel *model, - int position, - EggEditableToolbar *toolbar) -{ - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (model, position); - g_return_if_fail (t_name != NULL); - - egg_editable_toolbar_set_drag_dest - (toolbar, drag_targets, G_N_ELEMENTS (drag_targets), t_name); -} - static void maybe_finish_activation_cb (EphyWindow *window, GtkWidget *widget, @@ -528,42 +514,12 @@ ephy_toolbar_set_zoom (EphyToolbar *toolbar, static void ephy_toolbar_realize (GtkWidget *widget) { - EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (widget); - EphyToolbar *toolbar = EPHY_TOOLBAR (widget); - EggToolbarsModel *model = egg_editable_toolbar_get_model (etoolbar); - int i, n_toolbars; - GTK_WIDGET_CLASS (parent_class)->realize (widget); - - g_signal_connect_after (model, "toolbar_added", - G_CALLBACK (toolbar_added_cb), toolbar); - - /* now that the toolbar has been constructed, set drag dests */ - n_toolbars = egg_toolbars_model_n_toolbars (model); - for (i = 0; i < n_toolbars; i++) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (model, i); - g_return_if_fail (t_name != NULL); - - egg_editable_toolbar_set_drag_dest - (etoolbar, drag_targets, G_N_ELEMENTS (drag_targets), t_name); - } } static void ephy_toolbar_unrealize (GtkWidget *widget) { - EggEditableToolbar *eggtoolbar = EGG_EDITABLE_TOOLBAR (widget); - EphyToolbar *toolbar = EPHY_TOOLBAR (widget); - EggToolbarsModel *model; - - model = egg_editable_toolbar_get_model (eggtoolbar); - - g_signal_handlers_disconnect_by_func - (model, G_CALLBACK (toolbar_added_cb), toolbar); - GTK_WIDGET_CLASS (parent_class)->unrealize (widget); } @@ -649,7 +605,6 @@ ephy_toolbar_finalize (GObject *object) { EphyToolbar *toolbar = EPHY_TOOLBAR (object); EphyToolbarPrivate *priv = toolbar->priv; - EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object); if (priv->set_focus_handler != 0) { @@ -657,10 +612,6 @@ ephy_toolbar_finalize (GObject *object) priv->set_focus_handler); } - g_signal_handlers_disconnect_by_func - (egg_editable_toolbar_get_model (etoolbar), - G_CALLBACK (toolbar_added_cb), toolbar); - G_OBJECT_CLASS (parent_class)->finalize (object); } diff --git a/src/ephy-toolbars-model.c b/src/ephy-toolbars-model.c index b36c0cc1b..a575b53f4 100755 --- a/src/ephy-toolbars-model.c +++ b/src/ephy-toolbars-model.c @@ -30,8 +30,8 @@ #include <string.h> -#define EPHY_TOOLBARS_XML_FILE "epiphany-toolbars-2.xml" -#define EPHY_TOOLBARS_XML_VERSION "1.0" +#define EPHY_TOOLBARS_XML_FILE "epiphany-toolbars-3.xml" +#define EPHY_TOOLBARS_XML_VERSION "1.1" #define EPHY_TOOLBARS_MODEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_TOOLBARS_MODEL, EphyToolbarsModelPrivate)) @@ -106,7 +106,7 @@ update_flags (EphyToolbarsModel *model) { EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); int i, n_toolbars; - int flag = EGG_TB_MODEL_ACCEPT_ITEMS_ONLY; + int flag = 0; n_toolbars = egg_toolbars_model_n_toolbars (eggmodel); @@ -138,29 +138,6 @@ update_flags_and_save_changes (EphyToolbarsModel *model) save_changes (model); } -static int -get_toolbar_pos (EggToolbarsModel *model, - const char *name) -{ - int i, n_toolbars; - - n_toolbars = egg_toolbars_model_n_toolbars (model); - - for (i = 0; i < n_toolbars; i++) - { - const char *t_name; - - t_name = egg_toolbars_model_toolbar_nth (model, i); - g_return_val_if_fail (t_name != NULL, -1); - if (strcmp (name, t_name) == 0) - { - return i; - } - } - - return -1; -} - static EggTbModelFlags get_toolbar_style (void) { @@ -203,7 +180,28 @@ ephy_toolbars_model_load (EphyToolbarsModel *model) { EggToolbarsModel *eggmodel = EGG_TOOLBARS_MODEL (model); gboolean success; - + int i; + + egg_toolbars_model_set_n_avail (eggmodel, "NavigationBack", 1); + egg_toolbars_model_set_n_avail (eggmodel, "NavigationForward", 1); + egg_toolbars_model_set_n_avail (eggmodel, "NavigationUp", 1); + egg_toolbars_model_set_n_avail (eggmodel, "ViewStop", 1); + egg_toolbars_model_set_n_avail (eggmodel, "ViewReload", 1); + egg_toolbars_model_set_n_avail (eggmodel, "GoHome", 1); + egg_toolbars_model_set_n_avail (eggmodel, "GoHistory", 1); + egg_toolbars_model_set_n_avail (eggmodel, "GoBookmarks", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FileNewTab", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FileNewWindow", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FileOpen", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FileSaveAs", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FilePrint", 1); + egg_toolbars_model_set_n_avail (eggmodel, "FileBookmarkPage", 1); + egg_toolbars_model_set_n_avail (eggmodel, "ViewFullscreen", 1); + egg_toolbars_model_set_n_avail (eggmodel, "EditFind", 1); + egg_toolbars_model_set_n_avail (eggmodel, "Location", 1); + egg_toolbars_model_set_n_avail (eggmodel, "ToolbarGo", 1); + egg_toolbars_model_set_n_avail (eggmodel, "Zoom", 1); + success = egg_toolbars_model_load (eggmodel, model->priv->xml_file); LOG ("Loading the toolbars was %ssuccessful", success ? "" : "un"); @@ -213,25 +211,37 @@ ephy_toolbars_model_load (EphyToolbarsModel *model) if (success == FALSE) { char *old_xml; - int toolbar; old_xml = g_build_filename (ephy_dot_dir (), - "epiphany-toolbars.xml", + "epiphany-toolbars-2.xml", NULL); success = egg_toolbars_model_load (eggmodel, old_xml); g_free (old_xml); - if (success) + if (success == TRUE) { - toolbar = get_toolbar_pos (eggmodel, "BookmarksBar"); - if (toolbar != -1) - { - egg_toolbars_model_remove_toolbar (eggmodel, toolbar); - } + old_xml = g_build_filename (ephy_dot_dir (), + "epiphany-bookmarksbar.xml", + NULL); + egg_toolbars_model_load (eggmodel, old_xml); + g_free (old_xml); } LOG ("Migration was %ssuccessful", success ? "" : "un"); } + + if (success == FALSE) + { + char *old_xml; + + old_xml = g_build_filename (ephy_dot_dir (), + "epiphany-toolbars.xml", + NULL); + success = egg_toolbars_model_load (eggmodel, old_xml); + g_free (old_xml); + + LOG ("Migration was %ssuccessful", success ? "" : "un"); + } /* Still no success, load the default toolbars */ if (success == FALSE) @@ -241,6 +251,15 @@ ephy_toolbars_model_load (EphyToolbarsModel *model) LOG ("Loading the default toolbars was %ssuccessful", success ? "" : "un"); } + /* Cleanup any empty toolbars */ + for (i = egg_toolbars_model_n_toolbars (eggmodel)-1; i >= 0; i--) + { + if (egg_toolbars_model_n_items (eggmodel, i) == 0) + { + egg_toolbars_model_remove_toolbar (eggmodel, i); + } + } + /* Ensure we have at least 1 toolbar */ if (egg_toolbars_model_n_toolbars (eggmodel) < 1) { diff --git a/src/ephy-window.c b/src/ephy-window.c index 5493b4585..ceaaa8719 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -26,8 +26,6 @@ #include "ephy-type-builtins.h" #include "ephy-embed-type-builtins.h" #include "ephy-command-manager.h" -#include "ephy-bookmarks-menu.h" -#include "ephy-favorites-menu.h" #include "ephy-state.h" #include "ppview-toolbar.h" #include "window-commands.h" @@ -43,12 +41,12 @@ #include "ephy-statusbar.h" #include "egg-editable-toolbar.h" #include "ephy-toolbar.h" -#include "ephy-bookmarksbar.h" #include "popup-commands.h" #include "ephy-encoding-menu.h" #include "ephy-tabs-menu.h" #include "ephy-stock-icons.h" #include "ephy-extension.h" +#include "ephy-bookmarks-ui.h" #include "ephy-link.h" #include "ephy-gui.h" #include "ephy-notebook.h" @@ -94,11 +92,9 @@ static void ephy_window_notebook_switch_page_cb (GtkNotebook *notebook, guint page_num, EphyWindow *window); static void ephy_window_view_statusbar_cb (GtkAction *action, - EphyWindow *window); + EphyWindow *window); static void ephy_window_view_toolbar_cb (GtkAction *action, - EphyWindow *window); -static void ephy_window_view_bookmarksbar_cb (GtkAction *action, - EphyWindow *window); + EphyWindow *window); static void ephy_window_view_popup_windows_cb (GtkAction *action, EphyWindow *window); static void sync_tab_load_status (EphyTab *tab, @@ -295,9 +291,6 @@ static const GtkToggleActionEntry ephy_menu_toggle_entries [] = { "ViewToolbar", NULL, N_("_Toolbar"), "<shift><control>T", N_("Show or hide toolbar"), G_CALLBACK (ephy_window_view_toolbar_cb), TRUE }, - { "ViewBookmarksBar", NULL, N_("_Bookmarks Bar"), NULL, - N_("Show or hide bookmarks bar"), - G_CALLBACK (ephy_window_view_bookmarksbar_cb), TRUE }, { "ViewStatusbar", NULL, N_("St_atusbar"), NULL, N_("Show or hide statusbar"), G_CALLBACK (ephy_window_view_statusbar_cb), TRUE }, @@ -397,7 +390,7 @@ static const struct #define BOOKMARKS_MENU_PATH "/menubar/BookmarksMenu" /* Until https://bugzilla.mozilla.org/show_bug.cgi?id=296002 is fixed */ -#define KEEP_TAB_IN_SAME_TOPLEVEL +//#define KEEP_TAB_IN_SAME_TOPLEVEL #define EPHY_WINDOW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_WINDOW, EphyWindowPrivate)) @@ -407,15 +400,12 @@ struct _EphyWindowPrivate GtkWidget *menu_dock; GtkWidget *fullscreen_popup; EphyToolbar *toolbar; - GtkWidget *bookmarksbar; GtkWidget *statusbar; GtkUIManager *manager; GtkActionGroup *action_group; GtkActionGroup *popups_action_group; - EphyFavoritesMenu *fav_menu; EphyEncodingMenu *enc_menu; EphyTabsMenu *tabs_menu; - EphyBookmarksMenu *bmk_menu; PPViewToolbar *ppview_toolbar; GtkNotebook *notebook; EphyTab *active_tab; @@ -464,22 +454,22 @@ static GObjectClass *parent_class = NULL; GType ephy_window_get_type (void) { - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo our_info = - { - sizeof (EphyWindowClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_window_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphyWindow), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_window_init - }; + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyWindowClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_window_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyWindow), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_window_init + }; static const GInterfaceInfo link_info = { (GInterfaceInitFunc) ephy_window_link_iface_init, @@ -487,16 +477,16 @@ ephy_window_get_type (void) NULL }; - type = g_type_register_static (GTK_TYPE_WINDOW, + type = g_type_register_static (GTK_TYPE_WINDOW, "EphyWindow", &our_info, 0); g_type_add_interface_static (type, EPHY_TYPE_LINK, &link_info); - } + } - return type; + return type; } static void @@ -541,7 +531,6 @@ get_chromes_visibility (EphyWindow *window, gboolean *show_menubar, gboolean *show_statusbar, gboolean *show_toolbar, - gboolean *show_bookmarksbar, gboolean *show_tabsbar) { EphyWindowPrivate *priv = window->priv; @@ -551,14 +540,13 @@ get_chromes_visibility (EphyWindow *window, { *show_menubar = *show_statusbar = *show_toolbar - = *show_bookmarksbar = *show_tabsbar = FALSE; } else if (window->priv->fullscreen_mode) { *show_toolbar = (flags & EPHY_EMBED_CHROME_TOOLBAR) != 0; - *show_menubar = *show_statusbar = *show_bookmarksbar = FALSE; + *show_menubar = *show_statusbar = FALSE; *show_tabsbar = !priv->is_popup; } else @@ -566,7 +554,6 @@ get_chromes_visibility (EphyWindow *window, *show_menubar = (flags & EPHY_EMBED_CHROME_MENUBAR) != 0; *show_statusbar = (flags & EPHY_EMBED_CHROME_STATUSBAR) != 0; *show_toolbar = (flags & EPHY_EMBED_CHROME_TOOLBAR) != 0; - *show_bookmarksbar = (flags & EPHY_EMBED_CHROME_BOOKMARKSBAR) != 0; *show_tabsbar = !priv->is_popup; } } @@ -576,20 +563,19 @@ sync_chromes_visibility (EphyWindow *window) { EphyWindowPrivate *priv = window->priv; GtkWidget *menubar; - gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar, show_tabsbar; + gboolean show_statusbar, show_menubar, show_toolbar, show_tabsbar; if (priv->closing) return; get_chromes_visibility (window, &show_menubar, &show_statusbar, &show_toolbar, - &show_bookmarksbar, &show_tabsbar); + &show_tabsbar); menubar = gtk_ui_manager_get_widget (window->priv->manager, "/menubar"); g_assert (menubar != NULL); g_object_set (menubar, "visible", show_menubar, NULL); g_object_set (priv->toolbar, "visible", show_toolbar, NULL); - g_object_set (priv->bookmarksbar, "visible", show_bookmarksbar, NULL); g_object_set (priv->statusbar, "visible", show_statusbar, NULL); ephy_notebook_set_show_tabs (EPHY_NOTEBOOK (priv->notebook), show_tabsbar); @@ -765,7 +751,7 @@ ephy_window_key_press_event (GtkWidget *widget, } /* Show and activate the menubar, if it isn't visible */ - if (event->keyval == keyval && (event->state & mask) == (modifier & mask)) + if (event->keyval == keyval && (event->state & mask) == (modifier & mask)) { menubar = gtk_ui_manager_get_widget (window->priv->manager, "/menubar"); g_return_val_if_fail (menubar != NULL , FALSE); @@ -780,7 +766,7 @@ ephy_window_key_press_event (GtkWidget *widget, return TRUE; } - } + } return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event); } @@ -1010,6 +996,94 @@ menu_item_deselect_cb (GtkMenuItem *proxy, window->priv->help_message_cid); } +static gboolean +tool_item_enter_cb (GtkWidget *proxy, + GdkEventCrossing *event, + EphyWindow *window) +{ + if (event->mode == GDK_CROSSING_NORMAL && + event->detail == GDK_NOTIFY_NONLINEAR) + { + GtkToolItem *item; + GtkAction *action; + char *message; + + item = GTK_TOOL_ITEM (gtk_widget_get_ancestor (proxy, GTK_TYPE_TOOL_ITEM)); + + action = g_object_get_data (G_OBJECT (item), "gtk-action"); + g_return_val_if_fail (action != NULL, FALSE); + + g_object_get (G_OBJECT (action), "tooltip", &message, NULL); + if (message) + { + gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar), + window->priv->help_message_cid, message); + g_free (message); + } + } + + return FALSE; +} + +static gboolean +tool_item_leave_cb (GtkWidget *proxy, + GdkEventCrossing *event, + EphyWindow *window) +{ + if (event->mode == GDK_CROSSING_NORMAL && + event->detail == GDK_NOTIFY_NONLINEAR) + { + gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), + window->priv->help_message_cid); + } + + return FALSE; +} + +static void +tool_item_drag_begin_cb (GtkWidget *widget, + GdkDragContext *context, + EphyWindow *window) +{ + gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), + window->priv->help_message_cid); +} + + +static void +connect_tool_item (GtkWidget *proxy, EphyWindow *window) +{ + if (GTK_IS_CONTAINER (proxy)) + { + gtk_container_foreach (GTK_CONTAINER (proxy), + (GtkCallback) connect_tool_item, + (gpointer) window); + } + + g_signal_connect (proxy, "drag_begin", + G_CALLBACK (tool_item_drag_begin_cb), window); + g_signal_connect (proxy, "enter-notify-event", + G_CALLBACK (tool_item_enter_cb), window); + g_signal_connect (proxy, "leave-notify-event", + G_CALLBACK (tool_item_leave_cb), window); +} + +static void +disconnect_tool_item (GtkWidget *proxy, EphyWindow *window) +{ + if (GTK_IS_CONTAINER (proxy)) + { + gtk_container_foreach (GTK_CONTAINER (proxy), + (GtkCallback) disconnect_tool_item, + (gpointer) window); + } + + g_signal_handlers_disconnect_by_func + (proxy, G_CALLBACK (tool_item_enter_cb), window); + g_signal_handlers_disconnect_by_func + (proxy, G_CALLBACK (tool_item_leave_cb), window); +} + static void disconnect_proxy_cb (GtkUIManager *manager, GtkAction *action, @@ -1023,6 +1097,10 @@ disconnect_proxy_cb (GtkUIManager *manager, g_signal_handlers_disconnect_by_func (proxy, G_CALLBACK (menu_item_deselect_cb), window); } + else if (GTK_IS_TOOL_ITEM (proxy)) + { + disconnect_tool_item (proxy, window); + } } static void @@ -1038,6 +1116,10 @@ connect_proxy_cb (GtkUIManager *manager, g_signal_connect (proxy, "deselect", G_CALLBACK (menu_item_deselect_cb), window); } + else if (GTK_IS_TOOL_ITEM (proxy)) + { + connect_tool_item (proxy, window); + } } static void @@ -1045,11 +1127,11 @@ update_chromes_actions (EphyWindow *window) { GtkActionGroup *action_group = window->priv->action_group; GtkAction *action; - gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar, show_tabsbar; + gboolean show_statusbar, show_menubar, show_toolbar, show_tabsbar; get_chromes_visibility (window, &show_menubar, &show_statusbar, &show_toolbar, - &show_bookmarksbar, &show_tabsbar); + &show_tabsbar); action = gtk_action_group_get_action (action_group, "ViewToolbar"); g_signal_handlers_block_by_func (G_OBJECT (action), @@ -1060,15 +1142,6 @@ update_chromes_actions (EphyWindow *window) G_CALLBACK (ephy_window_view_toolbar_cb), window); - action = gtk_action_group_get_action (action_group, "ViewBookmarksBar"); - g_signal_handlers_block_by_func (G_OBJECT (action), - G_CALLBACK (ephy_window_view_bookmarksbar_cb), - window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_bookmarksbar); - g_signal_handlers_unblock_by_func (G_OBJECT (action), - G_CALLBACK (ephy_window_view_bookmarksbar_cb), - window); - action = gtk_action_group_get_action (action_group, "ViewStatusbar"); g_signal_handlers_block_by_func (G_OBJECT (action), G_CALLBACK (ephy_window_view_statusbar_cb), @@ -1845,6 +1918,7 @@ show_embed_popup (EphyWindow *window, G_CALLBACK (embed_popup_deactivate_cb), window); button = ephy_embed_event_get_button (event); + if (button == 0) { gtk_menu_popup (GTK_MENU (widget), NULL, NULL, @@ -2277,7 +2351,7 @@ tab_added_cb (EphyNotebook *notebook, EphyExtension *manager; EphyEmbed *embed; - g_return_if_fail (EPHY_IS_TAB (tab)); + g_return_if_fail (EPHY_IS_TAB (tab)); window->priv->num_tabs++; @@ -2314,7 +2388,7 @@ tab_removed_cb (EphyNotebook *notebook, EphyExtension *manager; EphyEmbed *embed; - g_return_if_fail (EPHY_IS_TAB (tab)); + g_return_if_fail (EPHY_IS_TAB (tab)); /* Let the extensions remove themselves from the tab */ manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell)); @@ -2447,11 +2521,6 @@ ephy_window_set_chrome (EphyWindow *window, EphyEmbedChrome mask) chrome_mask &= ~EPHY_EMBED_CHROME_STATUSBAR; } - if (!eel_gconf_get_boolean (CONF_WINDOWS_SHOW_BOOKMARKS_BAR)) - { - chrome_mask &= ~EPHY_EMBED_CHROME_BOOKMARKSBAR; - } - if (eel_gconf_get_boolean (CONF_LOCKDOWN_HIDE_MENUBAR)) { chrome_mask &= ~EPHY_EMBED_CHROME_MENUBAR; @@ -2507,6 +2576,7 @@ ephy_window_dispose (GObject *object) /* Let the extensions detach themselves from the window */ manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell)); ephy_extension_detach_window (manager, window); + ephy_bookmarks_ui_detach_window (window); /* Deactivate menus */ popups = gtk_ui_manager_get_toplevels (window->priv->manager, GTK_UI_MANAGER_POPUP); @@ -2530,18 +2600,12 @@ ephy_window_dispose (GObject *object) g_hash_table_foreach_remove (priv->tabs_to_remove, (GHRFunc) remove_true, NULL); - g_object_unref (priv->fav_menu); - priv->fav_menu = NULL; - g_object_unref (priv->enc_menu); priv->enc_menu = NULL; g_object_unref (priv->tabs_menu); priv->tabs_menu = NULL; - g_object_unref (priv->bmk_menu); - priv->bmk_menu = NULL; - if (priv->ppview_toolbar) { g_object_unref (priv->ppview_toolbar); @@ -2559,7 +2623,7 @@ ephy_window_dispose (GObject *object) destroy_fullscreen_popup (window); - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (parent_class)->dispose (object); } static void @@ -2710,11 +2774,11 @@ ephy_window_class_init (EphyWindowClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); + parent_class = g_type_class_peek_parent (klass); object_class->constructor = ephy_window_constructor; object_class->dispose = ephy_window_dispose; - object_class->finalize = ephy_window_finalize; + object_class->finalize = ephy_window_finalize; object_class->get_property = ephy_window_get_property; object_class->set_property = ephy_window_set_property; @@ -2799,14 +2863,6 @@ allow_popups_notifier (GConfClient *client, } } -static void -action_request_forward_cb (GObject *toolbar, - const char *name, - GObject *bookmarksbar) -{ - g_signal_emit_by_name (bookmarksbar, "action_request", name); -} - static EphyTab * ephy_window_open_link (EphyLink *link, const char *address, @@ -2950,10 +3006,6 @@ ephy_window_init (EphyWindow *window) G_CALLBACK (ephy_link_open), window); g_signal_connect_swapped (window->priv->toolbar, "exit-clicked", G_CALLBACK (exit_fullscreen_clicked_cb), window); - window->priv->bookmarksbar = ephy_bookmarksbar_new (window); - g_signal_connect_swapped (window->priv->bookmarksbar, "open-link", - G_CALLBACK (ephy_link_open), window); - g_signal_connect_swapped (window->priv->toolbar, "activation-finished", G_CALLBACK (sync_chromes_visibility), window); @@ -2964,37 +3016,21 @@ ephy_window_init (EphyWindow *window) { g_warning ("Could not merge epiphany-ui.xml: %s", error->message); g_error_free (error); - } + } /* Initialize the menus */ window->priv->tabs_menu = ephy_tabs_menu_new (window); window->priv->enc_menu = ephy_encoding_menu_new (window); - window->priv->fav_menu = ephy_favorites_menu_new (window); - g_signal_connect_swapped (window->priv->fav_menu, "open-link", - G_CALLBACK (ephy_link_open), window); - window->priv->bmk_menu = ephy_bookmarks_menu_new (window->priv->manager, - BOOKMARKS_MENU_PATH); - g_signal_connect_swapped (window->priv->bmk_menu, "open-link", - G_CALLBACK (ephy_link_open), window); - - /* forward the toolbar's action_request signal to the bookmarks toolbar, - * so the user can also have bookmarks on the normal toolbar - */ - g_signal_connect (window->priv->toolbar, "action_request", - G_CALLBACK (action_request_forward_cb), - window->priv->bookmarksbar); /* Add the toolbars to the window */ gtk_box_pack_end (GTK_BOX (window->priv->menu_dock), - window->priv->bookmarksbar, - FALSE, FALSE, 0); - gtk_box_pack_end (GTK_BOX (window->priv->menu_dock), GTK_WIDGET (window->priv->toolbar), FALSE, FALSE, 0); /* Once the window is sufficiently created let the extensions attach to it */ manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell)); ephy_extension_attach_window (manager, window); + ephy_bookmarks_ui_attach_window (window); /* We only set the model now after attaching the extensions, so that * extensions already have created their actions which may be on @@ -3051,7 +3087,7 @@ ephy_window_finalize (GObject *object) g_hash_table_destroy (priv->tabs_to_remove); - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (parent_class)->finalize (object); LOG ("EphyWindow finalised %p", object); @@ -3169,22 +3205,6 @@ ephy_window_get_toolbar (EphyWindow *window) } /** - * ephy_window_get_bookmarksbar: - * @window: an #EphyWindow - * - * Returns this window's bookmarks toolbar, which is an #EggEditableToolbar. - * - * Return value: an #EggEditableToolbar - **/ -GtkWidget * -ephy_window_get_bookmarksbar (EphyWindow *window) -{ - g_return_val_if_fail (EPHY_IS_WINDOW (window), NULL); - - return GTK_WIDGET (window->priv->bookmarksbar); -} - -/** * ephy_window_get_notebook: * @window: an #EphyWindow * @@ -3304,7 +3324,7 @@ real_get_active_tab (EphyWindow *window, int page_num) **/ void ephy_window_remove_tab (EphyWindow *window, - EphyTab *tab) + EphyTab *tab) { EphyEmbed *embed; gboolean modified; @@ -3483,10 +3503,10 @@ ephy_window_set_zoom (EphyWindow *window, EphyEmbed *embed; float current_zoom = 1.0; - g_return_if_fail (EPHY_IS_WINDOW (window)); + g_return_if_fail (EPHY_IS_WINDOW (window)); embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); + g_return_if_fail (embed != NULL); current_zoom = ephy_embed_get_zoom (embed); @@ -3512,8 +3532,6 @@ sync_prefs_with_chrome (EphyWindow *window) if (window->priv->should_save_chrome) { - eel_gconf_set_boolean (CONF_WINDOWS_SHOW_BOOKMARKS_BAR, - flags & EPHY_EMBED_CHROME_BOOKMARKSBAR); eel_gconf_set_boolean (CONF_WINDOWS_SHOW_TOOLBARS, flags & EPHY_EMBED_CHROME_TOOLBAR); eel_gconf_set_boolean (CONF_WINDOWS_SHOW_STATUSBAR, @@ -3552,14 +3570,6 @@ ephy_window_view_toolbar_cb (GtkAction *action, } static void -ephy_window_view_bookmarksbar_cb (GtkAction *action, - EphyWindow *window) -{ - sync_chrome_with_view_toggle (action, window, - EPHY_EMBED_CHROME_BOOKMARKSBAR); -} - -static void ephy_window_view_popup_windows_cb (GtkAction *action, EphyWindow *window) { diff --git a/src/ephy-window.h b/src/ephy-window.h index a3c31f994..9722488c4 100644 --- a/src/ephy-window.h +++ b/src/ephy-window.h @@ -43,15 +43,15 @@ typedef struct _EphyWindowPrivate EphyWindowPrivate; struct _EphyWindow { - GtkWindow parent; + GtkWindow parent; /*< private >*/ - EphyWindowPrivate *priv; + EphyWindowPrivate *priv; }; struct _EphyWindowClass { - GtkWindowClass parent_class; + GtkWindowClass parent_class; }; GType ephy_window_get_type (void); @@ -68,8 +68,6 @@ GObject *ephy_window_get_ui_manager (EphyWindow *window); GtkWidget *ephy_window_get_toolbar (EphyWindow *window); -GtkWidget *ephy_window_get_bookmarksbar (EphyWindow *window); - GtkWidget *ephy_window_get_notebook (EphyWindow *window); GtkWidget *ephy_window_get_find_toolbar (EphyWindow *window); |