From cc8f3060b3c57453f2128a573391add2a0bb47d4 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 19 May 2003 17:25:12 +0000 Subject: 2003-05-19 Marco Pesenti Gritti * lib/Makefile.am: * lib/ephy-dnd.c: (ephy_dnd_node_list_extract_nodes): * lib/ephy-node.c: (write_lock_to_read_lock), (read_lock_to_write_lock), (lock_gdk), (unlock_gdk), (callback), (ephy_node_emit_signal), (ephy_node_finalize), (real_remove_child), (remove_child), (signal_object_weak_notify), (unref_signal_objects), (ephy_node_dispose), (ephy_node_new), (ephy_node_new_with_id), (ephy_node_get_id), (ephy_node_ref), (ephy_node_unref), (ephy_node_freeze), (ephy_node_thaw), (child_changed), (real_set_property), (ephy_node_set_property), (ephy_node_get_property), (ephy_node_get_property_string), (ephy_node_get_property_boolean), (ephy_node_get_property_long), (ephy_node_get_property_int), (ephy_node_get_property_double), (ephy_node_get_property_float), (ephy_node_get_property_node), (save_parent), (ephy_node_save_to_xml), (real_add_child), (ephy_node_new_from_xml), (ephy_node_add_child), (ephy_node_remove_child), (ephy_node_has_child), (ephy_node_real_get_child_index), (ephy_node_sort_children), (ephy_node_reorder_children), (ephy_node_get_children), (ephy_node_get_n_children), (ephy_node_get_nth_child), (get_child_index_real), (ephy_node_get_child_index), (ephy_node_get_next_child), (ephy_node_get_previous_child), (ephy_node_signal_connect_object), (ephy_node_signal_disconnect): * lib/ephy-node.h: * lib/ephy-state.c: (ephy_states_load), (ensure_states), (ephy_state_add_window), (ephy_state_add_paned), (ephy_state_save): * lib/widgets/ephy-node-view.c: (ephy_node_view_class_init), (ephy_node_view_selection_changed_cb), (ephy_node_view_set_property), (ephy_node_view_get_property), (ephy_node_view_remove): * lib/widgets/ephy-tree-model-node.c: (ephy_tree_model_node_class_init), (ephy_tree_model_node_set_property), (ephy_tree_model_node_get_property), (ephy_tree_model_node_get_value), (ephy_tree_model_node_get_path), (ephy_tree_model_node_iter_next), (ephy_tree_model_node_node_from_iter): * src/bookmarks/ephy-bookmark-action.c: (ephy_bookmark_action_init), (ephy_bookmark_action_new): * src/bookmarks/ephy-bookmark-properties.c: (ephy_bookmark_properties_class_init), (ephy_bookmark_properties_set_property): * src/bookmarks/ephy-bookmarks-editor.c: (cmd_show_in_bookmarks_bar), (cmd_open_bookmarks_in_tabs), (cmd_open_bookmarks_in_browser), (cmd_delete), (cmd_bookmark_properties), (cmd_copy), (ephy_bookmarks_editor_node_activated_cb), (ephy_bookmarks_editor_update_menu), --- ChangeLog | 86 +++ embed/ephy-favicon-cache.c | 32 +- embed/ephy-history.c | 64 +- lib/Makefile.am | 2 + lib/ephy-dnd.c | 8 +- lib/ephy-node-db.c | 292 ++++++++ lib/ephy-node-db.h | 73 ++ lib/ephy-node.c | 1181 +++++++++++------------------- lib/ephy-node.h | 72 +- lib/ephy-state.c | 26 +- lib/widgets/ephy-node-view.c | 31 +- lib/widgets/ephy-tree-model-node.c | 63 +- src/bookmarks/ephy-bookmark-action.c | 8 +- src/bookmarks/ephy-bookmark-properties.c | 11 +- src/bookmarks/ephy-bookmarks-editor.c | 25 +- src/bookmarks/ephy-bookmarks-export.c | 2 +- src/bookmarks/ephy-bookmarks.c | 51 +- src/bookmarks/ephy-bookmarks.h | 7 +- src/bookmarks/ephy-topic-action.c | 23 +- src/bookmarks/ephy-topics-selector.c | 13 +- src/ephy-history-window.c | 11 +- src/ephy-shell.c | 2 - src/ephy-toolbars-model.c | 4 +- 23 files changed, 1109 insertions(+), 978 deletions(-) create mode 100644 lib/ephy-node-db.c create mode 100644 lib/ephy-node-db.h diff --git a/ChangeLog b/ChangeLog index d7352439c..1e5ecf483 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,89 @@ +2003-05-19 Marco Pesenti Gritti + + * lib/Makefile.am: + * lib/ephy-dnd.c: (ephy_dnd_node_list_extract_nodes): + * lib/ephy-node.c: (write_lock_to_read_lock), + (read_lock_to_write_lock), (lock_gdk), (unlock_gdk), (callback), + (ephy_node_emit_signal), (ephy_node_finalize), (real_remove_child), + (remove_child), (signal_object_weak_notify), + (unref_signal_objects), (ephy_node_dispose), (ephy_node_new), + (ephy_node_new_with_id), (ephy_node_get_id), (ephy_node_ref), + (ephy_node_unref), (ephy_node_freeze), (ephy_node_thaw), + (child_changed), (real_set_property), (ephy_node_set_property), + (ephy_node_get_property), (ephy_node_get_property_string), + (ephy_node_get_property_boolean), (ephy_node_get_property_long), + (ephy_node_get_property_int), (ephy_node_get_property_double), + (ephy_node_get_property_float), (ephy_node_get_property_node), + (save_parent), (ephy_node_save_to_xml), (real_add_child), + (ephy_node_new_from_xml), (ephy_node_add_child), + (ephy_node_remove_child), (ephy_node_has_child), + (ephy_node_real_get_child_index), (ephy_node_sort_children), + (ephy_node_reorder_children), (ephy_node_get_children), + (ephy_node_get_n_children), (ephy_node_get_nth_child), + (get_child_index_real), (ephy_node_get_child_index), + (ephy_node_get_next_child), (ephy_node_get_previous_child), + (ephy_node_signal_connect_object), (ephy_node_signal_disconnect): + * lib/ephy-node.h: + * lib/ephy-state.c: (ephy_states_load), (ensure_states), + (ephy_state_add_window), (ephy_state_add_paned), (ephy_state_save): + * lib/widgets/ephy-node-view.c: (ephy_node_view_class_init), + (ephy_node_view_selection_changed_cb), + (ephy_node_view_set_property), (ephy_node_view_get_property), + (ephy_node_view_remove): + * lib/widgets/ephy-tree-model-node.c: + (ephy_tree_model_node_class_init), + (ephy_tree_model_node_set_property), + (ephy_tree_model_node_get_property), + (ephy_tree_model_node_get_value), (ephy_tree_model_node_get_path), + (ephy_tree_model_node_iter_next), + (ephy_tree_model_node_node_from_iter): + * src/bookmarks/ephy-bookmark-action.c: + (ephy_bookmark_action_init), (ephy_bookmark_action_new): + * src/bookmarks/ephy-bookmark-properties.c: + (ephy_bookmark_properties_class_init), + (ephy_bookmark_properties_set_property): + * src/bookmarks/ephy-bookmarks-editor.c: + (cmd_show_in_bookmarks_bar), (cmd_open_bookmarks_in_tabs), + (cmd_open_bookmarks_in_browser), (cmd_delete), + (cmd_bookmark_properties), (cmd_copy), + (ephy_bookmarks_editor_node_activated_cb), + (ephy_bookmarks_editor_update_menu), + (ephy_bookmarks_editor_dispose), (node_dropped_cb), + (ephy_bookmarks_editor_construct): + * src/bookmarks/ephy-bookmarks-export.c: (add_topics_list): + * src/bookmarks/ephy-bookmarks.c: (ephy_bookmarks_load), + (ephy_bookmarks_init), (ephy_bookmarks_add), + (ephy_bookmarks_add_keyword), (ephy_bookmarks_get_from_id): + * src/bookmarks/ephy-bookmarks.h: + * src/bookmarks/ephy-topic-action.c: (menu_activate_cb), + (sort_bookmarks), (sort_topics), (build_menu), + (ephy_topic_action_init), (ephy_topic_action_new): + * src/bookmarks/ephy-topics-selector.c: + (ephy_topics_selector_class_init), + (ephy_topics_selector_set_property), + (ephy_topics_selector_get_property): + * src/ephy-history-window.c: (cmd_open_bookmarks_in_tabs), + (cmd_open_bookmarks_in_browser), (cmd_copy), (cmd_bookmark_link), + (ephy_history_window_node_activated_cb), + (ephy_history_window_update_menu): + * src/ephy-shell.c: (ephy_shell_init), (ephy_shell_finalize): + * src/ephy-toolbars-model.c: (impl_add_item): + * embed/ephy-favicon-cache.c: (ephy_favicon_cache_load), + (ephy_favicon_cache_init), (ephy_favicon_cache_finalize), + (ephy_favicon_cache_get): + * embed/ephy-history.c: + (ephy_history_autocompletion_source_foreach), (ephy_history_load), + (pages_removed_cb), (ephy_history_init), (ephy_history_finalize), + (ephy_history_add_host), (ephy_history_visited), + (ephy_history_add_page): + + Ok biggest commit of ephy history. + Extend node api to allow to branch different databases, deobjectify + nodes for better perfomance, smarted id factory. + Convert code to use the new api. + This will very likely break something, please backup your bookmarks (the .xml) + and report them. + 2003-05-19 David Bordoley * data/epiphany.schemas.in: diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c index 3b3efef40..6ae56c3f9 100644 --- a/embed/ephy-favicon-cache.c +++ b/embed/ephy-favicon-cache.c @@ -41,6 +41,7 @@ struct EphyFaviconCachePrivate { char *directory; char *xml_file; + EphyNodeDb *db; EphyNode *icons; GHashTable *icons_hash; GStaticRWLock *icons_hash_lock; @@ -141,7 +142,7 @@ ephy_favicon_cache_load (EphyFaviconCache *eb) { EphyNode *node; - node = ephy_node_new_from_xml (child); + node = ephy_node_new_from_xml (eb->priv->db, child); } xmlFreeDoc (doc); @@ -258,8 +259,13 @@ ephy_favicon_cache_save (EphyFaviconCache *eb) static void ephy_favicon_cache_init (EphyFaviconCache *cache) { + EphyNodeDb *db; + cache->priv = g_new0 (EphyFaviconCachePrivate, 1); + db = ephy_node_db_new ("EphyFaviconCache"); + cache->priv->db = db; + cache->priv->xml_file = g_build_filename (ephy_dot_dir (), "ephy-favicon-cache.xml", NULL); @@ -286,18 +292,16 @@ ephy_favicon_cache_init (EphyFaviconCache *cache) NULL); /* Icons */ - cache->priv->icons = ephy_node_new_with_id (ICONS_NODE_ID); + cache->priv->icons = ephy_node_new_with_id (db, ICONS_NODE_ID); ephy_node_ref (cache->priv->icons); - g_signal_connect_object (G_OBJECT (cache->priv->icons), - "child_added", - G_CALLBACK (icons_added_cb), - G_OBJECT (cache), - 0); - g_signal_connect_object (G_OBJECT (cache->priv->icons), - "child_removed", - G_CALLBACK (icons_removed_cb), - G_OBJECT (cache), - 0); + ephy_node_signal_connect_object (cache->priv->icons, + EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback) icons_added_cb, + G_OBJECT (cache)); + ephy_node_signal_connect_object (cache->priv->icons, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) icons_removed_cb, + G_OBJECT (cache)); ephy_favicon_cache_load (cache); } @@ -345,6 +349,8 @@ ephy_favicon_cache_finalize (GObject *object) g_return_if_fail (cache->priv != NULL); + g_object_unref (cache->priv->db); + cleanup_downloads_hash (cache); remove_obsolete_icons (cache); ephy_favicon_cache_save (cache); @@ -447,7 +453,7 @@ ephy_favicon_cache_get (EphyFaviconCache *cache, filename = favicon_name_build (url); - icon = ephy_node_new (); + icon = ephy_node_new (cache->priv->db); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, url); ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_URL, diff --git a/embed/ephy-history.c b/embed/ephy-history.c index f59e9169b..c9541c618 100644 --- a/embed/ephy-history.c +++ b/embed/ephy-history.c @@ -42,6 +42,7 @@ struct EphyHistoryPrivate { char *xml_file; + EphyNodeDb *db; EphyNode *hosts; EphyNode *pages; EphyNode *last_page; @@ -142,7 +143,7 @@ ephy_history_autocompletion_source_foreach (EphyAutocompletionSource *source, guint32 score; kid = g_ptr_array_index (children, i); - g_assert (EPHY_IS_NODE (kid)); + g_assert (kid != NULL); url = ephy_node_get_property_string (kid, EPHY_NODE_PAGE_PROP_LOCATION); @@ -218,7 +219,7 @@ ephy_history_load (EphyHistory *eb) { EphyNode *node; - node = ephy_node_new_from_xml (child); + node = ephy_node_new_from_xml (eb->priv->db, child); } xmlFreeDoc (doc); @@ -370,7 +371,7 @@ pages_removed_cb (EphyNode *node, g_static_rw_lock_writer_unlock (eb->priv->pages_hash_lock); host_id = ephy_node_get_property_int (child, EPHY_NODE_PAGE_PROP_HOST_ID); - host = ephy_node_get_from_id (host_id); + host = ephy_node_db_get_node_from_id (eb->priv->db, host_id); children = ephy_node_get_n_children (host); LOG ("Check host children: %d", children) @@ -394,9 +395,13 @@ static void ephy_history_init (EphyHistory *eb) { GValue value = { 0, }; + EphyNodeDb *db; eb->priv = g_new0 (EphyHistoryPrivate, 1); + db = ephy_node_db_new ("EphyHistory"); + eb->priv->db = db; + eb->priv->xml_file = g_build_filename (ephy_dot_dir (), "ephy-history.xml", NULL); @@ -412,7 +417,7 @@ ephy_history_init (EphyHistory *eb) g_static_rw_lock_init (eb->priv->hosts_hash_lock); /* Pages */ - eb->priv->pages = ephy_node_new_with_id (PAGES_NODE_ID); + eb->priv->pages = ephy_node_new_with_id (db, PAGES_NODE_ID); ephy_node_ref (eb->priv->pages); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, _("All")); @@ -429,30 +434,26 @@ ephy_history_init (EphyHistory *eb) EPHY_NODE_PAGE_PROP_PRIORITY, &value); g_value_unset (&value); - g_signal_connect_object (G_OBJECT (eb->priv->pages), - "child_added", - G_CALLBACK (pages_added_cb), - G_OBJECT (eb), - 0); - g_signal_connect_object (G_OBJECT (eb->priv->pages), - "child_removed", - G_CALLBACK (pages_removed_cb), - G_OBJECT (eb), - 0); + ephy_node_signal_connect_object (eb->priv->pages, + EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback) pages_added_cb, + G_OBJECT (eb)); + ephy_node_signal_connect_object (eb->priv->pages, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) pages_removed_cb, + G_OBJECT (eb)); /* Hosts */ - eb->priv->hosts = ephy_node_new_with_id (HOSTS_NODE_ID); + eb->priv->hosts = ephy_node_new_with_id (db, HOSTS_NODE_ID); ephy_node_ref (eb->priv->hosts); - g_signal_connect_object (G_OBJECT (eb->priv->hosts), - "child_added", - G_CALLBACK (hosts_added_cb), - G_OBJECT (eb), - 0); - g_signal_connect_object (G_OBJECT (eb->priv->hosts), - "child_removed", - G_CALLBACK (hosts_removed_cb), - G_OBJECT (eb), - 0); + ephy_node_signal_connect_object (eb->priv->hosts, + EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback) hosts_added_cb, + G_OBJECT (eb)); + ephy_node_signal_connect_object (eb->priv->hosts, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) hosts_removed_cb, + G_OBJECT (eb)); ephy_node_add_child (eb->priv->hosts, eb->priv->pages); @@ -482,6 +483,8 @@ ephy_history_finalize (GObject *object) ephy_node_unref (eb->priv->pages); ephy_node_unref (eb->priv->hosts); + g_object_unref (eb->priv->db); + g_hash_table_destroy (eb->priv->pages_hash); g_static_rw_lock_free (eb->priv->pages_hash_lock); g_hash_table_destroy (eb->priv->hosts_hash); @@ -610,7 +613,7 @@ ephy_history_add_host (EphyHistory *eh, EphyNode *page) if (!host) { - host = ephy_node_new (); + host = ephy_node_new (eh->priv->db); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, host_name); ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_TITLE, @@ -656,7 +659,7 @@ ephy_history_visited (EphyHistory *eh, EphyNode *node) now = time (NULL); - g_assert (EPHY_IS_NODE (node)); + g_assert (node != NULL); url = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); @@ -686,7 +689,10 @@ ephy_history_visited (EphyHistory *eh, EphyNode *node) host_id = ephy_node_get_property_int (node, EPHY_NODE_PAGE_PROP_HOST_ID); if (host_id >= 0) { - ephy_history_host_visited (eh, ephy_node_get_from_id (host_id), now); + EphyNode *host; + + host = ephy_node_db_get_node_from_id (eh->priv->db, host_id); + ephy_history_host_visited (eh, host, now); } eh->priv->last_page = node; @@ -727,7 +733,7 @@ ephy_history_add_page (EphyHistory *eb, return; } - bm = ephy_node_new (); + bm = ephy_node_new (eb->priv->db); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, url); diff --git a/lib/Makefile.am b/lib/Makefile.am index f02394725..9d16c7dd9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -41,6 +41,8 @@ libephy_la_SOURCES = \ ephy-node-filter.c \ ephy-node-filter.h \ ephy-node-common.h \ + ephy-node-db.c \ + ephy-node-db.h \ ephy-prefs.h \ ephy-prefs-utils.c \ ephy-prefs-utils.h \ diff --git a/lib/ephy-dnd.c b/lib/ephy-dnd.c index 84ea8d0da..def09d14f 100644 --- a/lib/ephy-dnd.c +++ b/lib/ephy-dnd.c @@ -110,13 +110,17 @@ ephy_dnd_drag_data_get (GtkWidget *widget, GList * ephy_dnd_node_list_extract_nodes (const char *node_list) { + EphyNodeDb *db; GList *result = NULL; char **nodes; int i; nodes = g_strsplit (node_list, ";", -1); - for (i = 0; nodes[i] != NULL; i++) + db = ephy_node_db_get_by_name (nodes[i]); + g_return_val_if_fail (db != NULL, NULL); + + for (i = 1; nodes[i] != NULL; i++) { gulong id; @@ -124,7 +128,7 @@ ephy_dnd_node_list_extract_nodes (const char *node_list) { EphyNode *node; - node = ephy_node_get_from_id (id); + node = ephy_node_db_get_node_from_id (db, id); g_return_val_if_fail (node != NULL, NULL); result = g_list_append (result, node); } diff --git a/lib/ephy-node-db.c b/lib/ephy-node-db.c new file mode 100644 index 000000000..f77bac0bd --- /dev/null +++ b/lib/ephy-node-db.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * 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. + * + * $Id$ + */ + +#include "ephy-node-db.h" + +static void ephy_node_db_class_init (EphyNodeDbClass *klass); +static void ephy_node_db_init (EphyNodeDb *node); +static void ephy_node_db_finalize (GObject *object); + +/* FIXME I want to find a better way to deal with "root" nodes */ +#define RESERVED_IDS 30 + +enum +{ + PROP_0, + PROP_NAME +}; + +struct EphyNodeDbPrivate +{ + char *name; + + GMutex *id_factory_lock; + long id_factory; + + GStaticRWLock *id_to_node_lock; + GPtrArray *id_to_node; +}; + +static GHashTable *ephy_node_databases = NULL; + +static GObjectClass *parent_class = NULL; + +GType +ephy_node_db_get_type (void) +{ + static GType ephy_node_db_type = 0; + + if (ephy_node_db_type == 0) { + static const GTypeInfo our_info = { + sizeof (EphyNodeDbClass), + NULL, + NULL, + (GClassInitFunc) ephy_node_db_class_init, + NULL, + NULL, + sizeof (EphyNodeDb), + 0, + (GInstanceInitFunc) ephy_node_db_init + }; + + ephy_node_db_type = g_type_register_static (G_TYPE_OBJECT, + "EphyNodeDb", + &our_info, 0); + } + + return ephy_node_db_type; +} + +static void +ephy_node_db_set_name (EphyNodeDb *db, const char *name) +{ + db->priv->name = g_strdup (name); + + if (ephy_node_databases == NULL) + { + ephy_node_databases = g_hash_table_new_full + (g_str_hash, g_str_equal, NULL, NULL); + } + + g_hash_table_insert (ephy_node_databases, db->priv->name, db); +} + +static void +ephy_node_db_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyNodeDb *db; + + db = EPHY_NODE_DB (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, db->priv->name); + break; + } +} + + +static void +ephy_node_db_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyNodeDb *db; + + db = EPHY_NODE_DB (object); + + switch (prop_id) + { + case PROP_NAME: + ephy_node_db_set_name (db, g_value_get_string (value)); + break; + } +} + +static void +ephy_node_db_class_init (EphyNodeDbClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_node_db_finalize; + object_class->set_property = ephy_node_db_set_property; + object_class->get_property = ephy_node_db_get_property; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE)); +} + +static void +ephy_node_db_init (EphyNodeDb *db) +{ + db->priv = g_new0 (EphyNodeDbPrivate, 1); + + db->priv->name = NULL; + + /* id to node */ + db->priv->id_to_node = g_ptr_array_new (); + + db->priv->id_to_node_lock = g_new0 (GStaticRWLock, 1); + g_static_rw_lock_init (db->priv->id_to_node_lock); + + /* id factory */ + db->priv->id_factory = RESERVED_IDS; + db->priv->id_factory_lock = g_mutex_new (); +} + +static void +ephy_node_db_finalize (GObject *object) +{ + EphyNodeDb *db; + + g_return_if_fail (object != NULL); + + db = EPHY_NODE_DB (object); + + g_return_if_fail (db->priv != NULL); + + g_hash_table_remove (ephy_node_databases, db->priv->name); + if (g_hash_table_size (ephy_node_databases) == 0) + { + g_hash_table_destroy (ephy_node_databases); + } + + g_ptr_array_free (db->priv->id_to_node, FALSE); + + g_static_rw_lock_free (db->priv->id_to_node_lock); + + g_mutex_free (db->priv->id_factory_lock); + + g_free (db->priv->name); + + g_free (db->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyNodeDb * +ephy_node_db_get_by_name (const char *name) +{ + EphyNodeDb *ret; + + ret = g_hash_table_lookup (ephy_node_databases, name); + + return ret; +} + +EphyNodeDb * +ephy_node_db_new (const char *name) +{ + EphyNodeDb *db; + + db = EPHY_NODE_DB (g_object_new (EPHY_TYPE_NODE_DB, + "name", name, + NULL)); + + g_return_val_if_fail (db->priv != NULL, NULL); + + return db; +} + +static inline EphyNode * +node_from_id_real (EphyNodeDb *db, long id) +{ + EphyNode *ret = NULL; + + if (id < db->priv->id_to_node->len) + ret = g_ptr_array_index (db->priv->id_to_node, id);; + + return ret; +} + +EphyNode * +ephy_node_db_get_node_from_id (EphyNodeDb *db, long id) +{ + EphyNode *ret = NULL; + + g_static_rw_lock_reader_lock (db->priv->id_to_node_lock); + + ret = node_from_id_real (db, id); + + g_static_rw_lock_reader_unlock (db->priv->id_to_node_lock); + + return ret; +} + +long +_ephy_node_db_new_id (EphyNodeDb *db) +{ + long ret; + + g_mutex_lock (db->priv->id_factory_lock); + + while (node_from_id_real (db, db->priv->id_factory) != NULL) + { + db->priv->id_factory++; + } + + ret = db->priv->id_factory; + + g_mutex_unlock (db->priv->id_factory_lock); + + return ret; +} + +void +_ephy_node_db_add_id (EphyNodeDb *db, + long id, + EphyNode *node) +{ + g_static_rw_lock_writer_lock (db->priv->id_to_node_lock); + + /* resize array if needed */ + if (id >= db->priv->id_to_node->len) + g_ptr_array_set_size (db->priv->id_to_node, id + 1); + + g_ptr_array_index (db->priv->id_to_node, id) = node; + + g_static_rw_lock_writer_unlock (db->priv->id_to_node_lock); +} + +void +_ephy_node_db_remove_id (EphyNodeDb *db, + long id) +{ + g_static_rw_lock_writer_lock (db->priv->id_to_node_lock); + + g_ptr_array_index (db->priv->id_to_node, id) = NULL; + + /* reset id factory so we use the freed node id */ + db->priv->id_factory = RESERVED_IDS; + + g_static_rw_lock_writer_unlock (db->priv->id_to_node_lock); +} diff --git a/lib/ephy-node-db.h b/lib/ephy-node-db.h new file mode 100644 index 000000000..2b8c7637c --- /dev/null +++ b/lib/ephy-node-db.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * 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. + * + * $Id$ + */ + +#ifndef EPHY_NODE_DB_H +#define EPHY_NODE_DB_H + +#include + +G_BEGIN_DECLS + +#define EPHY_TYPE_NODE_DB (ephy_node_db_get_type ()) +#define EPHY_NODE_DB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_NODE_DB, EphyNodeDb)) +#define EPHY_NODE_DB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_NODE_DB, EphyNodeDbClass)) +#define EPHY_IS_NODE_DB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_NODE_DB)) +#define EPHY_IS_NODE_DB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_NODE_DB)) +#define EPHY_NODE_DB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_NODE_DB, EphyNodeDbClass)) + +typedef struct EphyNodeDb EphyNodeDb; +typedef struct EphyNodeDbPrivate EphyNodeDbPrivate; + +struct EphyNodeDb +{ + GObject parent; + + EphyNodeDbPrivate *priv; +}; + +typedef struct +{ + GObjectClass parent; + +} EphyNodeDbClass; + +#include "ephy-node.h" + +GType ephy_node_db_get_type (void); + +EphyNodeDb *ephy_node_db_get_by_name (const char *name); + +EphyNodeDb *ephy_node_db_new (const char *name); + +EphyNode *ephy_node_db_get_node_from_id (EphyNodeDb *db, + long id); + +long _ephy_node_db_new_id (EphyNodeDb *db); + +void _ephy_node_db_add_id (EphyNodeDb *db, + long id, + EphyNode *node); + +void _ephy_node_db_remove_id (EphyNodeDb *db, + long id); + +G_END_DECLS + +#endif /* __EPHY_NODE_DB_H */ diff --git a/lib/ephy-node.c b/lib/ephy-node.c index 9af43551c..f860d7467 100644 --- a/lib/ephy-node.c +++ b/lib/ephy-node.c @@ -30,35 +30,14 @@ #include "ephy-string.h" #include "ephy-thread-helpers.h" -static void ephy_node_class_init (EphyNodeClass *klass); -static void ephy_node_init (EphyNode *node); -static void ephy_node_finalize (GObject *object); -static void ephy_node_dispose (GObject *object); -static void ephy_node_set_object_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ephy_node_get_object_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static inline void id_factory_set_to (gulong new_factory_pos); -static inline void real_set_property (EphyNode *node, - guint property_id, - GValue *value); -static inline void real_remove_child (EphyNode *node, - EphyNode *child, - gboolean remove_from_parent, - gboolean remove_from_child); -static inline void real_add_child (EphyNode *node, - EphyNode *child); -static inline void read_lock_to_write_lock (EphyNode *node); -static inline void write_lock_to_read_lock (EphyNode *node); -static inline void lock_gdk (void); -static inline void unlock_gdk (void); -static inline EphyNode *node_from_id_real (gulong id); -static inline int get_child_index_real (EphyNode *node, - EphyNode *child); +typedef struct +{ + EphyNode *node; + int id; + EphyNodeCallback callback; + EphyNodeSignalType type; + gpointer data; +} EphyNodeSignalData; typedef struct { @@ -66,7 +45,7 @@ typedef struct guint index; } EphyNodeParent; -struct EphyNodePrivate +struct EphyNode { GStaticRWLock *lock; @@ -78,141 +57,46 @@ struct EphyNodePrivate GHashTable *parents; GPtrArray *children; -}; -enum -{ - PROP_0, - PROP_ID -}; + GHashTable *signals; + int signal_id; -enum -{ - DESTROYED, - RESTORED, - CHILD_ADDED, - CHILD_CHANGED, - CHILD_REMOVED, - CHILDREN_REORDERED, - LAST_SIGNAL + EphyNodeDb *db; }; -static GObjectClass *parent_class = NULL; +/* evillish hacks to temporarily readlock->writelock and v.v. */ +static inline void +write_lock_to_read_lock (EphyNode *node) +{ + g_static_mutex_lock (&node->lock->mutex); + node->lock->read_counter++; + g_static_mutex_unlock (&node->lock->mutex); -static guint ephy_node_signals[LAST_SIGNAL] = { 0 }; + g_static_rw_lock_writer_unlock (node->lock); +} -static GMutex *id_factory_lock = NULL; -static long id_factory; +static inline void +read_lock_to_write_lock (EphyNode *node) +{ + g_static_mutex_lock (&node->lock->mutex); + node->lock->read_counter--; + g_static_mutex_unlock (&node->lock->mutex); -static GStaticRWLock *id_to_node_lock = NULL; -static GPtrArray *id_to_node; + g_static_rw_lock_writer_lock (node->lock); +} -GType -ephy_node_get_type (void) +static inline void +lock_gdk (void) { - static GType ephy_node_type = 0; - - if (ephy_node_type == 0) { - static const GTypeInfo our_info = { - sizeof (EphyNodeClass), - NULL, - NULL, - (GClassInitFunc) ephy_node_class_init, - NULL, - NULL, - sizeof (EphyNode), - 0, - (GInstanceInitFunc) ephy_node_init - }; - - ephy_node_type = g_type_register_static (G_TYPE_OBJECT, - "EphyNode", - &our_info, 0); - } - - return ephy_node_type; + if (ephy_thread_helpers_in_main_thread () == FALSE) + GDK_THREADS_ENTER (); } -static void -ephy_node_class_init (EphyNodeClass *klass) +static inline void +unlock_gdk (void) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_node_finalize; - object_class->dispose = ephy_node_dispose; - - object_class->set_property = ephy_node_set_object_property; - object_class->get_property = ephy_node_get_object_property; - - g_object_class_install_property (object_class, - PROP_ID, - g_param_spec_long ("id", - "Node ID", - "Node ID", - 0, G_MAXLONG, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - ephy_node_signals[DESTROYED] = - g_signal_new ("destroyed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, destroyed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - ephy_node_signals[RESTORED] = - g_signal_new ("restored", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, restored), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - ephy_node_signals[CHILD_ADDED] = - g_signal_new ("child_added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, child_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EPHY_TYPE_NODE); - ephy_node_signals[CHILD_CHANGED] = - g_signal_new ("child_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, child_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EPHY_TYPE_NODE); - ephy_node_signals[CHILD_REMOVED] = - g_signal_new ("child_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, child_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EPHY_TYPE_NODE); - ephy_node_signals[CHILDREN_REORDERED] = - g_signal_new ("children_reordered", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNodeClass, children_reordered), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); + if (ephy_thread_helpers_in_main_thread () == FALSE) + GDK_THREADS_LEAVE (); } static gboolean @@ -229,61 +113,124 @@ int_hash (gconstpointer a) } static void -ephy_node_init (EphyNode *node) +callback (long id, EphyNodeSignalData *data, gpointer *user_data) { - node->priv = g_new0 (EphyNodePrivate, 1); + va_list valist = (va_list) user_data[0]; + EphyNodeSignalType type = GPOINTER_TO_INT (user_data[1]); - node->priv->lock = g_new0 (GStaticRWLock, 1); - g_static_rw_lock_init (node->priv->lock); + if (data->type != type) return; - node->priv->ref_count = 0; + switch (data->type) + { + case EPHY_NODE_DESTROYED: + case EPHY_NODE_RESTORED: + data->callback (data->node, data->data); + break; + + case EPHY_NODE_CHILD_ADDED: + case EPHY_NODE_CHILD_CHANGED: + case EPHY_NODE_CHILD_REMOVED: + data->callback (data->node, va_arg (valist, EphyNode *), data->data); + break; - node->priv->id = -1; + case EPHY_NODE_CHILDREN_REORDERED: + data->callback (data->node, va_arg (valist, int *), data->data); + break; + } +} - node->priv->properties = g_ptr_array_new (); +static void +ephy_node_emit_signal (EphyNode *node, EphyNodeSignalType type, ...) +{ + va_list valist; + gpointer data[2]; - node->priv->parents = g_hash_table_new_full (int_hash, - int_equal, - NULL, - g_free); + va_start (valist, type); - node->priv->children = g_ptr_array_new (); + data[0] = (gpointer)valist; + data[1] = GINT_TO_POINTER (type); + g_hash_table_foreach (node->signals, + (GHFunc) callback, + data); + va_end (valist); } static void -ephy_node_finalize (GObject *object) +ephy_node_finalize (EphyNode *node) { - EphyNode *node; guint i; - g_return_if_fail (object != NULL); - g_return_if_fail (EPHY_IS_NODE (object)); - - node = EPHY_NODE (object); - - g_return_if_fail (node->priv != NULL); + g_hash_table_destroy (node->signals); + node->signals = NULL; - for (i = 0; i < node->priv->properties->len; i++) { + for (i = 0; i < node->properties->len; i++) { GValue *val; - val = g_ptr_array_index (node->priv->properties, i); + val = g_ptr_array_index (node->properties, i); if (val != NULL) { g_value_unset (val); g_free (val); } } - g_ptr_array_free (node->priv->properties, FALSE); + g_ptr_array_free (node->properties, FALSE); + + g_hash_table_destroy (node->parents); + + g_ptr_array_free (node->children, FALSE); + + g_static_rw_lock_free (node->lock); + + g_free (node); +} + +static inline void +real_remove_child (EphyNode *node, + EphyNode *child, + gboolean remove_from_parent, + gboolean remove_from_child) +{ + EphyNodeParent *node_info; + + node_info = g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)); + + if (remove_from_parent) { + guint i; + + g_ptr_array_remove_index (node->children, + node_info->index); + + /* correct indices on kids */ + for (i = node_info->index; i < node->children->len; i++) { + EphyNode *borked_node; + EphyNodeParent *borked_node_info; + + borked_node = g_ptr_array_index (node->children, i); + + g_static_rw_lock_writer_lock (borked_node->lock); + + borked_node_info = g_hash_table_lookup (borked_node->parents, + GINT_TO_POINTER (node->id)); + borked_node_info->index--; + + g_static_rw_lock_writer_unlock (borked_node->lock); + } + } - g_hash_table_destroy (node->priv->parents); + if (remove_from_child) { + g_hash_table_remove (child->parents, + GINT_TO_POINTER (node->id)); + } - g_ptr_array_free (node->priv->children, FALSE); + write_lock_to_read_lock (node); + write_lock_to_read_lock (child); - g_static_rw_lock_free (node->priv->lock); + ephy_node_emit_signal (node, EPHY_NODE_CHILD_REMOVED, child); - g_free (node->priv); + read_lock_to_write_lock (node); + read_lock_to_write_lock (child); - G_OBJECT_CLASS (parent_class)->finalize (object); } static void @@ -291,169 +238,123 @@ remove_child (long id, EphyNodeParent *node_info, EphyNode *node) { - g_static_rw_lock_writer_lock (node_info->node->priv->lock); + g_static_rw_lock_writer_lock (node_info->node->lock); real_remove_child (node_info->node, node, TRUE, FALSE); - g_static_rw_lock_writer_unlock (node_info->node->priv->lock); + g_static_rw_lock_writer_unlock (node_info->node->lock); } static void -ephy_node_dispose (GObject *object) +signal_object_weak_notify (EphyNodeSignalData *signal_data, + GObject *where_the_object_was) { - EphyNode *node; - guint i; - - node = EPHY_NODE (object); + ephy_node_signal_disconnect (signal_data->node, signal_data->id); +} - /* remove from id table */ - g_static_rw_lock_writer_lock (id_to_node_lock); +static void +unref_signal_objects (long id, + EphyNodeSignalData *signal_data, + EphyNode *node) +{ + g_object_weak_unref (G_OBJECT (signal_data->data), + (GWeakNotify)signal_object_weak_notify, + signal_data); +} - g_ptr_array_index (id_to_node, node->priv->id) = NULL; +static void +ephy_node_dispose (EphyNode *node) +{ + guint i; - g_static_rw_lock_writer_unlock (id_to_node_lock); + _ephy_node_db_remove_id (node->db, node->id); lock_gdk (); /* remove from DAG */ - g_hash_table_foreach (node->priv->parents, + g_hash_table_foreach (node->parents, (GHFunc) remove_child, node); - for (i = 0; i < node->priv->children->len; i++) { + g_hash_table_foreach (node->signals, + (GHFunc) unref_signal_objects, + node); + + for (i = 0; i < node->children->len; i++) { EphyNode *child; - child = g_ptr_array_index (node->priv->children, i); + child = g_ptr_array_index (node->children, i); - g_static_rw_lock_writer_lock (child->priv->lock); + g_static_rw_lock_writer_lock (child->lock); real_remove_child (node, child, FALSE, TRUE); - - g_static_rw_lock_writer_unlock (child->priv->lock); + + g_static_rw_lock_writer_unlock (child->lock); } - g_static_rw_lock_writer_unlock (node->priv->lock); + g_static_rw_lock_writer_unlock (node->lock); - g_signal_emit (G_OBJECT (node), ephy_node_signals[DESTROYED], 0); + ephy_node_emit_signal (node, EPHY_NODE_DESTROYED); unlock_gdk (); - - G_OBJECT_CLASS (parent_class)->dispose (object); } -static void -ephy_node_set_object_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +EphyNode * +ephy_node_new (EphyNodeDb *db) { - EphyNode *node = EPHY_NODE (object); - - switch (prop_id) - { - case PROP_ID: - node->priv->id = g_value_get_long (value); - - g_static_rw_lock_writer_lock (id_to_node_lock); - - /* resize array if needed */ - if (node->priv->id >= id_to_node->len) - g_ptr_array_set_size (id_to_node, node->priv->id + 1); + long id; - g_ptr_array_index (id_to_node, node->priv->id) = node; + id = _ephy_node_db_new_id (db); - g_static_rw_lock_writer_unlock (id_to_node_lock); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -ephy_node_get_object_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EphyNode *node = EPHY_NODE (object); - - switch (prop_id) - { - case PROP_ID: - g_value_set_long (value, node->priv->id); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + return ephy_node_new_with_id (db, id); } EphyNode * -ephy_node_new (void) +ephy_node_new_with_id (EphyNodeDb *db, gulong reserved_id) { EphyNode *node; - node = EPHY_NODE (g_object_new (EPHY_TYPE_NODE, - "id", ephy_node_new_id (), - NULL)); + node = g_new0 (EphyNode, 1); - g_return_val_if_fail (node->priv != NULL, NULL); + node->lock = g_new0 (GStaticRWLock, 1); + g_static_rw_lock_init (node->lock); - return node; -} - -EphyNode * -ephy_node_new_with_id (gulong reserved_id) -{ - EphyNode *node; + node->ref_count = 0; - node = EPHY_NODE (g_object_new (EPHY_TYPE_NODE, - "id", reserved_id, - NULL)); + node->id = reserved_id; - g_return_val_if_fail (node->priv != NULL, NULL); + node->db = db; - return node; -} + node->properties = g_ptr_array_new (); -long -ephy_node_get_id (EphyNode *node) -{ - long ret; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + node->children = g_ptr_array_new (); - g_static_rw_lock_reader_lock (node->priv->lock); + node->parents = g_hash_table_new_full (int_hash, + int_equal, + NULL, + g_free); - ret = node->priv->id; + node->signals = g_hash_table_new_full (int_hash, + int_equal, + NULL, + g_free); + node->signal_id = 0; - g_static_rw_lock_reader_unlock (node->priv->lock); + _ephy_node_db_add_id (db, reserved_id, node); - return ret; + return node; } -static inline EphyNode * -node_from_id_real (gulong id) +long +ephy_node_get_id (EphyNode *node) { - EphyNode *ret = NULL; - - if (id < id_to_node->len) - ret = g_ptr_array_index (id_to_node, id);; + long ret; - return ret; -} + g_static_rw_lock_reader_lock (node->lock); -EphyNode * -ephy_node_get_from_id (gulong id) -{ - EphyNode *ret = NULL; + ret = node->id; - g_static_rw_lock_reader_lock (id_to_node_lock); - - ret = node_from_id_real (id); - - g_static_rw_lock_reader_unlock (id_to_node_lock); + g_static_rw_lock_reader_unlock (node->lock); return ret; } @@ -461,45 +362,38 @@ ephy_node_get_from_id (gulong id) void ephy_node_ref (EphyNode *node) { - g_return_if_fail (EPHY_IS_NODE (node)); - - g_static_rw_lock_writer_lock (node->priv->lock); + g_static_rw_lock_writer_lock (node->lock); - node->priv->ref_count++; + node->ref_count++; - g_static_rw_lock_writer_unlock (node->priv->lock); + g_static_rw_lock_writer_unlock (node->lock); } void ephy_node_unref (EphyNode *node) { - g_return_if_fail (EPHY_IS_NODE (node)); - - g_static_rw_lock_writer_lock (node->priv->lock); + g_static_rw_lock_writer_lock (node->lock); - node->priv->ref_count--; + node->ref_count--; - if (node->priv->ref_count <= 0) { - g_object_unref (G_OBJECT (node)); + if (node->ref_count <= 0) { + ephy_node_dispose (node); + ephy_node_finalize (node); } else { - g_static_rw_lock_writer_unlock (node->priv->lock); + g_static_rw_lock_writer_unlock (node->lock); } } -void +void ephy_node_freeze (EphyNode *node) { - g_return_if_fail (EPHY_IS_NODE (node)); - - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); } void ephy_node_thaw (EphyNode *node) { - g_return_if_fail (EPHY_IS_NODE (node)); - - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); } static void @@ -507,11 +401,11 @@ child_changed (gulong id, EphyNodeParent *node_info, EphyNode *node) { - g_static_rw_lock_reader_lock (node_info->node->priv->lock); + g_static_rw_lock_reader_lock (node_info->node->lock); - g_signal_emit (G_OBJECT (node_info->node), ephy_node_signals[CHILD_CHANGED], 0, node); + ephy_node_emit_signal (node_info->node, EPHY_NODE_CHILD_CHANGED, node); - g_static_rw_lock_reader_unlock (node_info->node->priv->lock); + g_static_rw_lock_reader_unlock (node_info->node->lock); } static inline void @@ -521,17 +415,17 @@ real_set_property (EphyNode *node, { GValue *old; - if (property_id >= node->priv->properties->len) { - g_ptr_array_set_size (node->priv->properties, property_id + 1); + if (property_id >= node->properties->len) { + g_ptr_array_set_size (node->properties, property_id + 1); } - old = g_ptr_array_index (node->priv->properties, property_id); + old = g_ptr_array_index (node->properties, property_id); if (old != NULL) { g_value_unset (old); g_free (old); } - - g_ptr_array_index (node->priv->properties, property_id) = value; + + g_ptr_array_index (node->properties, property_id) = value; } void @@ -540,14 +434,13 @@ ephy_node_set_property (EphyNode *node, const GValue *value) { GValue *new; - - g_return_if_fail (EPHY_IS_NODE (node)); + g_return_if_fail (property_id >= 0); g_return_if_fail (value != NULL); lock_gdk (); - g_static_rw_lock_writer_lock (node->priv->lock); + g_static_rw_lock_writer_lock (node->lock); new = g_new0 (GValue, 1); g_value_init (new, G_VALUE_TYPE (value)); @@ -557,12 +450,12 @@ ephy_node_set_property (EphyNode *node, write_lock_to_read_lock (node); - g_hash_table_foreach (node->priv->parents, + g_hash_table_foreach (node->parents, (GHFunc) child_changed, node); - g_static_rw_lock_reader_unlock (node->priv->lock); - + g_static_rw_lock_reader_unlock (node->lock); + unlock_gdk (); } @@ -572,28 +465,27 @@ ephy_node_get_property (EphyNode *node, GValue *value) { GValue *ret; - - g_return_val_if_fail (EPHY_IS_NODE (node), FALSE); + g_return_val_if_fail (property_id >= 0, FALSE); g_return_val_if_fail (value != NULL, FALSE); - - g_static_rw_lock_reader_lock (node->priv->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); + + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return FALSE; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return FALSE; } - + g_value_init (value, G_VALUE_TYPE (ret)); g_value_copy (ret, value); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return TRUE; } @@ -604,27 +496,26 @@ ephy_node_get_property_string (EphyNode *node, { GValue *ret; const char *retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); + g_return_val_if_fail (property_id >= 0, NULL); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return NULL; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return NULL; } - + retval = g_value_get_string (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); - + g_static_rw_lock_reader_unlock (node->lock); + return retval; } @@ -634,26 +525,25 @@ ephy_node_get_property_boolean (EphyNode *node, { GValue *ret; gboolean retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), FALSE); + g_return_val_if_fail (property_id >= 0, FALSE); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return FALSE; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return FALSE; } - + retval = g_value_get_boolean (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -664,26 +554,25 @@ ephy_node_get_property_long (EphyNode *node, { GValue *ret; long retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_return_val_if_fail (property_id >= 0, -1); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return -1; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return -1; } - + retval = g_value_get_long (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -694,26 +583,25 @@ ephy_node_get_property_int (EphyNode *node, { GValue *ret; int retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_return_val_if_fail (property_id >= 0, -1); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return -1; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return -1; } - + retval = g_value_get_int (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -724,26 +612,25 @@ ephy_node_get_property_double (EphyNode *node, { GValue *ret; double retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_return_val_if_fail (property_id >= 0, -1); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return -1; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return -1; } - + retval = g_value_get_double (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -754,26 +641,25 @@ ephy_node_get_property_float (EphyNode *node, { GValue *ret; float retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_return_val_if_fail (property_id >= 0, -1); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return -1; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return -1; } - + retval = g_value_get_float (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -784,86 +670,25 @@ ephy_node_get_property_node (EphyNode *node, { GValue *ret; EphyNode *retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); + g_return_val_if_fail (property_id >= 0, NULL); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); + if (property_id >= node->properties->len) { + g_static_rw_lock_reader_unlock (node->lock); return NULL; } - ret = g_ptr_array_index (node->priv->properties, property_id); + ret = g_ptr_array_index (node->properties, property_id); if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return NULL; } - - retval = g_value_get_pointer (ret); - - g_static_rw_lock_reader_unlock (node->priv->lock); - - return retval; -} - -char * -ephy_node_get_property_time (EphyNode *node, - guint property_id) -{ - GValue *ret; - long mtime; - char *retval; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); - g_return_val_if_fail (property_id >= 0, NULL); - g_static_rw_lock_reader_lock (node->priv->lock); - - if (property_id >= node->priv->properties->len) { - g_static_rw_lock_reader_unlock (node->priv->lock); - return g_strdup (_("Never")); - } - - ret = g_ptr_array_index (node->priv->properties, property_id); - if (ret == NULL) { - g_static_rw_lock_reader_unlock (node->priv->lock); - return g_strdup (_("Never")); - } - - mtime = g_value_get_long (ret); - - if (retval >= 0) { - GDate *now, *file_date; - guint32 file_date_age; - const char *format = NULL; - - now = g_date_new (); - g_date_set_time (now, time (NULL)); - - file_date = g_date_new (); - g_date_set_time (file_date, mtime); - - file_date_age = (g_date_get_julian (now) - g_date_get_julian (file_date)); - - g_date_free (file_date); - g_date_free (now); - - if (file_date_age == 0) { - format = _("Today at %-H:%M"); - } else if (file_date_age == 1) { - format = _("Yesterday at %-H:%M"); - } else { - format = _("%A, %B %-d %Y at %-H:%M"); - } - - retval = ephy_string_time_to_string (file_date, format); - } else { - retval = g_strdup (_("Never")); - } + retval = g_value_get_pointer (ret); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return retval; } @@ -878,13 +703,13 @@ save_parent (gulong id, parent_xml_node = xmlNewChild (xml_node, NULL, "parent", NULL); - g_static_rw_lock_reader_lock (node_info->node->priv->lock); + g_static_rw_lock_reader_lock (node_info->node->lock); - xml = g_strdup_printf ("%ld", node_info->node->priv->id); + xml = g_strdup_printf ("%ld", node_info->node->id); xmlSetProp (parent_xml_node, "id", xml); g_free (xml); - - g_static_rw_lock_reader_unlock (node_info->node->priv->lock); + + g_static_rw_lock_reader_unlock (node_info->node->lock); } void @@ -895,24 +720,23 @@ ephy_node_save_to_xml (EphyNode *node, char *xml; guint i; - g_return_if_fail (EPHY_IS_NODE (node)); g_return_if_fail (parent_xml_node != NULL); - - g_static_rw_lock_reader_lock (node->priv->lock); + + g_static_rw_lock_reader_lock (node->lock); xml_node = xmlNewChild (parent_xml_node, NULL, "node", NULL); - xml = g_strdup_printf ("%ld", node->priv->id); + xml = g_strdup_printf ("%ld", node->id); xmlSetProp (xml_node, "id", xml); g_free (xml); xmlSetProp (xml_node, "type", G_OBJECT_TYPE_NAME (node)); - for (i = 0; i < node->priv->properties->len; i++) { + for (i = 0; i < node->properties->len; i++) { GValue *value; xmlNodePtr value_xml_node; - value = g_ptr_array_index (node->priv->properties, i); + value = g_ptr_array_index (node->properties, i); if (value == NULL) continue; @@ -965,13 +789,13 @@ ephy_node_save_to_xml (EphyNode *node, g_assert (prop_node != NULL); - g_static_rw_lock_reader_lock (prop_node->priv->lock); - - xml = g_strdup_printf ("%ld", prop_node->priv->id); + g_static_rw_lock_reader_lock (prop_node->lock); + + xml = g_strdup_printf ("%ld", prop_node->id); xmlNodeSetContent (value_xml_node, xml); g_free (xml); - - g_static_rw_lock_reader_unlock (prop_node->priv->lock); + + g_static_rw_lock_reader_unlock (prop_node->lock); break; } default: @@ -980,25 +804,46 @@ ephy_node_save_to_xml (EphyNode *node, } } - g_hash_table_foreach (node->priv->parents, + g_hash_table_foreach (node->parents, (GHFunc) save_parent, xml_node); - - g_static_rw_lock_reader_unlock (node->priv->lock); + + g_static_rw_lock_reader_unlock (node->lock); +} + +static inline void +real_add_child (EphyNode *node, + EphyNode *child) +{ + EphyNodeParent *node_info; + + if (g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)) != NULL) { + return; + } + + g_ptr_array_add (node->children, child); + + node_info = g_new0 (EphyNodeParent, 1); + node_info->node = node; + node_info->index = node->children->len - 1; + + g_hash_table_insert (child->parents, + GINT_TO_POINTER (node->id), + node_info); } /* this function assumes it's safe to not lock anything while loading, * this is at least true for the case where we're loading the library xml file * from the main loop */ EphyNode * -ephy_node_new_from_xml (xmlNodePtr xml_node) +ephy_node_new_from_xml (EphyNodeDb *db, xmlNodePtr xml_node) { EphyNode *node; xmlNodePtr xml_child; char *xml; long id; - GType type; - + g_return_val_if_fail (xml_node != NULL, NULL); xml = xmlGetProp (xml_node, "id"); @@ -1007,17 +852,7 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) id = atol (xml); g_free (xml); - id_factory_set_to (id); - - xml = xmlGetProp (xml_node, "type"); - type = g_type_from_name (xml); - g_free (xml); - - node = EPHY_NODE (g_object_new (type, - "id", id, - NULL)); - - g_return_val_if_fail (node->priv != NULL, NULL); + node = ephy_node_new_with_id (db, id); for (xml_child = xml_node->children; xml_child != NULL; xml_child = xml_child->next) { if (strcmp (xml_child->name, "parent") == 0) { @@ -1029,14 +864,13 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) parent_id = atol (xml); g_free (xml); - parent = node_from_id_real (parent_id); + parent = ephy_node_db_get_node_from_id (db, parent_id); if (parent != NULL) { real_add_child (parent, node); - - g_signal_emit (G_OBJECT (parent), ephy_node_signals[CHILD_ADDED], - 0, node); + + ephy_node_emit_signal (parent, EPHY_NODE_CHILD_ADDED, node); } } else if (strcmp (xml_child->name, "property") == 0) { GType value_type; @@ -1046,7 +880,7 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) xml = xmlGetProp (xml_child, "id"); property_id = atoi (xml); g_free (xml); - + xml = xmlGetProp (xml_child, "value_type"); value_type = g_type_from_name (xml); g_free (xml); @@ -1054,7 +888,7 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) xml = xmlNodeGetContent (xml_child); value = g_new0 (GValue, 1); g_value_init (value, value_type); - + switch (value_type) { case G_TYPE_STRING: @@ -1079,8 +913,8 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) { EphyNode *property_node; - property_node = node_from_id_real (atol (xml)); - + property_node = ephy_node_db_get_node_from_id (db, atol (xml)); + g_value_set_pointer (value, property_node); break; } @@ -1088,130 +922,53 @@ ephy_node_new_from_xml (xmlNodePtr xml_node) g_assert_not_reached (); break; } - + real_set_property (node, property_id, value); - + g_free (xml); } } - g_signal_emit (G_OBJECT (node), ephy_node_signals[RESTORED], 0); + ephy_node_emit_signal (node, EPHY_NODE_RESTORED); return node; } -static inline void -real_add_child (EphyNode *node, - EphyNode *child) -{ - EphyNodeParent *node_info; - - if (g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)) != NULL) { - return; - } - - g_ptr_array_add (node->priv->children, child); - - node_info = g_new0 (EphyNodeParent, 1); - node_info->node = node; - node_info->index = node->priv->children->len - 1; - - g_hash_table_insert (child->priv->parents, - GINT_TO_POINTER (node->priv->id), - node_info); -} - void ephy_node_add_child (EphyNode *node, EphyNode *child) { - g_return_if_fail (EPHY_IS_NODE (node)); - g_return_if_fail (EPHY_IS_NODE (child)); - lock_gdk (); - g_static_rw_lock_writer_lock (node->priv->lock); - g_static_rw_lock_writer_lock (child->priv->lock); + g_static_rw_lock_writer_lock (node->lock); + g_static_rw_lock_writer_lock (child->lock); real_add_child (node, child); write_lock_to_read_lock (node); write_lock_to_read_lock (child); - g_signal_emit (G_OBJECT (node), ephy_node_signals[CHILD_ADDED], 0, child); - - g_static_rw_lock_reader_unlock (node->priv->lock); - g_static_rw_lock_reader_unlock (child->priv->lock); - - unlock_gdk (); -} - -static inline void -real_remove_child (EphyNode *node, - EphyNode *child, - gboolean remove_from_parent, - gboolean remove_from_child) -{ - EphyNodeParent *node_info; - - node_info = g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); - - if (remove_from_parent) { - guint i; + ephy_node_emit_signal (node, EPHY_NODE_CHILD_ADDED, child); - g_ptr_array_remove_index (node->priv->children, - node_info->index); - - /* correct indices on kids */ - for (i = node_info->index; i < node->priv->children->len; i++) { - EphyNode *borked_node; - EphyNodeParent *borked_node_info; - - borked_node = g_ptr_array_index (node->priv->children, i); - - g_static_rw_lock_writer_lock (borked_node->priv->lock); - - borked_node_info = g_hash_table_lookup (borked_node->priv->parents, - GINT_TO_POINTER (node->priv->id)); - borked_node_info->index--; - - g_static_rw_lock_writer_unlock (borked_node->priv->lock); - } - } - - if (remove_from_child) { - g_hash_table_remove (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); - } - - write_lock_to_read_lock (node); - write_lock_to_read_lock (child); - - g_signal_emit (G_OBJECT (node), ephy_node_signals[CHILD_REMOVED], 0, child); - - read_lock_to_write_lock (node); - read_lock_to_write_lock (child); + g_static_rw_lock_reader_unlock (node->lock); + g_static_rw_lock_reader_unlock (child->lock); + unlock_gdk (); } void ephy_node_remove_child (EphyNode *node, EphyNode *child) { - g_return_if_fail (EPHY_IS_NODE (node)); - g_return_if_fail (EPHY_IS_NODE (child)); - lock_gdk (); - g_static_rw_lock_writer_lock (node->priv->lock); - g_static_rw_lock_writer_lock (child->priv->lock); + g_static_rw_lock_writer_lock (node->lock); + g_static_rw_lock_writer_lock (child->lock); real_remove_child (node, child, TRUE, TRUE); - g_static_rw_lock_writer_unlock (node->priv->lock); - g_static_rw_lock_writer_unlock (child->priv->lock); + g_static_rw_lock_writer_unlock (node->lock); + g_static_rw_lock_writer_unlock (child->lock); unlock_gdk (); } @@ -1222,17 +979,14 @@ ephy_node_has_child (EphyNode *node, { gboolean ret; - g_return_val_if_fail (EPHY_IS_NODE (node), FALSE); - g_return_val_if_fail (EPHY_IS_NODE (child), FALSE); + g_static_rw_lock_reader_lock (node->lock); + g_static_rw_lock_reader_lock (child->lock); - g_static_rw_lock_reader_lock (node->priv->lock); - g_static_rw_lock_reader_lock (child->priv->lock); + ret = (g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)) != NULL); - ret = (g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)) != NULL); - - g_static_rw_lock_reader_unlock (node->priv->lock); - g_static_rw_lock_reader_unlock (child->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); + g_static_rw_lock_reader_unlock (child->lock); return ret; } @@ -1244,14 +998,14 @@ ephy_node_real_get_child_index (EphyNode *node, EphyNodeParent *node_info; int ret; - node_info = g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); + node_info = g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)); if (node_info == NULL) return -1; ret = node_info->index; - + return ret; } @@ -1261,23 +1015,22 @@ ephy_node_sort_children (EphyNode *node, { GPtrArray *newkids; int i, *new_order; - - g_return_if_fail (EPHY_IS_NODE (node)); + g_return_if_fail (compare_func != NULL); lock_gdk (); - g_static_rw_lock_writer_lock (node->priv->lock); + g_static_rw_lock_writer_lock (node->lock); newkids = g_ptr_array_new (); - g_ptr_array_set_size (newkids, node->priv->children->len); + g_ptr_array_set_size (newkids, node->children->len); /* dup the array */ - for (i = 0; i < node->priv->children->len; i++) + for (i = 0; i < node->children->len; i++) { - g_ptr_array_index (newkids, i) = g_ptr_array_index (node->priv->children, i); + g_ptr_array_index (newkids, i) = g_ptr_array_index (node->children, i); } - + g_ptr_array_sort (newkids, compare_func); new_order = g_new (int, newkids->len); @@ -1290,62 +1043,62 @@ ephy_node_sort_children (EphyNode *node, child = g_ptr_array_index (newkids, i); new_order[ephy_node_real_get_child_index (node, child)] = i; - node_info = g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); + node_info = g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)); node_info->index = i; - } + } + + g_ptr_array_free (node->children, FALSE); + node->children = newkids; - g_ptr_array_free (node->priv->children, FALSE); - node->priv->children = newkids; - write_lock_to_read_lock (node); - - g_signal_emit (G_OBJECT (node), ephy_node_signals[CHILDREN_REORDERED], 0, new_order); + + ephy_node_emit_signal (node, EPHY_NODE_CHILDREN_REORDERED, new_order); + g_free (new_order); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); unlock_gdk (); } void ephy_node_reorder_children (EphyNode *node, - int *new_order) + int *new_order) { GPtrArray *newkids; int i; - g_return_if_fail (EPHY_IS_NODE (node)); g_return_if_fail (new_order != NULL); lock_gdk (); - g_static_rw_lock_writer_lock (node->priv->lock); + g_static_rw_lock_writer_lock (node->lock); newkids = g_ptr_array_new (); - g_ptr_array_set_size (newkids, node->priv->children->len); + g_ptr_array_set_size (newkids, node->children->len); - for (i = 0; i < node->priv->children->len; i++) { + for (i = 0; i < node->children->len; i++) { EphyNode *child; EphyNodeParent *node_info; - child = g_ptr_array_index (node->priv->children, i); + child = g_ptr_array_index (node->children, i); g_ptr_array_index (newkids, new_order[i]) = child; - node_info = g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); + node_info = g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)); node_info->index = new_order[i]; } - g_ptr_array_free (node->priv->children, FALSE); - node->priv->children = newkids; + g_ptr_array_free (node->children, FALSE); + node->children = newkids; write_lock_to_read_lock (node); - g_signal_emit (G_OBJECT (node), ephy_node_signals[CHILDREN_REORDERED], 0, new_order); + ephy_node_emit_signal (node, EPHY_NODE_CHILDREN_REORDERED, new_order); - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); unlock_gdk (); } @@ -1353,11 +1106,9 @@ ephy_node_reorder_children (EphyNode *node, GPtrArray * ephy_node_get_children (EphyNode *node) { - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); - - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - return node->priv->children; + return node->children; } int @@ -1365,13 +1116,11 @@ ephy_node_get_n_children (EphyNode *node) { int ret; - g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_static_rw_lock_reader_lock (node->lock); + + ret = node->children->len; - g_static_rw_lock_reader_lock (node->priv->lock); - - ret = node->priv->children->len; - - g_static_rw_lock_reader_unlock (node->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); return ret; } @@ -1381,20 +1130,19 @@ ephy_node_get_nth_child (EphyNode *node, guint n) { EphyNode *ret; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); + g_return_val_if_fail (n >= 0, NULL); - g_static_rw_lock_reader_lock (node->priv->lock); + g_static_rw_lock_reader_lock (node->lock); - if (n < node->priv->children->len) { - ret = g_ptr_array_index (node->priv->children, n); + if (n < node->children->len) { + ret = g_ptr_array_index (node->children, n); } else { ret = NULL; } - - g_static_rw_lock_reader_unlock (node->priv->lock); - + + g_static_rw_lock_reader_unlock (node->lock); + return ret; } @@ -1404,8 +1152,8 @@ get_child_index_real (EphyNode *node, { EphyNodeParent *node_info; - node_info = g_hash_table_lookup (child->priv->parents, - GINT_TO_POINTER (node->priv->id)); + node_info = g_hash_table_lookup (child->parents, + GINT_TO_POINTER (node->id)); if (node_info == NULL) return -1; @@ -1419,17 +1167,14 @@ ephy_node_get_child_index (EphyNode *node, EphyNode *child) { int ret; - - g_return_val_if_fail (EPHY_IS_NODE (node), -1); - g_return_val_if_fail (EPHY_IS_NODE (child), -1); - g_static_rw_lock_reader_lock (node->priv->lock); - g_static_rw_lock_reader_lock (child->priv->lock); + g_static_rw_lock_reader_lock (node->lock); + g_static_rw_lock_reader_lock (child->lock); ret = ephy_node_real_get_child_index (node, child); - g_static_rw_lock_reader_unlock (node->priv->lock); - g_static_rw_lock_reader_unlock (child->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); + g_static_rw_lock_reader_unlock (child->lock); return ret; } @@ -1440,23 +1185,20 @@ ephy_node_get_next_child (EphyNode *node, { EphyNode *ret; guint idx; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); - g_return_val_if_fail (EPHY_IS_NODE (child), NULL); - g_static_rw_lock_reader_lock (node->priv->lock); - g_static_rw_lock_reader_lock (child->priv->lock); + g_static_rw_lock_reader_lock (node->lock); + g_static_rw_lock_reader_lock (child->lock); idx = get_child_index_real (node, child); - if ((idx + 1) < node->priv->children->len) { - ret = g_ptr_array_index (node->priv->children, idx + 1); + if ((idx + 1) < node->children->len) { + ret = g_ptr_array_index (node->children, idx + 1); } else { ret = NULL; } - g_static_rw_lock_reader_unlock (node->priv->lock); - g_static_rw_lock_reader_unlock (child->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); + g_static_rw_lock_reader_unlock (child->lock); return ret; } @@ -1467,107 +1209,56 @@ ephy_node_get_previous_child (EphyNode *node, { EphyNode *ret; int idx; - - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); - g_return_val_if_fail (EPHY_IS_NODE (child), NULL); - g_static_rw_lock_reader_lock (node->priv->lock); - g_static_rw_lock_reader_lock (child->priv->lock); + g_static_rw_lock_reader_lock (node->lock); + g_static_rw_lock_reader_lock (child->lock); idx = get_child_index_real (node, child); if ((idx - 1) >= 0) { - ret = g_ptr_array_index (node->priv->children, idx - 1); + ret = g_ptr_array_index (node->children, idx - 1); } else { ret = NULL; } - g_static_rw_lock_reader_unlock (node->priv->lock); - g_static_rw_lock_reader_unlock (child->priv->lock); + g_static_rw_lock_reader_unlock (node->lock); + g_static_rw_lock_reader_unlock (child->lock); return ret; } -void -ephy_node_system_init (gulong reserved_ids) -{ - /* id to node */ - id_to_node = g_ptr_array_new (); - - id_to_node_lock = g_new0 (GStaticRWLock, 1); - g_static_rw_lock_init (id_to_node_lock); - - /* id factory */ - id_factory = reserved_ids; - id_factory_lock = g_mutex_new (); -} - -void -ephy_node_system_shutdown (void) -{ - g_ptr_array_free (id_to_node, FALSE); - - g_static_rw_lock_free (id_to_node_lock); - - g_mutex_free (id_factory_lock); -} - -long -ephy_node_new_id (void) +int +ephy_node_signal_connect_object (EphyNode *node, + EphyNodeSignalType type, + EphyNodeCallback callback, + GObject *object) { - long ret; - - g_mutex_lock (id_factory_lock); - - id_factory++; - - ret = id_factory; + EphyNodeSignalData *signal_data; + int ret; - g_mutex_unlock (id_factory_lock); + signal_data = g_new0 (EphyNodeSignalData, 1); + signal_data->node = node; + signal_data->id = node->signal_id; + signal_data->callback = callback; + signal_data->type = type; + signal_data->data = object; + + g_hash_table_insert (node->signals, + GINT_TO_POINTER (node->signal_id), + signal_data); + g_object_weak_ref (object, (GWeakNotify)signal_object_weak_notify, + signal_data); + ret = node->signal_id; + node->signal_id++; return ret; } -static void -id_factory_set_to (gulong new_factory_pos) -{ - if (new_factory_pos > id_factory) - { - id_factory = new_factory_pos + 1; - } -} - -/* evillish hacks to temporarily readlock->writelock and v.v. */ -static inline void -write_lock_to_read_lock (EphyNode *node) -{ - g_static_mutex_lock (&node->priv->lock->mutex); - node->priv->lock->read_counter++; - g_static_mutex_unlock (&node->priv->lock->mutex); - - g_static_rw_lock_writer_unlock (node->priv->lock); -} - -static inline void -read_lock_to_write_lock (EphyNode *node) -{ - g_static_mutex_lock (&node->priv->lock->mutex); - node->priv->lock->read_counter--; - g_static_mutex_unlock (&node->priv->lock->mutex); - - g_static_rw_lock_writer_lock (node->priv->lock); -} - -static inline void -lock_gdk (void) +void +ephy_node_signal_disconnect (EphyNode *node, + int signal_id) { - if (ephy_thread_helpers_in_main_thread () == FALSE) - GDK_THREADS_ENTER (); + g_hash_table_remove (node->signals, + GINT_TO_POINTER (signal_id)); } -static inline void -unlock_gdk (void) -{ - if (ephy_thread_helpers_in_main_thread () == FALSE) - GDK_THREADS_LEAVE (); -} diff --git a/lib/ephy-node.h b/lib/ephy-node.h index e7872400e..9fb3084a0 100644 --- a/lib/ephy-node.h +++ b/lib/ephy-node.h @@ -18,56 +18,38 @@ * $Id$ */ + #ifndef EPHY_NODE_H #define EPHY_NODE_H -#include - #include G_BEGIN_DECLS -#define EPHY_TYPE_NODE (ephy_node_get_type ()) -#define EPHY_NODE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_NODE, EphyNode)) -#define EPHY_NODE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_NODE, EphyNodeClass)) -#define EPHY_IS_NODE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_NODE)) -#define EPHY_IS_NODE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_NODE)) -#define EPHY_NODE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_NODE, EphyNodeClass)) - -typedef struct EphyNodePrivate EphyNodePrivate; - -typedef struct -{ - GObject parent; - - EphyNodePrivate *priv; -} EphyNode; +typedef struct EphyNode EphyNode; -typedef struct +typedef enum { - GObjectClass parent; + EPHY_NODE_DESTROYED, /* RBNode *node */ + EPHY_NODE_RESTORED, /* RBNode *node */ + EPHY_NODE_CHILD_ADDED, /* RBNode *node, RBNode *child */ + EPHY_NODE_CHILD_CHANGED, /* RBNode *node, RBNode *child */ + EPHY_NODE_CHILD_REMOVED, /* RBNode *node, RBNode *child */ + EPHY_NODE_CHILDREN_REORDERED /* RBNode *node, int *new_order */ +} EphyNodeSignalType; - /* signals */ - void (*destroyed) (EphyNode *node); - void (*restored) (EphyNode *node); +#include "ephy-node-db.h" - void (*child_added) (EphyNode *node, EphyNode *child); - void (*child_changed) (EphyNode *node, EphyNode *child); - void (*children_reordered) (EphyNode *node, int *new_order); - void (*child_removed) (EphyNode *node, EphyNode *child); -} EphyNodeClass; +typedef void (*EphyNodeCallback) (EphyNode *node, ...); -GType ephy_node_get_type (void); +EphyNode *ephy_node_new (EphyNodeDb *db); -EphyNode *ephy_node_new (void); - -EphyNode *ephy_node_new_with_id (gulong reserved_id); +EphyNode *ephy_node_new_with_id (EphyNodeDb *db, + gulong reserved_id); /* unique node ID */ long ephy_node_get_id (EphyNode *node); -EphyNode *ephy_node_get_from_id (gulong id); - /* refcounting */ void ephy_node_ref (EphyNode *node); void ephy_node_unref (EphyNode *node); @@ -76,13 +58,16 @@ void ephy_node_unref (EphyNode *node); void ephy_node_freeze (EphyNode *node); void ephy_node_thaw (EphyNode *node); -/* property interface */ -enum -{ - EPHY_NODE_PROP_NAME = 0, - EPHY_NODE_PROP_NAME_SORT_KEY = 1 -}; +/* signals */ +int ephy_node_signal_connect_object (EphyNode *node, + EphyNodeSignalType type, + EphyNodeCallback callback, + GObject *object); +void ephy_node_signal_disconnect (EphyNode *node, + int signal_id); + +/* properties */ void ephy_node_set_property (EphyNode *node, guint property_id, const GValue *value); @@ -111,7 +96,8 @@ char *ephy_node_get_property_time (EphyNode *node, /* xml storage */ void ephy_node_save_to_xml (EphyNode *node, xmlNodePtr parent_xml_node); -EphyNode *ephy_node_new_from_xml (xmlNodePtr xml_node); +EphyNode *ephy_node_new_from_xml (EphyNodeDb *db, + xmlNodePtr xml_node); /* DAG structure */ void ephy_node_add_child (EphyNode *node, @@ -139,12 +125,6 @@ EphyNode *ephy_node_get_next_child (EphyNode *node, EphyNode *ephy_node_get_previous_child (EphyNode *node, EphyNode *child); -/* node id services */ -void ephy_node_system_init (gulong reserved_ids); -void ephy_node_system_shutdown (void); - -long ephy_node_new_id (void); - G_END_DECLS #endif /* __EPHY_NODE_H */ diff --git a/lib/ephy-state.c b/lib/ephy-state.c index d6413ff76..90d06883c 100644 --- a/lib/ephy-state.c +++ b/lib/ephy-state.c @@ -21,7 +21,7 @@ #include "ephy-state.h" #include "ephy-file-helpers.h" -#include "ephy-node.h" +#include "ephy-node-db.h" #include "ephy-types.h" #include "ephy-node-common.h" @@ -43,6 +43,7 @@ enum }; static EphyNode *states = NULL; +static EphyNodeDb *states_db = NULL; static void ephy_states_load (void) @@ -67,7 +68,7 @@ ephy_states_load (void) { EphyNode *node; - node = ephy_node_new_from_xml (child); + node = ephy_node_new_from_xml (states_db, child); } xmlFreeDoc (doc); @@ -144,7 +145,8 @@ ensure_states (void) { if (states == NULL) { - states = ephy_node_new_with_id (STATES_NODE_ID); + states_db = ephy_node_db_new ("EphyStates"); + states = ephy_node_new_with_id (states_db, STATES_NODE_ID); ephy_states_load (); } } @@ -315,7 +317,7 @@ ephy_state_add_window (GtkWidget *window, { GValue value = { 0, }; - node = ephy_node_new (); + node = ephy_node_new (states_db); ephy_node_add_child (states, node); g_value_init (&value, G_TYPE_STRING); @@ -369,10 +371,10 @@ ephy_state_add_window (GtkWidget *window, ephy_state_window_set_position (window, node); } - g_signal_connect_object (window, "configure_event", - G_CALLBACK (window_configure_event_cb), node, 0); - g_signal_connect_object (window, "window_state_event", - G_CALLBACK (window_state_event_cb), node, 0); + g_signal_connect (window, "configure_event", + G_CALLBACK (window_configure_event_cb), node); + g_signal_connect (window, "window_state_event", + G_CALLBACK (window_state_event_cb), node); } static gboolean @@ -409,7 +411,7 @@ ephy_state_add_paned (GtkWidget *paned, { GValue value = { 0, }; - node = ephy_node_new (); + node = ephy_node_new (states_db); ephy_node_add_child (states, node); g_value_init (&value, G_TYPE_STRING); @@ -428,8 +430,8 @@ ephy_state_add_paned (GtkWidget *paned, width = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_WIDTH); gtk_paned_set_position (GTK_PANED (paned), width); - g_signal_connect_object (paned, "size_allocate", - G_CALLBACK (paned_size_allocate_cb), node, 0); + g_signal_connect (paned, "size_allocate", + G_CALLBACK (paned_size_allocate_cb), node); } void @@ -437,5 +439,7 @@ ephy_state_save (void) { ephy_states_save (); ephy_node_unref (states); + g_object_unref (states_db); states = NULL; + states_db = NULL; } diff --git a/lib/widgets/ephy-node-view.c b/lib/widgets/ephy-node-view.c index b1c4e003b..f42ef9955 100644 --- a/lib/widgets/ephy-node-view.c +++ b/lib/widgets/ephy-node-view.c @@ -132,11 +132,10 @@ ephy_node_view_class_init (EphyNodeViewClass *klass) g_object_class_install_property (object_class, PROP_ROOT, - g_param_spec_object ("root", - "Root node", - "Root node", - EPHY_TYPE_NODE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_pointer ("root", + "Root node", + "Root node", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_FILTER, g_param_spec_object ("filter", @@ -151,30 +150,30 @@ ephy_node_view_class_init (EphyNodeViewClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EphyNodeViewClass, node_activated), NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, - EPHY_TYPE_NODE); + G_TYPE_POINTER); ephy_node_view_signals[NODE_SELECTED] = g_signal_new ("node_selected", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EphyNodeViewClass, node_selected), NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, - EPHY_TYPE_NODE); + G_TYPE_POINTER); ephy_node_view_signals[NODE_DROPPED] = g_signal_new ("node_dropped", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EphyNodeViewClass, node_dropped), NULL, NULL, - ephy_marshal_VOID__OBJECT_POINTER, + ephy_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, - EPHY_TYPE_NODE, + G_TYPE_POINTER, G_TYPE_POINTER); ephy_node_view_signals[SHOW_POPUP] = g_signal_new ("show_popup", @@ -388,7 +387,7 @@ ephy_node_view_selection_changed_cb (GtkTreeSelection *selection, list = ephy_node_view_get_selection (view); if (list) { - node = EPHY_NODE (list->data); + node = list->data; } g_list_free (list); @@ -482,7 +481,7 @@ ephy_node_view_set_property (GObject *object, switch (prop_id) { case PROP_ROOT: - view->priv->root = g_value_get_object (value); + view->priv->root = g_value_get_pointer (value); break; case PROP_FILTER: view->priv->filter = g_value_get_object (value); @@ -513,7 +512,7 @@ ephy_node_view_get_property (GObject *object, switch (prop_id) { case PROP_ROOT: - g_value_set_object (value, view->priv->root); + g_value_set_pointer (value, view->priv->root); break; case PROP_FILTER: g_value_set_object (value, view->priv->filter); @@ -914,7 +913,7 @@ ephy_node_view_remove (EphyNodeView *view) list = ephy_node_view_get_selection (view); g_return_if_fail (list != NULL); - node = EPHY_NODE ((g_list_last (list))->data); + node = g_list_last (list)->data; ephy_tree_model_node_iter_from_node (EPHY_TREE_MODEL_NODE (view->priv->nodemodel), node, &iter); egg_tree_model_filter_convert_child_iter_to_iter (EGG_TREE_MODEL_FILTER (view->priv->filtermodel), @@ -941,7 +940,7 @@ ephy_node_view_remove (EphyNodeView *view) for (; list != NULL; list = list->next) { - ephy_node_unref (EPHY_NODE (list->data)); + ephy_node_unref (list->data); } g_list_free (list); diff --git a/lib/widgets/ephy-tree-model-node.c b/lib/widgets/ephy-tree-model-node.c index ebeb17fd3..73c654712 100644 --- a/lib/widgets/ephy-tree-model-node.c +++ b/lib/widgets/ephy-tree-model-node.c @@ -164,10 +164,9 @@ ephy_tree_model_node_class_init (EphyTreeModelNodeClass *klass) g_object_class_install_property (object_class, PROP_ROOT, - g_param_spec_object ("root", + g_param_spec_pointer ("root", "Root node", "Root node", - EPHY_TYPE_NODE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_FILTER, @@ -248,33 +247,28 @@ ephy_tree_model_node_set_property (GObject *object, switch (prop_id) { case PROP_ROOT: - model->priv->root = g_value_get_object (value); - - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_added", - G_CALLBACK (root_child_added_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_removed", - G_CALLBACK (root_child_removed_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_changed", - G_CALLBACK (root_child_changed_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "children_reordered", - G_CALLBACK (root_children_reordered_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "destroyed", - G_CALLBACK (root_destroyed_cb), - G_OBJECT (model), - 0); + model->priv->root = g_value_get_pointer (value); + + ephy_node_signal_connect_object (model->priv->root, + EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback) root_child_added_cb, + G_OBJECT (model)); + ephy_node_signal_connect_object (model->priv->root, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) root_child_removed_cb, + G_OBJECT (model)); + ephy_node_signal_connect_object (model->priv->root, + EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback) root_child_changed_cb, + G_OBJECT (model)); + ephy_node_signal_connect_object (model->priv->root, + EPHY_NODE_CHILDREN_REORDERED, + (EphyNodeCallback) root_children_reordered_cb, + G_OBJECT (model)); + ephy_node_signal_connect_object (model->priv->root, + EPHY_NODE_DESTROYED, + (EphyNodeCallback) root_destroyed_cb, + G_OBJECT (model)); break; case PROP_FILTER: @@ -306,7 +300,7 @@ ephy_tree_model_node_get_property (GObject *object, switch (prop_id) { case PROP_ROOT: - g_value_set_object (value, model->priv->root); + g_value_set_pointer (value, model->priv->root); break; case PROP_FILTER: g_value_set_object (value, model->priv->filter); @@ -411,12 +405,11 @@ ephy_tree_model_node_get_value (GtkTreeModel *tree_model, g_return_if_fail (EPHY_IS_TREE_MODEL_NODE (tree_model)); g_return_if_fail (iter != NULL); g_return_if_fail (iter->stamp == model->stamp); - g_return_if_fail (EPHY_IS_NODE (iter->user_data)); if (model->priv->root == NULL) return; - node = EPHY_NODE (iter->user_data); + node = iter->user_data; if (column == EPHY_TREE_MODEL_NODE_COL_VISIBLE) { @@ -530,7 +523,7 @@ ephy_tree_model_node_get_path (GtkTreeModel *tree_model, if (model->priv->root == NULL) return NULL; - node = EPHY_NODE (iter->user_data); + node = iter->user_data; if (node == model->priv->root) return gtk_tree_path_new (); @@ -552,7 +545,7 @@ ephy_tree_model_node_iter_next (GtkTreeModel *tree_model, if (model->priv->root == NULL) return FALSE; - node = EPHY_NODE (iter->user_data); + node = iter->user_data; if (node == model->priv->root) return FALSE; @@ -648,7 +641,7 @@ EphyNode * ephy_tree_model_node_node_from_iter (EphyTreeModelNode *model, GtkTreeIter *iter) { - return EPHY_NODE (iter->user_data); + return iter->user_data; } void diff --git a/src/bookmarks/ephy-bookmark-action.c b/src/bookmarks/ephy-bookmark-action.c index cbb49007f..8c2862534 100644 --- a/src/bookmarks/ephy-bookmark-action.c +++ b/src/bookmarks/ephy-bookmark-action.c @@ -427,9 +427,9 @@ ephy_bookmark_action_init (EphyBookmarkAction *action) bookmarks = ephy_shell_get_bookmarks (ephy_shell); node = ephy_bookmarks_get_bookmarks (bookmarks); - g_signal_connect_object (node, "child_changed", - G_CALLBACK (bookmarks_child_changed_cb), - action, 0); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback) bookmarks_child_changed_cb, + G_OBJECT (action)); } EggAction * @@ -441,7 +441,7 @@ ephy_bookmark_action_new (const char *name, guint id) bookmarks = ephy_shell_get_bookmarks (ephy_shell); - bmk = ephy_node_get_from_id (id); + bmk = ephy_bookmarks_get_from_id (bookmarks, id); g_return_val_if_fail (bmk != NULL, NULL); action = EGG_ACTION (g_object_new (EPHY_TYPE_BOOKMARK_ACTION, diff --git a/src/bookmarks/ephy-bookmark-properties.c b/src/bookmarks/ephy-bookmark-properties.c index f2b20f931..ad8afff56 100644 --- a/src/bookmarks/ephy-bookmark-properties.c +++ b/src/bookmarks/ephy-bookmark-properties.c @@ -122,11 +122,10 @@ ephy_bookmark_properties_class_init (EphyBookmarkPropertiesClass *klass) g_object_class_install_property (object_class, PROP_BOOKMARK, - g_param_spec_object ("bookmark", - "Bookmark", - "Bookmark", - EPHY_TYPE_NODE, - G_PARAM_READWRITE)); + g_param_spec_pointer ("bookmark", + "Bookmark", + "Bookmark", + G_PARAM_READWRITE)); } static void @@ -172,7 +171,7 @@ ephy_bookmark_properties_set_property (GObject *object, break; case PROP_BOOKMARK: ephy_bookmark_properties_set_bookmark - (selector, g_value_get_object (value)); + (selector, g_value_get_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c index ce4898f78..940c7595b 100644 --- a/src/bookmarks/ephy-bookmarks-editor.c +++ b/src/bookmarks/ephy-bookmarks-editor.c @@ -315,7 +315,7 @@ cmd_show_in_bookmarks_bar (EggAction *action, return; } - node = EPHY_NODE (selection->data); + node = selection->data; id = ephy_node_get_id (node); state = EGG_TOGGLE_ACTION (action)->active; @@ -346,7 +346,7 @@ cmd_open_bookmarks_in_tabs (EggAction *action, for (l = selection; l; l = l->next) { - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; const char *location; location = ephy_node_get_property_string (node, @@ -372,7 +372,7 @@ cmd_open_bookmarks_in_browser (EggAction *action, for (l = selection; l; l = l->next) { - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; const char *location; location = ephy_node_get_property_string (node, @@ -400,7 +400,7 @@ cmd_delete (EggAction *action, EphyNode *node; selected = ephy_node_view_get_selection (EPHY_NODE_VIEW (editor->priv->key_view)); - node = EPHY_NODE (selected->data); + node = selected->data; priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); if (priority == -1) priority = EPHY_NODE_NORMAL_PRIORITY; @@ -452,7 +452,7 @@ cmd_bookmark_properties (EggAction *action, for (l = selection; l; l = l->next) { - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; show_properties_dialog (editor, node); } @@ -491,7 +491,7 @@ cmd_copy (EggAction *action, if (g_list_length (selection) == 1) { const char *tmp; - EphyNode *node = EPHY_NODE (selection->data); + EphyNode *node = selection->data; tmp = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION); gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), tmp, -1); } @@ -632,7 +632,6 @@ ephy_bookmarks_editor_node_activated_cb (GtkWidget *view, const char *location; EphyWindow *window; - g_return_if_fail (EPHY_IS_NODE (node)); location = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION); g_return_if_fail (location != NULL); @@ -707,7 +706,7 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) selected = ephy_node_view_get_selection (EPHY_NODE_VIEW (editor->priv->key_view)); if (key_focus && selected) { - EphyNode *node = EPHY_NODE (selected->data); + EphyNode *node = selected->data; EphyNodePriority priority; gulong id; @@ -726,7 +725,7 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) selected = ephy_node_view_get_selection (EPHY_NODE_VIEW (editor->priv->bm_view)); if (bmk_focus && selected) { - EphyNode *node = EPHY_NODE (selected->data); + EphyNode *node = selected->data; gulong id; id = ephy_node_get_id (node); @@ -874,7 +873,7 @@ ephy_bookmarks_editor_dispose (GObject *object) return; } - selected_id = ephy_node_get_id (EPHY_NODE (selection->data)); + selected_id = ephy_node_get_id (selection->data); if (selected_id >= 0) { selected_id_str = g_strdup_printf ("%ld", selected_id); @@ -1065,11 +1064,9 @@ node_dropped_cb (EphyNodeView *view, EphyNode *node, { GList *l; - g_return_if_fail (EPHY_IS_NODE (node)); - for (l = nodes; l != NULL; l = l->next) { - EphyNode *bmk = EPHY_NODE (l->data); + EphyNode *bmk = l->data; ephy_bookmarks_set_keyword (editor->priv->bookmarks, node, bmk); } @@ -1290,7 +1287,7 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor) return; } - selected_node = ephy_node_get_from_id (selected_id); + selected_node = ephy_bookmarks_get_from_id (editor->priv->bookmarks, selected_id); if (selected_node != NULL) { ephy_node_view_select_node (EPHY_NODE_VIEW (key_view), selected_node); diff --git a/src/bookmarks/ephy-bookmarks-export.c b/src/bookmarks/ephy-bookmarks-export.c index e450250a5..3403a1931 100644 --- a/src/bookmarks/ephy-bookmarks-export.c +++ b/src/bookmarks/ephy-bookmarks-export.c @@ -57,7 +57,7 @@ add_topics_list (EphyNode *topics, EphyNode *bmk, xmlNodePtr parent) for (l = bmks; l != NULL; l = l->next) { const char *name; - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; name = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c index 791440049..b43b1f981 100644 --- a/src/bookmarks/ephy-bookmarks.c +++ b/src/bookmarks/ephy-bookmarks.c @@ -43,6 +43,7 @@ struct EphyBookmarksPrivate { char *xml_file; + EphyNodeDb *db; EphyNode *bookmarks; EphyNode *keywords; EphyNode *favorites; @@ -284,7 +285,7 @@ ephy_bookmarks_load (EphyBookmarks *eb) { EphyNode *node; - node = ephy_node_new_from_xml (child); + node = ephy_node_new_from_xml (eb->priv->db, child); } xmlFreeDoc (doc); @@ -581,15 +582,19 @@ static void ephy_bookmarks_init (EphyBookmarks *eb) { GValue value = { 0, }; + EphyNodeDb *db; eb->priv = g_new0 (EphyBookmarksPrivate, 1); + db = ephy_node_db_new ("EphyBookmarks"); + eb->priv->db = db; + eb->priv->xml_file = g_build_filename (ephy_dot_dir (), "bookmarks.xml", NULL); /* Bookmarks */ - eb->priv->bookmarks = ephy_node_new_with_id (BOOKMARKS_NODE_ID); + eb->priv->bookmarks = ephy_node_new_with_id (db, BOOKMARKS_NODE_ID); ephy_node_ref (eb->priv->bookmarks); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, _("All")); @@ -597,19 +602,17 @@ ephy_bookmarks_init (EphyBookmarks *eb) EPHY_NODE_KEYWORD_PROP_NAME, &value); g_value_unset (&value); - g_signal_connect_object (G_OBJECT (eb->priv->bookmarks), - "child_removed", - G_CALLBACK (bookmarks_removed_cb), - G_OBJECT (eb), - 0); - g_signal_connect_object (G_OBJECT (eb->priv->bookmarks), - "child_changed", - G_CALLBACK (bookmarks_changed_cb), - G_OBJECT (eb), - 0); + ephy_node_signal_connect_object (eb->priv->bookmarks, + 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)); /* Keywords */ - eb->priv->keywords = ephy_node_new_with_id (KEYWORDS_NODE_ID); + eb->priv->keywords = ephy_node_new_with_id (db, KEYWORDS_NODE_ID); ephy_node_ref (eb->priv->keywords); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, EPHY_NODE_ALL_PRIORITY); @@ -617,17 +620,16 @@ ephy_bookmarks_init (EphyBookmarks *eb) EPHY_NODE_KEYWORD_PROP_PRIORITY, &value); g_value_unset (&value); - g_signal_connect_object (G_OBJECT (eb->priv->keywords), - "child_removed", - G_CALLBACK (topics_removed_cb), - G_OBJECT (eb), - 0); + ephy_node_signal_connect_object (eb->priv->keywords, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback) topics_removed_cb, + G_OBJECT (eb)); ephy_node_add_child (eb->priv->keywords, eb->priv->bookmarks); /* Favorites */ - eb->priv->favorites = ephy_node_new_with_id (FAVORITES_NODE_ID); + eb->priv->favorites = ephy_node_new_with_id (db, FAVORITES_NODE_ID); ephy_node_ref (eb->priv->favorites); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, _("Most Visited")); @@ -644,7 +646,7 @@ ephy_bookmarks_init (EphyBookmarks *eb) ephy_node_add_child (eb->priv->keywords, eb->priv->favorites); /* Not categorized */ - eb->priv->notcategorized = ephy_node_new_with_id (BMKS_NOTCATEGORIZED_NODE_ID); + eb->priv->notcategorized = ephy_node_new_with_id (db, BMKS_NOTCATEGORIZED_NODE_ID); ephy_node_ref (eb->priv->notcategorized); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, _("Not Categorized")); @@ -715,7 +717,7 @@ ephy_bookmarks_add (EphyBookmarks *eb, EphyNode *bm; GValue value = { 0, }; - bm = ephy_node_new (); + bm = ephy_node_new (eb->priv->db); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, title); @@ -952,7 +954,7 @@ ephy_bookmarks_add_keyword (EphyBookmarks *eb, EphyNode *key; GValue value = { 0, }; - key = ephy_node_new (); + key = ephy_node_new (eb->priv->db); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, name); @@ -1094,3 +1096,8 @@ ephy_bookmarks_get_favorites (EphyBookmarks *eb) return eb->priv->favorites; } +EphyNode * +ephy_bookmarks_get_from_id (EphyBookmarks *eb, long id) +{ + return ephy_node_db_get_node_from_id (eb->priv->db, id); +} diff --git a/src/bookmarks/ephy-bookmarks.h b/src/bookmarks/ephy-bookmarks.h index 8cf8a4bf9..8ef47ce7d 100644 --- a/src/bookmarks/ephy-bookmarks.h +++ b/src/bookmarks/ephy-bookmarks.h @@ -67,11 +67,14 @@ GType ephy_bookmarks_get_type (void); EphyBookmarks *ephy_bookmarks_new (void); +EphyNode *ephy_bookmarks_get_from_id (EphyBookmarks *eb, + long id); + /* Bookmarks */ -void ephy_bookmarks_save (EphyBookmarks *eb); +void ephy_bookmarks_save (EphyBookmarks *eb); -EphyNode *ephy_bookmarks_add (EphyBookmarks *eb, +EphyNode *ephy_bookmarks_add (EphyBookmarks *eb, const char *title, const char *url, const char *smart_url); diff --git a/src/bookmarks/ephy-topic-action.c b/src/bookmarks/ephy-topic-action.c index 448e7ffb6..1670c099f 100644 --- a/src/bookmarks/ephy-topic-action.c +++ b/src/bookmarks/ephy-topic-action.c @@ -130,7 +130,7 @@ menu_activate_cb (GtkWidget *item, EggAction *action) EphyNode *node; const char *location; - node = EPHY_NODE (g_object_get_data (G_OBJECT (item), "node")); + node = g_object_get_data (G_OBJECT (item), "node"); location = ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_LOCATION); g_signal_emit (action, ephy_topic_action_signals[GO_LOCATION], @@ -159,9 +159,6 @@ sort_bookmarks (gconstpointer a, gconstpointer b) char *str_b = NULL; int retval; - g_return_val_if_fail (EPHY_IS_NODE (node_a), 1); - g_return_val_if_fail (EPHY_IS_NODE (node_b), -1); - str_a = g_utf8_casefold (ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE), -1); str_b = g_utf8_casefold (ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE), @@ -264,9 +261,6 @@ sort_topics (gconstpointer a, gconstpointer b) char *str_b = NULL; int retval; - g_return_val_if_fail (EPHY_IS_NODE (node_a), 1); - g_return_val_if_fail (EPHY_IS_NODE (node_b), -1); - priority_a = ephy_node_get_property_int (node_a, EPHY_NODE_KEYWORD_PROP_PRIORITY); priority_b = ephy_node_get_property_int (node_b, EPHY_NODE_KEYWORD_PROP_PRIORITY); @@ -366,21 +360,20 @@ static GtkWidget * build_menu (EphyTopicAction *action) { EphyNode *node; + EphyBookmarks *bookmarks; + bookmarks = ephy_shell_get_bookmarks (ephy_shell); if (action->priv->topic_id == BOOKMARKS_NODE_ID) { - EphyBookmarks *bookmarks; - LOG ("Build all bookmarks crap menu") - bookmarks = ephy_shell_get_bookmarks (ephy_shell); node = ephy_bookmarks_get_keywords (bookmarks); return build_topics_menu (action, node); } else { - node = ephy_node_get_from_id (action->priv->topic_id); + node = ephy_bookmarks_get_from_id (bookmarks, action->priv->topic_id); return build_bookmarks_menu (action, node); } } @@ -546,9 +539,9 @@ ephy_topic_action_init (EphyTopicAction *action) bookmarks = ephy_shell_get_bookmarks (ephy_shell); node = ephy_bookmarks_get_keywords (bookmarks); - g_signal_connect_object (node, "child_changed", - G_CALLBACK (topic_child_changed_cb), - action, 0); + ephy_node_signal_connect_object (node, EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback) topic_child_changed_cb, + G_OBJECT (action)); } EggAction * @@ -560,7 +553,7 @@ ephy_topic_action_new (const char *name, guint id) bookmarks = ephy_shell_get_bookmarks (ephy_shell); - bmk = ephy_node_get_from_id (id); + bmk = ephy_bookmarks_get_from_id (bookmarks, id); g_return_val_if_fail (bmk != NULL, NULL); action = EGG_ACTION (g_object_new (EPHY_TYPE_TOPIC_ACTION, diff --git a/src/bookmarks/ephy-topics-selector.c b/src/bookmarks/ephy-topics-selector.c index d97a9449f..994ed302e 100644 --- a/src/bookmarks/ephy-topics-selector.c +++ b/src/bookmarks/ephy-topics-selector.c @@ -114,11 +114,10 @@ ephy_topics_selector_class_init (EphyTopicsSelectorClass *klass) g_object_class_install_property (object_class, PROP_BOOKMARK, - g_param_spec_object ("bookmark", - "Bookmark", - "Bookmark", - EPHY_TYPE_NODE, - G_PARAM_READWRITE)); + g_param_spec_pointer ("bookmark", + "Bookmark", + "Bookmark", + G_PARAM_READWRITE)); } static void @@ -164,7 +163,7 @@ ephy_topics_selector_set_property (GObject *object, break; case PROP_BOOKMARK: ephy_topics_selector_set_bookmark - (selector, g_value_get_object (value)); + (selector, g_value_get_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -183,7 +182,7 @@ ephy_topics_selector_get_property (GObject *object, switch (prop_id) { case PROP_BOOKMARK: - g_value_set_object (value, selector); + g_value_set_pointer (value, selector); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/src/ephy-history-window.c b/src/ephy-history-window.c index 5921cde12..cd90e330e 100644 --- a/src/ephy-history-window.c +++ b/src/ephy-history-window.c @@ -321,7 +321,7 @@ cmd_open_bookmarks_in_tabs (EggAction *action, for (l = selection; l; l = l->next) { - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; const char *location; location = ephy_node_get_property_string (node, @@ -347,7 +347,7 @@ cmd_open_bookmarks_in_browser (EggAction *action, for (l = selection; l; l = l->next) { - EphyNode *node = EPHY_NODE (l->data); + EphyNode *node = l->data; const char *location; location = ephy_node_get_property_string (node, @@ -392,7 +392,7 @@ cmd_copy (EggAction *action, if (g_list_length (selection) == 1) { const char *tmp; - EphyNode *node = EPHY_NODE (selection->data); + EphyNode *node = selection->data; tmp = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), tmp, -1); } @@ -463,7 +463,7 @@ cmd_bookmark_link (EggAction *action, const char *title; EphyNode *node; - node = EPHY_NODE (selection->data); + node = selection->data; location = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); title = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_TITLE); if (ephy_new_bookmark_is_unique (bookmarks, GTK_WINDOW (window), @@ -577,7 +577,6 @@ ephy_history_window_node_activated_cb (GtkWidget *view, const char *location; EphyWindow *window; - g_return_if_fail (EPHY_IS_NODE (node)); location = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); g_return_if_fail (location != NULL); @@ -683,7 +682,7 @@ ephy_history_window_update_menu (EphyHistoryWindow *editor) g_object_set (action, "sensitive", select_all, NULL); action = egg_action_group_get_action (action_group, "Delete"); g_object_set (action, "sensitive", delete, NULL); - action = egg_action_group_get_action (action_group, "BookmarkPage"); + action = egg_action_group_get_action (action_group, "BookmarkLink"); g_object_set (action, "sensitive", bookmark_page, NULL); } diff --git a/src/ephy-shell.c b/src/ephy-shell.c index daf5f4513..373b9711c 100644 --- a/src/ephy-shell.c +++ b/src/ephy-shell.c @@ -248,7 +248,6 @@ ephy_shell_init (EphyShell *gs) ephy_debug_init (); ephy_thread_helpers_init (); - ephy_node_system_init (EPHY_NODE_RESERVED_IDS); ephy_file_helpers_init (); ephy_stock_icons_init (); ephy_ensure_dir_exists (ephy_dot_dir ()); @@ -342,7 +341,6 @@ ephy_shell_finalize (GObject *object) ephy_state_save (); ephy_file_helpers_shutdown (); - ephy_node_system_shutdown (); LOG ("Ephy shell finalized") diff --git a/src/ephy-toolbars-model.c b/src/ephy-toolbars-model.c index 43a081e22..f2eacbe20 100755 --- a/src/ephy-toolbars-model.c +++ b/src/ephy-toolbars-model.c @@ -91,7 +91,7 @@ impl_add_item (EggToolbarsModel *t, topic = TRUE; nodes = ephy_dnd_node_list_extract_nodes (name); - id = ephy_node_get_id (EPHY_NODE (nodes->data)); + id = ephy_node_get_id (nodes->data); action_name = g_strdup_printf ("GoTopicId%d", id); g_list_free (nodes); } @@ -100,7 +100,7 @@ impl_add_item (EggToolbarsModel *t, GList *nodes; nodes = ephy_dnd_node_list_extract_nodes (name); - id = ephy_node_get_id (EPHY_NODE (nodes->data)); + id = ephy_node_get_id (nodes->data); action_name = g_strdup_printf ("GoBookmarkId%d", id); g_list_free (nodes); } -- cgit v1.2.3