r15329 - gnucash/branches/sx-cleanup/src - Object cleanup and signal handling:

Joshua Sled jsled at cvs.gnucash.org
Sun Jan 7 19:44:01 EST 2007


Author: jsled
Date: 2007-01-07 19:43:58 -0500 (Sun, 07 Jan 2007)
New Revision: 15329
Trac: http://svn.gnucash.org/trac/changeset/15329

Modified:
   gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.c
   gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.h
   gnucash/branches/sx-cleanup/src/doc/sx.rst
   gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-store.c
   gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal.c
   gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
   gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c
   gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.c
Log:
Object cleanup and signal handling:
- Add dispose/finalize handlers for SX {ui,model,adapter} objects.
- Add support for "adding" and "removing" signals on GncSxInstanceModel.
- Update sx.rst todo list and docs.
- Other formatting/cleanup.


Modified: gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.c
===================================================================
--- gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -38,6 +38,8 @@
 #include "gnc-ui-util.h"
 #include "qof.h"
 
+static GObjectClass *parent_class = NULL;
+
 static void gnc_sx_instance_model_class_init (GncSxInstanceModelClass *klass);
 static void gnc_sx_instance_model_init(GTypeInstance *instance, gpointer klass);
 static GncSxInstanceModel* gnc_sx_instance_model_new(void);
@@ -401,21 +403,68 @@
 }
 
 static void
-gnc_sx_instance_model_dispose (GObject *object)
+gnc_sx_instance_model_dispose(GObject *object)
 {
-     printf("dispose\n");
+     GncSxInstanceModel *model;
+     g_return_if_fail(object != NULL);
+     model = GNC_SX_INSTANCE_MODEL(object);
+
+     g_return_if_fail(!model->disposed);
+     model->disposed = TRUE;
+
+     qof_event_unregister_handler(model->qof_event_handler_id);
+
+     G_OBJECT_CLASS(parent_class)->dispose(object);
 }
 
 static void
+gnc_sx_instances_free(GncSxInstances *instances)
+{
+     GList *instance_iter;
+     for (instance_iter = instances->list; instance_iter != NULL; instance_iter = instance_iter->next)
+     {
+          GncSxInstance *inst = (GncSxInstance*)instance_iter->data;
+          // gnc_sx_instance_free(inst); {...
+
+          // @fixme:
+          // variable_bindings elts + map
+          // temporal_state (iff not postponed?)
+          // object itself
+          g_free(inst);
+     }
+     g_list_free(instances->list);
+     instances->list = NULL;
+
+     g_free(instances);
+}
+
+static void
 gnc_sx_instance_model_finalize (GObject *object)
 {
-     printf("finalize\n");
+     GncSxInstanceModel *model;
+     GList *sx_list_iter;
+
+     g_return_if_fail(object != NULL);
+
+     model = GNC_SX_INSTANCE_MODEL(object);
+     for (sx_list_iter = model->sx_instance_list; sx_list_iter != NULL; sx_list_iter = sx_list_iter->next)
+     {
+          GncSxInstances *instances = (GncSxInstances*)sx_list_iter->data;
+          gnc_sx_instances_free(instances);
+     }
+     g_list_free(model->sx_instance_list);
+     model->sx_instance_list = NULL;
+
+     G_OBJECT_CLASS(parent_class)->finalize(object);
 }
 
 static void
 gnc_sx_instance_model_class_init (GncSxInstanceModelClass *klass)
 {
      GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+     parent_class = g_type_class_peek_parent(klass);
+
      object_class->dispose = gnc_sx_instance_model_dispose;
      object_class->finalize = gnc_sx_instance_model_finalize;
 
@@ -438,9 +487,10 @@
                        0, /* class offset */
                        NULL, /* accumulator */
                        NULL, /* accum data */
-                       g_cclosure_marshal_VOID__VOID,
+                       g_cclosure_marshal_VOID__POINTER,
                        G_TYPE_NONE,
-                       0, NULL);
+                       1,
+                       G_TYPE_POINTER);
 
      klass->added_signal_id =
           g_signal_new("added",
@@ -466,9 +516,9 @@
 }
 
 static gint
-_gnc_sx_instance_find_by_sx(GncSxInstances *in_list_instances, GncSxInstances *to_find)
+_gnc_sx_instance_find_by_sx(GncSxInstances *in_list_instances, SchedXaction *sx_to_find)
 {
-     if (in_list_instances->sx == to_find->sx)
+     if (in_list_instances->sx == sx_to_find)
           return 0;
      return -1;
 }
@@ -489,19 +539,14 @@
      if (GNC_IS_SX(ent))
      {
           SchedXaction *sx;
+          gboolean sx_is_in_model = FALSE;
+
           sx = GNC_SX(ent);
-          if (event_type & QOF_EVENT_MODIFY)
+          // only send `updated` if it's actually in the model
+          sx_is_in_model = (g_list_find_custom(instances->sx_instance_list, sx, (GCompareFunc)_gnc_sx_instance_find_by_sx) != NULL);
+          if (sx_is_in_model && event_type & QOF_EVENT_MODIFY)
           {
-               GncSxInstances *new_instances;
-               GList *link;
-
-               new_instances = _gnc_sx_gen_instances((gpointer)sx, &instances->range_end);
-
-               link = g_list_find_custom(instances->sx_instance_list, new_instances, (GCompareFunc)_gnc_sx_instance_find_by_sx);
-               g_assert(link != NULL);
-               // @fixme g_object_unref(link->data);
-               link->data = new_instances;
-               g_signal_emit_by_name(instances, "updated"); // , new_instances[->sx].
+               g_signal_emit_by_name(instances, "updated", GUINT_TO_POINTER(GPOINTER_TO_UINT(sx)));
           }
           /* else { unsupported event type; ignore } */
      }
