aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Harvey <pah06@uow.edu.au>2005-10-17 04:29:26 +0800
committerChristian Persch <chpe@src.gnome.org>2005-10-17 04:29:26 +0800
commitd21007362f8d0701d63e50fe6b219de067d95a87 (patch)
tree46326d5633d4f3c8504049476d0e72ae7ed0ca2c
parent35b9deda1f37ac0cc81d926b5295983de6b55dcf (diff)
downloadgsoc2013-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.
-rw-r--r--ChangeLog301
-rw-r--r--data/ui/epiphany-bookmark-editor-ui.xml5
-rw-r--r--data/ui/epiphany-ui.xml1
-rwxr-xr-xlib/egg/egg-editable-toolbar.c1147
-rwxr-xr-xlib/egg/egg-editable-toolbar.h3
-rwxr-xr-xlib/egg/egg-toolbar-editor.c442
-rwxr-xr-xlib/egg/egg-toolbar-editor.h5
-rwxr-xr-xlib/egg/egg-toolbars-model.c670
-rwxr-xr-xlib/egg/egg-toolbars-model.h98
-rw-r--r--src/bookmarks/Makefile.am24
-rw-r--r--src/bookmarks/ephy-bookmark-action-group.c178
-rw-r--r--src/bookmarks/ephy-bookmark-action-group.h33
-rw-r--r--src/bookmarks/ephy-bookmark-action.c444
-rw-r--r--src/bookmarks/ephy-bookmark-action.h19
-rw-r--r--src/bookmarks/ephy-bookmark-factory-action.c319
-rw-r--r--src/bookmarks/ephy-bookmark-factory-action.h54
-rw-r--r--src/bookmarks/ephy-bookmark-properties.c77
-rw-r--r--src/bookmarks/ephy-bookmarks-editor.c239
-rw-r--r--src/bookmarks/ephy-bookmarks-menu.c902
-rw-r--r--src/bookmarks/ephy-bookmarks-menu.h37
-rw-r--r--src/bookmarks/ephy-bookmarks-ui.c552
-rw-r--r--src/bookmarks/ephy-bookmarks-ui.h33
-rw-r--r--src/bookmarks/ephy-bookmarks.c293
-rw-r--r--src/bookmarks/ephy-bookmarks.h8
-rwxr-xr-xsrc/bookmarks/ephy-bookmarksbar-model.c588
-rwxr-xr-xsrc/bookmarks/ephy-bookmarksbar-model.h76
-rw-r--r--src/bookmarks/ephy-bookmarksbar.c380
-rw-r--r--src/bookmarks/ephy-bookmarksbar.h64
-rw-r--r--src/bookmarks/ephy-favorites-menu.c319
-rw-r--r--src/bookmarks/ephy-favorites-menu.h59
-rw-r--r--src/bookmarks/ephy-new-bookmark.c33
-rw-r--r--src/bookmarks/ephy-nodes-cover.c196
-rw-r--r--src/bookmarks/ephy-nodes-cover.h41
-rw-r--r--src/bookmarks/ephy-open-tabs-action.c119
-rw-r--r--src/bookmarks/ephy-open-tabs-action.h30
-rw-r--r--src/bookmarks/ephy-related-action.c178
-rw-r--r--src/bookmarks/ephy-related-action.h59
-rw-r--r--src/bookmarks/ephy-topic-action-group.c123
-rw-r--r--src/bookmarks/ephy-topic-action-group.h34
-rw-r--r--src/bookmarks/ephy-topic-action.c996
-rw-r--r--src/bookmarks/ephy-topic-action.h38
-rw-r--r--src/bookmarks/ephy-topic-factory-action.c318
-rw-r--r--src/bookmarks/ephy-topic-factory-action.h55
-rw-r--r--src/ephy-link-action.c44
-rw-r--r--src/ephy-link-action.h41
-rw-r--r--src/ephy-lockdown.c18
-rw-r--r--src/ephy-notebook.c39
-rw-r--r--src/ephy-shell.c16
-rw-r--r--src/ephy-toolbar-editor.c36
-rwxr-xr-xsrc/ephy-toolbar.c49
-rwxr-xr-xsrc/ephy-toolbars-model.c89
-rw-r--r--src/ephy-window.c268
-rw-r--r--src/ephy-window.h8
53 files changed, 4973 insertions, 5225 deletions
diff --git a/ChangeLog b/ChangeLog
index 16f121f93..ee687b164 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,304 @@
+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.
+
2005-10-16 Philip Langdale <philipl@mail.utexas.edu>
* configure.ac: Add another necessary mozilla include subdir to
diff --git a/data/ui/epiphany-bookmark-editor-ui.xml b/data/ui/epiphany-bookmark-editor-ui.xml
index 9002767bf..79bb82e49 100644
--- a/data/ui/epiphany-bookmark-editor-ui.xml
+++ b/data/ui/epiphany-bookmark-editor-ui.xml
@@ -10,7 +10,6 @@
<menuitem name="FileRename" action="Rename"/>
<menuitem name="FileDelete" action="Delete"/>
<separator name="FileSep3"/>
- <menuitem name="FileShowInBookmarksBar" action="ShowInBookmarksBar"/>
<menuitem name="FileProperties" action="Properties"/>
<separator name="FileSep4"/>
<menuitem name="FileImport" action="Import"/>
@@ -47,16 +46,12 @@
<menuitem name="RenameBMK" action="Rename"/>
<menuitem name="DeleteBMK" action="Delete"/>
<separator name="BookmarksPopupSep3"/>
- <menuitem name="ShowInBookmarksBarBMK" action="ShowInBookmarksBar"/>
- <separator name="BookmarksPopupSep4"/>
<menuitem name="BMKProperties" action="Properties"/>
</popup>
<popup name="EphyBookmarkKeywordPopup" action="PopupAction">
<menuitem name="RenameTPC" action="Rename"/>
<menuitem name="DeleteTPC" action="Delete"/>
- <separator name="TopicPopupSep3"/>
- <menuitem name="ShowInBookmarksBarTPC" action="ShowInBookmarksBar"/>
</popup>
</ui>
diff --git a/data/ui/epiphany-ui.xml b/data/ui/epiphany-ui.xml
index b7c3b4a1a..1e30279c5 100644
--- a/data/ui/epiphany-ui.xml
+++ b/data/ui/epiphany-ui.xml
@@ -38,7 +38,6 @@
<menu name="ViewMenu" action="View">
<placeholder name="ViewTogglesGroup" position="top">
<menuitem name="ViewToolbarMenu" action="ViewToolbar"/>
- <menuitem name="ViewBookmarksBarMenu" action="ViewBookmarksBar"/>
<menuitem name="ViewStatusbarMenu" action="ViewStatusbar"/>
</placeholder>
<separator name="ViewSep1"/>
diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c
index 006df26a7..87b26b3bd 100755
--- a/lib/egg/egg-editable-toolbar.c
+++ b/lib/egg/egg-editable-toolbar.c
@@ -32,20 +32,27 @@
#include <gtk/gtkdnd.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkimage.h>
+#include <gtk/gtkcheckmenuitem.h>
#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkseparatormenuitem.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkstock.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkbutton.h>
#include <gtk/gtktoolbar.h>
#include <gtk/gtktoolitem.h>
+#include <gtk/gtktoolbutton.h>
#include <gtk/gtkseparatortoolitem.h>
#include <glib/gi18n.h>
#include <string.h>
static void egg_editable_toolbar_class_init (EggEditableToolbarClass *klass);
-static void egg_editable_toolbar_init (EggEditableToolbar *t);
+static void egg_editable_toolbar_init (EggEditableToolbar *etoolbar);
static void egg_editable_toolbar_finalize (GObject *object);
#define MIN_TOOLBAR_HEIGHT 20
+#define EGG_ITEM_NAME "egg-item-name"
+#define EGG_TOOLITEM "egg-toolitem"
static const GtkTargetEntry dest_drag_types[] = {
{EGG_TOOLBAR_ITEM_TYPE, GTK_TARGET_SAME_APP, 0},
@@ -74,13 +81,13 @@ struct _EggEditableToolbarPrivate
{
GtkUIManager *manager;
EggToolbarsModel *model;
- gboolean edit_mode;
- GtkWidget *selected_toolbar;
+ guint edit_mode;
+ gboolean save_hidden;
GtkWidget *fixed_toolbar;
- gboolean pending;
- GtkToolbar *target_toolbar;
- GtkWidget *dragged_item;
+ guint dnd_pending;
+ GtkToolbar *dnd_toolbar;
+ GtkToolItem *dnd_toolitem;
};
GType
@@ -111,19 +118,25 @@ egg_editable_toolbar_get_type (void)
}
static int
-get_toolbar_position (EggEditableToolbar *etoolbar, GtkWidget *toolbar)
+get_dock_position (EggEditableToolbar *etoolbar, GtkWidget *dock)
{
GList *l;
int result;
l = gtk_container_get_children (GTK_CONTAINER (etoolbar));
- result = g_list_index (l, toolbar->parent);
+ result = g_list_index (l, dock);
g_list_free (l);
return result;
}
static int
+get_toolbar_position (EggEditableToolbar *etoolbar, GtkWidget *toolbar)
+{
+ return get_dock_position (etoolbar, toolbar->parent);
+}
+
+static int
get_n_toolbars (EggEditableToolbar *etoolbar)
{
GList *l;
@@ -159,6 +172,7 @@ get_toolbar_nth (EggEditableToolbar *etoolbar,
GtkWidget *result;
dock = get_dock_nth (etoolbar, position);
+ g_return_val_if_fail (dock != NULL, NULL);
l = gtk_container_get_children (GTK_CONTAINER (dock));
result = GTK_WIDGET (l->data);
@@ -168,13 +182,13 @@ get_toolbar_nth (EggEditableToolbar *etoolbar,
}
static GtkAction *
-find_action (EggEditableToolbar *t,
+find_action (EggEditableToolbar *etoolbar,
const char *name)
{
GList *l;
GtkAction *action = NULL;
- l = gtk_ui_manager_get_action_groups (t->priv->manager);
+ l = gtk_ui_manager_get_action_groups (etoolbar->priv->manager);
g_return_val_if_fail (name != NULL, NULL);
@@ -197,6 +211,8 @@ drag_data_delete_cb (GtkWidget *widget,
{
int pos, toolbar_pos;
+ widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
+ g_return_if_fail (widget != NULL);
g_return_if_fail (EGG_IS_EDITABLE_TOOLBAR (etoolbar));
pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (widget->parent),
@@ -212,7 +228,9 @@ drag_begin_cb (GtkWidget *widget,
GdkDragContext *context,
EggEditableToolbar *etoolbar)
{
- gtk_widget_hide (widget);
+ widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
+ g_return_if_fail (widget != NULL);
+ gtk_widget_hide (widget);
}
static void
@@ -220,7 +238,9 @@ drag_end_cb (GtkWidget *widget,
GdkDragContext *context,
EggEditableToolbar *etoolbar)
{
- gtk_widget_show (widget);
+ widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
+ g_return_if_fail (widget != NULL);
+ gtk_widget_show (widget);
}
static void
@@ -231,223 +251,481 @@ drag_data_get_cb (GtkWidget *widget,
guint32 time,
EggEditableToolbar *etoolbar)
{
- const char *id, *type;
- char *target;
+ EggToolbarsModel *model;
+ const char *name;
+ char *data;
+ widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
+ g_return_if_fail (widget != NULL);
+
g_return_if_fail (EGG_IS_EDITABLE_TOOLBAR (etoolbar));
-
- type = g_object_get_data (G_OBJECT (widget), "type");
- id = g_object_get_data (G_OBJECT (widget), "id");
- if (strcmp (id, "separator") == 0)
+ model = egg_editable_toolbar_get_model (etoolbar);
+
+ name = g_object_get_data (G_OBJECT (widget), EGG_ITEM_NAME);
+ if (name == NULL)
{
- target = g_strdup (id);
+ name = g_object_get_data (G_OBJECT (gtk_widget_get_parent (widget)), EGG_ITEM_NAME);
+ g_return_if_fail (name != NULL);
}
- else
+
+ data = egg_toolbars_model_get_data (model, selection_data->target, name);
+ if (data != NULL)
{
- target = egg_toolbars_model_get_item_data (etoolbar->priv->model,
- type, id);
+ gtk_selection_data_set (selection_data, selection_data->target, 8, (unsigned char *)data, strlen (data));
+ g_free (data);
}
+}
- gtk_selection_data_set (selection_data,
- selection_data->target, 8,
- (const guchar *)target, strlen (target));
-
- g_free (target);
+static void
+move_item_cb (GtkWidget *menuitem,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *toolitem = g_object_get_data (G_OBJECT (menuitem), EGG_TOOLITEM);
+ GtkTargetList *list = gtk_target_list_new (dest_drag_types, G_N_ELEMENTS (dest_drag_types));
+ gtk_drag_begin (toolitem, list, GDK_ACTION_MOVE, 1, NULL);
+ gtk_target_list_unref (list);
}
static void
-set_drag_cursor (GtkWidget *widget)
+set_dock_visible (EggEditableToolbar *etoolbar,
+ GtkWidget *dock,
+ gboolean visible)
{
- if (widget->window)
+ if (visible)
{
- GdkCursor *cursor;
- GdkPixbuf *pixbuf;
-
- pixbuf = gdk_pixbuf_new_from_file (CURSOR_DIR "/hand-open.png", NULL);
- cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (),
- pixbuf, 12, 12);
- gdk_window_set_cursor (widget->window, cursor);
- gdk_cursor_unref (cursor);
- g_object_unref (pixbuf);
+ gtk_widget_show (dock);
+ }
+ else
+ {
+ gtk_widget_hide (dock);
+ }
+
+ if (etoolbar->priv->save_hidden)
+ {
+ int position = get_dock_position (etoolbar, dock);
+ EggTbModelFlags flags = egg_toolbars_model_get_flags
+ (etoolbar->priv->model, position);
+
+ if (visible)
+ {
+ flags &= ~(EGG_TB_MODEL_HIDDEN);
+ }
+ else
+ {
+ flags |= (EGG_TB_MODEL_HIDDEN);
+ }
+
+ egg_toolbars_model_set_flags (etoolbar->priv->model, position, flags);
}
}
static void
-unset_drag_cursor (GtkWidget *widget)
+remove_item_cb (GtkWidget *menuitem,
+ EggEditableToolbar *etoolbar)
{
- if (widget->window)
+ GtkWidget *toolitem = g_object_get_data (G_OBJECT (menuitem), EGG_TOOLITEM);
+ int pos, toolbar_pos;
+
+ toolbar_pos = get_toolbar_position (etoolbar, toolitem->parent);
+ pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolitem->parent),
+ GTK_TOOL_ITEM (toolitem));
+
+ egg_toolbars_model_remove_item (etoolbar->priv->model,
+ toolbar_pos, pos);
+
+ if (egg_toolbars_model_n_items (etoolbar->priv->model, toolbar_pos) == 0)
{
- gdk_window_set_cursor (widget->window, NULL);
+ egg_toolbars_model_remove_toolbar (etoolbar->priv->model, toolbar_pos);
}
}
static void
-set_item_drag_source (EggToolbarsModel *model,
- GtkWidget *item,
- GtkAction *action,
- gboolean is_separator,
- const char *type)
+remove_toolbar_cb (GtkWidget *menuitem,
+ EggEditableToolbar *etoolbar)
{
- GtkTargetEntry target_entry;
- const char *id;
+ GtkWidget *toolbar = g_object_get_data (G_OBJECT (menuitem), "egg-toolbar");
+ int toolbar_pos;
- target_entry.target = (char *)type;
- target_entry.flags = GTK_TARGET_SAME_APP;
- target_entry.info = 0;
+ toolbar_pos = get_toolbar_position (etoolbar, toolbar);
+ egg_toolbars_model_remove_toolbar (etoolbar->priv->model, toolbar_pos);
+}
- gtk_drag_source_set (item, GDK_BUTTON1_MASK,
- &target_entry, 1,
- GDK_ACTION_MOVE);
+static void
+toggle_visibility_cb (GtkWidget *menuitem,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *dock = g_object_get_data (G_OBJECT (menuitem), "egg-dock");
+ set_dock_visible (etoolbar, dock, !GTK_WIDGET_VISIBLE (dock));
+}
- if (is_separator)
- {
- GtkWidget *icon;
- GdkPixbuf *pixbuf;
+static void
+egg_editable_toolbar_add_visibility_items (EggEditableToolbar *etoolbar,
+ GtkMenu *popup)
+{
+ EggToolbarsModel *model = etoolbar->priv->model;
+ GtkCheckMenuItem *item;
+ GtkWidget *dock;
+ int n_toolbars, n_items, n_visible = 0;
+ int i, j, k, l;
- id = "separator";
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (etoolbar->priv->manager != NULL);
- icon = _egg_editable_toolbar_new_separator_image ();
- pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (icon));
- gtk_drag_source_set_icon_pixbuf (item, pixbuf);
+ n_toolbars = egg_toolbars_model_n_toolbars (model);
+
+ for (i = 0; i < n_toolbars; i++)
+ {
+ dock = get_dock_nth (etoolbar, i);
+ if (GTK_WIDGET_VISIBLE (dock))
+ n_visible++;
}
- else
+
+ if (GTK_MENU_SHELL(popup)->children != NULL)
{
- const char *stock_id;
- GValue value = { 0, };
- GdkPixbuf *pixbuf;
+ GtkWidget *separator = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator);
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), separator);
+ }
+
+ for (i = 0; i < n_toolbars; i++)
+ {
+ char buffer[40] = "Empty";
- id = gtk_action_get_name (action);
+ n_items = egg_toolbars_model_n_items (model, i);
+ for (k = 0, j = 0; j < n_items && k < sizeof(buffer)-1; j++)
+ {
+ GValue value = { 0, };
+ GtkAction *action;
+ const char *name;
+
+ name = egg_toolbars_model_item_nth (model, i, j);
+ if (name == NULL) continue;
+ action = find_action (etoolbar, name);
+ if (action == NULL) continue;
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_object_get_property (G_OBJECT (action), "label", &value);
+ name = g_value_get_string (&value);
+ if (name == NULL) continue;
+
+ if (j > 0)
+ {
+ if(k<sizeof(buffer)-1) buffer[k++] = ',';
+ if(k<sizeof(buffer)-1) buffer[k++] = ' ';
+ }
+
+ for (l = 0; name[l] && k<sizeof(buffer)-1; l++)
+ {
+ switch(name[l])
+ {
+ case '_':
+ case '.':
+ case ',':
+ break;
+ default:
+ buffer[k++] = name[l];
+ }
+ }
+
+ if (name[l])
+ {
+ l = k-5;
+ while(l>0 && buffer[l] != ',') l--;
+ if(buffer[l] == ',') k = l + 2;
+ else k = k-3;
+
+ buffer[k++] = '.';
+ buffer[k++] = '.';
+ buffer[k++] = '.';
+ buffer[k] = 0;
+ break;
+ }
+
+ buffer[k] = 0;
- g_value_init (&value, G_TYPE_STRING);
- g_object_get_property (G_OBJECT (action), "stock_id", &value);
- stock_id = g_value_get_string (&value);
+ g_value_unset (&value);
+ }
+
+
+ dock = get_dock_nth (etoolbar, i);
+ item = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (buffer));
+ gtk_check_menu_item_set_active (item, GTK_WIDGET_VISIBLE (dock));
+ gtk_widget_set_sensitive (GTK_WIDGET (item), (n_visible > 1 || !GTK_WIDGET_VISIBLE (dock)));
+ gtk_widget_show (GTK_WIDGET (item));
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), GTK_WIDGET (item));
+
+ g_object_set_data (G_OBJECT (item), "egg-dock", dock);
+ g_signal_connect (item, "toggled",
+ G_CALLBACK (toggle_visibility_cb),
+ etoolbar);
+ }
+}
- if (stock_id != NULL)
+void
+egg_editable_toolbar_add_popup_items (GtkWidget *widget,
+ GtkMenu *popup)
+{
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR
+ (gtk_widget_get_ancestor (widget, EGG_TYPE_EDITABLE_TOOLBAR));
+ GtkWidget *toolbar = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR);
+ GtkWidget *toolitem = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
+ GtkWidget *item, *image;
+ int separated;
+
+ separated = (GTK_MENU_SHELL(popup)->children == NULL);
+
+ if (etoolbar != NULL && toolitem != NULL)
+ {
+ if (!separated)
{
- pixbuf = gtk_widget_render_icon (item, stock_id,
- GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
+ item = gtk_separator_menu_item_new ();
+ gtk_widget_show (item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ separated = 1;
}
- else
+
+ item = gtk_menu_item_new_with_mnemonic (_("_Move on Toolbar"));
+ g_object_set_data (G_OBJECT (item), EGG_TOOLITEM, toolitem);
+ gtk_widget_show (item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (item, "activate",
+ G_CALLBACK (move_item_cb),
+ etoolbar);
+
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Remove from Toolbar"));
+ g_object_set_data (G_OBJECT (item), EGG_TOOLITEM, toolitem);
+ 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_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (item, "activate",
+ G_CALLBACK (remove_item_cb),
+ etoolbar);
+ }
+
+ if (etoolbar != NULL && toolbar != NULL)
+ {
+ int position;
+ EggTbModelFlags flags;
+
+ position = get_toolbar_position (etoolbar, toolbar);
+ flags = egg_toolbars_model_get_flags (etoolbar->priv->model, position);
+
+ if (etoolbar->priv->edit_mode > 0 && (flags & EGG_TB_MODEL_NOT_REMOVABLE)==0)
{
- pixbuf = gtk_widget_render_icon (item, GTK_STOCK_DND,
- GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
+ if (!separated)
+ {
+ item = gtk_separator_menu_item_new ();
+ gtk_widget_show (item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ separated = 1;
+ }
+
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar"));
+ g_object_set_data (G_OBJECT (item), "egg-toolbar", 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_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (item, "activate",
+ G_CALLBACK (remove_toolbar_cb),
+ etoolbar);
}
- gtk_drag_source_set_icon_pixbuf (item, pixbuf);
- g_object_unref (pixbuf);
-
- g_value_unset (&value);
+ if (egg_toolbars_model_n_toolbars (etoolbar->priv->model) > 1)
+ {
+ egg_editable_toolbar_add_visibility_items (etoolbar, popup);
+ }
}
+}
- g_object_set_data_full (G_OBJECT (item), "id",
- g_strdup (id), g_free);
- g_object_set_data_full (G_OBJECT (item), "type",
- g_strdup (type), g_free);
+static void
+popup_context_menu_cb (GtkWidget *toolbar,
+ gint x,
+ gint y,
+ gint button_number,
+ EggEditableToolbar *etoolbar)
+{
+ GtkMenu *menu = GTK_MENU (gtk_menu_new ());
+ egg_editable_toolbar_add_popup_items (toolbar, menu);
+ gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_number,
+ gtk_get_current_event_time ());
}
-static GtkWidget *
-create_item_from_action (EggEditableToolbar *t,
- const char *action_name,
- const char *type,
- gboolean is_separator,
- GtkAction **ret_action)
+static gboolean
+button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ EggEditableToolbar *etoolbar)
+{
+ if (event->button == 3)
+ {
+ GtkMenu *menu = GTK_MENU (gtk_menu_new ());
+ egg_editable_toolbar_add_popup_items (widget, menu);
+ gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button,
+ event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+configure_item_sensitivity (GtkToolItem *item, EggEditableToolbar *etoolbar)
{
- GtkWidget *item;
GtkAction *action;
+ char *name;
+
+ g_return_if_fail (etoolbar != NULL);
+
+ if (etoolbar->priv->edit_mode > 0)
+ {
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE);
+ gtk_tool_item_set_use_drag_window (item, TRUE);
+ gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
+ return;
+ }
+
+ name = g_object_get_data (G_OBJECT (item), EGG_ITEM_NAME);
+ action = name ? find_action (etoolbar, name) : NULL;
- if (is_separator)
+ if (action != NULL && gtk_action_is_sensitive (action))
{
- item = GTK_WIDGET (gtk_separator_tool_item_new ());
- action = NULL;
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE);
+ gtk_tool_item_set_use_drag_window (item, FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
}
else
{
- g_return_val_if_fail (action_name != NULL, NULL);
-
- g_signal_emit (G_OBJECT (t), egg_editable_toolbar_signals[ACTION_REQUEST],
- 0, action_name);
-
- action = find_action (t, action_name);
- if (action)
- {
- item = gtk_action_create_tool_item (action);
- }
- else
- {
- return NULL;
- }
+ gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
+ gtk_tool_item_set_use_drag_window (item, TRUE);
+ GTK_WIDGET_SET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE);
}
+}
- gtk_widget_show (item);
+static void
+configure_item_cursor (GtkToolItem *item, EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (etoolbar != NULL);
+ g_return_if_fail (GTK_WIDGET(item)->window != NULL);
+
+ if (etoolbar->priv->edit_mode > 0)
+ {
+ GdkCursor *cursor;
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gdk_pixbuf_new_from_file (CURSOR_DIR "/hand-open.png", NULL);
+ cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (),
+ pixbuf, 12, 12);
+ gdk_window_set_cursor (GTK_WIDGET(item)->window, cursor);
+ gdk_cursor_unref (cursor);
+ g_object_unref (pixbuf);
- g_signal_connect (item, "drag_begin",
- G_CALLBACK (drag_begin_cb), t);
- g_signal_connect (item, "drag_end",
- G_CALLBACK (drag_end_cb), t);
- g_signal_connect (item, "drag_data_get",
- G_CALLBACK (drag_data_get_cb), t);
- g_signal_connect (item, "drag_data_delete",
- G_CALLBACK (drag_data_delete_cb), t);
+ gtk_drag_source_set (GTK_WIDGET (item), GDK_BUTTON1_MASK, dest_drag_types,
+ G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE);
+ }
+ else
+ {
+ gdk_window_set_cursor (GTK_WIDGET(item)->window, NULL);
+
+ gtk_drag_source_set (GTK_WIDGET (item), GDK_BUTTON2_MASK, dest_drag_types,
+ G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE);
+ }
+}
- if (t->priv->edit_mode)
+static void
+connect_widget_signals (GtkWidget *proxy, EggEditableToolbar *etoolbar)
+{
+ if (GTK_IS_CONTAINER (proxy))
{
- set_drag_cursor (item);
- gtk_widget_set_sensitive (item, TRUE);
- set_item_drag_source (t->priv->model, item, action,
- is_separator, type);
- gtk_tool_item_set_use_drag_window (GTK_TOOL_ITEM (item), TRUE);
+ gtk_container_foreach (GTK_CONTAINER (proxy),
+ (GtkCallback) connect_widget_signals,
+ (gpointer) etoolbar);
}
- if (ret_action)
+ if (GTK_IS_BUTTON (proxy) || GTK_IS_TOOL_ITEM (proxy))
{
- *ret_action = action;
+ g_signal_connect (proxy, "drag_begin",
+ G_CALLBACK (drag_begin_cb), etoolbar);
+ g_signal_connect (proxy, "drag_end",
+ G_CALLBACK (drag_end_cb), etoolbar);
+ g_signal_connect (proxy, "drag_data_get",
+ G_CALLBACK (drag_data_get_cb), etoolbar);
+ g_signal_connect (proxy, "drag_data_delete",
+ G_CALLBACK (drag_data_delete_cb), etoolbar);
+ g_signal_connect (proxy, "drag_data_get",
+ G_CALLBACK (drag_data_get_cb), etoolbar);
+ g_signal_connect (proxy, "button-press-event",
+ G_CALLBACK (button_press_event_cb), etoolbar);
+ gtk_drag_source_set (proxy, GDK_BUTTON2_MASK, dest_drag_types,
+ G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE);
}
+}
- return item;
+static void
+action_sensitive_cb (GtkAction *action,
+ GParamSpec *pspec,
+ GtkToolItem *item)
+{
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR
+ (gtk_widget_get_ancestor (GTK_WIDGET (item), EGG_TYPE_EDITABLE_TOOLBAR));
+ configure_item_sensitivity (item, etoolbar);
}
-static GtkWidget *
-create_item (EggEditableToolbar *t,
- EggToolbarsModel *model,
- int toolbar_position,
- int position,
- GtkAction **ret_action)
+static GtkToolItem *
+create_item_from_action (EggEditableToolbar *etoolbar,
+ const char *name)
{
- const char *action_name, *type;
- gboolean is_separator;
+ GtkToolItem *item;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ if (strcmp (name, "_separator") == 0)
+ {
+ item = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_use_drag_window (item, TRUE);
+ }
+ else
+ {
+ GtkAction *action = find_action (etoolbar, name);
+ g_return_val_if_fail (action != NULL, NULL);
+ item = GTK_TOOL_ITEM (gtk_action_create_tool_item (action));
+
+ g_signal_connect_object (action, "notify::sensitive",
+ G_CALLBACK (action_sensitive_cb), item, 0);
+ }
- egg_toolbars_model_item_nth (model, toolbar_position, position,
- &is_separator, &action_name, &type);
- return create_item_from_action (t, action_name, type,
- is_separator, ret_action);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ g_object_set_data_full (G_OBJECT (item), EGG_ITEM_NAME,
+ g_strdup (name), g_free);
+
+ return item;
}
-static gboolean
-data_is_separator (const char *data)
+static GtkToolItem *
+create_item_from_position (EggEditableToolbar *etoolbar,
+ int toolbar_position,
+ int position)
{
- return strcmp (data, "separator") == 0;
+ GtkToolItem *item;
+ const char *name;
+
+ name = egg_toolbars_model_item_nth (etoolbar->priv->model, toolbar_position, position);
+ item = create_item_from_action (etoolbar, name);
+
+ return item;
}
static void
-drag_data_received_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- EggEditableToolbar *etoolbar)
+toolbar_drag_data_received_cb (GtkToolbar *toolbar,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EggEditableToolbar *etoolbar)
{
- char *type;
- char *id;
-
- GdkAtom target;
-
- target = gtk_drag_dest_find_target (widget, context, NULL);
- type = egg_toolbars_model_get_item_type (etoolbar->priv->model, target);
- id = egg_toolbars_model_get_item_id (etoolbar->priv->model, type,
- (const char*)selection_data->data);
-
/* This function can be called for two reasons
*
* (1) drag_motion() needs an item to pass to
@@ -459,113 +737,60 @@ drag_data_received_cb (GtkWidget *widget,
* actually add a new item to the toolbar.
*/
- if (id == NULL)
+ GdkAtom type = selection_data->type;
+ const char *data = (char *)selection_data->data;
+
+ int ipos = -1;
+ char *name = NULL;
+
+ /* Find out where the drop is occuring, and the name of what is being dropped. */
+ if (selection_data->length >= 0)
{
- etoolbar->priv->pending = FALSE;
- g_free (type);
- return;
+ ipos = gtk_toolbar_get_drop_index (toolbar, x, y);
+ name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, FALSE);
}
- if (etoolbar->priv->pending)
+ /* If we just want a highlight item, then . */
+ if (etoolbar->priv->dnd_pending > 0)
{
- etoolbar->priv->pending = FALSE;
- etoolbar->priv->dragged_item =
- create_item_from_action (etoolbar, id, type,
- data_is_separator (id), NULL);
- g_object_ref (etoolbar->priv->dragged_item);
- gtk_object_sink (GTK_OBJECT (etoolbar->priv->dragged_item));
- }
- else
- {
- int pos, toolbar_pos;
-
- pos = gtk_toolbar_get_drop_index (GTK_TOOLBAR (widget), x, y);
- toolbar_pos = get_toolbar_position (etoolbar, widget);
-
- if (data_is_separator ((const char*)selection_data->data))
- {
- egg_toolbars_model_add_separator (etoolbar->priv->model,
- toolbar_pos, pos);
- }
- else
- {
- egg_toolbars_model_add_item (etoolbar->priv->model,
- toolbar_pos, pos, id, type);
- }
+ etoolbar->priv->dnd_pending--;
- gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE,
- time);
- }
-
- g_free (type);
- g_free (id);
-}
-
-static void
-remove_toolbar_cb (GtkWidget *menuitem,
- EggEditableToolbar *etoolbar)
-{
- int pos;
-
- pos = get_toolbar_position (etoolbar, etoolbar->priv->selected_toolbar);
- egg_toolbars_model_remove_toolbar (etoolbar->priv->model, pos);
-}
-
-static void
-popup_toolbar_context_menu_cb (GtkWidget *toolbar,
- gint x,
- gint y,
- gint button_number,
- EggEditableToolbar *t)
-{
- GtkWidget *menu;
- GtkWidget *item;
- GtkWidget *image;
-
- if (t->priv->edit_mode)
- {
- EggTbModelFlags flags;
- int position;
-
- t->priv->selected_toolbar = toolbar;
-
- menu = gtk_menu_new ();
-
- item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar"));
- gtk_widget_show (item);
- image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
- gtk_widget_show (image);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- g_signal_connect (item, "activate",
- G_CALLBACK (remove_toolbar_cb),
- t);
-
- position = get_toolbar_position (t, toolbar);
- flags = egg_toolbars_model_get_flags (t->priv->model, position);
- if (flags & EGG_TB_MODEL_NOT_REMOVABLE)
+ if (name != NULL && etoolbar->priv->dnd_toolbar == toolbar)
{
- gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
+ etoolbar->priv->dnd_toolitem = create_item_from_action (etoolbar, name);
+ gtk_toolbar_set_drop_highlight_item (etoolbar->priv->dnd_toolbar,
+ etoolbar->priv->dnd_toolitem, ipos);
}
-
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 2,
- gtk_get_current_event_time ());
}
-}
-
-static void
-free_dragged_item (EggEditableToolbar *etoolbar)
-{
- if (etoolbar->priv->dragged_item)
+ else
{
- gtk_widget_destroy (etoolbar->priv->dragged_item);
- g_object_unref (etoolbar->priv->dragged_item);
- etoolbar->priv->dragged_item = NULL;
+ gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0);
+ etoolbar->priv->dnd_toolbar = NULL;
+ etoolbar->priv->dnd_toolitem = NULL;
+
+ /* If we don't have a name to use yet, try to create one. */
+ if (name == NULL && selection_data->length >= 0)
+ {
+ name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, TRUE);
+ }
+
+ if (name != NULL)
+ {
+ gint tpos = get_toolbar_position (etoolbar, GTK_WIDGET (toolbar));
+ egg_toolbars_model_add_item (etoolbar->priv->model, tpos, ipos, name);
+ gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE, time);
+ }
+ else
+ {
+ gtk_drag_finish (context, FALSE, context->action == GDK_ACTION_MOVE, time);
+ }
}
+
+ g_free (name);
}
static gboolean
-toolbar_drag_drop_cb (GtkWidget *widget,
+toolbar_drag_drop_cb (GtkToolbar *toolbar,
GdkDragContext *context,
gint x,
gint y,
@@ -574,88 +799,46 @@ toolbar_drag_drop_cb (GtkWidget *widget,
{
GdkAtom target;
- target = gtk_drag_dest_find_target (widget, context, NULL);
+ target = gtk_drag_dest_find_target (GTK_WIDGET (toolbar), context, NULL);
if (target != GDK_NONE)
{
- gtk_drag_get_data (widget, context,
- target,
- time);
+ gtk_drag_get_data (GTK_WIDGET (toolbar), context, target, time);
return TRUE;
}
- free_dragged_item (etoolbar);
-
return FALSE;
}
static gboolean
-toolbar_drag_motion_cb (GtkWidget *widget,
+toolbar_drag_motion_cb (GtkToolbar *toolbar,
GdkDragContext *context,
gint x,
gint y,
guint time,
EggEditableToolbar *etoolbar)
{
- GdkAtom target;
- int index;
- GtkToolbar *toolbar = GTK_TOOLBAR (widget);
- GtkToolItem *item;
- GtkWidget *source;
-
- source = gtk_drag_get_source_widget (context);
- if (source)
- {
- EggTbModelFlags flags;
- int pos;
- gboolean is_item;
-
- pos = get_toolbar_position (etoolbar, widget);
- flags = egg_toolbars_model_get_flags (etoolbar->priv->model, pos);
-
- is_item = etoolbar->priv->edit_mode &&
- (gtk_widget_get_ancestor (source, EGG_TYPE_EDITABLE_TOOLBAR) ||
- gtk_widget_get_ancestor (source, EGG_TYPE_TOOLBAR_EDITOR));
-
- if ((flags & EGG_TB_MODEL_ACCEPT_ITEMS_ONLY) && !is_item)
- {
- gdk_drag_status (context, 0, time);
- return FALSE;
- }
-
- if (gtk_widget_is_ancestor (source, widget))
- {
- context->suggested_action = GDK_ACTION_MOVE;
- }
- }
-
- target = gtk_drag_dest_find_target (widget, context, NULL);
+ GdkAtom target = gtk_drag_dest_find_target (GTK_WIDGET (toolbar), context, NULL);
if (target == GDK_NONE)
{
gdk_drag_status (context, 0, time);
return FALSE;
}
- if (etoolbar->priv->target_toolbar != toolbar)
+ /* Make ourselves the current dnd toolbar, and request a highlight item. */
+ if (etoolbar->priv->dnd_toolbar != toolbar)
{
- if (etoolbar->priv->target_toolbar)
- gtk_toolbar_set_drop_highlight_item
- (etoolbar->priv->target_toolbar, NULL, 0);
-
- free_dragged_item (etoolbar);
- etoolbar->priv->pending = TRUE;
-
- etoolbar->priv->target_toolbar = toolbar;
-
- gtk_drag_get_data (widget, context, target, time);
+ etoolbar->priv->dnd_toolbar = toolbar;
+ etoolbar->priv->dnd_toolitem = NULL;
+ etoolbar->priv->dnd_pending++;
+ gtk_drag_get_data (GTK_WIDGET (toolbar), context, target, time);
}
-
- if (etoolbar->priv->dragged_item != NULL &&
- etoolbar->priv->edit_mode)
+
+ /* If a highlight item is available, use it. */
+ else if (etoolbar->priv->dnd_toolitem)
{
- item = GTK_TOOL_ITEM (etoolbar->priv->dragged_item);
-
- index = gtk_toolbar_get_drop_index (toolbar, x, y);
- gtk_toolbar_set_drop_highlight_item (toolbar, item, index);
+ gint ipos = gtk_toolbar_get_drop_index (etoolbar->priv->dnd_toolbar, x, y);
+ gtk_toolbar_set_drop_highlight_item (etoolbar->priv->dnd_toolbar,
+ etoolbar->priv->dnd_toolitem, ipos);
}
gdk_drag_status (context, context->suggested_action, time);
@@ -669,53 +852,68 @@ toolbar_drag_leave_cb (GtkToolbar *toolbar,
guint time,
EggEditableToolbar *etoolbar)
{
- /* This is a workaround for bug 125557. Sometimes
- * we seemingly enter another toolbar *before* leaving
- * the current one.
- *
- * In that case etoolbar->priv->target_toolbar will
- * have been set to something else and the highlighting
- * will already have been turned off
- */
-
- if (etoolbar->priv->target_toolbar == toolbar)
- {
- gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0);
+ gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0);
- etoolbar->priv->target_toolbar = NULL;
- free_dragged_item (etoolbar);
+ /* If we were the current dnd toolbar target, remove the item. */
+ if (etoolbar->priv->dnd_toolbar == toolbar)
+ {
+ etoolbar->priv->dnd_toolbar = NULL;
+ etoolbar->priv->dnd_toolitem = NULL;
}
}
+static void
+configure_drag_dest (EggEditableToolbar *etoolbar,
+ GtkToolbar *toolbar)
+{
+ EggToolbarsItemType *type;
+ GtkTargetList *targets;
+ GList *list;
+
+ /* Make every toolbar able to receive drag-drops. */
+ gtk_drag_dest_set (GTK_WIDGET (toolbar), 0,
+ dest_drag_types, G_N_ELEMENTS (dest_drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
+
+ /* Add any specialist drag-drop abilities. */
+ targets = gtk_drag_dest_get_target_list (GTK_WIDGET (toolbar));
+ list = egg_toolbars_model_get_types (etoolbar->priv->model);
+ while (list)
+ {
+ type = list->data;
+ if (type->new_name != NULL || type->get_name != NULL)
+ gtk_target_list_add (targets, type->type, 0, 0);
+ list = list->next;
+ }
+}
+
+
static GtkWidget *
-create_dock (EggEditableToolbar *t)
+create_dock (EggEditableToolbar *etoolbar)
{
GtkWidget *toolbar, *hbox;
hbox = gtk_hbox_new (0, FALSE);
- gtk_widget_show (hbox);
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE);
gtk_widget_show (toolbar);
gtk_box_pack_start (GTK_BOX (hbox), toolbar, TRUE, TRUE, 0);
- gtk_drag_dest_set (toolbar, 0,
- dest_drag_types, G_N_ELEMENTS (dest_drag_types),
- GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
g_signal_connect (toolbar, "drag_drop",
- G_CALLBACK (toolbar_drag_drop_cb), t);
+ G_CALLBACK (toolbar_drag_drop_cb), etoolbar);
g_signal_connect (toolbar, "drag_motion",
- G_CALLBACK (toolbar_drag_motion_cb), t);
+ G_CALLBACK (toolbar_drag_motion_cb), etoolbar);
g_signal_connect (toolbar, "drag_leave",
- G_CALLBACK (toolbar_drag_leave_cb), t);
+ G_CALLBACK (toolbar_drag_leave_cb), etoolbar);
g_signal_connect (toolbar, "drag_data_received",
- G_CALLBACK (drag_data_received_cb), t);
+ G_CALLBACK (toolbar_drag_data_received_cb), etoolbar);
g_signal_connect (toolbar, "popup_context_menu",
- G_CALLBACK (popup_toolbar_context_menu_cb), t);
+ G_CALLBACK (popup_context_menu_cb), etoolbar);
+ configure_drag_dest (etoolbar, GTK_TOOLBAR (toolbar));
+
return hbox;
}
@@ -737,14 +935,14 @@ unset_fixed_style (EggEditableToolbar *t)
static void
toolbar_changed_cb (EggToolbarsModel *model,
int position,
- EggEditableToolbar *t)
+ EggEditableToolbar *etoolbar)
{
GtkWidget *toolbar;
EggTbModelFlags flags;
GtkToolbarStyle style;
flags = egg_toolbars_model_get_flags (model, position);
- toolbar = get_toolbar_nth (t, position);
+ toolbar = get_toolbar_nth (etoolbar, position);
if (flags & EGG_TB_MODEL_ICONS)
{
@@ -765,28 +963,28 @@ toolbar_changed_cb (EggToolbarsModel *model,
else
{
gtk_toolbar_unset_style (GTK_TOOLBAR (toolbar));
- if (position == 0 && t->priv->fixed_toolbar)
+ if (position == 0 && etoolbar->priv->fixed_toolbar)
{
- unset_fixed_style (t);
+ unset_fixed_style (etoolbar);
}
return;
}
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), style);
- if (position == 0 && t->priv->fixed_toolbar)
+ if (position == 0 && etoolbar->priv->fixed_toolbar)
{
- set_fixed_style (t, style);
+ set_fixed_style (etoolbar, style);
}
}
static void
-unparent_fixed (EggEditableToolbar *t)
+unparent_fixed (EggEditableToolbar *etoolbar)
{
GtkWidget *toolbar, *dock;
- g_return_if_fail (GTK_IS_TOOLBAR (t->priv->fixed_toolbar));
+ g_return_if_fail (GTK_IS_TOOLBAR (etoolbar->priv->fixed_toolbar));
- toolbar = t->priv->fixed_toolbar;
- dock = get_dock_nth (t, 0);
+ toolbar = etoolbar->priv->fixed_toolbar;
+ dock = get_dock_nth (etoolbar, 0);
if (dock && toolbar->parent != NULL)
{
@@ -795,13 +993,13 @@ unparent_fixed (EggEditableToolbar *t)
}
static void
-update_fixed (EggEditableToolbar *t)
+update_fixed (EggEditableToolbar *etoolbar)
{
GtkWidget *toolbar, *dock;
- if (!t->priv->fixed_toolbar) return;
+ if (!etoolbar->priv->fixed_toolbar) return;
- toolbar = t->priv->fixed_toolbar;
- dock = get_dock_nth (t, 0);
+ toolbar = etoolbar->priv->fixed_toolbar;
+ dock = get_dock_nth (etoolbar, 0);
if (dock && toolbar && toolbar->parent == NULL)
{
@@ -817,97 +1015,103 @@ update_fixed (EggEditableToolbar *t)
static void
toolbar_added_cb (EggToolbarsModel *model,
int position,
- EggEditableToolbar *t)
+ EggEditableToolbar *etoolbar)
{
GtkWidget *dock;
- dock = create_dock (t);
+ dock = create_dock (etoolbar);
+ if ((egg_toolbars_model_get_flags (model, position) & EGG_TB_MODEL_HIDDEN) == 0)
+ gtk_widget_show (dock);
gtk_widget_set_size_request (dock, -1, MIN_TOOLBAR_HEIGHT);
- gtk_box_pack_start (GTK_BOX (t), dock, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (etoolbar), dock, TRUE, TRUE, 0);
- gtk_box_reorder_child (GTK_BOX (t), dock, position);
+ gtk_box_reorder_child (GTK_BOX (etoolbar), dock, position);
gtk_widget_show_all (dock);
- update_fixed (t);
+ update_fixed (etoolbar);
}
static void
toolbar_removed_cb (EggToolbarsModel *model,
int position,
- EggEditableToolbar *t)
+ EggEditableToolbar *etoolbar)
{
- GtkWidget *toolbar;
+ GtkWidget *dock;
+ int i;
- if (position == 0 && t->priv->fixed_toolbar != NULL)
+ if (position == 0 && etoolbar->priv->fixed_toolbar != NULL)
{
- unparent_fixed (t);
+ unparent_fixed (etoolbar);
}
- toolbar = get_dock_nth (t, position);
- gtk_widget_destroy (toolbar);
+ dock = get_dock_nth (etoolbar, position);
+ gtk_widget_destroy (dock);
- update_fixed (t);
+ dock = NULL;
+ for (i = egg_toolbars_model_n_toolbars (model)-1; i >= 0; i--)
+ {
+ dock = get_dock_nth (etoolbar, i);
+ if (GTK_WIDGET_VISIBLE (dock)) break;
+ }
+
+ if (i < 0 && dock != NULL)
+ {
+ set_dock_visible (etoolbar, dock, TRUE);
+ }
+
+ update_fixed (etoolbar);
}
static void
item_added_cb (EggToolbarsModel *model,
- int toolbar_position,
- int position,
- EggEditableToolbar *t)
+ int tpos,
+ int ipos,
+ EggEditableToolbar *etoolbar)
{
GtkWidget *dock;
GtkWidget *toolbar;
- GtkWidget *item;
- GtkAction *action;
-
- toolbar = get_toolbar_nth (t, toolbar_position);
- item = create_item (t, model, toolbar_position, position, &action);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar),
- GTK_TOOL_ITEM (item), position);
+ GtkToolItem *item;
- dock = get_dock_nth (t, toolbar_position);
+ toolbar = get_toolbar_nth (etoolbar, tpos);
+ item = create_item_from_position (etoolbar, tpos, ipos);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, ipos);
+
+ connect_widget_signals (GTK_WIDGET (item), etoolbar);
+ configure_item_cursor (item, etoolbar);
+ configure_item_sensitivity (item, etoolbar);
+
+ dock = get_dock_nth (etoolbar, tpos);
gtk_widget_set_size_request (dock, -1, -1);
gtk_widget_queue_resize_no_redraw (dock);
-
- /* FIXME Hack to make tooltip work from gtk */
- if (action)
- {
- g_object_notify (G_OBJECT (action), "tooltip");
- }
}
static void
item_removed_cb (EggToolbarsModel *model,
int toolbar_position,
int position,
- EggEditableToolbar *t)
+ EggEditableToolbar *etoolbar)
{
GtkWidget *toolbar;
GtkWidget *item;
- toolbar = get_toolbar_nth (t, toolbar_position);
+ toolbar = get_toolbar_nth (etoolbar, toolbar_position);
item = GTK_WIDGET (gtk_toolbar_get_nth_item
(GTK_TOOLBAR (toolbar), position));
g_return_if_fail (item != NULL);
gtk_container_remove (GTK_CONTAINER (toolbar), item);
-
- if (egg_toolbars_model_n_items (model, toolbar_position) == 0)
- {
- egg_toolbars_model_remove_toolbar (model, toolbar_position);
- }
}
static void
-egg_editable_toolbar_construct (EggEditableToolbar *t)
+egg_editable_toolbar_construct (EggEditableToolbar *etoolbar)
{
int i, l, n_items, n_toolbars;
- EggToolbarsModel *model = t->priv->model;
+ EggToolbarsModel *model = etoolbar->priv->model;
g_return_if_fail (model != NULL);
- g_return_if_fail (t->priv->manager != NULL);
+ g_return_if_fail (etoolbar->priv->manager != NULL);
n_toolbars = egg_toolbars_model_n_toolbars (model);
@@ -915,26 +1119,24 @@ egg_editable_toolbar_construct (EggEditableToolbar *t)
{
GtkWidget *toolbar, *dock;
- dock = create_dock (t);
- gtk_box_pack_start (GTK_BOX (t), dock, TRUE, TRUE, 0);
- toolbar = get_toolbar_nth (t, i);
+ dock = create_dock (etoolbar);
+ if ((egg_toolbars_model_get_flags (model, i) & EGG_TB_MODEL_HIDDEN) == 0)
+ gtk_widget_show (dock);
+ gtk_box_pack_start (GTK_BOX (etoolbar), dock, TRUE, TRUE, 0);
+ toolbar = get_toolbar_nth (etoolbar, i);
n_items = egg_toolbars_model_n_items (model, i);
for (l = 0; l < n_items; l++)
{
- GtkWidget *item;
- GtkAction *action;
+ GtkToolItem *item;
- item = create_item (t, model, i, l, &action);
+ item = create_item_from_position (etoolbar, i, l);
if (item)
{
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar),
- GTK_TOOL_ITEM (item), l);
- /* FIXME Hack to make tooltip work from gtk */
- if (action)
- {
- g_object_notify (G_OBJECT (action), "tooltip");
- }
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, l);
+
+ connect_widget_signals (GTK_WIDGET (item), etoolbar);
+ configure_item_sensitivity (item, etoolbar);
}
else
{
@@ -950,12 +1152,12 @@ egg_editable_toolbar_construct (EggEditableToolbar *t)
}
}
- update_fixed (t);
+ update_fixed (etoolbar);
/* apply styles */
for (i = 0; i < n_toolbars; i ++)
{
- toolbar_changed_cb (model, i, t);
+ toolbar_changed_cb (model, i, etoolbar);
}
}
@@ -1030,12 +1232,12 @@ egg_editable_toolbar_set_model (EggEditableToolbar *toolbar,
}
static void
-egg_editable_toolbar_set_ui_manager (EggEditableToolbar *t,
+egg_editable_toolbar_set_ui_manager (EggEditableToolbar *etoolbar,
GtkUIManager *manager)
{
g_return_if_fail (GTK_IS_UI_MANAGER (manager));
- t->priv->manager = g_object_ref (manager);
+ etoolbar->priv->manager = g_object_ref (manager);
}
static void
@@ -1044,15 +1246,15 @@ egg_editable_toolbar_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
switch (prop_id)
{
case PROP_UI_MANAGER:
- egg_editable_toolbar_set_ui_manager (t, g_value_get_object (value));
+ egg_editable_toolbar_set_ui_manager (etoolbar, g_value_get_object (value));
break;
case PROP_TOOLBARS_MODEL:
- egg_editable_toolbar_set_model (t, g_value_get_object (value));
+ egg_editable_toolbar_set_model (etoolbar, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1066,15 +1268,15 @@ egg_editable_toolbar_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
switch (prop_id)
{
case PROP_UI_MANAGER:
- g_value_set_object (value, t->priv->manager);
+ g_value_set_object (value, etoolbar->priv->manager);
break;
case PROP_TOOLBARS_MODEL:
- g_value_set_object (value, t->priv->model);
+ g_value_set_object (value, etoolbar->priv->model);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1120,30 +1322,31 @@ egg_editable_toolbar_class_init (EggEditableToolbarClass *klass)
}
static void
-egg_editable_toolbar_init (EggEditableToolbar *t)
+egg_editable_toolbar_init (EggEditableToolbar *etoolbar)
{
- t->priv = EGG_EDITABLE_TOOLBAR_GET_PRIVATE (t);
+ etoolbar->priv = EGG_EDITABLE_TOOLBAR_GET_PRIVATE (etoolbar);
+ etoolbar->priv->save_hidden = TRUE;
}
static void
egg_editable_toolbar_finalize (GObject *object)
{
- EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
- if (t->priv->fixed_toolbar)
+ if (etoolbar->priv->fixed_toolbar)
{
- g_object_unref (t->priv->fixed_toolbar);
+ g_object_unref (etoolbar->priv->fixed_toolbar);
}
- if (t->priv->manager)
+ if (etoolbar->priv->manager)
{
- g_object_unref (t->priv->manager);
+ g_object_unref (etoolbar->priv->manager);
}
- if (t->priv->model)
+ if (etoolbar->priv->model)
{
- egg_editable_toolbar_disconnect_model (t);
- g_object_unref (t->priv->model);
+ egg_editable_toolbar_disconnect_model (etoolbar);
+ g_object_unref (etoolbar->priv->model);
}
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -1170,55 +1373,52 @@ egg_editable_toolbar_new_with_model (GtkUIManager *manager,
gboolean
egg_editable_toolbar_get_edit_mode (EggEditableToolbar *etoolbar)
{
- return etoolbar->priv->edit_mode;
+ return (etoolbar->priv->edit_mode > 0);
}
void
egg_editable_toolbar_set_edit_mode (EggEditableToolbar *etoolbar,
gboolean mode)
{
- int i, l, n_toolbars, n_items;
+ int i, l, n_items;
- etoolbar->priv->edit_mode = mode;
-
- n_toolbars = get_n_toolbars (etoolbar);
- for (i = 0; i < n_toolbars; i++)
+ i = etoolbar->priv->edit_mode;
+ if (mode)
{
- GtkWidget *toolbar;
-
- toolbar = get_toolbar_nth (etoolbar, i);
- n_items = gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar));
- for (l = 0; l < n_items; l++)
+ etoolbar->priv->edit_mode++;
+ }
+ else
+ {
+ g_return_if_fail (etoolbar->priv->edit_mode > 0);
+ etoolbar->priv->edit_mode--;
+ }
+ i *= etoolbar->priv->edit_mode;
+
+ if (i == 0)
+ {
+ for (i = get_n_toolbars (etoolbar)-1; i >= 0; i--)
{
- GtkToolItem *item;
- const char *action_name, *type;
- gboolean is_separator;
- GtkAction *action = NULL;
-
- egg_toolbars_model_item_nth (etoolbar->priv->model, i, l,
- &is_separator, &action_name, &type);
- action = find_action (etoolbar, action_name);
-
- item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), l);
- gtk_tool_item_set_use_drag_window (item, mode);
-
- if (mode)
- {
- set_drag_cursor (GTK_WIDGET (item));
- gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
- set_item_drag_source (etoolbar->priv->model, GTK_WIDGET (item),
- action, is_separator, type);
- }
- else
- {
- unset_drag_cursor (GTK_WIDGET (item));
- gtk_drag_source_unset (GTK_WIDGET (item));
+ GtkWidget *toolbar;
+
+ toolbar = get_toolbar_nth (etoolbar, i);
+ n_items = gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar));
- if (!is_separator)
+ if (n_items == 0 && etoolbar->priv->edit_mode == 0)
+ {
+ egg_toolbars_model_remove_toolbar (etoolbar->priv->model, i);
+ }
+ else
+ {
+ for (l = 0; l < n_items; l++)
{
- g_object_notify (G_OBJECT (action), "sensitive");
+ GtkToolItem *item;
+
+ item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), l);
+
+ configure_item_cursor (item, etoolbar);
+ configure_item_sensitivity (item, etoolbar);
}
- }
+ }
}
}
}
@@ -1292,35 +1492,6 @@ egg_editable_toolbar_set_fixed (EggEditableToolbar *toolbar,
update_fixed (toolbar);
}
-void
-egg_editable_toolbar_set_drag_dest (EggEditableToolbar *etoolbar,
- const GtkTargetEntry *targets,
- gint n_targets,
- const char *toolbar_name)
-{
- int i, n_toolbars;
- EggToolbarsModel *model = etoolbar->priv->model;
-
- g_return_if_fail (model != NULL);
-
- n_toolbars = egg_toolbars_model_n_toolbars (model);
- for (i = 0; i < n_toolbars; i++)
- {
- const char *name;
-
- name = egg_toolbars_model_toolbar_nth (model, i);
- if (strcmp (toolbar_name, name) == 0)
- {
- GtkWidget *widget = get_toolbar_nth (etoolbar, i);
-
- gtk_drag_dest_unset (widget);
- gtk_drag_dest_set (widget, 0,
- targets, n_targets,
- GDK_ACTION_MOVE | GDK_ACTION_COPY);
- }
- }
-}
-
#define DEFAULT_ICON_HEIGHT 20
#define DEFAULT_ICON_WIDTH 0
diff --git a/lib/egg/egg-editable-toolbar.h b/lib/egg/egg-editable-toolbar.h
index 9f143da70..d91e916dd 100755
--- a/lib/egg/egg-editable-toolbar.h
+++ b/lib/egg/egg-editable-toolbar.h
@@ -29,6 +29,7 @@
#include <gtk/gtkvbox.h>
#include <gtk/gtktoolitem.h>
#include <gtk/gtktoolbar.h>
+#include <gtk/gtkmenu.h>
G_BEGIN_DECLS
@@ -80,6 +81,8 @@ void egg_editable_toolbar_set_drag_dest (EggEditableToolbar *etoolbar,
void egg_editable_toolbar_set_fixed (EggEditableToolbar *etoolbar,
GtkToolbar *fixed_toolbar);
+void egg_editable_toolbar_add_popup_items (GtkWidget *widget,
+ GtkMenu *popup);
/* Private Functions */
diff --git a/lib/egg/egg-toolbar-editor.c b/lib/egg/egg-toolbar-editor.c
index bd79724a8..4cb7d0ccc 100755
--- a/lib/egg/egg-toolbar-editor.c
+++ b/lib/egg/egg-toolbar-editor.c
@@ -34,6 +34,7 @@
#include <gtk/gtktable.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkhbox.h>
+#include <gtk/gtk.h>
static const GtkTargetEntry dest_drag_types[] = {
{EGG_TOOLBAR_ITEM_TYPE, GTK_TARGET_SAME_APP, 0},
@@ -46,7 +47,6 @@ static const GtkTargetEntry source_drag_types[] = {
static void egg_toolbar_editor_class_init (EggToolbarEditorClass *klass);
static void egg_toolbar_editor_init (EggToolbarEditor *t);
static void egg_toolbar_editor_finalize (GObject *object);
-static void update_actions_list (EggToolbarEditor *editor);
static void update_editor_sheet (EggToolbarEditor *editor);
enum
@@ -67,9 +67,8 @@ struct EggToolbarEditorPrivate
GtkWidget *table;
GtkWidget *scrolled_window;
-
- GList *default_actions_list;
- GList *actions_list;
+ GList *actions_list;
+ GList *factory_list;
};
GType
@@ -100,27 +99,18 @@ egg_toolbar_editor_get_type (void)
}
static gint
-compare_actions (gconstpointer a,
- gconstpointer b)
+compare_items (gconstpointer a,
+ gconstpointer b)
{
- GValue value_a = { 0, }, value_b = { 0, };
- const char *short_label_a, *short_label_b;
- int ret;
-
- g_value_init (&value_a, G_TYPE_STRING);
- g_object_get_property (G_OBJECT (a), "short_label", &value_a);
- short_label_a = g_value_get_string (&value_a);
-
- g_value_init (&value_b, G_TYPE_STRING);
- g_object_get_property (G_OBJECT (b), "short_label", &value_b);
- short_label_b = g_value_get_string (&value_b);
-
- ret = g_utf8_collate (short_label_a, short_label_b);
-
- g_value_unset (&value_a);
- g_value_unset (&value_b);
-
- return ret;
+ const GtkWidget *item1 = a;
+ const GtkWidget *item2 = b;
+
+ char *key1 = g_object_get_data (G_OBJECT (item1),
+ "egg-collate-key");
+ char *key2 = g_object_get_data (G_OBJECT (item2),
+ "egg-collate-key");
+
+ return strcmp (key1, key2);
}
static GtkAction *
@@ -157,11 +147,19 @@ egg_toolbar_editor_set_ui_manager (EggToolbarEditor *t,
}
static void
+item_added_or_removed_cb (EggToolbarsModel *model,
+ int tpos,
+ int ipos,
+ EggToolbarEditor *editor)
+{
+ update_editor_sheet (editor);
+}
+
+static void
toolbar_removed_cb (EggToolbarsModel *model,
int position,
EggToolbarEditor *editor)
{
- update_actions_list (editor);
update_editor_sheet (editor);
}
@@ -172,7 +170,13 @@ egg_toolbar_editor_set_model (EggToolbarEditor *t,
g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (t));
t->priv->model = g_object_ref (model);
+
+ update_editor_sheet (t);
+ g_signal_connect_object (model, "item_added",
+ G_CALLBACK (item_added_or_removed_cb), t, 0);
+ g_signal_connect_object (model, "item_removed",
+ G_CALLBACK (item_added_or_removed_cb), t, 0);
g_signal_connect_object (model, "toolbar_removed",
G_CALLBACK (toolbar_removed_cb), t, 0);
}
@@ -261,8 +265,8 @@ egg_toolbar_editor_finalize (GObject *object)
g_object_unref (editor->priv->model);
}
- g_list_free (editor->priv->default_actions_list);
g_list_free (editor->priv->actions_list);
+ g_list_free (editor->priv->factory_list);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -281,66 +285,14 @@ static void
drag_begin_cb (GtkWidget *widget,
GdkDragContext *context)
{
- gtk_widget_hide (widget);
+ gtk_widget_hide (widget);
}
static void
drag_end_cb (GtkWidget *widget,
GdkDragContext *context)
{
- gtk_widget_show (widget);
-}
-
-static void
-editor_drag_data_received_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time_,
- EggToolbarEditor *editor)
-{
- GtkAction *action;
- const char *data;
-
- g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (editor));
- g_return_if_fail (selection_data != NULL);
-
- if (selection_data->length <= 0 || selection_data->data == NULL) return;
-
- data = (const char *) selection_data->data;
-
- if (strcmp (data, "separator") == 0) return;
-
- action = find_action (editor, data);
- g_return_if_fail (action != NULL);
-
- if (g_list_find (editor->priv->default_actions_list, action))
- {
- editor->priv->actions_list = g_list_insert_sorted
- (editor->priv->actions_list, action, compare_actions);
- }
-
- update_editor_sheet (editor);
-}
-
-static void
-editor_drag_data_delete_cb (GtkWidget *widget,
- GdkDragContext *context,
- EggToolbarEditor *editor)
-{
- GtkAction *action;
- g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (editor));
-
- action = GTK_ACTION (g_object_get_data (G_OBJECT (widget), "egg-action"));
- if (action)
- {
- editor->priv->actions_list = g_list_remove
- (editor->priv->actions_list, action);
- }
-
- update_editor_sheet (editor);
+ gtk_widget_show (widget);
}
static void
@@ -351,23 +303,12 @@ drag_data_get_cb (GtkWidget *widget,
guint32 time,
EggToolbarEditor *editor)
{
- GtkAction *action;
const char *target;
- action = GTK_ACTION (g_object_get_data (G_OBJECT (widget), "egg-action"));
-
- if (action)
- {
- target = gtk_action_get_name (action);
- }
- else
- {
- target = "separator";
- }
-
- gtk_selection_data_set (selection_data,
- selection_data->target, 8,
- (const guchar *)target, strlen (target));
+ target = g_object_get_data (G_OBJECT (widget), "egg-item-name");
+ g_return_if_fail (target != NULL);
+
+ gtk_selection_data_set (selection_data, selection_data->target, 8, target, strlen (target));
}
static gchar *
@@ -454,8 +395,6 @@ editor_create_item (EggToolbarEditor *editor,
source_drag_types, G_N_ELEMENTS (source_drag_types), action);
g_signal_connect (event_box, "drag_data_get",
G_CALLBACK (drag_data_get_cb), editor);
- g_signal_connect (event_box, "drag_data_delete",
- G_CALLBACK (editor_drag_data_delete_cb), editor);
g_signal_connect_after (event_box, "realize",
G_CALLBACK (event_box_realize_cb), icon);
@@ -482,80 +421,174 @@ editor_create_item (EggToolbarEditor *editor,
return event_box;
}
-static void
-update_editor_sheet (EggToolbarEditor *editor)
+static GtkWidget *
+editor_create_item_from_name (EggToolbarEditor *editor,
+ const char * name,
+ GdkDragAction drag_action)
{
- GList *l;
- GList *to_drag;
- int x, y, height, width;
- GtkWidget *table;
- GtkWidget *viewport;
GtkWidget *item;
- GtkWidget *icon;
-
- g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (editor));
-
- viewport = GTK_BIN (editor->priv->scrolled_window)->child;
- if (viewport)
+ const char *item_name;
+ const char *stock_id;
+ const char *short_label;
+ const char *collate_key;
+
+ if (strcmp (name, "_separator") == 0)
{
- table = GTK_BIN (viewport)->child;
- gtk_container_remove (GTK_CONTAINER (viewport), table);
+ GtkWidget *icon;
+
+ icon = _egg_editable_toolbar_new_separator_image ();
+ short_label = _("Separator");
+ item_name = strdup (name);
+ collate_key = g_utf8_collate_key (short_label, -1);
+ item = editor_create_item (editor, GTK_IMAGE (icon),
+ short_label, drag_action);
}
- table = gtk_table_new (0, 0, TRUE);
- editor->priv->table = table;
- gtk_container_set_border_width (GTK_CONTAINER (table), 12);
- gtk_widget_show (table);
- gtk_scrolled_window_add_with_viewport
- (GTK_SCROLLED_WINDOW (editor->priv->scrolled_window), table);
- gtk_drag_dest_set (table, GTK_DEST_DEFAULT_ALL,
- dest_drag_types, G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE);
- g_signal_connect (table, "drag_data_received",
- G_CALLBACK (editor_drag_data_received_cb), editor);
-
- to_drag = editor->priv->actions_list;
-
- x = y = 0;
- width = 4;
- height = (g_list_length (to_drag)) / width + 1;
- gtk_table_resize (GTK_TABLE (editor->priv->table), height, width);
-
- for (l = to_drag; l != NULL; l = l->next)
+ else
{
- GtkAction *action = (l->data);
- const char *stock_id, *short_label;
GValue value = { 0, };
+ GtkAction *action;
+ GtkWidget *icon;
+
+ action = find_action (editor, name);
+ g_return_val_if_fail (action != NULL, NULL);
g_value_init (&value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (action), "stock_id", &value);
stock_id = g_value_get_string (&value);
- icon = gtk_image_new_from_stock
- (stock_id ? stock_id : GTK_STOCK_DND,
- GTK_ICON_SIZE_LARGE_TOOLBAR);
+ icon = gtk_image_new_from_stock (stock_id ? stock_id : GTK_STOCK_DND,
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
g_value_unset (&value);
-
+
g_value_init (&value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (action), "short_label", &value);
short_label = g_value_get_string (&value);
+
+ item_name = strdup (name);
+ collate_key = g_utf8_collate_key (short_label, -1);
item = editor_create_item (editor, GTK_IMAGE (icon),
- short_label, GDK_ACTION_MOVE);
+ short_label, drag_action);
g_value_unset (&value);
- g_object_set_data (G_OBJECT (item), "egg-action", action);
- gtk_table_attach_defaults (GTK_TABLE (editor->priv->table),
- item, x, x + 1, y, y + 1);
+ }
+
+ g_object_set_data_full (G_OBJECT (item), "egg-collate-key",
+ (gpointer) collate_key, g_free);
+ g_object_set_data_full (G_OBJECT (item), "egg-item-name",
+ (gpointer) item_name, g_free);
+
+ return item;
+}
- x++;
- if (x >= width)
- {
- x = 0;
- y++;
- }
+static gint
+append_table (GtkTable *table, GList *items, gint y, gint width)
+{
+ if (items != NULL)
+ {
+ gint x = 0, height;
+ GtkWidget *alignment;
+ GtkWidget *item;
+
+ height = g_list_length (items) / width + 1;
+ gtk_table_resize (table, height, width);
+
+ if (y > 0)
+ {
+ item = gtk_hseparator_new ();
+ alignment = gtk_alignment_new (0.5, 0.5, 1.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (alignment), item);
+ gtk_widget_show (alignment);
+ gtk_widget_show (item);
+
+ gtk_table_attach_defaults (table, alignment, 0, width, y-1, y+1);
+ }
+
+ for (; items != NULL; items = items->next)
+ {
+ item = items->data;
+ alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (alignment), item);
+ gtk_widget_show (alignment);
+ gtk_widget_show (item);
+
+ if (x >= width)
+ {
+ x = 0;
+ y++;
+ }
+ gtk_table_attach_defaults (table, alignment, x, x+1, y, y+1);
+ x++;
+ }
+
+ y++;
}
+ return y;
+}
+
+static void
+update_editor_sheet (EggToolbarEditor *editor)
+{
+ gint y;
+ GPtrArray *items;
+ GList *to_move = NULL, *to_copy = NULL;
+ GtkWidget *table;
+ GtkWidget *viewport;
+
+ g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (editor));
+
+ /* Create new table. */
+ table = gtk_table_new (0, 0, TRUE);
+ editor->priv->table = table;
+ gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 24);
+ gtk_widget_show (table);
+ gtk_drag_dest_set (table, GTK_DEST_DEFAULT_ALL,
+ dest_drag_types, G_N_ELEMENTS (dest_drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
+
+ /* Build two lists of items (one for copying, one for moving). */
+ items = egg_toolbars_model_get_avail (editor->priv->model);
+ while (items->len > 0)
+ {
+ GtkWidget *item;
+ const char *name;
+
+ name = g_ptr_array_index (items, 0);
+ g_ptr_array_remove_index_fast (items, 0);
+
+ if (egg_toolbars_model_get_n_avail (editor->priv->model, name) == 1)
+ {
+ item = editor_create_item_from_name (editor, name, GDK_ACTION_MOVE);
+ if (item != NULL)
+ to_move = g_list_insert_sorted (to_move, item, compare_items);
+ }
+ else
+ {
+ item = editor_create_item_from_name (editor, name, GDK_ACTION_COPY);
+ if (item != NULL)
+ to_copy = g_list_insert_sorted (to_copy, item, compare_items);
+ }
+ }
+
+ /* Add them to the sheet. */
+ y = 0;
+ y = append_table (GTK_TABLE (table), to_move, y, 4);
+ y = append_table (GTK_TABLE (table), to_copy, y, 4);
+
+ g_list_free (to_move);
+ g_list_free (to_copy);
+ g_ptr_array_free (items, TRUE);
+
+ /* Delete old table. */
+ viewport = GTK_BIN (editor->priv->scrolled_window)->child;
+ if (viewport)
+ {
+ gtk_container_remove (GTK_CONTAINER (viewport),
+ GTK_BIN (viewport)->child);
+ }
+
+ /* Add table to window. */
+ gtk_scrolled_window_add_with_viewport
+ (GTK_SCROLLED_WINDOW (editor->priv->scrolled_window), table);
- icon = _egg_editable_toolbar_new_separator_image ();
- item = editor_create_item (editor, GTK_IMAGE (icon), _("Separator"),
- GDK_ACTION_COPY);
- gtk_table_attach_defaults (GTK_TABLE (editor->priv->table),
- item, x, x + 1, y, y + 1);
}
static void
@@ -578,113 +611,8 @@ egg_toolbar_editor_init (EggToolbarEditor *t)
t->priv = EGG_TOOLBAR_EDITOR_GET_PRIVATE (t);
t->priv->manager = NULL;
- t->priv->default_actions_list = NULL;
t->priv->actions_list = NULL;
setup_editor (t);
}
-void
-egg_toolbar_editor_add_action (EggToolbarEditor *editor,
- const char *action_name)
-{
- GtkAction *action;
-
- action = find_action (editor, action_name);
- g_return_if_fail (action != NULL);
-
- editor->priv->default_actions_list = g_list_insert_sorted
- (editor->priv->default_actions_list, action, compare_actions);
-}
-
-static void
-parse_item_list (EggToolbarEditor *t,
- xmlNodePtr child)
-{
- while (child)
- {
- if (xmlStrEqual (child->name, (const xmlChar*) "toolitem"))
- {
- xmlChar *name;
-
- name = xmlGetProp (child, (const xmlChar*) "name");
- egg_toolbar_editor_add_action (t, (const char*)name);
- xmlFree (name);
- }
- child = child->next;
- }
-}
-
-static gboolean
-model_has_action (EggToolbarsModel *model, GtkAction *action)
-{
- int i, l, n_items, n_toolbars;
-
- n_toolbars = egg_toolbars_model_n_toolbars (model);
- for (i = 0; i < n_toolbars; i++)
- {
- n_items = egg_toolbars_model_n_items (model, i);
- for (l = 0; l < n_items; l++)
- {
- const char *name;
- const char *action_name;
- gboolean sep;
-
- egg_toolbars_model_item_nth (model, i, l, &sep, &name, NULL);
- action_name = gtk_action_get_name (action);
- if (!sep && strcmp (name, action_name) == 0) return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-update_actions_list (EggToolbarEditor *editor)
-{
- GList *l;
-
- if (editor->priv->actions_list)
- g_list_free (editor->priv->actions_list);
-
- /* Remove the already used items */
- editor->priv->actions_list = NULL;
-
- for (l = editor->priv->default_actions_list; l != NULL; l = l->next)
- {
- GtkAction *action = GTK_ACTION (l->data);
-
- if (!model_has_action (editor->priv->model, action))
- {
- editor->priv->actions_list = g_list_insert_sorted
- (editor->priv->actions_list, action, compare_actions);
- }
- }
-}
-
-void
-egg_toolbar_editor_load_actions (EggToolbarEditor *editor,
- const char *xml_file)
-{
- xmlDocPtr doc;
- xmlNodePtr root;
- xmlNodePtr child;
-
- doc = xmlParseFile (xml_file);
- root = xmlDocGetRootElement (doc);
- child = root->children;
-
- while (child)
- {
- if (xmlStrEqual (child->name, (const xmlChar*) "available"))
- {
- parse_item_list (editor, child->children);
- }
- child = child->next;
- }
-
- xmlFreeDoc (doc);
-
- update_actions_list (editor);
- update_editor_sheet (editor);
-}
diff --git a/lib/egg/egg-toolbar-editor.h b/lib/egg/egg-toolbar-editor.h
index e1e1f35ab..e29e5482b 100755
--- a/lib/egg/egg-toolbar-editor.h
+++ b/lib/egg/egg-toolbar-editor.h
@@ -56,11 +56,6 @@ struct EggToolbarEditorClass
GType egg_toolbar_editor_get_type (void);
GtkWidget *egg_toolbar_editor_new (GtkUIManager *manager,
EggToolbarsModel *model);
-void egg_toolbar_editor_load_actions (EggToolbarEditor *editor,
- const char *xml_file);
-
-void egg_toolbar_editor_add_action (EggToolbarEditor *editor,
- const char *action_name);
G_END_DECLS
diff --git a/lib/egg/egg-toolbars-model.c b/lib/egg/egg-toolbars-model.c
index 56f4c8fbf..1d8c59476 100755
--- a/lib/egg/egg-toolbars-model.c
+++ b/lib/egg/egg-toolbars-model.c
@@ -31,7 +31,7 @@
#include <gdk/gdkproperty.h>
static void egg_toolbars_model_class_init (EggToolbarsModelClass *klass);
-static void egg_toolbars_model_init (EggToolbarsModel *t);
+static void egg_toolbars_model_init (EggToolbarsModel *model);
static void egg_toolbars_model_finalize (GObject *object);
enum
@@ -41,9 +41,6 @@ enum
TOOLBAR_ADDED,
TOOLBAR_CHANGED,
TOOLBAR_REMOVED,
- GET_ITEM_TYPE,
- GET_ITEM_ID,
- GET_ITEM_DATA,
LAST_SIGNAL
};
@@ -55,9 +52,7 @@ typedef struct
typedef struct
{
- char *id;
- char *type;
- gboolean separator;
+ char *name;
} EggToolbarsItem;
static guint signals[LAST_SIGNAL] = { 0 };
@@ -69,6 +64,8 @@ static GObjectClass *parent_class = NULL;
struct EggToolbarsModelPrivate
{
GNode *toolbars;
+ GList *types;
+ GHashTable *avail;
};
GType
@@ -103,45 +100,64 @@ egg_toolbars_model_get_type (void)
}
static xmlDocPtr
-egg_toolbars_model_to_xml (EggToolbarsModel *t)
+egg_toolbars_model_to_xml (EggToolbarsModel *model)
{
GNode *l1, *l2, *tl;
+ GList *l3;
xmlDocPtr doc;
- g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (t), NULL);
+ g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (model), NULL);
- tl = t->priv->toolbars;
+ tl = model->priv->toolbars;
xmlIndentTreeOutput = TRUE;
- doc = xmlNewDoc ((const xmlChar*) "1.0");
- doc->children = xmlNewDocNode (doc, NULL, (const xmlChar*) "toolbars", NULL);
+ doc = xmlNewDoc ("1.0");
+ doc->children = xmlNewDocNode (doc, NULL, "toolbars", NULL);
for (l1 = tl->children; l1 != NULL; l1 = l1->next)
{
xmlNodePtr tnode;
EggToolbarsToolbar *toolbar = l1->data;
- tnode = xmlNewChild (doc->children, NULL, (const xmlChar*) "toolbar", NULL);
- xmlSetProp (tnode, (const xmlChar*) "name", (const xmlChar*) toolbar->name);
+ tnode = xmlNewChild (doc->children, NULL, "toolbar", NULL);
+ xmlSetProp (tnode, "name", toolbar->name);
+ xmlSetProp (tnode, "hidden", (toolbar->flags&EGG_TB_MODEL_HIDDEN)?"true":"false");
for (l2 = l1->children; l2 != NULL; l2 = l2->next)
{
xmlNodePtr node;
EggToolbarsItem *item = l2->data;
- if (item->separator)
- {
- node = xmlNewChild (tnode, NULL, (const xmlChar*) "separator", NULL);
- }
- else
- {
- char *data;
-
- node = xmlNewChild (tnode, NULL, (const xmlChar*) "toolitem", NULL);
- data = egg_toolbars_model_get_item_data (t, item->type, item->id);
- xmlSetProp (node, (const xmlChar*) "type", (const xmlChar*) item->type);
- xmlSetProp (node, (const xmlChar*) "name", (const xmlChar*) data);
- g_free (data);
+ if (strcmp (item->name, "_separator") == 0)
+ {
+ node = xmlNewChild (tnode, NULL, "separator", NULL);
+ continue;
+ }
+
+ node = xmlNewChild (tnode, NULL, "toolitem", NULL);
+ xmlSetProp (node, "name", item->name);
+
+ /* Add 'data' nodes for each data type which can be written out for this
+ * item. Only write types which can be used to restore the data. */
+ for (l3 = model->priv->types; l3 != NULL; l3 = l3->next)
+ {
+ EggToolbarsItemType *type = l3->data;
+ if (type->get_name != NULL && type->get_data != NULL)
+ {
+ xmlNodePtr dnode;
+ char *tmp;
+
+ tmp = type->get_data (type, item->name);
+ if (tmp != NULL)
+ {
+ dnode = xmlNewTextChild (node, NULL, "data", tmp);
+ g_free (tmp);
+
+ tmp = gdk_atom_name (type->type);
+ xmlSetProp (dnode, "type", tmp);
+ g_free (tmp);
+ }
+ }
}
}
}
@@ -206,24 +222,24 @@ safe_save_xml (const char *xml_file, xmlDocPtr doc)
}
void
-egg_toolbars_model_save (EggToolbarsModel *t,
+egg_toolbars_model_save (EggToolbarsModel *model,
const char *xml_file,
const char *version)
{
xmlDocPtr doc;
xmlNodePtr root;
- g_return_if_fail (EGG_IS_TOOLBARS_MODEL (t));
+ g_return_if_fail (EGG_IS_TOOLBARS_MODEL (model));
- doc = egg_toolbars_model_to_xml (t);
+ doc = egg_toolbars_model_to_xml (model);
root = xmlDocGetRootElement (doc);
- xmlSetProp (root, (const xmlChar*) "version", (const xmlChar*) version);
+ xmlSetProp (root, "version", version);
safe_save_xml (xml_file, doc);
xmlFreeDoc (doc);
}
-static EggToolbarsToolbar *
-toolbars_toolbar_new (const char *name)
+static GNode *
+toolbar_node_new (const char *name)
{
EggToolbarsToolbar *toolbar;
@@ -231,58 +247,67 @@ toolbars_toolbar_new (const char *name)
toolbar->name = g_strdup (name);
toolbar->flags = 0;
- return toolbar;
+ return g_node_new (toolbar);
}
-static EggToolbarsItem *
-toolbars_item_new (const char *id,
- const char *type,
- gboolean separator)
+static GNode *
+item_node_new (const char *name, EggToolbarsModel *model)
{
EggToolbarsItem *item;
- g_return_val_if_fail (id != NULL, NULL);
- g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
item = g_new (EggToolbarsItem, 1);
- item->id = g_strdup (id);
- item->type = g_strdup (type);
- item->separator = separator;
+ item->name = g_strdup (name);
+
+ gint count = (gint) g_hash_table_lookup (model->priv->avail, item->name);
+ if (count > G_MININT && count < G_MAXINT)
+ g_hash_table_insert (model->priv->avail,
+ g_strdup (item->name),
+ (gpointer) (count-1));
- return item;
+ return g_node_new (item);
}
static void
-free_toolbar_node (GNode *toolbar_node)
+item_node_free (GNode *item_node, EggToolbarsModel *model)
{
- EggToolbarsToolbar *toolbar = toolbar_node->data;
+ EggToolbarsItem *item = item_node->data;
- g_free (toolbar->name);
- g_free (toolbar);
+ gint count = (gint) g_hash_table_lookup (model->priv->avail, item->name);
+ if (count < G_MAXINT-1)
+ g_hash_table_insert (model->priv->avail,
+ g_strdup (item->name),
+ (gpointer) (count+1));
- g_node_destroy (toolbar_node);
+ g_free (item->name);
+ g_free (item);
+
+ g_node_destroy (item_node);
}
static void
-free_item_node (GNode *item_node)
+toolbar_node_free (GNode *toolbar_node, EggToolbarsModel *model)
{
- EggToolbarsItem *item = item_node->data;
+ EggToolbarsToolbar *toolbar = toolbar_node->data;
- g_free (item->id);
- g_free (item->type);
- g_free (item);
+ g_node_children_foreach (toolbar_node, G_TRAVERSE_ALL,
+ (GNodeForeachFunc) item_node_free, model);
+
+ g_free (toolbar->name);
+ g_free (toolbar);
- g_node_destroy (item_node);
+ g_node_destroy (toolbar_node);
}
EggTbModelFlags
-egg_toolbars_model_get_flags (EggToolbarsModel *t,
+egg_toolbars_model_get_flags (EggToolbarsModel *model,
int toolbar_position)
{
GNode *toolbar_node;
EggToolbarsToolbar *toolbar;
- toolbar_node = g_node_nth_child (t->priv->toolbars, toolbar_position);
+ toolbar_node = g_node_nth_child (model->priv->toolbars, toolbar_position);
g_return_val_if_fail (toolbar_node != NULL, 0);
toolbar = toolbar_node->data;
@@ -291,162 +316,262 @@ egg_toolbars_model_get_flags (EggToolbarsModel *t,
}
void
-egg_toolbars_model_set_flags (EggToolbarsModel *t,
+egg_toolbars_model_set_flags (EggToolbarsModel *model,
int toolbar_position,
EggTbModelFlags flags)
{
GNode *toolbar_node;
EggToolbarsToolbar *toolbar;
- toolbar_node = g_node_nth_child (t->priv->toolbars, toolbar_position);
+ toolbar_node = g_node_nth_child (model->priv->toolbars, toolbar_position);
g_return_if_fail (toolbar_node != NULL);
toolbar = toolbar_node->data;
toolbar->flags = flags;
- g_signal_emit (G_OBJECT (t), signals[TOOLBAR_CHANGED],
+ g_signal_emit (G_OBJECT (model), signals[TOOLBAR_CHANGED],
0, toolbar_position);
}
-void
-egg_toolbars_model_add_separator (EggToolbarsModel *t,
- int toolbar_position,
- int position)
+
+char *
+egg_toolbars_model_get_data (EggToolbarsModel *model,
+ GdkAtom type,
+ const char *name)
+{
+ EggToolbarsItemType *t;
+ char *data = NULL;
+ GList *l;
+
+ if (type == GDK_NONE || type == gdk_atom_intern (EGG_TOOLBAR_ITEM_TYPE, FALSE))
+ {
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (*name != 0, NULL);
+ return strdup (name);
+ }
+
+ for (l = model->priv->types; l != NULL; l = l->next)
+ {
+ t = l->data;
+ if (t->type == type && t->get_data != NULL)
+ {
+ data = t->get_data (t, name);
+ if (data != NULL) break;
+ }
+ }
+
+ return data;
+}
+
+char *
+egg_toolbars_model_get_name (EggToolbarsModel *model,
+ GdkAtom type,
+ const char *data,
+ gboolean create)
+{
+ EggToolbarsItemType *t;
+ char *name = NULL;
+ GList *l;
+
+ if (type == GDK_NONE || type == gdk_atom_intern (EGG_TOOLBAR_ITEM_TYPE, FALSE))
+ {
+ g_return_val_if_fail (data, NULL);
+ g_return_val_if_fail (*data, NULL);
+ return strdup (data);
+ }
+
+ if (create)
+ {
+ for (l = model->priv->types; name == NULL && l != NULL; l = l->next)
+ {
+ t = l->data;
+ if (t->type == type && t->new_name != NULL)
+ name = t->new_name (t, data);
+ }
+
+ return name;
+ }
+ else
+ {
+ for (l = model->priv->types; name == NULL && l != NULL; l = l->next)
+ {
+ t = l->data;
+ if (t->type == type && t->get_name != NULL)
+ name = t->get_name (t, data);
+ }
+
+ return name;
+ }
+}
+
+static gboolean
+impl_add_item (EggToolbarsModel *model,
+ int toolbar_position,
+ int position,
+ const char *name)
{
GNode *parent_node;
- GNode *node;
- EggToolbarsItem *item;
+ GNode *child_node;
int real_position;
- g_return_if_fail (EGG_IS_TOOLBARS_MODEL (t));
+ g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (model), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
- parent_node = g_node_nth_child (t->priv->toolbars, toolbar_position);
- item = toolbars_item_new ("separator", EGG_TOOLBAR_ITEM_TYPE, TRUE);
- node = g_node_new (item);
- g_node_insert (parent_node, position, node);
+ parent_node = g_node_nth_child (model->priv->toolbars, toolbar_position);
+ child_node = item_node_new (name, model);
+ g_node_insert (parent_node, position, child_node);
- real_position = g_node_child_position (parent_node, node);
+ real_position = g_node_child_position (parent_node, child_node);
- g_signal_emit (G_OBJECT (t), signals[ITEM_ADDED], 0,
+ g_signal_emit (G_OBJECT (model), signals[ITEM_ADDED], 0,
toolbar_position, real_position);
+
+ return TRUE;
}
-static gboolean
-impl_add_item (EggToolbarsModel *t,
- int toolbar_position,
- int position,
- const char *id,
- const char *type)
+gboolean
+egg_toolbars_model_add_item (EggToolbarsModel *model,
+ int toolbar_position,
+ int position,
+ const char *name)
+{
+ EggToolbarsModelClass *klass = EGG_TOOLBARS_MODEL_GET_CLASS (model);
+ return klass->add_item (model, toolbar_position, position, name);
+}
+
+int
+egg_toolbars_model_add_toolbar (EggToolbarsModel *model,
+ int position,
+ const char *name)
{
- GNode *parent_node;
GNode *node;
- EggToolbarsItem *item;
int real_position;
- g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (t), FALSE);
- g_return_val_if_fail (id != NULL, FALSE);
- g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (model), -1);
- parent_node = g_node_nth_child (t->priv->toolbars, toolbar_position);
- item = toolbars_item_new (id, type, FALSE);
- node = g_node_new (item);
- g_node_insert (parent_node, position, node);
+ node = toolbar_node_new (name);
+ g_node_insert (model->priv->toolbars, position, node);
- real_position = g_node_child_position (parent_node, node);
+ real_position = g_node_child_position (model->priv->toolbars, node);
- g_signal_emit (G_OBJECT (t), signals[ITEM_ADDED], 0,
- toolbar_position, real_position);
+ g_signal_emit (G_OBJECT (model), signals[TOOLBAR_ADDED],
+ 0, real_position);
- return TRUE;
+ return g_node_child_position (model->priv->toolbars, node);
+}
+
+static char *
+parse_data_list (EggToolbarsModel *model,
+ xmlNodePtr child,
+ gboolean create)
+{
+ char *name = NULL;
+ while (child && name == NULL)
+ {
+ if (xmlStrEqual (child->name, "data"))
+ {
+ xmlChar *type = xmlGetProp (child, "type");
+ xmlChar *data = xmlNodeGetContent (child);
+
+ if (type != NULL)
+ {
+ GdkAtom atom = gdk_atom_intern (type, TRUE);
+ name = egg_toolbars_model_get_name (model, atom, data, create);
+ }
+
+ xmlFree (type);
+ xmlFree (data);
+ }
+
+ child = child->next;
+ }
+
+ return name;
}
static void
-parse_item_list (EggToolbarsModel *t,
+parse_item_list (EggToolbarsModel *model,
xmlNodePtr child,
int position)
{
while (child)
{
- if (xmlStrEqual (child->name, (const xmlChar*) "toolitem"))
+ if (xmlStrEqual (child->name, "toolitem"))
{
- xmlChar *name, *type;
- char *id;
+ char *name;
- name = xmlGetProp (child, (const xmlChar*) "name");
- type = xmlGetProp (child, (const xmlChar*) "type");
- if (type == NULL)
+ /* Try to get the name using the data elements first,
+ as they are more 'portable' or 'persistent'. */
+ name = parse_data_list (model, child->children, FALSE);
+ if (name == NULL)
{
- type = xmlCharStrdup (EGG_TOOLBAR_ITEM_TYPE);
+ name = parse_data_list (model, child->children, TRUE);
}
-
- if (name != NULL && name[0] != '\0' && type != NULL)
- {
- id = egg_toolbars_model_get_item_id (t, (const char*)type, (const char*)name);
- if (id != NULL)
- {
- egg_toolbars_model_add_item (t, position, -1, id, (const char*)type);
+
+ /* If that fails, try to use the name. */
+ if (name == NULL)
+ {
+ xmlChar *type = xmlGetProp (child, "type");
+ xmlChar *data = xmlGetProp (child, "name");
+ GdkAtom atom = type ? gdk_atom_intern (type, TRUE) : GDK_NONE;
+
+ /* If an old format, try to use it. */
+ name = egg_toolbars_model_get_name (model, atom, data, FALSE);
+ if (name == NULL)
+ {
+ name = egg_toolbars_model_get_name (model, atom, data, TRUE);
}
- g_free (id);
+
+ xmlFree (type);
+ xmlFree (data);
+ }
+
+ if (name != NULL)
+ {
+ egg_toolbars_model_add_item (model, position, -1, name);
+ g_free (name);
}
- xmlFree (name);
- xmlFree (type);
}
- else if (xmlStrEqual (child->name, (const xmlChar*) "separator"))
+ else if (xmlStrEqual (child->name, "separator"))
{
- egg_toolbars_model_add_separator (t, position, -1);
+ egg_toolbars_model_add_item (model, position, -1, "_separator");
}
child = child->next;
}
}
-int
-egg_toolbars_model_add_toolbar (EggToolbarsModel *t,
- int position,
- const char *name)
-{
- GNode *node;
- int real_position;
-
- g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (t), -1);
-
- node = g_node_new (toolbars_toolbar_new (name));
- g_node_insert (t->priv->toolbars, position, node);
-
- real_position = g_node_child_position (t->priv->toolbars, node);
-
- g_signal_emit (G_OBJECT (t), signals[TOOLBAR_ADDED],
- 0, real_position);
-
- return g_node_child_position (t->priv->toolbars, node);
-}
-
static void
-parse_toolbars (EggToolbarsModel *t,
+parse_toolbars (EggToolbarsModel *model,
xmlNodePtr child)
{
while (child)
{
- if (xmlStrEqual (child->name, (const xmlChar*) "toolbar"))
+ if (xmlStrEqual (child->name, "toolbar"))
{
- xmlChar *name;
- xmlChar *style;
+ xmlChar *string;
int position;
-
- name = xmlGetProp (child, (const xmlChar*) "name");
- position = egg_toolbars_model_add_toolbar (t, -1, (const char*) name);
- xmlFree (name);
-
- style = xmlGetProp (child, (const xmlChar*) "style");
- if (style && xmlStrEqual (style, (const xmlChar*) "icons-only"))
- {
- /* FIXME: use toolbar position instead of 0 */
- egg_toolbars_model_set_flags (t, 0, EGG_TB_MODEL_ICONS);
- }
- xmlFree (style);
-
- parse_item_list (t, child->children, position);
+ EggTbModelFlags flags;
+
+ string = xmlGetProp (child, "name");
+ position = egg_toolbars_model_add_toolbar (model, -1, string);
+ flags = egg_toolbars_model_get_flags (model, position);
+ xmlFree (string);
+
+ string = xmlGetProp (child, "hidden");
+ if (string && xmlStrEqual (string, "true"))
+ flags |= EGG_TB_MODEL_HIDDEN;
+ xmlFree (string);
+
+ string = xmlGetProp (child, "style");
+ if (string && xmlStrEqual (string, "icons-only"))
+ flags |= EGG_TB_MODEL_ICONS;
+ xmlFree (string);
+
+ egg_toolbars_model_set_flags (model, position, flags);
+
+ parse_item_list (model, child->children, position);
}
child = child->next;
@@ -454,13 +579,13 @@ parse_toolbars (EggToolbarsModel *t,
}
gboolean
-egg_toolbars_model_load (EggToolbarsModel *t,
+egg_toolbars_model_load (EggToolbarsModel *model,
const char *xml_file)
{
xmlDocPtr doc;
xmlNodePtr root;
- g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (t), FALSE);
+ g_return_val_if_fail (EGG_IS_TOOLBARS_MODEL (model), FALSE);
if (!xml_file || !g_file_test (xml_file, G_FILE_TEST_EXISTS)) return FALSE;
@@ -472,68 +597,13 @@ egg_toolbars_model_load (EggToolbarsModel *t,
}
root = xmlDocGetRootElement (doc);
- parse_toolbars (t, root->children);
+ parse_toolbars (model, root->children);
xmlFreeDoc (doc);
return TRUE;
}
-static char *
-impl_get_item_id (EggToolbarsModel *t,
- const char *type,
- const char *data)
-{
- if (strcmp (type, EGG_TOOLBAR_ITEM_TYPE) == 0)
- {
- return g_strdup (data);
- }
-
- return NULL;
-}
-
-static char *
-impl_get_item_data (EggToolbarsModel *t,
- const char *type,
- const char *id)
-{
- if (strcmp (type, EGG_TOOLBAR_ITEM_TYPE) == 0)
- {
- return g_strdup (id);
- }
-
- return NULL;
-}
-
-static char *
-impl_get_item_type (EggToolbarsModel *t,
- GdkAtom type)
-{
- if (gdk_atom_intern (EGG_TOOLBAR_ITEM_TYPE, FALSE) == type)
- {
- return g_strdup (EGG_TOOLBAR_ITEM_TYPE);
- }
-
- return NULL;
-}
-
-static gboolean
-_egg_accumulator_STRING (GSignalInvocationHint *ihint,
- GValue *return_accu,
- const GValue *handler_return,
- gpointer dummy)
-{
- gboolean continue_emission;
- const char *retval;
-
- retval = g_value_get_string (handler_return);
- g_value_set_string (return_accu, retval);
- continue_emission = !retval || !retval[0];
-
- return continue_emission;
-}
-
-
static void
egg_toolbars_model_class_init (EggToolbarsModelClass *klass)
{
@@ -544,9 +614,6 @@ egg_toolbars_model_class_init (EggToolbarsModelClass *klass)
object_class->finalize = egg_toolbars_model_finalize;
klass->add_item = impl_add_item;
- klass->get_item_id = impl_get_item_id;
- klass->get_item_data = impl_get_item_data;
- klass->get_item_type = impl_get_item_type;
signals[ITEM_ADDED] =
g_signal_new ("item_added",
@@ -583,58 +650,29 @@ egg_toolbars_model_class_init (EggToolbarsModelClass *klass)
G_STRUCT_OFFSET (EggToolbarsModelClass, toolbar_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- signals[GET_ITEM_TYPE] =
- g_signal_new ("get_item_type",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggToolbarsModelClass, get_item_type),
- _egg_accumulator_STRING, NULL,
- _egg_marshal_STRING__POINTER,
- G_TYPE_STRING, 1, G_TYPE_POINTER);
- signals[GET_ITEM_ID] =
- g_signal_new ("get_item_id",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggToolbarsModelClass, get_item_id),
- _egg_accumulator_STRING, NULL,
- _egg_marshal_STRING__STRING_STRING,
- G_TYPE_STRING, 2, G_TYPE_STRING, G_TYPE_STRING);
- signals[GET_ITEM_DATA] =
- g_signal_new ("get_item_data",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggToolbarsModelClass, get_item_data),
- _egg_accumulator_STRING, NULL,
- _egg_marshal_STRING__STRING_STRING,
- G_TYPE_STRING, 2, G_TYPE_STRING, G_TYPE_STRING);
g_type_class_add_private (object_class, sizeof (EggToolbarsModelPrivate));
}
static void
-egg_toolbars_model_init (EggToolbarsModel *t)
+egg_toolbars_model_init (EggToolbarsModel *model)
{
- t->priv =EGG_TOOLBARS_MODEL_GET_PRIVATE (t);
-
- t->priv->toolbars = g_node_new (NULL);
-}
+ model->priv =EGG_TOOLBARS_MODEL_GET_PRIVATE (model);
-static void
-free_toolbar (GNode *toolbar_node)
-{
- g_node_children_foreach (toolbar_node, G_TRAVERSE_ALL,
- (GNodeForeachFunc) free_item_node, NULL);
- free_toolbar_node (toolbar_node);
+ model->priv->toolbars = g_node_new (NULL);
+ model->priv->avail = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ egg_toolbars_model_set_n_avail (model, "_separator", G_MAXINT);
}
static void
egg_toolbars_model_finalize (GObject *object)
{
- EggToolbarsModel *t = EGG_TOOLBARS_MODEL (object);
+ EggToolbarsModel *model = EGG_TOOLBARS_MODEL (object);
- g_node_children_foreach (t->priv->toolbars, G_TRAVERSE_ALL,
- (GNodeForeachFunc) free_toolbar, NULL);
- g_node_destroy (t->priv->toolbars);
+ g_node_children_foreach (model->priv->toolbars, G_TRAVERSE_ALL,
+ (GNodeForeachFunc) toolbar_node_free, model);
+ g_node_destroy (model->priv->toolbars);
+ g_hash_table_destroy (model->priv->avail);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -646,51 +684,51 @@ egg_toolbars_model_new (void)
}
void
-egg_toolbars_model_remove_toolbar (EggToolbarsModel *t,
+egg_toolbars_model_remove_toolbar (EggToolbarsModel *model,
int position)
{
GNode *node;
EggTbModelFlags flags;
- g_return_if_fail (EGG_IS_TOOLBARS_MODEL (t));
+ g_return_if_fail (EGG_IS_TOOLBARS_MODEL (model));
- flags = egg_toolbars_model_get_flags (t, position);
+ flags = egg_toolbars_model_get_flags (model, position);
if (!(flags & EGG_TB_MODEL_NOT_REMOVABLE))
{
- node = g_node_nth_child (t->priv->toolbars, position);
+ node = g_node_nth_child (model->priv->toolbars, position);
g_return_if_fail (node != NULL);
- free_toolbar_node (node);
+ toolbar_node_free (node, model);
- g_signal_emit (G_OBJECT (t), signals[TOOLBAR_REMOVED],
+ g_signal_emit (G_OBJECT (model), signals[TOOLBAR_REMOVED],
0, position);
}
}
void
-egg_toolbars_model_remove_item (EggToolbarsModel *t,
+egg_toolbars_model_remove_item (EggToolbarsModel *model,
int toolbar_position,
int position)
{
GNode *node, *toolbar;
- g_return_if_fail (EGG_IS_TOOLBARS_MODEL (t));
+ g_return_if_fail (EGG_IS_TOOLBARS_MODEL (model));
- toolbar = g_node_nth_child (t->priv->toolbars, toolbar_position);
+ toolbar = g_node_nth_child (model->priv->toolbars, toolbar_position);
g_return_if_fail (toolbar != NULL);
node = g_node_nth_child (toolbar, position);
g_return_if_fail (node != NULL);
- free_item_node (node);
+ item_node_free (node, model);
- g_signal_emit (G_OBJECT (t), signals[ITEM_REMOVED], 0,
+ g_signal_emit (G_OBJECT (model), signals[ITEM_REMOVED], 0,
toolbar_position, position);
}
void
-egg_toolbars_model_move_item (EggToolbarsModel *t,
+egg_toolbars_model_move_item (EggToolbarsModel *model,
int toolbar_position,
int position,
int new_toolbar_position,
@@ -698,12 +736,12 @@ egg_toolbars_model_move_item (EggToolbarsModel *t,
{
GNode *node, *toolbar, *new_toolbar;
- g_return_if_fail (EGG_IS_TOOLBARS_MODEL (t));
+ g_return_if_fail (EGG_IS_TOOLBARS_MODEL (model));
- toolbar = g_node_nth_child (t->priv->toolbars, toolbar_position);
+ toolbar = g_node_nth_child (model->priv->toolbars, toolbar_position);
g_return_if_fail (toolbar != NULL);
- new_toolbar = g_node_nth_child (t->priv->toolbars, new_toolbar_position);
+ new_toolbar = g_node_nth_child (model->priv->toolbars, new_toolbar_position);
g_return_if_fail (new_toolbar != NULL);
node = g_node_nth_child (toolbar, position);
@@ -711,74 +749,60 @@ egg_toolbars_model_move_item (EggToolbarsModel *t,
g_node_unlink (node);
- g_signal_emit (G_OBJECT (t), signals[ITEM_REMOVED], 0,
+ g_signal_emit (G_OBJECT (model), signals[ITEM_REMOVED], 0,
toolbar_position, position);
g_node_insert (new_toolbar, new_position, node);
- g_signal_emit (G_OBJECT (t), signals[ITEM_ADDED], 0,
+ g_signal_emit (G_OBJECT (model), signals[ITEM_ADDED], 0,
new_toolbar_position, new_position);
}
int
-egg_toolbars_model_n_items (EggToolbarsModel *t,
+egg_toolbars_model_n_items (EggToolbarsModel *model,
int toolbar_position)
{
GNode *toolbar;
- toolbar = g_node_nth_child (t->priv->toolbars, toolbar_position);
+ toolbar = g_node_nth_child (model->priv->toolbars, toolbar_position);
g_return_val_if_fail (toolbar != NULL, -1);
return g_node_n_children (toolbar);
}
-void
-egg_toolbars_model_item_nth (EggToolbarsModel *t,
+const char *
+egg_toolbars_model_item_nth (EggToolbarsModel *model,
int toolbar_position,
- int position,
- gboolean *is_separator,
- const char **id,
- const char **type)
+ int position)
{
GNode *toolbar;
GNode *item;
EggToolbarsItem *idata;
- toolbar = g_node_nth_child (t->priv->toolbars, toolbar_position);
- g_return_if_fail (toolbar != NULL);
+ toolbar = g_node_nth_child (model->priv->toolbars, toolbar_position);
+ g_return_val_if_fail (toolbar != NULL, NULL);
item = g_node_nth_child (toolbar, position);
- g_return_if_fail (item != NULL);
+ g_return_val_if_fail (item != NULL, NULL);
idata = item->data;
-
- *is_separator = idata->separator;
-
- if (id)
- {
- *id = idata->id;
- }
-
- if (type)
- {
- *type = idata->type;
- }
+ return idata->name;
}
int
-egg_toolbars_model_n_toolbars (EggToolbarsModel *t)
+egg_toolbars_model_n_toolbars (EggToolbarsModel *model)
{
- return g_node_n_children (t->priv->toolbars);
+ return g_node_n_children (model->priv->toolbars);
}
const char *
-egg_toolbars_model_toolbar_nth (EggToolbarsModel *t,
+egg_toolbars_model_toolbar_nth (EggToolbarsModel *model,
int position)
{
GNode *toolbar;
EggToolbarsToolbar *tdata;
- toolbar = g_node_nth_child (t->priv->toolbars, position);
+ toolbar = g_node_nth_child (model->priv->toolbars, position);
g_return_val_if_fail (toolbar != NULL, NULL);
tdata = toolbar->data;
@@ -786,48 +810,40 @@ egg_toolbars_model_toolbar_nth (EggToolbarsModel *t,
return tdata->name;
}
-gboolean
-egg_toolbars_model_add_item (EggToolbarsModel *t,
- int toolbar_position,
- int position,
- const char *id,
- const char *type)
+GList *
+egg_toolbars_model_get_types (EggToolbarsModel *model)
{
- EggToolbarsModelClass *klass = EGG_TOOLBARS_MODEL_GET_CLASS (t);
- return klass->add_item (t, toolbar_position, position, id, type);
+ return model->priv->types;
}
-char *
-egg_toolbars_model_get_item_id (EggToolbarsModel *t,
- const char *type,
- const char *name)
+void
+egg_toolbars_model_set_types (EggToolbarsModel *model, GList *types)
{
- char *retval;
-
- g_signal_emit (t, signals[GET_ITEM_ID], 0, type, name, &retval);
-
- return retval;
+ model->priv->types = types;
}
-char *
-egg_toolbars_model_get_item_data (EggToolbarsModel *t,
- const char *type,
- const char *id)
+static void
+fill_avail_array (gpointer key, gpointer value, GPtrArray *array)
{
- char *retval;
-
- g_signal_emit (t, signals[GET_ITEM_DATA], 0, type, id, &retval);
-
- return retval;
+ if (GPOINTER_TO_INT (value) > 0) g_ptr_array_add (array, key);
}
-char *
-egg_toolbars_model_get_item_type (EggToolbarsModel *t,
- GdkAtom type)
+GPtrArray *
+egg_toolbars_model_get_avail (EggToolbarsModel *model)
{
- char *retval;
+ GPtrArray *array = g_ptr_array_new ();
+ g_hash_table_foreach (model->priv->avail, (GHFunc) fill_avail_array, array);
+ return array;
+}
- g_signal_emit (t, signals[GET_ITEM_TYPE], 0, type, &retval);
+gint
+egg_toolbars_model_get_n_avail (EggToolbarsModel *model, const char *name)
+{
+ return (gint) g_hash_table_lookup (model->priv->avail, name);
+}
- return retval;
+void
+egg_toolbars_model_set_n_avail (EggToolbarsModel *model, const char *name, gint count)
+{
+ g_hash_table_insert (model->priv->avail, g_strdup (name), (gpointer) count);
}
diff --git a/lib/egg/egg-toolbars-model.h b/lib/egg/egg-toolbars-model.h
index aaaa2140a..fe5467aa8 100755
--- a/lib/egg/egg-toolbars-model.h
+++ b/lib/egg/egg-toolbars-model.h
@@ -48,7 +48,8 @@ typedef enum
EGG_TB_MODEL_ICONS = 1 << 3,
EGG_TB_MODEL_TEXT = 1 << 4,
EGG_TB_MODEL_STYLES_MASK = 0x1F,
- EGG_TB_MODEL_ACCEPT_ITEMS_ONLY = 1 << 5
+ EGG_TB_MODEL_ACCEPT_ITEMS_ONLY = 1 << 5,
+ EGG_TB_MODEL_HIDDEN = 1 << 6
} EggTbModelFlags;
struct EggToolbarsModel
@@ -76,21 +77,35 @@ struct EggToolbarsModelClass
int position);
void (* toolbar_removed) (EggToolbarsModel *model,
int position);
- char * (* get_item_type) (EggToolbarsModel *model,
- GdkAtom dnd_type);
- char * (* get_item_id) (EggToolbarsModel *model,
- const char *type,
- const char *data);
- char * (* get_item_data) (EggToolbarsModel *model,
- const char *type,
- const char *id);
/* Virtual Table */
gboolean (* add_item) (EggToolbarsModel *t,
int toolbar_position,
int position,
- const char *id,
- const char *type);
+ const char *name);
+};
+
+typedef struct EggToolbarsItemType EggToolbarsItemType;
+
+struct EggToolbarsItemType
+{
+ GdkAtom type;
+
+ gboolean (* has_data) (EggToolbarsItemType *type,
+ const char *name);
+ char * (* get_data) (EggToolbarsItemType *type,
+ const char *name);
+
+ char * (* new_name) (EggToolbarsItemType *type,
+ const char *data);
+ char * (* get_name) (EggToolbarsItemType *type,
+ const char *data);
+};
+
+struct EggToolbarsItemAvailable
+{
+ const char * name;
+ guint available;
};
GType egg_toolbars_model_flags_get_type (void);
@@ -101,32 +116,48 @@ gboolean egg_toolbars_model_load (EggToolbarsModel *model,
void egg_toolbars_model_save (EggToolbarsModel *model,
const char *xml_file,
const char *version);
-int egg_toolbars_model_add_toolbar (EggToolbarsModel *model,
- int position,
- const char *name);
+
+/* Functions for manipulating the types of portable data this toolbar understands. */
+GList * egg_toolbars_model_get_types (EggToolbarsModel *model);
+void egg_toolbars_model_set_types (EggToolbarsModel *model,
+ GList *types);
+
+/* Functions for converting between name and portable data. */
+char * egg_toolbars_model_get_name (EggToolbarsModel *model,
+ GdkAtom type,
+ const char *data,
+ gboolean create);
+char * egg_toolbars_model_get_data (EggToolbarsModel *model,
+ GdkAtom type,
+ const char *name);
+
+/* Functions for retrieving what items are available for adding to the toolbars. */
+GPtrArray * egg_toolbars_model_get_avail (EggToolbarsModel *model);
+gint egg_toolbars_model_get_n_avail (EggToolbarsModel *model,
+ const char *name);
+void egg_toolbars_model_set_n_avail (EggToolbarsModel *model,
+ const char *name,
+ gint count);
+
+/* Functions for manipulating flags on individual toolbars. */
EggTbModelFlags egg_toolbars_model_get_flags (EggToolbarsModel *model,
int toolbar_position);
void egg_toolbars_model_set_flags (EggToolbarsModel *model,
int toolbar_position,
EggTbModelFlags flags);
-void egg_toolbars_model_add_separator (EggToolbarsModel *model,
- int toolbar_position,
+
+/* Functions for adding and removing toolbars. */
+int egg_toolbars_model_add_toolbar (EggToolbarsModel *model,
+ int position,
+ const char *name);
+void egg_toolbars_model_remove_toolbar (EggToolbarsModel *model,
int position);
-char *egg_toolbars_model_get_item_type (EggToolbarsModel *model,
- GdkAtom dnd_type);
-char *egg_toolbars_model_get_item_id (EggToolbarsModel *model,
- const char *type,
- const char *name);
-char *egg_toolbars_model_get_item_data (EggToolbarsModel *model,
- const char *type,
- const char *id);
+
+/* Functions for adding, removing and moving items. */
gboolean egg_toolbars_model_add_item (EggToolbarsModel *model,
int toolbar_position,
int position,
- const char *id,
- const char *type);
-void egg_toolbars_model_remove_toolbar (EggToolbarsModel *model,
- int position);
+ const char *name);
void egg_toolbars_model_remove_item (EggToolbarsModel *model,
int toolbar_position,
int position);
@@ -135,14 +166,15 @@ void egg_toolbars_model_move_item (EggToolbarsModel *model,
int position,
int new_toolbar_position,
int new_position);
+
+/* Functions for accessing the names of items. */
int egg_toolbars_model_n_items (EggToolbarsModel *model,
int toolbar_position);
-void egg_toolbars_model_item_nth (EggToolbarsModel *model,
+const char * egg_toolbars_model_item_nth (EggToolbarsModel *model,
int toolbar_position,
- int position,
- gboolean *is_separator,
- const char **id,
- const char **type);
+ int position);
+
+/* Functions for accessing the names of toolbars. */
int egg_toolbars_model_n_toolbars (EggToolbarsModel *model);
const char *egg_toolbars_model_toolbar_nth (EggToolbarsModel *model,
int position);
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);