summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b13e710)
raw | patch | inline | side by side (parent: b13e710)
author | knutux <knutux@users.sourceforge.net> | |
Thu, 6 Apr 2006 12:49:42 +0000 (12:49 +0000) | ||
committer | knutux <knutux@users.sourceforge.net> | |
Thu, 6 Apr 2006 12:49:42 +0000 (12:49 +0000) |
* fixed by making SPKnotHolder a referenced class and adding ref/unref in knot_click_handler (which sometime change attributes and knot handler is destroyed before calling knotholder_update_knots);
* fixed another crash by adding ref/unref to sp_knot_handler
* also added signal disconnecting
* fixed another crash by adding ref/unref to sp_knot_handler
* also added signal disconnecting
src/knot-holder-entity.h | patch | blob | history | |
src/knot.cpp | patch | blob | history | |
src/knot.h | patch | blob | history | |
src/knotholder.cpp | patch | blob | history | |
src/knotholder.h | patch | blob | history |
index 1e9001e67839107e7b037a7e9abbc550b2b03fd0..bbc0c5634d4a32fb5096b45dddac93213d1d00ea 100644 (file)
--- a/src/knot-holder-entity.h
+++ b/src/knot-holder-entity.h
/** Connection to \a knot's "moved" signal. */
guint handler_id;
+ /** Connection to \a knot's "clicked" signal. */
+ guint _click_handler_id;
+ /** Connection to \a knot's "ungrabbed" signal. */
+ guint _ungrab_handler_id;
/**
* Called solely from knot_moved_handler.
diff --git a/src/knot.cpp b/src/knot.cpp
index 01ccca69337d59db83272dcb994d998e4ab364ef..95cadfdb7aee1a44c030dfb31d6c96ea2f08a4e8 100644 (file)
--- a/src/knot.cpp
+++ b/src/knot.cpp
knot->shape = SP_KNOT_SHAPE_SQUARE;
knot->mode = SP_KNOT_MODE_XOR;
knot->tip = NULL;
+ knot->_event_handler_id = 0;
knot->fill[SP_KNOT_STATE_NORMAL] = 0xffffff00;
knot->fill[SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff;
gdk_pointer_ungrab (GDK_CURRENT_TIME);
}
+ if (knot->_event_handler_id > 0)
+ {
+ g_signal_handler_disconnect(GTK_OBJECT (knot->item), knot->_event_handler_id);
+ knot->_event_handler_id = 0;
+ }
+
if (knot->item) {
gtk_object_destroy (GTK_OBJECT (knot->item));
knot->item = NULL;
g_assert(knot != NULL);
g_assert(SP_IS_KNOT(knot));
+ g_object_ref(G_OBJECT(knot));
tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100);
gboolean consumed = FALSE;
break;
}
+ g_object_unref(G_OBJECT(knot));
return consumed;
}
"mode", SP_KNOT_MODE_XOR,
NULL);
- gtk_signal_connect(GTK_OBJECT(knot->item), "event",
- GTK_SIGNAL_FUNC(sp_knot_handler), knot);
+ knot->_event_handler_id = gtk_signal_connect(GTK_OBJECT(knot->item), "event",
+ GTK_SIGNAL_FUNC(sp_knot_handler), knot);
return knot;
}
diff --git a/src/knot.h b/src/knot.h
index 795eeb8e30064f2d860dc2b5810efad69a9ec146..5693417fd19db2589651a0836e74f344cacc798b 100644 (file)
--- a/src/knot.h
+++ b/src/knot.h
gchar *tip;
+ gulong _event_handler_id;
+
//TODO: all the members above should eventualle become private, accessible via setters/getters
inline void setSize (guint i) {size = i;}
inline void setShape (guint i) {shape = (SPKnotShapeType) i;}
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index 0ea3ed98ab49ab9c1c377aa7236c81dbc37ee8a6..82d49d22341162e804372a53e8d7ea16e0024a98 100644 (file)
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
static void knot_clicked_handler (SPKnot *knot, guint state, gpointer data);
static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gpointer data);
static void knot_ungrabbed_handler (SPKnot *knot, unsigned int state, SPKnotHolder *kh);
+static void sp_knot_holder_class_init(SPKnotHolderClass *klass);
+
+void sp_knot_holder_dispose(GObject *object);
#ifdef KNOT_HOLDER_DEBUG
}
#endif
+static GObjectClass *parent_class;
+
+/**
+ * Registers SPKnotHolder class and returns its type number.
+ */
+GType sp_knot_holder_get_type()
+{
+ static GType type = 0;
+ if (!type) {
+ GTypeInfo info = {
+ sizeof(SPKnotHolderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sp_knot_holder_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SPKnotHolder),
+ 16, /* n_preallocs */
+ NULL,
+ NULL
+ };
+ type = g_type_register_static (G_TYPE_OBJECT, "SPKnotHolder", &info, (GTypeFlags) 0);
+ }
+ return type;
+}
+
+/**
+ * SPKnotHolder vtable initialization.
+ */
+static void sp_knot_holder_class_init(SPKnotHolderClass *klass){
+ GObjectClass *object_class = (GObjectClass *) klass;
+ parent_class = (GObjectClass*) g_type_class_peek_parent(klass);
+ object_class->dispose = sp_knot_holder_dispose;
+}
+
SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler)
{
Inkscape::XML::Node *repr = SP_OBJECT(item)->repr;
g_return_val_if_fail(item != NULL, NULL);
g_return_val_if_fail(SP_IS_ITEM(item), NULL);
- SPKnotHolder *knot_holder = g_new(SPKnotHolder, 1);
+ SPKnotHolder *knot_holder = (SPKnotHolder*)g_object_new (SP_TYPE_KNOT_HOLDER, 0);
knot_holder->desktop = desktop;
knot_holder->item = item;
g_object_ref(G_OBJECT(item));
@@ -62,22 +100,25 @@ SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderR
return knot_holder;
}
-void sp_knot_holder_destroy(SPKnotHolder *kh)
-{
- if (kh) {
- g_object_unref(G_OBJECT(kh->item));
- while (kh->entity) {
- SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
- /* unref should call destroy */
- g_object_unref(G_OBJECT(e->knot));
- g_free(e);
- kh->entity = g_slist_remove(kh->entity, e);
- }
-
- g_free(kh);
+void sp_knot_holder_dispose(GObject *object) {
+ SPKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), SP_TYPE_KNOT_HOLDER, SPKnotHolder);
+
+ g_object_unref(G_OBJECT(kh->item));
+ while (kh->entity) {
+ SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
+ g_signal_handler_disconnect(GTK_OBJECT (e->knot), e->_click_handler_id);
+ g_signal_handler_disconnect(GTK_OBJECT (e->knot), e->_ungrab_handler_id);
+ /* unref should call destroy */
+ g_object_unref(G_OBJECT(e->knot));
+ g_free(e);
+ kh->entity = g_slist_remove(kh->entity, e);
}
}
+void sp_knot_holder_destroy(SPKnotHolder *kh) {
+ g_object_unref(G_OBJECT(kh));
+ }
+
void sp_knot_holder_add(
SPKnotHolder *knot_holder,
SPKnotHolderSetFunc knot_set,
sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
e->handler_id = g_signal_connect(G_OBJECT(e->knot), "moved", G_CALLBACK(knot_moved_handler), knot_holder);
- g_signal_connect(G_OBJECT(e->knot), "clicked", G_CALLBACK(knot_clicked_handler), knot_holder);
- g_signal_connect(G_OBJECT(e->knot), "ungrabbed", G_CALLBACK(knot_ungrabbed_handler), knot_holder);
+ e->_click_handler_id = g_signal_connect(G_OBJECT(e->knot), "clicked", G_CALLBACK(knot_clicked_handler), knot_holder);
+ e->_ungrab_handler_id = g_signal_connect(G_OBJECT(e->knot), "ungrabbed", G_CALLBACK(knot_ungrabbed_handler), knot_holder);
#ifdef KNOT_HOLDER_DEBUG
g_signal_connect(ob, "destroy", sp_knot_holder_debug, "SPKnotHolder::knot");
SPKnotHolder *knot_holder = (SPKnotHolder *) data;
SPItem *item = SP_ITEM (knot_holder->item);
+ g_object_ref(G_OBJECT(knot_holder));
for (GSList *el = knot_holder->entity; el; el = el->next) {
SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data;
if (e->knot == knot) {
}
knotholder_update_knots(knot_holder, item);
+ g_object_unref(G_OBJECT(knot_holder));
// for drag, this is done by ungrabbed_handler, but for click we must do it here
sp_document_done(SP_OBJECT_DOCUMENT(knot_holder->item));
diff --git a/src/knotholder.h b/src/knotholder.h
index 6980e2fdd327cc40029b4e9270bf74019ac756f6..971dae3b0747a2036ebe338ea6d32ef74bb47957 100644 (file)
--- a/src/knotholder.h
+++ b/src/knotholder.h
/* fixme: Think how to make callbacks most sensitive (Lauris) */
typedef void (* SPKnotHolderReleasedFunc) (SPItem *item);
-struct SPKnotHolder {
+struct SPKnotHolder : GObject {
SPDesktop *desktop;
SPItem *item;
GSList *entity;
gboolean local_change; ///< if true, no need to recreate knotholder if repr was changed.
};
+struct SPKnotHolderClass : GObjectClass {
+};
/* fixme: As a temporary solution, if released is NULL knotholder flushes undo itself (Lauris) */
SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler);
SPKnotModeType mode,
gchar const *tip);
+GType sp_knot_holder_get_type();
+
+#define SP_TYPE_KNOT_HOLDER (sp_knot_holder_get_type())
#endif /* !__SP_KNOTHOLDER_H__ */