@@ -513,36 +558,61 @@
           sxes = NULL;
           if (event_type & GNC_EVENT_ITEM_REMOVED)
           {
-               gpointer sx_instance_to_remove = NULL;
-               GList *list;
-
-               /* find, remove, update */
-               for (list = instances->sx_instance_list; list != NULL; list = list->next)
+               GList *instances_link;
+               instances_link = g_list_find_custom(instances->sx_instance_list, sx, (GCompareFunc)_gnc_sx_instance_find_by_sx);
+               if (instances_link != NULL)
                {
-                    if (sx == ((GncSxInstances*)list->data)->sx)
-                    {
-                         sx_instance_to_remove = list->data;
-                         break;
-                    }
+                    g_signal_emit_by_name(instances, "removing", GUINT_TO_POINTER(GPOINTER_TO_UINT(sx)));
                }
-               if (sx_instance_to_remove != NULL)
+               else
                {
-                    g_signal_emit_by_name(instances, "removing", GUINT_TO_POINTER(GPOINTER_TO_UINT(((GncSxInstances*)sx_instance_to_remove)->sx)));
-                    instances->sx_instance_list = g_list_remove(instances->sx_instance_list, sx_instance_to_remove);
-                    g_signal_emit_by_name(instances, "updated"); // @@fixme remove when callers support "removing"
+                    // @@ fixme:
+                    printf("err\n");
                }
-               // @@fixme: uh, actually remove...?
-               else { printf("err\n"); }
           }
           else if (event_type & GNC_EVENT_ITEM_ADDED)
           {
                /* generate instances, add to instance list, emit update. */
                instances->sx_instance_list
                     = g_list_append(instances->sx_instance_list,
-                                    (*_gnc_sx_gen_instances)((gpointer)sx, (gpointer)&instances->range_end));
+                                    _gnc_sx_gen_instances((gpointer)sx, (gpointer)&instances->range_end));
                g_signal_emit_by_name(instances, "added", GUINT_TO_POINTER(GPOINTER_TO_UINT(sx)));
-               g_signal_emit_by_name(instances, "updated"); // @fixme remove when callers look for "added".
           }
           /* else { printf("unsupported event type [%d]\n", event_type); } */
      }
 }
+
+void
+gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
+{
+     GncSxInstances *new_instances;
+     GList *link;
+
+     link = g_list_find_custom(model->sx_instance_list, sx, (GCompareFunc)_gnc_sx_instance_find_by_sx);
+     if (link == NULL)
+     {
+          // @fixme: log/error
+          printf("couldn't find sx [%p]\n", sx);
+          return;
+     }
+     gnc_sx_instances_free((GncSxInstances*)link->data);
+
+     new_instances = _gnc_sx_gen_instances((gpointer)sx, &model->range_end);
+     link->data = new_instances;
+}
+
+void
+gnc_sx_instance_model_remove_sx_instances(GncSxInstanceModel *model, SchedXaction *sx)
+{
+     GList *instance_link = NULL;
+
+     instance_link = g_list_find_custom(model->sx_instance_list, sx, (GCompareFunc)_gnc_sx_instance_find_by_sx);
+     if (instance_link == NULL)
+     {
+          // @fixme: perr or something.
+          return;
+     }
+
+     model->sx_instance_list = g_list_remove(model->sx_instance_list, instance_link);
+     gnc_sx_instances_free((GncSxInstances*)instance_link->data);
+}

Modified: gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.h
===================================================================
--- gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.h	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.h	2007-01-08 00:43:58 UTC (rev 15329)
@@ -40,14 +40,15 @@
 typedef struct _GncSxInstanceModel
 {
      GObject parent;
+     gboolean disposed;
 
      /* private */
      gint qof_event_handler_id;
 
      /* signals */
-     /* void (*added)(GncSxInstance *sx); // gpointer user_data */
-     /* void (*removed)(GncSxInstance *sx); // gpointer user_data */
-     /* void (*changed)(GncSxInstance *inst); // gpointer user_data */
+     /* void (*added)(GncSxInstance *inst); // gpointer user_data */
+     /* void (*updated)(); // gpointer user_data */
+     /* void (*removing)(GncSxInstance *inst); // gpointer user_data */
 
      /* public */
      GDate range_end;
@@ -106,6 +107,15 @@
 
 GncSxInstanceModel* gnc_sx_get_instances(GDate *range_end);
 
+/**
+ * Regenerates and updates the GncSxInstances* for the given SX.  Model
+ * consumers are probably going to call this in response to seeing the
+ * "update" signal, unless they need to be doing something else like
+ * finishing an iteration over an existing GncSxInstances*.
+ **/
+void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx);
+void gnc_sx_instance_model_remove_sx_instances(GncSxInstanceModel *model, SchedXaction *sx);
+
 /** @return GList<GncSxVariable*> **/
 GList *gnc_sx_instance_get_variables(GncSxInstance *inst);
 

Modified: gnucash/branches/sx-cleanup/src/doc/sx.rst
===================================================================
--- gnucash/branches/sx-cleanup/src/doc/sx.rst	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/doc/sx.rst	2007-01-08 00:43:58 UTC (rev 15329)
@@ -19,26 +19,39 @@
 ----------
 
 - meta
-  - [ ] move files around
+  - [x] move files around
   - [ ] GncSxListTreeModelAdapter: s/real/adapted/
   - [ ] generic tree model adapter setup code
 
 - core
   - [x] sx list -> qof collection
-  - [ ] sx engine events
+  - [/] sx engine events
     - [x] sx list collection add/remove -- sx-list GNC_EVENT_ITEM_ADDED, _REMOVED
