diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/ephy-dnd.c | 8 | ||||
-rw-r--r-- | lib/ephy-node-db.c | 292 | ||||
-rw-r--r-- | lib/ephy-node-db.h | 73 | ||||
-rw-r--r-- | lib/ephy-node.c | 1181 | ||||
-rw-r--r-- | lib/ephy-node.h | 72 | ||||
-rw-r--r-- | lib/ephy-state.c | 26 | ||||
-rw-r--r-- | lib/widgets/ephy-node-view.c | 31 | ||||
-rw-r--r-- | lib/widgets/ephy-tree-model-node.c | 63 |
9 files changed, 893 insertions, 855 deletions
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 <jorn@nl.linux.org> + * + * 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 <jorn@nl.linux.org> + * + * 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 <glib-object.h> + +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 <glib-object.h> - #include <libxml/tree.h> 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 |