-    - [ ] sx modified -- QOF_EVENT_MODIFY
+    - [x] sx modified -- QOF_EVENT_MODIFY
   - [ ] sx upcoming instance model
     - [ ] implement sort model
+  - [#] testing
+    - [x] open SLR dialog, create new SX, see it populated
+    - [x] open SX editor dialog, run SLR, see next-instance update
+    - [ ] unit testing
 
+- sx editor page
+  - [ ] make into split panel
+  - [ ] {0, 1, 2, 4, 8, 12} month selection for dense calendar
+
 - gnc_dense_cal
+  - [ ] fix static variables that should be instance fields.
+  - [ ] remove clist usage
   - [ ] change number-of-month properties to display-named properties (width, length)
+  - [ ] better transient/floating window?
   - [x] set_model(GncTemporalInstancesModel *mdl)
     - [x] new interface creation.
     - [x] register callbacks for signals
+  - [ ] (re-format file)
 
 - sx-from-trans
-  - [ ] convert to GObject, hookup destroy/finalize
+  - [ ] convert to GObject
+  - [x] hookup destroy/finalize
 
 - use Recurrence instead of Freq Spec
   - [ ] XML migration, handling
@@ -48,24 +61,23 @@
   - [ ] add obsolete flag to SxInstanceModel
   - [x] add mutation support to sx instance model
     - [x] state machine
-  - [x] add variable state to sx instance model
+  - [/] add variable state to sx instance model
     - [ ] handle (hidden/system not for editing) variables.
   - [x] add sx_upcoming_instance_model()
-      - [ ] add effect_auto_create()
-  - [/] add some sort of "ready to go" flag and api
+      - [x] add effect_auto_create()
+  - [x] add some sort of "ready to go" flag and api
     - [x] variable setting, primarily
-  - [/] some sort of commit_changes()
-    - ??? does effect_auto_create() imply or need commit_changes()?
-  - [/] add variable table to instances
+  - [x] some sort of commit_changes()
+  - [x] add variable table to instances
   - [x] ui: add 'review created transactions' checkbox to SLR dialog
         using txn search.
 
 - destroy/cleanup
-  - [ ] GncSxInstanceModel
-  - [ ] GncSxSlr[Tree]Model[Adapter]
-  - [ ] GncSxList adapter
-  - [ ] GncPluginPageSxList
-  - ...
+  - notes
+    - dispose: should no longer hold references to other objects; callable
+      multiple times; chain up at end
+    - finalize: complete destruction; just before free; only called once;
+      chain up at end.
 
 Pedantic Todo
 ----------------------
@@ -216,4 +228,4 @@
     - only auto-create (-notify): no SLR, info dialog w/count (***)
     - only auto-create (+notify): SLR dialog, already created
     - others, auto-create (-notify): SLR dialog, incl. created 
-    - others, auto-create (+notify): SLR dialog, incl. created
\ No newline at end of file
+    - others, auto-create (+notify): SLR dialog, incl. created

Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -76,8 +76,7 @@
 static void sxftd_destroy( GtkWidget *w, gpointer user_data );
 
 typedef enum { FREQ_DAILY = 0,  /* I know the =0 is redundant, but I'm using
-                                 * the numeric equivalences explicitly here
-                                 */
+                                 * the numeric equivalences explicitly here */
                FREQ_WEEKLY,
                FREQ_BIWEEKLY,
                FREQ_MONTHLY, 
@@ -109,9 +108,6 @@
 static void sxftd_update_example_cal( SXFromTransInfo *sxfti );
 static void sxftd_update_excal_adapt( GObject *o, gpointer ud );
 
-/* Stolen from jsled - nice and neat, actually (if a little light on 
- * for typechecking, but we'll be careful) . . . 
- */
 typedef struct
 {
   gchar *name;
@@ -119,11 +115,9 @@
   void (*handlerFn)();
 } widgetSignalHandlerTuple;
 
-
 static void sxftd_ok_clicked(SXFromTransInfo *sxfti);
 static void sxftd_advanced_clicked(SXFromTransInfo *sxfti);
 
-
 static void
 sxfti_attach_callbacks(SXFromTransInfo *sxfti)
 {
@@ -136,7 +130,6 @@
       { SXFTD_END_ON_DATE_BUTTON,   "clicked",      sxftd_update_excal_adapt },
       { SXFTD_N_OCCURRENCES_BUTTON, "clicked",      sxftd_update_excal_adapt },
       { SXFTD_N_OCCURRENCES_ENTRY,  "changed",      sxftd_update_excal_adapt },
-
       { NULL,                  NULL,      NULL }
     };
   
@@ -367,6 +360,7 @@
     w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME ));
     sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks);
     sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model)));
+    g_object_ref_sink(sxfti->example_cal);
 
     g_assert( sxfti->example_cal );
     gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
@@ -632,15 +626,14 @@
     sxfti->sx = NULL;
   }
 
+  g_object_unref(G_OBJECT(sxfti->dense_cal_model));
+  g_object_unref(G_OBJECT(sxfti->example_cal));
+
   /* FIXME: do we need to clean up the GladeXML pointer? */
 
   g_free(sxfti);
 }
 
-
-/**
- *
- **/
 static void
 gnc_sx_trans_window_response_cb (GtkDialog *dialog,
                                 gint response,
@@ -668,7 +661,6 @@
 	LEAVE(" ");
 }
 
-
 /**
  * Update the example calendar; make sure to take into account the end
  * specification.
@@ -737,10 +729,6 @@
   sxftd_update_example_cal( sxfti );
 }
 
-
-/**
- *
- **/
 void
 gnc_sx_create_from_trans( Transaction *trans )
 {

Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -60,11 +60,16 @@
 
 /* ------------------------------------------------------------ */
 
+static GObjectClass *parent_class = NULL;
+
 struct _GncSxSlrTreeModelAdapter
 {
      GObject parent;
 
-     /* protected */
+     /* protected: */
+     gulong updated_cb_id;
+     gboolean disposed;
+
      GncSxInstanceModel *instances;
      GtkTreeStore *real;
 };
@@ -79,6 +84,8 @@
 static void gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data);
 static void gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
 GncSxSlrTreeModelAdapter* gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances);
+static void gnc_sx_slr_tree_model_adapter_dispose(GObject *obj);
+static void gnc_sx_slr_tree_model_adapter_finalize(GObject *obj);
 
 GncSxInstances* gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
 static GncSxInstances* _gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth);
@@ -135,8 +142,8 @@
 GType
 gnc_sx_slr_tree_model_adapter_get_type(void)
 {
-     static GType type = 0;
-     if (type == 0) {
+     static GType gsstma_type = 0;
+     if (gsstma_type == 0) {
           static const GTypeInfo info = {
                sizeof (GncSxSlrTreeModelAdapterClass),
                NULL,   /* base_init */
@@ -154,20 +161,27 @@
                NULL                /* interface_data */
           };
 
-          type = g_type_register_static (G_TYPE_OBJECT,
-                                         "GncSxSlrTreeModelAdapterType",
-                                         &info, 0);
-          g_type_add_interface_static(type,
+          gsstma_type = g_type_register_static (G_TYPE_OBJECT,
+                                                "GncSxSlrTreeModelAdapterType",
+                                                &info, 0);
+          g_type_add_interface_static(gsstma_type,
                                       GTK_TYPE_TREE_MODEL,
                                       &itreeModel_info);
      }
-     return type;
+     return gsstma_type;
 }
 
 static void
 gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass)
 {
-     ; /* nop */
+     GObjectClass *obj_class;
+
+     parent_class = g_type_class_peek_parent(klass);
+
+     obj_class = G_OBJECT_CLASS(klass);
+
+     obj_class->dispose = gnc_sx_slr_tree_model_adapter_dispose;
+     obj_class->finalize = gnc_sx_slr_tree_model_adapter_finalize;
 }
 
 static GtkTreeModelFlags
@@ -716,25 +730,58 @@
 }
 
 static void
-gsslrtma_updated_cb(GncSxInstanceModel *instances, gpointer user_data)
+gsslrtma_updated_cb(GncSxInstanceModel *instances, SchedXaction *updated_sx, gpointer user_data)
 {
      GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data); 
-     printf("update\n");
+     printf("gsslrtma update\n");
+
      // @@fixme: this should be better about, say, trying to match up changed
      // instance-state and variable-binding values.  More of a merge
      // operation than a replace...
+     
+     gnc_sx_instance_model_update_sx_instances(instances, updated_sx);
+
      gtk_tree_store_clear(model->real);
      gsslrtma_populate_tree_store(model);
+
+     // gtk_tree_view_expand_all(dialog->instance_view);
 }
 
+static void
+gnc_sx_slr_tree_model_adapter_dispose(GObject *obj)
+{
+     GncSxSlrTreeModelAdapter *adapter;
+     g_return_if_fail(obj != NULL);
+     adapter = GNC_SX_SLR_TREE_MODEL_ADAPTER(obj);
+     g_return_if_fail(!adapter->disposed);
+     adapter->disposed = TRUE;
+     
+     g_object_unref(G_OBJECT(adapter->instances));
+     adapter->instances = NULL;
+     g_object_unref(G_OBJECT(adapter->real));
+     adapter->real = NULL;
+
+     G_OBJECT_CLASS(parent_class)->dispose(obj);
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_finalize(GObject *obj)
+{
+     g_return_if_fail(obj != NULL);
+     G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
 GncSxSlrTreeModelAdapter*
 gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances)
 {
      GncSxSlrTreeModelAdapter *rtn;
      rtn = GNC_SX_SLR_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, NULL));
      rtn->instances = instances;
+     g_object_ref(G_OBJECT(rtn->instances));
      gsslrtma_populate_tree_store(rtn);
-     g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsslrtma_updated_cb, (gpointer)rtn);
+     g_signal_connect(G_OBJECT(rtn->instances), "added", (GCallback)gsslrtma_added_cb, (gpointer)rtn);
+     rtn->updated_cb_id = g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsslrtma_updated_cb, (gpointer)rtn);
+     g_signal_connect(G_OBJECT(rtn->instances), "removing", (GCallback)gsslrtma_removing_cb, (gpointer)rtn);
      return rtn;
 }
 
@@ -748,6 +795,7 @@
      g_date_set_time_t(&now, time(NULL));
      instance_model = gnc_sx_get_instances(&now);
      slr_model = gnc_sx_slr_tree_model_adapter_new(instance_model);
+     g_object_unref(G_OBJECT(instance_model));
      return slr_model;
 }
 
@@ -847,7 +895,7 @@
                gnc_sx_slr_model_effect_change(slr_model, TRUE, NULL, NULL);
           }
      }
-     // @@fixme g_object_unref(G_OBJECT(slr_model))
+     g_object_unref(G_OBJECT(slr_model));
 }
 
 void
@@ -856,6 +904,7 @@
      GncSxSlrTreeModelAdapter *slr_model = gnc_sx_get_slr_model();
      gnc_sx_slr_model_effect_change(slr_model, TRUE, NULL, NULL);
      gnc_ui_sx_since_last_run_dialog(slr_model);
+     g_object_unref(G_OBJECT(slr_model));
 }
 
 static void
@@ -943,6 +992,7 @@
      dialog->dialog = glade_xml_get_widget(glade, "since-last-run-dialog");
 
      dialog->editing_model = slr_model;
+     g_object_ref(G_OBJECT(dialog->editing_model));
      
      {
           GtkPaned *paned;
@@ -966,7 +1016,6 @@
                                                          NULL);
           gtk_tree_view_append_column(dialog->instance_view, col);
 
-
           renderer = gtk_cell_renderer_combo_new();
           g_object_set(G_OBJECT(renderer),
                        "model", gnc_sx_get_slr_state_model(),
@@ -1093,7 +1142,8 @@
      case GTK_RESPONSE_CANCEL: 
      case GTK_RESPONSE_DELETE_EVENT:
           gtk_widget_destroy(GTK_WIDGET(dialog));
-          // @@fixme: destroy models, &c.
+          g_object_unref(G_OBJECT(app_dialog->editing_model));
+          app_dialog->editing_model = NULL;
           break;
      default:
           printf("unknown response id [%d]\n", response_id);
@@ -1422,7 +1472,7 @@
 {
      GList *list;
 
-     // @@fixme engine event supression
+     g_signal_handler_block(model->instances, model->updated_cb_id);
 
      for (list = model->instances->sx_instance_list; list != NULL; list = list->next)
      {
@@ -1494,7 +1544,7 @@
           xaccSchedXactionSetRemOccur(instances->sx, remain_occur_count);
      }
 
-     // @fixme: re-generate instance model, repopulate [?]
+     g_signal_handler_unblock(model->instances, model->updated_cb_id);
 }
 
 static void

Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -480,7 +480,7 @@
                       summary.num_auto_create_no_notify_instances);
     }
   }
-  // @fixme g_object_unref(G_OBJECT(slr_model));
+  g_object_unref(G_OBJECT(slr_model));
 }
 
 static void

Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -71,6 +71,8 @@
 
 typedef struct GncPluginPageSxListPrivate
 {
+     gboolean disposed;
+
      GtkWidget* widget;
      gint gnc_component_id;
      gint gppsl_event_handler_id;
@@ -82,7 +84,6 @@
      GncSxInstanceModel* instances;
      GncSxListTreeModelAdapter* tree_model;
      GtkTreeView* tree_view;
-
 } GncPluginPageSxListPrivate;
 
 #define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o)  \
@@ -96,7 +97,8 @@
 /* Plugin Actions */
 static void gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass);
 static void gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page);
-static void gnc_plugin_page_sx_list_finalize (GObject *object);
+static void gnc_plugin_page_sx_list_dispose(GObject *object);
+static void gnc_plugin_page_sx_list_finalize(GObject *object);
 
 static GtkWidget *gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page);
@@ -168,6 +170,7 @@
 
      parent_class = g_type_class_peek_parent(klass);
 
+     object_class->dispose = gnc_plugin_page_sx_list_dispose;
      object_class->finalize = gnc_plugin_page_sx_list_finalize;
 
      gnc_plugin_class->tab_icon        = GNC_STOCK_ACCOUNT;
@@ -216,17 +219,52 @@
 }
 
 static void
+gnc_plugin_page_sx_list_dispose(GObject *object)
+{
+     GncPluginPageSxList *page;
+     GncPluginPageSxListPrivate *priv;
+
+     ENTER("object %p", object);
+
+     page = GNC_PLUGIN_PAGE_SX_LIST (object);
+     g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     g_return_if_fail(priv != NULL);
+
+     g_return_if_fail(!priv->disposed);
+     priv->disposed = TRUE;
+     
+     qof_event_unregister_handler(priv->gppsl_event_handler_id);
+
+     g_object_unref(G_OBJECT(priv->dense_cal_model));
+     priv->dense_cal_model = NULL;
+     gtk_widget_unref(GTK_WIDGET(priv->gdcal));
+     priv->gdcal = NULL;
+     g_object_unref(G_OBJECT(priv->instances)); 
+     priv->instances = NULL;
+     g_object_unref(G_OBJECT(priv->tree_model));
+     priv->tree_model = NULL;
+
+     G_OBJECT_CLASS (parent_class)->dispose(object);
+     LEAVE(" ");
+}
+
+static void
 gnc_plugin_page_sx_list_finalize (GObject *object)
 {
      GncPluginPageSxList *page;
      GncPluginPageSxListPrivate *priv;
 
      ENTER("object %p", object);
+
      page = GNC_PLUGIN_PAGE_SX_LIST (object);
-     g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST (page));
+     g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
      priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
-     g_return_if_fail (priv != NULL);
+     g_return_if_fail(priv != NULL);
 
+     // by virtue of being a g_type_instance_..._private, does the private
+     // data get freed somewhere else?
+
      G_OBJECT_CLASS (parent_class)->finalize (object);
      LEAVE(" ");
 }
@@ -360,6 +398,7 @@
 
           priv->dense_cal_model = gnc_sx_instance_dense_cal_adapter_new(GNC_SX_INSTANCE_MODEL(priv->instances));
           priv->gdcal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(priv->dense_cal_model)));
+          g_object_ref_sink(G_OBJECT(priv->gdcal));
           gnc_dense_cal_set_months_per_col(priv->gdcal, 4);
           gnc_dense_cal_set_num_months(priv->gdcal, 12);
 
@@ -369,11 +408,11 @@
      }
 
      priv->gppsl_event_handler_id = qof_event_register_handler(gppsl_event_handler, page);
-     gnc_register_gui_component("plugin-page-sx-list",
-                                gnc_plugin_page_sx_list_refresh_cb,
-                                gnc_plugin_page_sx_list_close_cb,
-                                page);
-
+     priv->gnc_component_id = gnc_register_gui_component("plugin-page-sx-list",
+                                                         gnc_plugin_page_sx_list_refresh_cb,
+                                                         gnc_plugin_page_sx_list_close_cb,
+                                                         page);
+     
      /* @@fixme */
      /* gnc_restore_window_size(SX_LIST_GCONF_SECTION, GTK_WINDOW(priv->widget)); */
 
@@ -410,6 +449,7 @@
         return; */
      /* - correlate SX to tree_store data */
      /* - update || add || remove */
+
      return;
 }
 

Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -32,6 +32,7 @@
      GObject parent;
 
      /* protected */
+     gboolean disposed;
      GncSxInstanceModel *instances;
      GtkTreeStore *real;
 };
@@ -41,9 +42,13 @@
      GObjectClass parent;
 };
 
+static GObjectClass *parent_class = NULL;
+
 static void gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass);
 static void gnc_sx_list_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data);
 static void gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
+static void gnc_sx_list_tree_model_adapter_dispose(GObject *obj);
+static void gnc_sx_list_tree_model_adapter_finalize(GObject *obj);
 
 GType
 gnc_sx_list_tree_model_adapter_get_type(void)
@@ -80,7 +85,13 @@
 static void
 gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass)
 {
-     ; /* nop */
+     GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+     parent_class = g_type_class_peek_parent(klass);
+
+     obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
+     obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
+
 }
 
 static GtkTreeModelFlags
@@ -309,14 +320,34 @@
 }
 
 static void
-gsltma_updated_cb(GncSxInstanceModel *instances, gpointer user_data)
+gsltma_added_cb(GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
 {
      GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
-     printf("update\n");
+     printf("added\n");
      gtk_tree_store_clear(model->real);
      gsltma_populate_tree_store(model);
 }
 
+static void
+gsltma_updated_cb(GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
+{
+     GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
+     printf("sx list tree model adapter update\n");
+     gnc_sx_instance_model_update_sx_instances(instances, sx_updated);
+     gtk_tree_store_clear(model->real);
+     gsltma_populate_tree_store(model);
+}
+
+static void
+gsltma_removing_cb(GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
+{
+     GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
+     printf("removing\n");
+     gnc_sx_instance_model_remove_sx_instance(instances, sx_removing);
+     gtk_tree_store_clear(model->real);
+     gsltma_populate_tree_store(model);
+}
+
 GncSxListTreeModelAdapter*
 gnc_sx_list_tree_model_adapter_new(GncSxInstanceModel *instances)
 {
@@ -324,10 +355,13 @@
 
      rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
      rtn->instances = instances;
+     g_object_ref(G_OBJECT(rtn->instances));
 
      gsltma_populate_tree_store(rtn);
 
+     g_signal_connect(G_OBJECT(rtn->instances), "added", (GCallback)gsltma_added_cb, (gpointer)rtn);
      g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsltma_updated_cb, (gpointer)rtn);
+     g_signal_connect(G_OBJECT(rtn->instances), "removing", (GCallback)gsltma_removing_cb, (gpointer)rtn);
 
      return rtn;
 }
@@ -351,3 +385,28 @@
      gtk_tree_path_free(path);
      return (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
 }
+
+static void
+gnc_sx_list_tree_model_adapter_dispose(GObject *obj)
+{
+     GncSxListTreeModelAdapter *adapter;
+
+     g_return_if_fail(obj != NULL);
+     adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
+     g_return_if_fail(adapter->disposed);
+     adapter->disposed = TRUE;
+
+     g_object_unref(G_OBJECT(adapter->instances));
+     adapter->instances = NULL;
+     g_object_unref(G_OBJECT(adapter->real));
+     adapter->real = NULL;
+
+     G_OBJECT_CLASS(parent_class)->dispose(obj);
+}
+
+static void
+gnc_sx_list_tree_model_adapter_finalize(GObject *obj)
+{
+     g_return_if_fail(obj != NULL);
+     G_OBJECT_CLASS(parent_class)->finalize(obj);
+}

Modified: gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-store.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-store.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-store.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -47,6 +47,12 @@
      GObjectClass parent_class;
 };
 
+static GObjectClass *parent_class = NULL;
+
+static void gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass);
+
+static void gnc_dense_cal_store_finalize(GObject *obj);
+
 static GList* gdcs_get_contained(GncDenseCalModel *model);
 static gchar* gdcs_get_name(GncDenseCalModel *model, guint tag);
 static gchar* gdcs_get_info(GncDenseCalModel *model, guint tag);
@@ -54,6 +60,15 @@
 static void gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
 
 static void
+gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass)
+{
+     GObjectClass *object_class = G_OBJECT_CLASS(klass);
+     parent_class = g_type_class_peek_parent(klass);
+     
+     object_class->finalize = gnc_dense_cal_store_finalize;
+}
+
+static void
 gnc_dense_cal_store_iface_init(gpointer g_iface, gpointer iface_data)
 {
      GncDenseCalModelIface *iface = (GncDenseCalModelIface*)g_iface;
@@ -74,7 +89,7 @@
                sizeof (GncDenseCalStoreClass),
                NULL,   /* base_init */
                NULL,   /* base_finalize */
-               NULL,   /* class_init */
+               (GClassInitFunc)gnc_dense_cal_store_class_init,   /* class_init */
                NULL,   /* class_finalize */
                NULL,   /* class_data */
                sizeof(GncDenseCalStore),
@@ -238,3 +253,37 @@
      // assert 0 < instance_index < model->num_marks;
      *date = *mdl->cal_marks[instance_index];
 }
+
+static void
+gnc_dense_cal_store_finalize(GObject *obj)
+{
+     GncDenseCalStore *store;
+     g_return_if_fail(obj != NULL);
+
+     store = GNC_DENSE_CAL_STORE(obj);
+
+     if (store->name != NULL)
+     {
+          g_free(store->name);
+          store->name = NULL;
+     }
+
+     if (store->info != NULL)
+     {
+          g_free(store->info);
+          store->info = NULL;
+     }
+
+     for (int i = 0; i < store->num_marks; i++)
+     {
+          g_free(store->cal_marks[i]);
+          store->cal_marks[i] = NULL;
+     }
+     if (store->cal_marks != NULL)
+     {
+          g_free(store->cal_marks);
+          store->cal_marks = NULL;
+     }
+
+     G_OBJECT_CLASS(parent_class)->finalize(obj);
+}

Modified: gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -37,7 +37,7 @@
  *   . color-per-marker (configurable)
  *   X all-or-nothing
  * \ handle errors properly
- * X mouse-over -> "hottip"
+ * X mouse-over -> "tool tip"
  * X rotated month labels
  * X weeksPerCol -> monthsPerCol
  **/
@@ -152,14 +152,10 @@
 
 static GtkWidgetClass *parent_class = NULL;
 
-/*static const gchar* MONTH_NAMES[] = {
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-  };*/
 #define MONTH_NAME_BUFSIZE 5
 /* Takes the number of months since January, in the range 0 to
  * 11. Returns the abbreviated month name according to the current
- * locale. (i18n'd version of the above static character array.) */
+ * locale.
 static const gchar *month_name(int mon) 
 {
     static gchar buf[MONTH_NAME_BUFSIZE];
@@ -172,10 +168,6 @@
     i = strftime (buf, MONTH_NAME_BUFSIZE-1, "%b", &my_tm);
     return buf;
 }
-/* FIXME: i18n 
-   static const gchar *dayLabels[7] = {
-   "Su", "M", "Tu", "W", "Th", "F", "Sa"
-   };*/
 /* Takes the number of days since Sunday, in the range 0 to 6. Returns
  * the abbreviated weekday name according to the current locale. */
 static const gchar *day_label(int wday)
@@ -193,9 +185,8 @@
     return buf;
 }
 
-
 GType
-gnc_dense_cal_get_type ()
+gnc_dense_cal_get_type()
 {
         static GType dense_cal_type = 0;
 
@@ -214,8 +205,8 @@
 		};
 
                 dense_cal_type = g_type_register_static(GTK_TYPE_WIDGET,
-						"GncDenseCal",
-						&dense_cal_info, 0);
+                                                        "GncDenseCal",
+                                                        &dense_cal_info, 0);
         }
 
         return dense_cal_type;
@@ -227,7 +218,7 @@
         GObjectClass *object_class;
         GtkWidgetClass *widget_class;
 
-        object_class =  G_OBJECT_CLASS (klass);
+        object_class = G_OBJECT_CLASS (klass);
         widget_class = GTK_WIDGET_CLASS (klass);
 
         parent_class = g_type_class_peek_parent (klass);
@@ -378,7 +369,6 @@
 {
         GncDenseCal *dcal;
         dcal = g_object_new(GNC_TYPE_DENSE_CAL, NULL, NULL);
-
         return GTK_WIDGET (dcal);
 }
 
@@ -474,9 +464,8 @@
 
         dcal = GNC_DENSE_CAL(object);
 
-	if(dcal->disposed)
-		return;
-
+	if (dcal->disposed)
+                return;
 	dcal->disposed = TRUE;
 
         if ( GTK_WIDGET_REALIZED( dcal->transPopup ) ) {
@@ -496,10 +485,12 @@
 		gdk_font_unref( dcal->monthLabelFont );
 		dcal->monthLabelFont = NULL;
 	}
+
         if ( dcal->dayLabelFont ) {
 		gdk_font_unref( dcal->dayLabelFont );
 		dcal->dayLabelFont = NULL;
 	}
+
         /* month labels */
 	if ( dcal->monthLabels[0] ) {
         	for ( i=0; i < 12; i++ ) {
@@ -507,11 +498,12 @@
                 	dcal->monthLabels[i] = NULL;
 		}
         }
-        /* mark data */
-        gdc_free_all_mark_data( dcal );
+        gdc_free_all_mark_data(dcal);
 
+        g_object_unref(G_OBJECT(dcal->model));
+
         if (G_OBJECT_CLASS (parent_class)->dispose)
-                (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+             G_OBJECT_CLASS(parent_class)->dispose(object);
 }
 
 static void
@@ -524,7 +516,7 @@
         dcal = GNC_DENSE_CAL(object);
 
         if (G_OBJECT_CLASS (parent_class)->finalize)
-                (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+             G_OBJECT_CLASS(parent_class)->finalize(object);
 }
 
 static void
@@ -1553,6 +1545,10 @@
      name = gnc_dense_cal_model_get_name(cal->model, tag);
      info = gnc_dense_cal_model_get_info(cal->model, tag);
      num_marks = gnc_dense_cal_model_get_instance_count(cal->model, tag);
+
+     if (num_marks == 0)
+       return;
+
      dates = g_new0(GDate*, num_marks);
      for (idx = 0; idx < num_marks; idx++)
      {
@@ -1624,11 +1620,11 @@
      if (cal->model != NULL)
      {
           gdc_remove_markings(cal);
-          // g_object_unref(cal->model);
+          g_object_unref(G_OBJECT(cal->model));
           cal->model = NULL;
      }
      cal->model = model;
-     //g_object_ref(model);
+     g_object_ref(G_OBJECT(model));
      g_signal_connect(G_OBJECT(cal->model), "added", (GCallback)gdc_model_added_cb, cal);
      g_signal_connect(G_OBJECT(cal->model), "update", (GCallback)gdc_model_update_cb, cal);
      g_signal_connect(G_OBJECT(cal->model), "removing", (GCallback)gdc_model_removing_cb, cal);

Modified: gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c	2007-01-07 21:33:26 UTC (rev 15328)
+++ gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c	2007-01-08 00:43:58 UTC (rev 15329)
@@ -25,27 +25,38 @@
 #include "gnc-sx-instance-dense-cal-adapter.h"
 #include "gnc-dense-cal.h"
 
+static void gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj);
+static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj);
+
 static GList* gsidca_get_contained(GncDenseCalModel *model);
 static gchar* gsidca_get_name(GncDenseCalModel *model, guint tag);
 static gchar* gsidca_get_info(GncDenseCalModel *model, guint tag);
 static gint gsidca_get_instance_count(GncDenseCalModel *model, guint tag);
 static void gsidca_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
 
+static GObjectClass *parent_class = NULL;
+
 struct _GncSxInstanceDenseCalAdapterClass
 {
-  GObjectClass parent;
+     GObjectClass parent;
 };
 
 struct _GncSxInstanceDenseCalAdapter 
 {
-  GObject parent;
-  GncSxInstanceModel *instances;
+     GObject parent;
+     gboolean disposed;
+     GncSxInstanceModel *instances;
 };
 
 static void
 gnc_sx_instance_dense_cal_adapter_class_init(GncSxInstanceDenseCalAdapterClass *klass)
 {
-     ; /* nop */
+     GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+     obj_class->dispose = gnc_sx_instance_dense_cal_adapter_dispose;
+     obj_class->finalize = gnc_sx_instance_dense_cal_adapter_finalize;
+
+     parent_class = g_type_class_peek_parent(klass);
 }
 
 static void
@@ -67,31 +78,29 @@
 }
 
 static void
-gsidca_instances_added_cb(GncSxInstanceModel *model, gpointer instance_added, gpointer user_data)
+gsidca_instances_added_cb(GncSxInstanceModel *model, SchedXaction *sx_added, gpointer user_data)
 {
      GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
-     g_signal_emit_by_name(adapter, "added", GPOINTER_TO_UINT(instance_added));
+     printf("instance added\n");
+     g_signal_emit_by_name(adapter, "added", GPOINTER_TO_UINT(sx_added));
 }
 
 static void
-gsidca_instances_updated_cb(GncSxInstanceModel *model, gpointer user_data)
+gsidca_instances_updated_cb(GncSxInstanceModel *model, SchedXaction *sx_updated, gpointer user_data)
 {
      GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
-     // @@fixme figure out which; emit appropriate signal.
-     GList *exposed_tags;
+     gnc_sx_instance_model_update_sx_instances(model, sx_updated);
      printf("instances updated\n");
-     for (exposed_tags = gsidca_get_contained(GNC_DENSE_CAL_MODEL(adapter)); exposed_tags != NULL; exposed_tags = exposed_tags->next)
-     {
-          g_signal_emit_by_name(adapter, "update", GPOINTER_TO_UINT(exposed_tags->data));
-     }
+     g_signal_emit_by_name(adapter, "update", GPOINTER_TO_UINT((gpointer)sx_updated));
 }
 
 static void
-gsidca_instances_removing_cb(GncSxInstanceModel *model, gpointer instance_to_be_removed, gpointer user_data)
+gsidca_instances_removing_cb(GncSxInstanceModel *model, SchedXaction *sx_to_be_removed, gpointer user_data)
 {
      GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
      printf("removing instance...\n");
-     g_signal_emit_by_name(adapter, "removing", GPOINTER_TO_UINT(instance_to_be_removed));
+     g_signal_emit_by_name(adapter, "removing", GPOINTER_TO_UINT(sx_to_be_removed));
+     gnc_sx_instance_model_remove_sx_instance(model, sx_to_be_removed);
 }
 
 GncSxInstanceDenseCalAdapter*
@@ -99,6 +108,8 @@
 {
      GncSxInstanceDenseCalAdapter *adapter = g_object_new(GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, NULL);
      adapter->instances = instances;
+     g_object_ref(G_OBJECT(adapter->instances));
+
      g_signal_connect(instances, "added", (GCallback)gsidca_instances_added_cb, adapter);
      g_signal_connect(instances, "updated", (GCallback)gsidca_instances_updated_cb, adapter);
      g_signal_connect(instances, "removing", (GCallback)gsidca_instances_removing_cb, adapter);
@@ -146,6 +157,7 @@
      return (GUINT_TO_POINTER(GPOINTER_TO_UINT(sx_instances->sx)) == find_data ? 0 : 1);
 }
 
+// @@ fixme this list is leaked.
 static GList*
 gsidca_get_contained(GncDenseCalModel *model)
 {
@@ -217,3 +229,26 @@
      *date = inst->date;
      g_date_valid(date);
 }
+
+static void
+gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj)
+{
+     GncSxInstanceDenseCalAdapter *adapter;
+     g_return_if_fail(obj != NULL);
+     adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(obj);
+     // g_return_if_fail(!adapter->disposed);
+     if (adapter->disposed) return;
+     adapter->disposed = TRUE;
+
+     g_object_unref(G_OBJECT(adapter->instances));
+     adapter->instances = NULL;
+
+     G_OBJECT_CLASS(parent_class)->dispose(obj);
+}
+
+static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj)
+{
+     g_return_if_fail(obj != NULL);
+     // nop
+     G_OBJECT_CLASS(parent_class)->finalize(obj);
+}



More information about the gnucash-changes mailing list