r15399 - gnucash/trunk - Fold branches/sx-cleanup/ [14463:14917] back into trunk/.

Josh Sled jsled at cvs.gnucash.org
Fri Jan 19 18:45:56 EST 2007


Author: jsled
Date: 2007-01-19 18:45:45 -0500 (Fri, 19 Jan 2007)
New Revision: 15399
Trac: http://svn.gnucash.org/trac/changeset/15399

Added:
   gnucash/trunk/src/app-utils/gnc-sx-instance-model.c
   gnucash/trunk/src/app-utils/gnc-sx-instance-model.h
   gnucash/trunk/src/app-utils/test/test-sx.c
   gnucash/trunk/src/doc/sx.rst
   gnucash/trunk/src/gnome-utils/gnc-dense-cal-model.c
   gnucash/trunk/src/gnome-utils/gnc-dense-cal-model.h
   gnucash/trunk/src/gnome-utils/gnc-dense-cal-store.c
   gnucash/trunk/src/gnome-utils/gnc-dense-cal-store.h
   gnucash/trunk/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
   gnucash/trunk/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
   gnucash/trunk/src/gnome-utils/test/test-sx.c
   gnucash/trunk/src/gnome/dialog-sx-editor.c
   gnucash/trunk/src/gnome/dialog-sx-editor.h
   gnucash/trunk/src/gnome/dialog-sx-since-last-run.c
   gnucash/trunk/src/gnome/dialog-sx-since-last-run.h
   gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c
   gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.h
   gnucash/trunk/src/gnome/gnc-sx-list-tree-model-adapter.c
   gnucash/trunk/src/gnome/gnc-sx-list-tree-model-adapter.h
   gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml
Removed:
   gnucash/trunk/src/gnome/dialog-scheduledxaction.c
   gnucash/trunk/src/gnome/dialog-scheduledxaction.h
   gnucash/trunk/src/gnome/dialog-sxsincelast.c
   gnucash/trunk/src/gnome/dialog-sxsincelast.h
Modified:
   gnucash/trunk/ChangeLog
   gnucash/trunk/src/app-utils/Makefile.am
   gnucash/trunk/src/app-utils/test/
   gnucash/trunk/src/app-utils/test/Makefile.am
   gnucash/trunk/src/app-utils/test/test-exp-parser.c
   gnucash/trunk/src/backend/file/io-gncxml-v2.c
   gnucash/trunk/src/core-utils/gnc-glib-utils.c
   gnucash/trunk/src/core-utils/gnc-glib-utils.h
   gnucash/trunk/src/engine/SX-book-p.h
   gnucash/trunk/src/engine/SX-book.c
   gnucash/trunk/src/engine/SX-book.h
   gnucash/trunk/src/engine/SchedXaction.c
   gnucash/trunk/src/engine/SchedXaction.h
   gnucash/trunk/src/engine/gnc-engine.h
   gnucash/trunk/src/engine/test-core/test-engine-stuff.c
   gnucash/trunk/src/engine/test-core/test-engine-stuff.h
   gnucash/trunk/src/engine/test/test-freq-spec.c
   gnucash/trunk/src/engine/test/test-transaction-voiding.c
   gnucash/trunk/src/gnome-utils/Makefile.am
   gnucash/trunk/src/gnome-utils/gnc-dense-cal.c
   gnucash/trunk/src/gnome-utils/gnc-dense-cal.h
   gnucash/trunk/src/gnome-utils/gnc-frequency.c
   gnucash/trunk/src/gnome-utils/test/
   gnucash/trunk/src/gnome-utils/test/Makefile.am
   gnucash/trunk/src/gnome/Makefile.am
   gnucash/trunk/src/gnome/dialog-sx-from-trans.c
   gnucash/trunk/src/gnome/druid-loan.c
   gnucash/trunk/src/gnome/glade/sched-xact.glade
   gnucash/trunk/src/gnome/gnc-plugin-basic-commands.c
   gnucash/trunk/src/gnome/gnc-split-reg.c
   gnucash/trunk/src/gnome/top-level.c
   gnucash/trunk/src/gnome/ui/Makefile.am
Log:
Fold branches/sx-cleanup/ [14463:14917] back into trunk/.


Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/ChangeLog	2007-01-19 23:45:45 UTC (rev 15399)
@@ -77,6 +77,17 @@
 	relocation of previously compiled-in paths. With the exception of
 	the env variables in src/bin/gnucash, we're fully relocatable now.
 
+2006-09-16  Joshua Sled  <jsled at asynchronous.org>
+
+	* src/gnome/gnc-plugin-page-sx-list.c (sxsl_get_sx_vars): Add
+	variable extraction to instance-model creation.  The
+	GncSxInstances now has a hashtable of variables parsed from the
+	formula, and the GncSxInstance has a copy of that variables hash.
+	Not finished, but mostly in place.
+
+	* src/gnome/dialog-sx-since-last-run.c: New, simplified version of
+	the since-last-run dialog.  GncSxSlrTreeModelAdapter.
+
 2006-09-13  Christian Stimming <stimming at tuhh.de>
 
 	* src/import-export/hbci/gnc-plugin-hbci.c: Move the MT940
@@ -270,6 +281,30 @@
 	  preferences_dialog->Windows. Move "Show close button on notebook
 	  tabs" from General to Windows. Fixes #340299.
 
+2006-07-27  Joshua Sled  <jsled at asynchronous.org>
+
+	* src/gnome-utils/gnc-dense-cal.c
+	(gnc_dense_cal_transient_model_new): Actually implement
+	GncDenseCalTransientModel. 
+
+	* src/gnome/dialog-sx-editor.c (gnc_sxed_update_cal): 
+	* src/gnome/dialog-sx-from-trans.c (sxftd_update_example_cal):
+	Use GncDenseCalTransientModel from previous ad-hoc updaters.
+
+
+2006-07-25  Joshua Sled  <jsled at asynchronous.org>
+
+	* src/gnome-utils/gnc-dense-cal.c:
+	Add GncDenseCalModel interface, support.
+	Add unfinished GncDenseCalTransient model impl. for
+	one-off being-edited-SX calendar usage.
+
+	* src/gnome/gnc-plugin-page-sx-list.c:
+	Add GncSxInstanceDenseCalAdapter between GncSxInstanceModel and
+	GncDenseCalModel.  Start to hook up 'added' and 'removing' signals
+	on the GncSxInstanceModel.  The SX-List dense-cal works again, and
+	reflects both removed and new SXes.
+
 2006-07-24  Derek Atkins  <derek at ihtfp.com>
 
 	* [lots of Makefile.am files]:
@@ -302,6 +337,27 @@
 	extra de-quoting of path names that is done on the GNC_MODULE_PATH
 	env variable.
 
+2006-07-16  Joshua Sled  <jsled at asynchronous.org>
+
+	* src/engine/SX-book-p.h:
+	* src/engine/SX-book.h:
+	* src/engine/SX-book.c: Promote SX list from a GList to a
+	`SchedXactions` QOF Entity.  Create add/remove API that emits
+	GNC_EVENT_{INSERT,REMOVE} signals.  Correctly associate the SX
+	List with the collection of SchedXaction qof-type rather than the
+	SX template transactions qof-type.  Remove some (now-)dead
+	code.  Fix long-standing bug in registration of SX qof types.
+	
+	* src/gnome/dialog-sx-editor.[ch]:
+	* src/gnome/dialog-schedxaction.[ch]:
+	Move the SX editor dialog subset of dialog-schedxaction to
+	dialog-sx-editor.[ch].
+
+	* src/gnome/gnc-plugin-page-sx-list.c:
+	Hookup SX editor for both 'new' and 'edit' actions. Hookup
+	row-activation from tree-view.  Extend GncSxInstanceModel to
+	support SchedXactions (sx list) modification events.
+
 2006-07-16  Derek Atkins  <derek at ihtfp.com>
 
 	* configure.in:
@@ -331,6 +387,18 @@
 	* src/gnome-utils/gnc-main-window.c: Do not move windows on
 	  restoration that would be offscreen.
 
+2006-07-15  Joshua Sled  <jsled at asynchronous.org>
+
+	* src/engine/SchedXaction.h (GNC_IS_SX,GNC_SX): added for convenience.
+
+	* src/gnome/ui/gnc-plugin-page-sx-list-ui.xml:
+	* src/gnome/gnc-plugin-page-sx-list.[ch]: SX List as a plugin page.
+
+	* src/gnome/gnc-plugin-basic-commands.c: Call SX List plugin page,
+	not dialog.
+
+	* src/doc/sx.rst: Added.
+
 2006-07-15  Derek Atkins  <derek at ihtfp.com>
 
 	* src/business/business-core/gncAddress.[ch]:

Modified: gnucash/trunk/src/app-utils/Makefile.am
===================================================================
--- gnucash/trunk/src/app-utils/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/app-utils/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -34,6 +34,7 @@
   gnc-exp-parser.c \
   gnc-gettext-util.c \
   gnc-helpers.c \
+  gnc-sx-instance-model.c \
   gncmod-app-utils.c \
   gnc-ui-util.c \
   guile-util.c \
@@ -59,6 +60,7 @@
   gnc-exp-parser.h \
   gnc-gettext-util.h \
   gnc-helpers.h \
+  gnc-sx-instance-model.h \
   gnc-ui-common.h \
   gnc-ui-util.h \
   guile-util.h \

Copied: gnucash/trunk/src/app-utils/gnc-sx-instance-model.c (from rev 15384, gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.c)

Copied: gnucash/trunk/src/app-utils/gnc-sx-instance-model.h (from rev 15384, gnucash/branches/sx-cleanup/src/app-utils/gnc-sx-instance-model.h)


Property changes on: gnucash/trunk/src/app-utils/test
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
test-exp-parser
test-link-module
test-print-parse-amount
test-print-queries
test-scm-query-string
.deps
.libs
semantic.cache
TAGS
*.exe

   + Makefile
Makefile.in
test-exp-parser
test-link-module
test-print-parse-amount
test-print-queries
test-scm-query-string
test-sx
.deps
.libs
semantic.cache
TAGS
*.exe


Modified: gnucash/trunk/src/app-utils/test/Makefile.am
===================================================================
--- gnucash/trunk/src/app-utils/test/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/app-utils/test/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -3,7 +3,8 @@
   test-load-module \
   test-exp-parser \
   test-scm-query-string \
-  test-print-parse-amount
+  test-print-parse-amount \
+  test-sx
 
 test_exp_parser_SOURCES = \
   ${top_builddir}/src/core-utils/gnc-gconf-utils.c \
@@ -48,7 +49,8 @@
   test-exp-parser \
   test-print-parse-amount \
   test-scm-query-string \
-  test-print-queries
+  test-print-queries \
+  test-sx
 
 EXTRA_DIST = \
   test-load-module

Modified: gnucash/trunk/src/app-utils/test/test-exp-parser.c
===================================================================
--- gnucash/trunk/src/app-utils/test/test-exp-parser.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/app-utils/test/test-exp-parser.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -209,10 +209,22 @@
 }
 
 static void
+test_variable_expressions()
+{
+  gnc_numeric num;
+  gchar *errLoc = NULL;
+  GHashTable *vars = g_hash_table_new(g_str_hash, g_str_equal);
+  do_test(gnc_exp_parser_parse_separate_vars("123 + a", &num, &errLoc, vars), "parsing");
+  do_test(g_hash_table_size(vars) == 1, "'a' is the variable; good job, gnc-exp-parser!");
+  success("variable found");
+}
+
+static void
 real_main (void *closure, int argc, char **argv)
 {
   /* set_should_print_success (TRUE); */
   test_parser();
+  test_variable_expressions();
   print_test_results();
   exit(get_rv());
 }

Copied: gnucash/trunk/src/app-utils/test/test-sx.c (from rev 15384, gnucash/branches/sx-cleanup/src/app-utils/test/test-sx.c)

Modified: gnucash/trunk/src/backend/file/io-gncxml-v2.c
===================================================================
--- gnucash/trunk/src/backend/file/io-gncxml-v2.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/backend/file/io-gncxml-v2.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -237,16 +237,19 @@
 static gboolean
 add_schedXaction_local(sixtp_gdv2 *data, SchedXaction *sx)
 {
-    GList *list;
-
-    list = gnc_book_get_schedxactions (data->book);
-    list = g_list_append(list, sx);
-
-    gnc_book_set_schedxactions(data->book, list);
-    data->counter.schedXactions_loaded++;
-    run_callback(data, "schedXactions");
-
-    return TRUE;
+     SchedXactions *sxes;
+#if 0 // old
+     GList *list;
+     list = gnc_book_get_schedxactions (data->book);
+     list = g_list_append(list, sx);
+     gnc_book_set_schedxactions(data->book, list);
+#endif // 0
+     sxes = gnc_book_get_schedxactions(data->book);
+     gnc_sxes_add_sx(sxes, sx);
+     data->counter.schedXactions_loaded++;
+     run_callback(data, "schedXactions");
+     
+     return TRUE;
 }
 
 static gboolean
@@ -932,7 +935,7 @@
                  "transaction",
                  gnc_book_count_transactions(book),
                  "schedxaction",
-                 g_list_length( gnc_book_get_schedxactions(book) ),
+                 g_list_length(gnc_book_get_schedxactions(book)->sx_list),
 		 "budget", qof_collection_count(
                      qof_book_get_collection(book, GNC_ID_BUDGET)),
 		 NULL);
@@ -1067,25 +1070,24 @@
 static void
 write_schedXactions( FILE *out, QofBook *book, sixtp_gdv2 *gd)
 {
-    GList *schedXactions;
-    SchedXaction *tmpSX;
-    xmlNodePtr node;
+     GList *schedXactions;
+     SchedXaction *tmpSX;
+     xmlNodePtr node;
+     
+     schedXactions = gnc_book_get_schedxactions(book)->sx_list;
 
-    /* get list of scheduled transactions from QofBook */
-    schedXactions = gnc_book_get_schedxactions( book );
+     if ( schedXactions == NULL )
+          return;
 
-    if ( schedXactions == NULL )
-        return;
-
-    do {
-        tmpSX = schedXactions->data;
-        node = gnc_schedXaction_dom_tree_create( tmpSX );
-        xmlElemDump( out, NULL, node );
-        fprintf( out, "\n" );
-        xmlFreeNode( node );
-        gd->counter.schedXactions_loaded++;
-        run_callback(gd, "schedXactions");
-    } while ( (schedXactions = schedXactions->next) );
+     do {
+          tmpSX = schedXactions->data;
+          node = gnc_schedXaction_dom_tree_create( tmpSX );
+          xmlElemDump( out, NULL, node );
+          fprintf( out, "\n" );
+          xmlFreeNode( node );
+          gd->counter.schedXactions_loaded++;
+          run_callback(gd, "schedXactions");
+     } while ( (schedXactions = schedXactions->next) );
 }
 
 static void
@@ -1175,7 +1177,7 @@
       xaccGroupGetNumSubAccounts(gnc_book_get_group(book));
     gd->counter.transactions_total = gnc_book_count_transactions(book);
     gd->counter.schedXactions_total =
-      g_list_length( gnc_book_get_schedxactions(book));
+      g_list_length(gnc_book_get_schedxactions(book)->sx_list);
     gd->counter.budgets_total = qof_collection_count(
         qof_book_get_collection(book, GNC_ID_BUDGET));
 

Modified: gnucash/trunk/src/core-utils/gnc-glib-utils.c
===================================================================
--- gnucash/trunk/src/core-utils/gnc-glib-utils.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/core-utils/gnc-glib-utils.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -27,7 +27,7 @@
 
 #include "gnc-glib-utils.h"
 
-int 
+int
 safe_utf8_collate (const char * da, const char * db)
 {
   if (da && !(*da))
@@ -222,3 +222,31 @@
   gnc_utf8_strip_invalid (result);
   return result;
 }
+
+GList*
+gnc_g_list_map(GList* list, GncGMapFunc fn, gpointer user_data)
+{
+     GList *rtn = NULL;
+     for (; list != NULL; list = list->next)
+     {
+          rtn = g_list_append(rtn, (*fn)(list->data, user_data));
+     }
+     return rtn;
+}
+
+void
+gnc_g_list_cut(GList **list, GList *cut_point)
+{
+     if (list == NULL || *list == NULL)
+          return;
+
+     // if it's the first element.
+     if (cut_point->prev == NULL)
+     {
+          *list = NULL;
+          return;
+     }
+
+     cut_point->prev->next = NULL;
+     cut_point->prev = NULL;
+}

Modified: gnucash/trunk/src/core-utils/gnc-glib-utils.h
===================================================================
--- gnucash/trunk/src/core-utils/gnc-glib-utils.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/core-utils/gnc-glib-utils.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -81,7 +81,20 @@
  * caller. */
 gchar *gnc_utf8_strip_invalid_strdup (const gchar* str);
 
+typedef gpointer (*GncGMapFunc)(gpointer data, gpointer user_data);
 
+/**
+ * @return Caller-owned GList* of results of apply `fn` to `list` in order.
+ **/
+GList* gnc_g_list_map(GList* list, GncGMapFunc fn, gpointer user_data);
+
+/**
+ * Cut a GList into two parts; the {@param cut_point} is the beginning of the
+ * new list; {@param list} may need to be modified, but will be the list
+ * before the {@param cut_point}.
+ **/
+void gnc_g_list_cut(GList **list, GList *cut_point);
+
 /** @} */
 
 #endif /* GNC_GLIB_UTILS_H */

Copied: gnucash/trunk/src/doc/sx.rst (from rev 15384, gnucash/branches/sx-cleanup/src/doc/sx.rst)

Modified: gnucash/trunk/src/engine/SX-book-p.h
===================================================================
--- gnucash/trunk/src/engine/SX-book-p.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/SX-book-p.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -35,23 +35,16 @@
 #define GNC_SX_BOOK_P_H
 
 #include "qof.h"
+#include "SX-book.h"
 
 /* ====================================================================== */
 
-struct xaccSchedXactionsDef {
-	GList *sx_list;
-	gboolean sx_notsaved;
-};
+SchedXactions* gnc_collection_get_schedxactions(const QofCollection *col);
 
-void gnc_book_set_schedxactions( QofBook *book, GList *newList );
-void gnc_collection_set_schedxactions( QofCollection *col, GList *newList );
-
-
 /* Associate the given template group with a book */
 void gnc_book_set_template_group (QofBook *book, AccountGroup *templateGroup);
 void gnc_collection_set_template_group (QofCollection *col, AccountGroup *templateGroup);
 
-
 gboolean gnc_sxtt_register (void);
 
 #endif /* GNC_SX_BOOK_P_H */

Modified: gnucash/trunk/src/engine/SX-book.c
===================================================================
--- gnucash/trunk/src/engine/SX-book.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/SX-book.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -44,6 +44,7 @@
 #include "SchedXaction.h"
 #include "SX-book.h"
 #include "SX-book-p.h"
+#include "gnc-event.h"
 
 static QofLogModule log_module = GNC_MOD_SX;
 
@@ -116,7 +117,6 @@
   gnc_book_set_template_group (book, NULL);
 }
 
-
 static gboolean
 sxtg_is_dirty(const QofCollection *col)
 {
@@ -144,78 +144,45 @@
 
 /* ====================================================================== */
 
-SchedXactions *
-gnc_collection_get_schedxaction_list(const QofCollection *col)
-{
-  return qof_collection_get_data (col);
-}
-
-GList *
+SchedXactions*
 gnc_collection_get_schedxactions(const QofCollection *col)
 {
-  SchedXactions *list;
-  list = qof_collection_get_data (col);
-  if (list) return list->sx_list;
-  return NULL;
+  SchedXactions *rtn = qof_collection_get_data(col);
+  // @@assert(rtn != null);
+  return rtn;
 }
 
-GList *
+SchedXactions*
 gnc_book_get_schedxactions(QofBook *book)
 {
   QofCollection *col;
-  col = qof_book_get_collection (book, GNC_ID_SXTT);
-  return gnc_collection_get_schedxactions (col);
+  col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
+  return gnc_collection_get_schedxactions(col);
 }
 
 void
-gnc_collection_set_schedxactions( QofCollection *col, GList *newList )
+gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx)
 {
-  SchedXactions *old_list, *new_list;
-  if ( col == NULL ) return;
-
-  old_list = qof_collection_get_data (col);
-  if (old_list && old_list->sx_list == newList) 
-  {
-     /* Assume the worst, that any 'set' means the data has 
-      * changed, and needs to be saved. */
-     old_list->sx_notsaved = TRUE;
-     return;
-  }
-  
-  new_list = g_new (SchedXactions, 1);
-  new_list->sx_list = newList;
-  new_list->sx_notsaved = TRUE;
-  if (NULL == newList) new_list->sx_notsaved = FALSE;
-  
-  qof_collection_set_data (col, new_list);
-
-  g_free (old_list);
+  if (g_list_find(sxes->sx_list, sx) != NULL)
+    return;
+  sxes->sx_list = g_list_append(sxes->sx_list, sx);
+  qof_event_gen(&sxes->inst.entity, GNC_EVENT_ITEM_ADDED, (gpointer)sx);
 }
 
 void
-gnc_book_set_schedxactions( QofBook *book, GList *newList )
+gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx)
 {
-  QofCollection *col;
-  if ( book == NULL ) return;
-
-  col = qof_book_get_collection (book, GNC_ID_SXTT);
-  gnc_collection_set_schedxactions (col, newList);
+  GList *to_remove;
+  to_remove = g_list_find(sxes->sx_list, sx);
+  if (to_remove == NULL)
+    return;
+  sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove);
+  qof_event_gen(&sxes->inst.entity, GNC_EVENT_ITEM_REMOVED, (gpointer)sx);
 }
 
 /* ====================================================================== */
 /* SX-trans stuff */
 
-static void 
-sxtt_book_begin (QofBook *book)
-{
-  gnc_book_set_schedxactions (book, NULL);
-}
-
-static void 
-sxtt_book_end (QofBook *book)
-{
-  gnc_book_set_schedxactions (book, NULL);
-}
 static void
 mark_sx_clean(gpointer data, gpointer user_data)
 {
@@ -224,13 +191,28 @@
 }
 
 static void
+book_sxes_setup(QofBook *book)
+{
+     QofCollection *col;
+     SchedXactions *sxes;
+
+     col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
+     sxes = g_new (SchedXactions, 1);
+     qof_instance_init(&sxes->inst, GNC_ID_SXES, book);
+     sxes->sx_list = NULL;
+     sxes->sx_notsaved = TRUE;
+     qof_collection_set_data(col, sxes);
+}
+
+static void
 book_sxns_mark_saved(QofCollection *col)
 {
   SchedXactions *sxl;
-
-  sxl = gnc_collection_get_schedxaction_list (col);
-  if (sxl) sxl->sx_notsaved = FALSE;
-  g_list_foreach(gnc_collection_get_schedxactions(col),
+  sxl = gnc_collection_get_schedxactions(col);
+  if (!sxl)
+       return;
+  sxl->sx_notsaved = FALSE;
+  g_list_foreach(sxl->sx_list,
                  mark_sx_clean, 
                  NULL);
 }
@@ -241,10 +223,11 @@
   GList *sxlist;
   SchedXactions *sxl;
 
-  sxl = gnc_collection_get_schedxaction_list (col);
+  sxl = gnc_collection_get_schedxactions(col);
+  if (!sxl) return FALSE;
   if((sxl && sxl->sx_notsaved)) return TRUE;
  
-  for(sxlist = gnc_collection_get_schedxactions(col);
+  for(sxlist = sxl->sx_list;
       sxlist != NULL;
       sxlist = g_list_next(sxlist))
   {
@@ -256,6 +239,21 @@
 
   return FALSE;
 }
+
+static QofObject sxes_object_def =
+{
+  interface_version: QOF_OBJECT_VERSION,
+  e_type:            GNC_ID_SXES,
+  type_label:        "Scheduled Transactions List",
+  create:            NULL,
+  book_begin:        book_sxes_setup,
+  book_end:          NULL,
+  is_dirty:          book_sxlist_notsaved,
+  mark_clean:        book_sxns_mark_saved,
+  foreach:           NULL,
+  printable:         NULL,
+  version_cmp:       NULL
+};
   
 static QofObject sxtt_object_def = 
 {
@@ -263,10 +261,10 @@
   e_type:            GNC_ID_SXTT,
   type_label:        "Scheduled Transaction Templates",
   create:            NULL,
-  book_begin:        sxtt_book_begin,
-  book_end:          sxtt_book_end,
-  is_dirty:          book_sxlist_notsaved,
-  mark_clean:        book_sxns_mark_saved,
+  book_begin:        NULL,
+  book_end:          NULL,
+  is_dirty:          NULL,
+  mark_clean:        NULL,
   foreach:           NULL,
   printable:         NULL,
   version_cmp:       NULL,
@@ -275,8 +273,11 @@
 gboolean 
 gnc_sxtt_register (void)
 {
-  return qof_object_register (&sxtg_object_def);
-  return qof_object_register (&sxtt_object_def);
+  if (!qof_object_register(&sxes_object_def))
+    return FALSE;
+  if (!qof_object_register(&sxtg_object_def))
+    return FALSE;
+  return qof_object_register(&sxtt_object_def);
 }
 
 GList*
@@ -284,7 +285,7 @@
 {
   GList *rtn = NULL;
   const GUID *acct_guid = xaccAccountGetGUID(acct);
-  GList *sx_list = gnc_book_get_schedxactions(book);
+  GList *sx_list = gnc_book_get_schedxactions(book)->sx_list;
   for (; sx_list != NULL; sx_list = sx_list->next)
   {
     SchedXaction *sx = (SchedXaction*)sx_list->data;

Modified: gnucash/trunk/src/engine/SX-book.h
===================================================================
--- gnucash/trunk/src/engine/SX-book.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/SX-book.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -30,6 +30,7 @@
  * @brief Anchor Scheduled Transaction info in a book.
  *        See src/doc/books.txt for design overview.
  * @author Copyright (c) 2003 Linas Vepstas <linas at linas.org>
+ * @author Copyright (c) 2006 Joshua Sled <jsled at asynchronous.org>
  * 
  * XXX currently, this is crufty, it should be modified to use
  * entities a bit more whole-heartedly than it does.
@@ -39,17 +40,28 @@
 #define GNC_SX_BOOK_H
 
 #include <glib.h>
+#include "SchedXaction.h"
 #include "qof.h"
 
 typedef struct xaccSchedXactionsDef SchedXactions;
 
-SchedXactions * gnc_collection_get_schedxaction_list(const QofCollection *col);
-GList * gnc_collection_get_schedxactions(const QofCollection *col);
-GList * gnc_book_get_schedxactions(QofBook *book);
+struct xaccSchedXactionsDef {
+  QofInstance inst;
+  GList* sx_list;
+  gboolean sx_notsaved;
+};
 
+#define GNC_IS_SXES(obj)  (QOF_CHECK_TYPE((obj), GNC_ID_SXES))
+#define GNC_SXES(obj)     (QOF_CHECK_CAST((obj), GNC_ID_SXES, SchedXactions))
+
+SchedXactions* gnc_book_get_schedxactions(QofBook* book);
+
+void gnc_sxes_add_sx(SchedXactions* sxes, SchedXaction* sx);
+void gnc_sxes_del_sx(SchedXactions* sxes, SchedXaction* sx);
+
 /** Returns the template group from the book. **/
-AccountGroup * gnc_book_get_template_group(QofBook *book);
-AccountGroup * gnc_collection_get_template_group(const QofCollection *col);
+AccountGroup* gnc_book_get_template_group(QofBook* book);
+AccountGroup* gnc_collection_get_template_group(const QofCollection *col);
 
 /** @return The list of SXes which reference the given Account. Caller should free this list. **/
 GList* gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct);

Modified: gnucash/trunk/src/engine/SchedXaction.c
===================================================================
--- gnucash/trunk/src/engine/SchedXaction.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/SchedXaction.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -192,13 +192,18 @@
   PERR ("Failed to commit: %d", errcode);
 }
 
-static void noop (QofInstance *inst) {}
+static void commit_done(QofInstance *inst)
+{
+  qof_event_gen (&inst->entity, QOF_EVENT_MODIFY, NULL);
+}
 
+static void noop(QofInstance *inst) {}
+
 void
 gnc_sx_commit_edit (SchedXaction *sx)
 {
   if (!qof_commit_edit (QOF_INSTANCE(sx))) return;
-  qof_commit_edit_part2 (&sx->inst, commit_err, noop, noop);
+  qof_commit_edit_part2 (&sx->inst, commit_err, commit_done, noop);
 }
 
 /* ============================================================ */
@@ -375,8 +380,10 @@
                                gboolean *outAutoCreate,
                                gboolean *outNotify )
 {
-  *outAutoCreate = sx->autoCreateOption;
-  *outNotify     = sx->autoCreateNotify;
+  if (outAutoCreate != NULL)
+    *outAutoCreate = sx->autoCreateOption;
+  if (outNotify != NULL)
+    *outNotify     = sx->autoCreateNotify;
   return;
 }
 

Modified: gnucash/trunk/src/engine/SchedXaction.h
===================================================================
--- gnucash/trunk/src/engine/SchedXaction.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/SchedXaction.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -42,6 +42,9 @@
 #include "FreqSpec.h"
 #include "gnc-engine.h"
 
+#define GNC_IS_SX(obj)  (QOF_CHECK_TYPE((obj), GNC_ID_SCHEDXACTION))
+#define GNC_SX(obj)     (QOF_CHECK_CAST((obj), GNC_ID_SCHEDXACTION, SchedXaction))
+
 /**
  * The SchedXaction data.
 */
@@ -196,7 +199,7 @@
 
  This is a date-sorted state-data instance list.
  The list should not be modified by the caller; use the
- gnc_sx_{add,remove}_defer_instance() functions to modifiy the list.
+ gnc_sx_{add,remove}_defer_instance() functions to modify the list.
 */
 GList *gnc_sx_get_defer_instances( SchedXaction *sx );
 

Modified: gnucash/trunk/src/engine/gnc-engine.h
===================================================================
--- gnucash/trunk/src/engine/gnc-engine.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/gnc-engine.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -98,8 +98,9 @@
 #define GNC_ID_PRICE          "Price"
 #define GNC_ID_PRICEDB        "PriceDB"
 #define GNC_ID_SPLIT          "Split"
+#define GNC_ID_BUDGET         "Budget"
 #define GNC_ID_SCHEDXACTION   "SchedXaction"
-#define GNC_ID_BUDGET         "Budget"
+#define GNC_ID_SXES           "SchedXactions"
 #define GNC_ID_SXTG           "SXTGroup"
 #define GNC_ID_SXTT           "SXTTrans"
 #define GNC_ID_TRANS          "Trans"

Modified: gnucash/trunk/src/engine/test/test-freq-spec.c
===================================================================
--- gnucash/trunk/src/engine/test/test-freq-spec.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/test/test-freq-spec.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -559,6 +559,50 @@
    xaccFreqSpecFree(fs);
 }
 
+static void
+test_monthly_31st_bug_104844()
+{
+     gchar date_buf[128];
+     GDate start, next, expected;
+     FreqSpec *fs = xaccFreqSpecMalloc(book);
+
+     g_date_clear(&next, 1);
+
+     g_date_clear(&start, 1);
+     g_date_set_dmy(&start, 31, 1, 2003);
+     xaccFreqSpecSetMonthly(fs, &start, 1);
+
+     //g_date_add_days(&start, 1);
+     xaccFreqSpecGetNextInstance(fs, &start, &next);
+     g_date_clear(&expected, 1);
+     g_date_set_dmy(&expected, 28, 2, 2003);
+     g_date_strftime(date_buf, 128, "%c", &next);
+     do_test(g_date_compare(&expected, &next) == 0, date_buf);
+
+     start = next;
+     xaccFreqSpecGetNextInstance(fs, &start, &next);
+     g_date_set_dmy(&expected, 31, 3, 2003);
+     g_date_strftime(date_buf, 128, "%c", &next);
+     do_test(g_date_compare(&expected, &next) == 0, date_buf);
+
+     // test...
+     g_date_set_dmy(&start, 31, 1, 2003);
+     xaccFreqSpecSetMonthly(fs, &start, 1);
+     g_date_set_dmy(&start, 31, 1, 2007);
+     xaccFreqSpecGetNextInstance(fs, &start, &next);
+     g_date_set_dmy(&expected, 28, 2, 2007);
+     g_date_strftime(date_buf, 128, "%c", &next);
+     do_test(g_date_compare(&expected, &next) == 0, date_buf);
+
+     start = next;
+     xaccFreqSpecGetNextInstance(fs, &start, &next);
+     g_date_set_dmy(&expected, 31, 3, 2007);
+     g_date_strftime(date_buf, 128, "%c", &next);
+     do_test(g_date_compare(&expected, &next) == 0, date_buf);
+
+     xaccFreqSpecFree(fs);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -568,6 +612,9 @@
     g_return_val_if_fail(cashobjects_register(), -1);
     session = qof_session_new ();
     book = qof_session_get_book(session);
+
+    test_monthly_31st_bug_104844();
+
     test_once();
     test_caseA();
     test_daily();
@@ -575,6 +622,7 @@
     test_monthly();
     test_month_relative();
     test_composite();
+
     print_test_results();
     qof_session_end(session);
     qof_close();

Modified: gnucash/trunk/src/engine/test/test-transaction-voiding.c
===================================================================
--- gnucash/trunk/src/engine/test/test-transaction-voiding.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/test/test-transaction-voiding.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -193,14 +193,14 @@
 int
 main (int argc, char **argv)
 {
-	qof_init();
-	if(cashobjects_register())
-	{
-  xaccLogDisable ();
-  run_test ();
-  success("transaction voiding seems OK");
-  print_test_results();
-	}
-	qof_close();
+  qof_init();
+  if(cashobjects_register())
+    {
+      xaccLogDisable ();
+      run_test ();
+      success("transaction voiding seems OK");
+      print_test_results();
+    }
+  qof_close();
   return get_rv();
 }

Modified: gnucash/trunk/src/engine/test-core/test-engine-stuff.c
===================================================================
--- gnucash/trunk/src/engine/test-core/test-engine-stuff.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/test-core/test-engine-stuff.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -32,8 +32,12 @@
 #include "Group.h"
 #include "GroupP.h"
 #include "gnc-engine.h"
+#include "gnc-session.h"
 #include "Transaction.h"
 #include "TransactionP.h"
+#include "FreqSpec.h"
+#include "SchedXaction.h"
+#include "SX-book.h"
 
 #include "test-engine-stuff.h"
 #include "test-stuff.h"
@@ -2160,3 +2164,61 @@
 
   return q;
 }
+
+static FreqSpec*
+daily_freq(GDate* start, int multiplier)
+{
+     QofBook *book = qof_session_get_book(gnc_get_current_session());
+     FreqSpec *freq = xaccFreqSpecMalloc(book);
+     xaccFreqSpecSetDaily(freq, start, multiplier);
+     xaccFreqSpecSetUIType(freq, UIFREQ_DAILY);
+     return freq;
+}
+
+static FreqSpec*
+once_freq(GDate *when)
+{
+     QofBook *book = qof_session_get_book(gnc_get_current_session());
+     FreqSpec *freq = xaccFreqSpecMalloc(book);
+     xaccFreqSpecSetOnceDate(freq, when);
+     xaccFreqSpecSetUIType(freq, UIFREQ_ONCE);
+     return freq;
+}
+
+static SchedXaction*
+add_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur, FreqSpec *fs)
+{
+     QofBook *book = qof_session_get_book(gnc_get_current_session());
+     SchedXaction *sx = xaccSchedXactionMalloc(book);
+     xaccSchedXactionSetName(sx, name);
+     xaccSchedXactionSetStartDate(sx, start);
+     if (end != NULL)
+          xaccSchedXactionSetEndDate(sx, end);
+     if (last_occur != NULL)
+          xaccSchedXactionSetLastOccurDate(sx, last_occur);
+     xaccSchedXactionSetFreqSpec(sx, fs);
+
+     gnc_sxes_add_sx(gnc_book_get_schedxactions(book), sx);
+
+     return sx;
+}
+
+SchedXaction*
+add_daily_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur)
+{
+     return add_sx(name, start, end, last_occur, daily_freq(start, 1));
+}
+
+SchedXaction*
+add_once_sx(gchar *name, GDate *when)
+{
+     return add_sx(name, when, NULL, NULL, once_freq(when));
+}
+
+void
+remove_sx(SchedXaction *sx)
+{
+     QofBook *book = qof_session_get_book(gnc_get_current_session());
+     SchedXactions *sxes = gnc_book_get_schedxactions(book);
+     gnc_sxes_del_sx(sxes, sx);
+}

Modified: gnucash/trunk/src/engine/test-core/test-engine-stuff.h
===================================================================
--- gnucash/trunk/src/engine/test-core/test-engine-stuff.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/engine/test-core/test-engine-stuff.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -11,6 +11,7 @@
 #include "qof.h"
 #include "Query.h"
 #include "gnc-pricedb.h"
+#include "SchedXaction.h"
 
 Timespec* get_random_timespec(void);
 void random_timespec_zero_nsec (gboolean zero_nsec);
@@ -88,4 +89,8 @@
 void make_random_changes_to_book (QofBook *book);
 void make_random_changes_to_session (QofSession *session);
 
+SchedXaction* add_daily_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur);
+SchedXaction* add_once_sx(gchar *name, GDate *when);
+void remove_sx(SchedXaction *sx);
+
 #endif

Modified: gnucash/trunk/src/gnome/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -29,11 +29,11 @@
   dialog-price-edit-db.c \
   dialog-print-check.c \
   dialog-progress.c \
+  dialog-sx-editor.c \
   dialog-sx-from-trans.c \
-  dialog-sxsincelast.c \
+  dialog-sx-since-last-run.c \
   dialog-tax-info.c \
   dialog-userpass.c \
-  dialog-scheduledxaction.c \
   druid-acct-period.c \
   druid-hierarchy.c \
   druid-merge.c \
@@ -45,8 +45,10 @@
   gnc-plugin-register.c \
   gnc-plugin-page-account-tree.c \
   gnc-plugin-page-budget.c \
+  gnc-plugin-page-sx-list.c \
   gnc-plugin-page-register.c \
   gnc-split-reg.c \
+  gnc-sx-list-tree-model-adapter.c \
   lot-viewer.c \
   reconcile-list.c \
   top-level.c \
@@ -67,9 +69,9 @@
   dialog-new-user.h \
   dialog-print-check.h \
   dialog-progress.h \
+  dialog-sx-editor.h \
   dialog-sx-from-trans.h \
-  dialog-sxsincelast.h \
-  dialog-scheduledxaction.h \
+  dialog-sx-since-last-run.h \
   druid-acct-period.h \
   druid-hierarchy.h \
   druid-merge.h \
@@ -81,8 +83,10 @@
   gnc-plugin-register.h \
   gnc-plugin-page-account-tree.h \
   gnc-plugin-page-budget.h \
+  gnc-plugin-page-sx-list.h \
   gnc-plugin-page-register.h \
   gnc-split-reg.h \
+  gnc-sx-list-tree-model-adapter.h \
   lot-viewer.h \
   reconcile-list.h \
   top-level.h \

Deleted: gnucash/trunk/src/gnome/dialog-scheduledxaction.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-scheduledxaction.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/dialog-scheduledxaction.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,2595 +0,0 @@
-/********************************************************************\
- * dialog-scheduledxaction.c : dialog for scheduled transaction     *
- *    list and editor                                               *
- * Copyright (C) 2001,2002,2006 Joshua Sled <jsled at asynchronous.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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include "glib-compat.h"
-#include <locale.h>
-#include <time.h>
-
-#include "qof.h"
-#include "gnc-book.h"
-#include "Account.h"
-#include "FreqSpec.h"
-#include "SchedXaction.h"
-#include "SX-book.h"
-#include "SX-book-p.h"
-#include "dialog-preferences.h"
-#include "dialog-scheduledxaction.h"
-#include "dialog-utils.h"
-#include "gnc-book.h"
-#include "gnc-component-manager.h"
-#include "gnc-date.h"
-#include "gnc-date-edit.h"
-#include "gnc-dense-cal.h"
-#include "gnc-embedded-window.h"
-#include "gnc-engine.h"
-#include "gnc-frequency.h"
-#include "gnc-gconf-utils.h"
-#include "gnc-gui-query.h"
-#include "gnc-hooks.h"
-#include "gnc-ledger-display.h"
-#include "gnc-plugin-page.h"
-#include "gnc-plugin-page-register.h"
-#include "gnc-ui.h"
-#include "gnc-ui-util.h"
-#include "gnucash-sheet.h"
-
-#include "gnc-split-reg.h"
-
-/* FIXME: temp until variable-related-stuff settled. */
-#include "dialog-sxsincelast.h"
-
-#ifdef HAVE_LANGINFO_D_FMT
-#include <langinfo.h>
-#endif
-
-static QofLogModule log_module = GNC_MOD_SX;
-
-static gint _sx_engine_event_handler_id = -1;
-
-#define SX_LIST_GCONF_SECTION "dialogs/scheduled_trans/transaction_list"
-#define SX_LIST_WIN_PREFIX "sx_list_win"
-#define SX_LIST_GLADE_NAME "Scheduled Transaction List"
-#define SX_LIST "sched_xact_list"
-#define SX_LIST_EDIT_BUTTON "edit_button"
-#define SX_LIST_DELETE_BUTTON "delete_button"
-#define SX_LIST_UPCOMING_BOX "upcoming_cal_hbox"
-#define SX_EDITOR_GLADE_NAME "Scheduled Transaction Editor"
-
-#define SXED_WIN_PREFIX "sx_editor_win"
-#define SXED_NAME_ENTRY "sxe_name"
-#define SXED_LAST_OCCUR_LABEL "last_occur_label"
-#define AUTOCREATE_OPT "autocreate_opt"
-#define NOTIFY_OPT "notify_opt"
-#define ADVANCE_OPT "advance_opt"
-#define ADVANCE_DAYS_SPIN "advance_days"
-#define REMIND_OPT "remind_opt"
-#define REMIND_DAYS_SPIN "remind_days"
-#define END_DATE_BOX "end_date_hbox"
-#define END_SPIN "end_spin"
-#define REMAIN_SPIN "remain_spin"
-
-#define SX_GLADE_FILE "sched-xact.glade"
-
-#define END_NEVER_OPTION 0
-#define END_DATE_OPTION  1
-#define NUM_OCCUR_OPTION 2
-
-#define NUM_LEDGER_LINES_DEFAULT 6
-
-#define EX_CAL_NUM_MONTHS 6
-#define EX_CAL_MO_PER_COL 2
-
-#define GNC_D_WIDTH 25
-#define GNC_D_BUF_WIDTH 26
-
-/** Datatypes ***********************************************************/
-
-typedef enum _EndTypeEnum {
-        END_NEVER,
-        END_DATE,
-        END_OCCUR,
-} EndType;
-
-/* Runtime/dialog information about a particular SX. */
-typedef struct _SxRuntimeInfo
-{
-        SchedXaction *sx;
-        // the gnc-dense-cal mark-tag
-        gint         markTag;
-        // which row in the GTK CList this SX is.
-        gint         row;
-} SxRuntimeInfo;
-
-struct _SchedXactionDialog
-{
-        GtkWidget   *dialog;
-        GladeXML    *gxml;
-        GncDenseCal *gdcal;
-        GHashTable  *sxData;
-
-        gint        currentSortCol;
-        GtkSortType currentSortType;
-};
-
-struct _SchedXactionEditorDialog
-{
-        GladeXML *gxml;
-        GtkWidget *dialog;
-        SchedXactionDialog *sxd;
-        SchedXaction *sx;
-        /* If this is a new scheduled transaction or not. */
-        int newsxP;
-
-        /* The various widgets in the dialog */
-        GNCLedgerDisplay *ledger;
-
-        GNCFrequency *gncfreq;
-        GncDenseCal *example_cal;
-        GDate **cal_marks;
-        gint markId;
-
-        GtkEditable *nameEntry;
-
-        GtkLabel *lastOccurLabel;
-
-        GtkToggleButton *autocreateOpt;
-        GtkToggleButton *notifyOpt;
-        GtkToggleButton *advanceOpt;
-        GtkSpinButton *advanceSpin;
-        GtkToggleButton *remindOpt;
-        GtkSpinButton *remindSpin;
-
-        GtkToggleButton *optEndDate;
-        GtkToggleButton *optEndNone;
-        GtkToggleButton *optEndCount;
-        GtkEntry *endCountSpin;
-        GtkEntry *endRemainSpin;
-        GNCDateEdit *endDateEntry;
-
-        char *sxGUIDstr;
-
-        GncEmbeddedWindow *embed_window;
-	GncPluginPage *plugin_page;
-};
-
-/** Prototypes **********************************************************/
-
-static void putSchedXactionInDialog( gpointer data, gpointer user_data );
-
-static void generate_instances( SchedXaction *sx,
-                                GDate *end, GList **instanceList );
-
-static void schedXact_populate( SchedXactionDialog * );
-static void schedXact_editor_create_freq_sel( SchedXactionEditorDialog *sxed );
-static void schedXact_editor_create_ledger( SchedXactionEditorDialog *sxed );
-static void schedXact_editor_populate( SchedXactionEditorDialog * );
-
-static void sxd_close_handler ( gpointer user_data );
-
-static void new_button_clicked( GtkButton *b, gpointer d );
-static void edit_button_clicked( GtkButton *b, gpointer d );
-static void delete_button_clicked( GtkButton *b, gpointer d );
-static void close_button_clicked( GtkButton *b, gpointer d );
-static void gnc_sxl_record_size( SchedXactionDialog *sxd );
-static void gnc_sxd_row_click_handler( GtkCList *clist,
-                                       gint col,
-                                       gpointer ud );
-static void gnc_sxd_set_sort_compare( GtkCList *cl, gint col );
-static gint gnc_sxd_clist_compare_sx_name( GtkCList *cl,
-                                           gconstpointer a,
-                                           gconstpointer b );
-static gint gnc_sxd_clist_compare_sx_freq( GtkCList *cl,
-                                           gconstpointer a,
-                                           gconstpointer b );
-static gint gnc_sxd_clist_compare_sx_next_occur( GtkCList *cl,
-                                                 gconstpointer a,
-                                                 gconstpointer b );
-
-static void gnc_sxed_record_size( SchedXactionEditorDialog *sxed );
-static void gnc_sxed_get_widgets( SchedXactionEditorDialog *sxed );
-static void endgroup_rb_toggled( GtkButton *b, gpointer d );
-static void set_endgroup_toggle_states( SchedXactionEditorDialog *sxed, EndType t );
-static void advance_toggle( GtkButton *b, SchedXactionEditorDialog *sxed );
-static gboolean gnc_sxed_check_consistent( SchedXactionEditorDialog *sxed );
-static gboolean gnc_sxed_check_changed( SchedXactionEditorDialog *sxed );
-static void free_keys_and_numerics_ea( gpointer key,
-                                       gpointer value,
-                                       gpointer user_data );
-static void gnc_sxed_save_sx( SchedXactionEditorDialog *sxed );
-static void gnc_sxed_freq_changed( GNCFrequency *gf, gpointer ud );
-static void sxed_excal_update_adapt( GtkObject *o, gpointer ud );
-static void gnc_sxed_update_cal( SchedXactionEditorDialog *sxed );
-
-static void gnc_sxed_reg_check_close(SchedXactionEditorDialog *sxed);
-
-static gint sxed_close_event( GtkDialog *dlg, gpointer ud );
-
-static gboolean sxed_confirmed_cancel( SchedXactionEditorDialog *sxed );
-
-static gboolean editor_component_sx_equality( gpointer find_data,
-                                              gpointer user_data );
-
-static SxRuntimeInfo* _new_sx_runtime_info( SchedXaction *sx );
-static void _clear_runtime_info_row( gpointer key, gpointer value, gpointer user_data );
-
-
-static GtkActionEntry gnc_sxed_menu_entries [] =
-{
-	{ "EditAction", NULL, N_("_Edit"), NULL, NULL, NULL },
-	{ "TransactionAction", NULL, N_("_Transaction"), NULL, NULL, NULL },
-	{ "ViewAction", NULL, N_("_View"), NULL, NULL, NULL },
-	{ "ActionsAction", NULL, N_("_Actions"), NULL, NULL, NULL },
-};
-static guint gnc_sxed_menu_n_entries = G_N_ELEMENTS (gnc_sxed_menu_entries);
-
-/** Implementations *****************************************************/
-
-static
-void
-sxd_close_handler (gpointer user_data)
-{
-        SchedXactionDialog        *sxd = user_data;
-        gnc_sxl_record_size(sxd);
-        gtk_widget_hide(sxd->dialog);
-        gtk_widget_destroy(sxd->dialog);
-}
-
-static
-void
-_clear_runtime_info_row( gpointer key, gpointer value, gpointer user_data )
-{
-        SxRuntimeInfo *sxri;
-        sxri = (SxRuntimeInfo*)value;
-        sxri->row = -1;
-}
-
-void
-gnc_sxd_list_refresh( SchedXactionDialog *sxd )
-{
-        GList *sxList;
-        GtkCList *cl;
-	GtkWidget *widget;
-
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_EDIT_BUTTON );
-	gtk_widget_set_sensitive(widget, FALSE);
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_DELETE_BUTTON );
-	gtk_widget_set_sensitive(widget, FALSE);
-
-        /* Update the clist. */
-        cl = GTK_CLIST( glade_xml_get_widget( sxd->gxml, SX_LIST ) );
-        gtk_clist_freeze( cl );
-
-        gtk_clist_clear( cl );
-        // Also, flush the row-numbers from storage
-        g_hash_table_foreach( sxd->sxData, _clear_runtime_info_row, NULL );
-        sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
-        g_list_foreach( sxList, putSchedXactionInDialog, sxd );
-
-        gtk_clist_thaw( cl );
-}
-
-static
-void
-sxed_close_handler ( gpointer user_data )
-{
-        SchedXactionEditorDialog *sxed = user_data;
-
-        gnc_sxed_reg_check_close( sxed );
-        gnc_sxed_record_size( sxed );
-        gtk_widget_destroy( sxed->dialog );
-        /* The data will be cleaned up in the destroy handler. */
-}
-
-static
-void
-close_button_clicked( GtkButton *b, gpointer d )
-{
-        sxd_close_handler( d );
-}
-
-/**
- * @return TRUE if the user does want to cancel, FALSE if not.  If TRUE is
- * returned, the register's changes have been cancelled.
- **/
-static
-gboolean
-sxed_confirmed_cancel( SchedXactionEditorDialog *sxed )
-{
-        SplitRegister *reg;
-
-        reg = gnc_ledger_display_get_split_register( sxed->ledger );
-        /* check for changes */
-        if ( gnc_sxed_check_changed( sxed ) ) {
-                const char *sx_changed_msg =
-                        _( "This SX has changed; are you "
-                           "sure you want to cancel?" );
-                if (!gnc_verify_dialog(sxed->dialog, FALSE, sx_changed_msg)) {
-                        return FALSE;
-                }
-        }
-        /* cancel ledger changes */
-        gnc_split_register_cancel_cursor_trans_changes( reg );
-        return TRUE;
-}
-
-static
-void
-editor_cancel_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
-{
-        /* close */
-        gnc_close_gui_component_by_data( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
-                                         sxed );
-}
-
-static
-void
-editor_help_button_clicked(GtkButton *b, SchedXactionEditorDialog *sxed)
-{
-	gnc_gnome_help(HF_HELP, HL_SXEDITOR);
-}
-
-static void
-set_var_to_random_value( gpointer key, gpointer value, gpointer ud )
-{
-        if ( !value ) {
-                value = g_new0( gnc_numeric, 1 );
-        }
-        *(gnc_numeric*)value =
-                double_to_gnc_numeric( rand() + 2, 1,
-                                       GNC_NUMERIC_RND_MASK
-                                       | GNC_RND_FLOOR );
-        g_hash_table_insert( ud, key, value );
-}
-
-static
-void
-free_keys_and_numerics_ea( gpointer key, gpointer val, gpointer ud )
-{
-        g_assert( key );
-        g_assert( val );
-        g_free( (gchar*)key );
-        g_free( (gnc_numeric*)val );
-}
-
-static
-void
-editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
-{
-        GNCBook *book;
-        GList *sxList;
-
-        if ( !gnc_sxed_check_consistent( sxed ) ) 
-                return;
-
-        gnc_sxed_save_sx( sxed );
-
-        /* add to list */
-        if ( sxed->newsxP ) {
-                book = gnc_get_current_book ();
-                sxList = gnc_book_get_schedxactions( book );
-                sxList = g_list_append( sxList, sxed->sx );
-                gnc_book_set_schedxactions( book, sxList );
-                sxed->newsxP = FALSE;
-        }
-
-        /* update lists */
-        /* We now do this by getting the list of SX Lists and updating them
-           [if they exist].  Otherwise, our pointer to our SXD might not be
-           valid; see Bug#103629. */
-        {
-                GList *listDialogs, *ldIter;
-                listDialogs =
-                        gnc_find_gui_components( DIALOG_SCHEDXACTION_CM_CLASS,
-                                                 NULL, NULL );
-                for ( ldIter = listDialogs;
-                      ldIter != NULL;
-                      ldIter = ldIter->next )
-                {
-                        gnc_sxd_list_refresh( (SchedXactionDialog*)ldIter
-                                              ->data );
-                }
-                if ( listDialogs != NULL )
-                {
-                        g_list_free( listDialogs );
-                }
-        }
-
-        /* cleanup */
-        gnc_close_gui_component_by_data( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
-                                         sxed );
-}
-
-/**
- * Checks to see if the SX has been modified from it's previously-saved
- * state.
- * @return TRUE if this is a 'new' SX, or if the SX has changed from it's
- *   previous configuration.
- **/
-static
-gboolean
-gnc_sxed_check_changed( SchedXactionEditorDialog *sxed )
-{
-        if ( sxed->newsxP )
-                return TRUE;
-
-        /* name */
-        {
-                char *name;
-
-                name = gtk_editable_get_chars( GTK_EDITABLE(sxed->nameEntry), 0, -1 );
-                if ( strlen(name) == 0 ) {
-                        return TRUE;
-                        
-                }
-                if ( (xaccSchedXactionGetName(sxed->sx) == NULL)
-                     || (strcmp( xaccSchedXactionGetName(sxed->sx),
-                                 name ) != 0) ) {
-                        return TRUE;
-                }
-        }
-
-        /* end options */
-        {
-                /* dialog says... no end */
-                if ( gtk_toggle_button_get_active( sxed->optEndNone ) ) {
-                        if ( xaccSchedXactionHasEndDate(sxed->sx)
-                             || xaccSchedXactionHasOccurDef(sxed->sx) ) {
-                                return TRUE;
-                        }
-                }
-
-                /* dialog says... end date */
-                if ( gtk_toggle_button_get_active( sxed->optEndDate ) ) {
-                        GDate sxEndDate, dlgEndDate;
-
-                        if ( ! xaccSchedXactionHasEndDate( sxed->sx ) ) {
-                                return TRUE;
-                        }
-                        sxEndDate = *xaccSchedXactionGetEndDate( sxed->sx );
-                        g_date_set_time_t( &dlgEndDate,
-					   gnc_date_edit_get_date( sxed->
-								   endDateEntry ) );
-
-                        if ( g_date_compare( &sxEndDate, &dlgEndDate ) != 0 ) {
-                                return TRUE;
-                        }
-                }
-
-                /* dialog says... num occur */
-                if ( gtk_toggle_button_get_active( sxed->optEndCount ) ) {
-                        gint sxNumOccur, sxNumRem, dlgNumOccur, dlgNumRem;
-
-                        if ( ! xaccSchedXactionGetNumOccur( sxed->sx ) ) {
-                                return TRUE;
-                        }
-
-			dlgNumOccur  =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endCountSpin) );
-
-			dlgNumRem =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endRemainSpin) );
-
-                        sxNumOccur = xaccSchedXactionGetNumOccur( sxed->sx );
-                        sxNumRem = xaccSchedXactionGetRemOccur( sxed->sx );
-
-                        if ( (dlgNumOccur != sxNumOccur)
-                             || (dlgNumRem != sxNumRem) ) {
-                                return TRUE;
-                        }
-                }
-        }
-
-        /* SX options [autocreate, notify, reminder, advance] */
-        {
-                gboolean dlgAutoCreate, dlgNotify, sxAutoCreate, sxNotify;
-                gint dlgAdvance, sxAdvance;
-                gint dlgRemind, sxRemind;
-
-                dlgAutoCreate =
-                        gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sxed->
-                                                                        autocreateOpt) );
-                dlgNotify =
-                        gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sxed->
-                                                                        notifyOpt) );
-
-                xaccSchedXactionGetAutoCreate( sxed->sx, &sxAutoCreate, &sxNotify );
-                if ( ! ((dlgAutoCreate == sxAutoCreate)
-                        && (dlgNotify == sxNotify)) ) {
-                        return TRUE;
-                }
-
-                dlgAdvance = 0;
-                if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sxed->advanceOpt) ) ) {
-                        dlgAdvance =
-                                gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(sxed->
-                                                                                  advanceSpin) );
-                }
-                sxAdvance = xaccSchedXactionGetAdvanceCreation( sxed->sx );
-                if ( dlgAdvance != sxAdvance ) {
-                        return TRUE;
-                }
-
-                dlgRemind = 0;
-                if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sxed->remindOpt) ) ) {
-                        dlgRemind =
-                                gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(sxed->remindSpin) );
-                }
-                sxRemind = xaccSchedXactionGetAdvanceReminder( sxed->sx );
-                if ( dlgRemind != sxRemind ) {
-                        return TRUE;
-                }
-        }
-
-        /* FS, startdate */
-        {
-                FreqSpec *dlgFS, *sxFS;
-                GDate dlgStartDate, sxStartDate;
-                GString *dlgFSstr, *sxFSstr;
-                gboolean fsStrCmpResult;
-
-                dlgFS = xaccFreqSpecMalloc( gnc_get_current_book() );
-                /* save gncFreq data */
-                gnc_frequency_save_state( sxed->gncfreq, dlgFS, &dlgStartDate );
-                dlgFSstr = g_string_sized_new( 16 );
-                xaccFreqSpecGetFreqStr( dlgFS, dlgFSstr );
-                /* get SX startdate/fs data */
-                sxStartDate = *xaccSchedXactionGetStartDate( sxed->sx );
-                sxFS = xaccSchedXactionGetFreqSpec( sxed->sx );
-                sxFSstr = g_string_sized_new( 16 );
-                xaccFreqSpecGetFreqStr( sxFS, sxFSstr );
-                /* compare */
-
-                fsStrCmpResult = /* lame version of comparison */
-                        (strcmp( dlgFSstr->str, sxFSstr->str) != 0);
-                g_string_free( dlgFSstr, TRUE );
-                g_string_free( sxFSstr, TRUE );
-                xaccFreqSpecFree( dlgFS );
-
-                if ( (g_date_compare(&dlgStartDate, &sxStartDate) != 0)
-                     ||  fsStrCmpResult ) {
-                        return TRUE;
-                }
-        }
-
-        /* template transactions */
-        {
-                SplitRegister *sr =
-                        gnc_ledger_display_get_split_register( sxed->ledger );
-
-                if ( gnc_split_register_changed( sr ) ) {
-                        return TRUE;
-                }
-        }
-        return FALSE;
-}
-
-
-/**
- * Holds the credit- and debit-sum for a given Transaction, as used in
- * gnc_sxed_check_consistent.
- **/
-typedef struct _txnCreditDebitSums {
-  gnc_numeric creditSum;
-  gnc_numeric debitSum;
-} txnCreditDebitSums;
-
-static
-void
-set_sums_to_zero( gpointer key,
-                  gpointer val,
-                  gpointer ud )
-{
-  txnCreditDebitSums *tcds = (txnCreditDebitSums*)val;
-  tcds->creditSum = gnc_numeric_zero();
-  tcds->debitSum  = gnc_numeric_zero();
-}
-
-static
-void
-free_sums( gpointer key,
-           gpointer val,
-           gpointer ud )
-{
-  txnCreditDebitSums *tcds = (txnCreditDebitSums*)val;
-  g_free( tcds );
-}
-
-static
-void
-check_credit_debit_balance( gpointer key,
-                            gpointer val,
-                            gpointer ud )
-{
-        txnCreditDebitSums *tcds = (txnCreditDebitSums*)val;
-        gboolean *unbalanced = (gboolean*)ud;
-        *unbalanced |= !(gnc_numeric_zero_p(
-                                 gnc_numeric_sub_fixed( tcds->debitSum,
-                                                        tcds->creditSum ) ));
-#if GNC_DEBUG
-
-        if ( gnc_numeric_zero_p( gnc_numeric_sub_fixed( tcds->debitSum,
-                                                        tcds->creditSum ) ) ) {
-                DEBUG( "%.8x | true [%s - %s = %s]",
-                        (unsigned int)key,
-                        gnc_numeric_to_string( tcds->debitSum ),
-                        gnc_numeric_to_string( tcds->creditSum ),
-                        gnc_numeric_to_string(gnc_numeric_sub_fixed( tcds->debitSum,
-                                                                     tcds->creditSum )) );
-        } else {
-                DEBUG( "%.8x | false [%s - %s = %s]",
-                        (unsigned int)key,
-                        gnc_numeric_to_string( tcds->debitSum ),
-                        gnc_numeric_to_string( tcds->creditSum ),
-                        gnc_numeric_to_string(gnc_numeric_sub_fixed( tcds->debitSum,
-                                                                     tcds->creditSum )) );
-        }
-#endif /* GNC_DEBUG */
-}
-
-/**
- * Checks to make sure that the SX is in a reasonable state to save.
- * @return true if checks out okay, false otherwise.
- **/
-static
-gboolean
-gnc_sxed_check_consistent( SchedXactionEditorDialog *sxed )
-{
-        gboolean multi_commodity = FALSE;
-        gnc_commodity *base_cmdty = NULL;
-        gint ttVarCount, splitCount;
-        FreqSpec *fs;
-
-        /* Do checks on validity and such, interrupting the user if
-         * things aren't right.
-         *
-         * Features...
-         * X support formulas [?!]
-         * X balancing the SX if contain numeric-only formula data.
-         *   X agreement with create-automagically/notification controls
-         * X the 'will ever be valid' check should take num-occur vals into
-         *   account.
-         * X SX name is unique
-         * X SX has a name
-         * X "weekly" FS has some days set.
-         * X "once" with reasonable start/end dates.
-         *   X This doesn't work at the time the 'weekly' one was fixed with
-         *     user-confirmation, below; the once SX is always valid.
-         * [X more generically, creating a "not scheduled" SX is probably not
-         *   right... ]
-         */
-
-        ttVarCount = 0;
-        splitCount = 0;
-        {
-                static const int NUM_ITERS_WITH_VARS = 5;
-                static const int NUM_ITERS_NO_VARS = 1;
-                int numIters, i;
-                GHashTable *vars, *txns;
-                GList *splitList = NULL;
-                char *str;
-                kvp_frame *f;
-                kvp_value *v;
-                Split *s;
-                Transaction *t;
-                gnc_numeric tmp;
-                gboolean unbalanceable;
-                gpointer unusedKey, unusedValue;
-
-                unbalanceable = FALSE; /* innocent until proven guilty */
-                vars = g_hash_table_new( g_str_hash, g_str_equal );
-                txns = g_hash_table_new( g_direct_hash, g_direct_equal );
-                numIters = NUM_ITERS_NO_VARS;
-                /**
-                 * Plan:
-                 * . Do a first pass to get the variables.
-                 * . Set each variable to random values.
-                 * . see if we balance after that
-                 *   . true: all good
-                 *   . false: indicate to user, allow decision.
-                 */
-
-                /* FIXME: This _really_ shouldn't require a modification of the
-                 * SX just to get the var names... */
-                gnc_split_register_save ( gnc_ledger_display_get_split_register(sxed->ledger),
-                                          FALSE );
-                /* numeric-formulas-get-balanced determination */
-                sxsl_get_sx_vars( sxed->sx, vars );
-
-                ttVarCount = g_hash_table_size( vars );
-                if ( ttVarCount != 0 ) {
-                        /* balance with random variable bindings some number
-                         * of times in an attempt to ferret out
-                         * un-balanceable transactions.
-                         * 
-                         * NOTE: The Real Way to do this is with some
-                         * symbolic math to eliminate the variables.  This is
-                         * hard, and we don't do it.  This solution will
-                         * suffice for now, and perhaps for the lifetime of
-                         * the software. --jsled */
-                        numIters = NUM_ITERS_WITH_VARS;
-                }
-
-                srand(time(NULL));
-                for ( i=0; i < numIters && !unbalanceable; i++ ) {
-                        g_hash_table_foreach( vars, set_var_to_random_value,
-                                              (gpointer)vars );
-                        g_hash_table_foreach( txns, set_sums_to_zero, NULL );
-                        tmp = gnc_numeric_zero();
-
-                        splitList = xaccSchedXactionGetSplits( sxed->sx );
-                        splitCount += g_list_length( splitList );
-
-                        for ( ; splitList; splitList = splitList->next )
-                        {
-                                GUID *acct_guid;
-                                Account *acct;
-                                gnc_commodity *split_cmdty;
-                                txnCreditDebitSums *tcds;
-
-                                s = (Split*)splitList->data;
-                                t = xaccSplitGetParent( s );
-
-                                if ( !(tcds =
-                                       (txnCreditDebitSums*)g_hash_table_lookup( txns,
-                                                                                 (gpointer)t )) )
-                                {
-                                        tcds = g_new0( txnCreditDebitSums, 1 );
-                                        tcds->creditSum = gnc_numeric_zero();
-                                        tcds->debitSum  = gnc_numeric_zero();
-                                        g_hash_table_insert( txns, (gpointer)t, (gpointer)tcds );
-                                }
-
-                                f = xaccSplitGetSlots( s );
-
-                                /* contains the guid of the split's actual account. */
-                                v = kvp_frame_get_slot_path(f,
-                                                            GNC_SX_ID,
-                                                            GNC_SX_ACCOUNT,
-                                                            NULL);
-                                acct_guid = kvp_value_get_guid( v );
-                                acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
-                                split_cmdty = xaccAccountGetCommodity(acct);
-                                if (base_cmdty == NULL)
-                                {
-                                        base_cmdty = split_cmdty;
-                                }
-                                multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
-                                        
-                                v = kvp_frame_get_slot_path( f,
-                                                             GNC_SX_ID,
-                                                             GNC_SX_CREDIT_FORMULA,
-                                                             NULL );
-                                if ( v
-                                     && (str = kvp_value_get_string(v))
-                                     && strlen( str ) != 0 ) {
-                                        if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
-                                                GString *errStr;
-
-                                                errStr = g_string_sized_new( 32 );
-                                                g_string_printf( errStr,
-                                                                 _( "Couldn't parse credit formula for "
-                                                                    "split \"%s\"." ),
-                                                                 xaccSplitGetMemo( s ) );
-                                                gnc_error_dialog( GTK_WIDGET(sxed->dialog),
-                                                                  errStr->str );
-                                                g_string_free( errStr, TRUE );
-
-                                                return FALSE;
-                                        }
-                                        tcds->creditSum =
-                                                gnc_numeric_add( tcds->creditSum, tmp, 100,
-                                                                 (GNC_DENOM_AUTO | GNC_DENOM_LCD) );
-                                        tmp = gnc_numeric_zero();
-                                }
-                                v = kvp_frame_get_slot_path( f,
-                                                             GNC_SX_ID,
-                                                             GNC_SX_DEBIT_FORMULA,
-                                                             NULL );
-                                if ( v
-                                     && (str = kvp_value_get_string(v))
-                                     && strlen(str) != 0 ) {
-                                        if ( parse_vars_from_formula( str, vars, &tmp ) < 0 ) {
-                                                GString *errStr;
-
-                                                errStr = g_string_sized_new( 32 );
-                                                g_string_printf( errStr,
-                                                                 _( "Couldn't parse debit formula for "
-                                                                    "split \"%s\"." ),
-                                                                 xaccSplitGetMemo( s ) );
-                                                gnc_error_dialog( GTK_WIDGET(sxed->dialog),
-                                                                  (gchar*)errStr->str );
-                                                g_string_free( errStr, TRUE );
-
-                                                return FALSE;
-                                        }
-                                        tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
-                                                                          (GNC_DENOM_AUTO | GNC_DENOM_LCD) );
-                                        tmp = gnc_numeric_zero();
-                                }
-                        }
-
-                        g_hash_table_foreach( txns,
-                                              check_credit_debit_balance,
-                                              &unbalanceable );
-                }
-
-                /* Subtract out pre-defined vars */
-                if ( g_hash_table_lookup_extended( vars, "i",
-                                                   &unusedKey,
-                                                   &unusedValue ) ) {
-                        ttVarCount -= 1;
-                }
-
-                g_hash_table_foreach( vars,
-                                      free_keys_and_numerics_ea,
-                                      NULL );
-                g_hash_table_destroy( vars );
-
-                g_hash_table_foreach( txns, free_sums, NULL );
-                g_hash_table_destroy( txns );
-
-                if ( unbalanceable
-                     && !gnc_verify_dialog( sxed->dialog, FALSE,
-					    "%s",
-					    _("The Scheduled Transaction Editor "
-					      "cannot automatically balance "
-					      "this transaction. "
-					      "Should it still be "
-					      "entered?") ) ) {
-                        return FALSE;
-                }
-        }
-
-        /* read out data back into SchedXaction object. */
-        /* FIXME: this is getting too deep; split out. */
-        {
-                gchar *name, *nameKey;
-                gboolean nameExists, nameHasChanged;
-                GList *sxList;
-
-                name = gtk_editable_get_chars( GTK_EDITABLE(sxed->nameEntry), 0, -1 );
-                if ( strlen(name) == 0 ) {
-                        const char *sx_has_no_name_msg =
-                                _( "Please name the Scheduled Transaction." );
-                        gnc_error_dialog( sxed->dialog, sx_has_no_name_msg );
-                        g_free( name );
-                        return FALSE;
-                        
-                }
-
-                nameExists = FALSE;
-                nameKey = g_utf8_collate_key(name, -1);
-                nameHasChanged =
-                        (xaccSchedXactionGetName(sxed->sx) == NULL)
-                        || (strcmp( xaccSchedXactionGetName(sxed->sx), name ) != 0);
-                for ( sxList =
-                          gnc_book_get_schedxactions( gnc_get_current_book() );
-                      nameHasChanged && !nameExists && sxList ;
-                      sxList = sxList->next ) {
-                        char *existingName, *existingNameKey;
-                        existingName =
-                                xaccSchedXactionGetName( (SchedXaction*)sxList->
-                                                         data );
-                        existingNameKey = g_utf8_collate_key(existingName, -1);
-                        nameExists |= ( strcmp(nameKey, existingNameKey) == 0 );
-                        g_free( existingNameKey );
-                }
-                if ( nameHasChanged && nameExists ) {
-                        const char *sx_has_existing_name_msg =
-                                _( "A Scheduled Transaction with the "
-                                   "name \"%s\" already exists. "
-                                   "Are you sure you want to name "
-                                   "this one the same?" );
-                        if ( ! gnc_verify_dialog( sxed->dialog, FALSE,
-						  sx_has_existing_name_msg,
-						  name) ) {
-                                g_free( nameKey );
-                                g_free( name );
-                                return FALSE;
-                        }
-                }
-                g_free( nameKey );
-                g_free( name );
-        }
-
-        // @@fixme: similar to below, check the commodities involved, and disallow autocreation
-        {
-                gboolean autocreateState, notifyState;
-
-                autocreateState =
-                        gtk_toggle_button_get_active(
-                                GTK_TOGGLE_BUTTON(sxed->autocreateOpt) );
-                notifyState =
-                        gtk_toggle_button_get_active(
-                                GTK_TOGGLE_BUTTON(sxed->notifyOpt) );
-
-                if (((ttVarCount > 0) || multi_commodity) && autocreateState) {
-                        gnc_warning_dialog(sxed->dialog,
-                                           _("Scheduled Transactions with variables "
-                                             "cannot be automatically created."));
-                        return FALSE;
-                }
-
-                /* Fix for part of Bug#121740 -- auto-create transactions are
-                 * only valid if there's actually a transaction to create. */
-                if ( autocreateState && splitCount == 0 ) {
-                        gnc_warning_dialog( sxed->dialog,
-                                            _("Scheduled Transactions without a template "
-                                              "transaction cannot be automatically created.") );
-                        return FALSE;
-                }
-        }
-
-        /* deal with time. */
-        {
-                GDate startDate, endDate, nextDate;
-
-                if ( !gtk_toggle_button_get_active(sxed->optEndDate)
-                     && !gtk_toggle_button_get_active(sxed->optEndCount)
-                     && !gtk_toggle_button_get_active(sxed->optEndNone) ) {
-                        const char *sx_end_spec_msg =
-                                _( "Please provide a valid end selection." );
-                        gnc_error_dialog( sxed->dialog, sx_end_spec_msg );
-                        return FALSE;
-                }
-
-                if ( gtk_toggle_button_get_active(sxed->optEndCount)) {
-                        gint occur, rem;
-
-			occur  =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endCountSpin) );
-
-			rem =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endRemainSpin) );
-
-                        if ( occur == 0 ) {
-                                const char *sx_occur_count_zero_msg =
-                                        _( "There must be some number of occurrences." );
-                                gnc_error_dialog( sxed->dialog,
-						  sx_occur_count_zero_msg );
-                                return FALSE;
-                        }
-
-                        if ( rem > occur ) {
-                                const char *sx_occur_counts_wrong_msg =
-                                        _( "The number of remaining occurrences "
-                                           "(%d) is greater than the number of "
-                                           "total occurrences (%d)." );
-                                gnc_error_dialog( sxed->dialog,
-						  sx_occur_counts_wrong_msg,
-						  rem, occur );
-                                return FALSE;
-                        }
-
-                }
-
-                g_date_clear( &endDate, 1 );
-                if ( gtk_toggle_button_get_active(sxed->optEndDate) ) {
-                        g_date_set_time_t( &endDate,
-					   gnc_date_edit_get_date( sxed->
-								   endDateEntry ) );
-                }
-
-                /* Now, see if the user is attempting to create a SX that can't exist
-                 * [will never run]. */
-
-                /* get the frequency spec data */
-                fs = xaccFreqSpecMalloc( gnc_get_current_book() );
-                gnc_frequency_save_state( sxed->gncfreq, fs, &startDate );
-                /* Replicate just a smidgen of the code in the SX
-                 * ...GetNextInstance routine */
-                g_date_subtract_days( &startDate, 1 );
-                xaccFreqSpecGetNextInstance( fs, &startDate, &nextDate );
-                xaccFreqSpecFree( fs );
-
-                if ( !g_date_valid( &nextDate )
-                     || (g_date_valid( &endDate )
-                         && (g_date_compare( &nextDate, &endDate ) > 0)) ) {
-                        const char *invalid_sx_check_msg =
-                                _( "You have attempted to create a Scheduled "
-                                   "Transaction which will never run. Do you "
-                                   "really want to do this?" );
-                        if ( ! gnc_verify_dialog( sxed->dialog, FALSE,
-						  invalid_sx_check_msg) ) {
-                        
-                                return FALSE;
-                        }
-                }
-        }
-        return TRUE;
-}
-
-/**
- * Saves the contents of the SX.  This assumes that gnc_sxed_check_consistent
- * has returned true.
- **/
-static
-void
-gnc_sxed_save_sx( SchedXactionEditorDialog *sxed )
-{
-        /* name */
-        {
-                char *name;
-
-                name = gtk_editable_get_chars( sxed->nameEntry, 0, -1 );
-                xaccSchedXactionSetName( sxed->sx, name );
-                g_free( name );
-        }
-
-        /* date */
-        {
-                GDate gdate;
-
-                if ( gtk_toggle_button_get_active(sxed->optEndDate) ) {
-                        /* get the end date data */
-                        g_date_set_time_t( &gdate,
-					   gnc_date_edit_get_date(
-                                                 sxed->endDateEntry ) );
-                        xaccSchedXactionSetEndDate( sxed->sx, &gdate );
-                        /* set the num occurances data */
-                        xaccSchedXactionSetNumOccur( sxed->sx, 0 );
-                } else if ( gtk_toggle_button_get_active(sxed->optEndCount) ) {
-                        gint num;
-
-                        /* get the occurances data */
-			num  =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endCountSpin) );
-                        xaccSchedXactionSetNumOccur( sxed->sx, num );
-
-			num =
-			  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endRemainSpin) );
-                        xaccSchedXactionSetRemOccur( sxed->sx, num );
-
-                        g_date_clear( &gdate, 1 );
-                        xaccSchedXactionSetEndDate( sxed->sx, &gdate );
-                } else if ( gtk_toggle_button_get_active( sxed->optEndNone ) ) {
-                        xaccSchedXactionSetNumOccur( sxed->sx, 0 );
-                        g_date_clear( &gdate, 1 );
-                        xaccSchedXactionSetEndDate( sxed->sx, &gdate );
-                } else {
-                        PERR( "No valid end specified\n" );
-                }
-        }
-
-        /* Auto-create/notification states */
-        {
-                gboolean autocreateState, notifyState;
-
-                autocreateState = gtk_toggle_button_get_active( sxed->autocreateOpt );
-                notifyState = gtk_toggle_button_get_active( sxed->notifyOpt );
-                /* "Notify" only makes sense if AutoCreate is actived;
-                 * enforce that here. */
-                xaccSchedXactionSetAutoCreate( sxed->sx,
-                                               autocreateState,
-                                               (autocreateState & notifyState) );
-        }
-
-        /* days in advance */
-        {
-                int daysInAdvance;
-
-                daysInAdvance = 0;
-                if ( gtk_toggle_button_get_active( sxed->advanceOpt ) ) {
-                        daysInAdvance =
-                                gtk_spin_button_get_value_as_int( sxed->advanceSpin );
-                }
-                xaccSchedXactionSetAdvanceCreation( sxed->sx, daysInAdvance );
-
-                daysInAdvance = 0;
-                if ( gtk_toggle_button_get_active( sxed->remindOpt ) ) {
-                        daysInAdvance =
-                                gtk_spin_button_get_value_as_int( sxed->remindSpin );
-                }
-                xaccSchedXactionSetAdvanceReminder( sxed->sx, daysInAdvance );
-        }
-
-        /* start date and freq spec */
-        {
-                FreqSpec *fs;
-                GDate gdate;
-		GString *str;
-
-                fs = xaccSchedXactionGetFreqSpec( sxed->sx );
-                gnc_frequency_save_state( sxed->gncfreq, fs, &gdate );
-
-                str = g_string_new( "" );
-                xaccFreqSpecGetFreqStr( fs, str );
-                DEBUG( "fs: %s", str->str );
-
-                /* now that we have it, set the start date */
-                xaccSchedXactionSetStartDate( sxed->sx, &gdate );
-        }
-
-}
-
-static void
-autocreate_toggled( GtkObject *o, SchedXactionEditorDialog *sxed )
-{
-        if ( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o)) ) {
-                gtk_toggle_button_set_active( sxed->notifyOpt, FALSE );
-        }
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->notifyOpt),
-                                  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) );
-}
-
-static void
-advance_toggle( GtkButton *o, SchedXactionEditorDialog *sxed )
-{
-        gchar *spinName;
-        GtkWidget *spin;
-
-        spinName = (gchar*)g_object_get_data( G_OBJECT(o), "whichOneAmI" );
-        spin = glade_xml_get_widget( sxed->gxml, spinName );
-        if ( !spin ) {
-                PERR( "Error getting widget with name \"%s\"", spinName );
-                return;
-        }
-        gtk_widget_set_sensitive( spin,
-                                  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) );
-        /* FIXME: this doesn't do what we want... :( */
-        gtk_editable_set_editable( GTK_EDITABLE(spin), TRUE );
-}
-
-/* Local destruction of dialog */
-static void
-scheduledxaction_dialog_destroy(GtkObject *object, gpointer data)
-{
-        SchedXactionDialog *sxd = data;
-
-        if ( !sxd ) return;
-
-        gnc_unregister_gui_component_by_data
-                (DIALOG_SCHEDXACTION_CM_CLASS, sxd);
-
-        // FIXME: um.  We should free memory and stuff, here...
-        /*
-        GladeXML    *gxml;
-        GncDenseCal *gdcal;
-        GHashTable  *sxData;
-        */
-
-        g_free( sxd );
-}
-
-/* Local destruction of dialog */
-static void
-scheduledxaction_editor_dialog_destroy(GtkObject *object, gpointer data)
-{
-        int i;
-        SchedXactionEditorDialog *sxed = data;
-
-        if (sxed == NULL)
-                return;
-
-        gnc_unregister_gui_component_by_data
-                (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS, sxed);
-
-        gnc_embedded_window_close_page(sxed->embed_window, sxed->plugin_page);
-        gtk_widget_destroy(GTK_WIDGET(sxed->embed_window));
-        sxed->embed_window = NULL;
-        sxed->plugin_page = NULL;
-        sxed->ledger = NULL;
-
-        g_free (sxed->sxGUIDstr);
-        sxed->sxGUIDstr = NULL;
-
-        for ( i=0; i<(EX_CAL_NUM_MONTHS*31); i++ ) {
-                g_free( sxed->cal_marks[i] );
-        }
-        g_free( sxed->cal_marks );
-
-        if ( sxed->newsxP ) {
-                /* FIXME: WTF???
-                 *
-                 * "WTF" explaination: in the "new" click from the caller, we
-                 * set this flag.  When "ok" is pressed on the dialog, we set
-                 * this flag to false, and thus leave the SX live.  If
-                 * "Cancel" is clicked, the flag will still be true, and this
-                 * SX will be cleaned, here. -- jsled
-                 */
-                xaccSchedXactionFree( sxed->sx );
-        }
-        sxed->sx = NULL;
-
-        g_free (sxed);
-}
-
-SchedXactionDialog*
-gnc_ui_scheduled_xaction_dialog_create(void)
-{
-        SchedXactionDialog *sxd = NULL;
-        GtkObject *sxdo;
-        GtkWidget *button;
-        GtkWidget *w;
-        SchedXactionDialog *alreadyExisting = NULL;
-
-        alreadyExisting = 
-                (SchedXactionDialog*)
-                gnc_find_first_gui_component( DIALOG_SCHEDXACTION_CM_CLASS,
-                                              NULL,
-                                              (gpointer)sxd );
-        if ( alreadyExisting != NULL ) {
-                gtk_window_present( GTK_WINDOW(alreadyExisting->dialog) );
-                return alreadyExisting;
-        }
-
-        sxd = g_new0( SchedXactionDialog, 1 );
-
-        sxd->gxml = gnc_glade_xml_new( SX_GLADE_FILE, SX_LIST_GLADE_NAME );
-        sxd->dialog = glade_xml_get_widget( sxd->gxml, SX_LIST_GLADE_NAME );
-
-        sxd->sxData = g_hash_table_new( NULL, NULL );
-
-        sxdo = GTK_OBJECT(sxd->dialog);
-
-        w = glade_xml_get_widget( sxd->gxml, SX_LIST_UPCOMING_BOX );
-        sxd->gdcal = GNC_DENSE_CAL( gnc_dense_cal_new() );
-        gnc_dense_cal_set_months_per_col( sxd->gdcal, 4 );
-        gnc_dense_cal_set_num_months( sxd->gdcal, 12 );
-        gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxd->gdcal) );
-
-        g_signal_connect( sxdo, "destroy",
-                          G_CALLBACK(scheduledxaction_dialog_destroy),
-                          sxd );
-
-        button = glade_xml_get_widget( sxd->gxml, "new_button" );
-        g_signal_connect( button, "clicked",
-                          G_CALLBACK(new_button_clicked), sxd );
-        button = glade_xml_get_widget( sxd->gxml, "edit_button" );
-        g_signal_connect( button, "clicked",
-                          G_CALLBACK(edit_button_clicked), sxd );
-        button = glade_xml_get_widget( sxd->gxml, "delete_button" );
-        g_signal_connect( button, "clicked",
-                          G_CALLBACK(delete_button_clicked), sxd );
-        button = glade_xml_get_widget( sxd->gxml, "close_button" );
-        g_signal_connect( button, "clicked",
-                          G_CALLBACK(close_button_clicked), sxd );
-
-        w = glade_xml_get_widget( sxd->gxml, SX_LIST );
-        g_signal_connect( w, "select-row",
-                          G_CALLBACK(row_select_handler), sxd );
-        g_signal_connect( w, "unselect-row",
-                          G_CALLBACK(row_unselect_handler), sxd );
-        g_signal_connect( w, "click-column",
-                          G_CALLBACK(gnc_sxd_row_click_handler), sxd );
-
-        // gtk_clist_column_titles_active( GTK_CLIST( w ) );
-
-        /* Default to sorting by ascending next-instance date. */
-        sxd->currentSortCol = 2;
-        sxd->currentSortType = GTK_SORT_ASCENDING;
-        gnc_sxd_set_sort_compare( GTK_CLIST(w), sxd->currentSortCol );
-        gtk_clist_set_auto_sort( GTK_CLIST(w), TRUE );
-
-	gnc_restore_window_size(SX_LIST_GCONF_SECTION, GTK_WINDOW(sxd->dialog));
-
-        gnc_register_gui_component( DIALOG_SCHEDXACTION_CM_CLASS,
-                                    NULL, /* no refresh_handler */
-                                    sxd_close_handler,
-                                    sxd );
-
-        schedXact_populate( sxd );
-
-        gtk_widget_show_all(sxd->dialog);
-
-        return sxd;
-}
-
-static
-void
-gnc_sxl_record_size( SchedXactionDialog *sxd )
-{
-	gnc_save_window_size(SX_LIST_GCONF_SECTION, GTK_WINDOW(sxd->dialog));
-}
-
-void
-row_select_handler( GtkCList *clist,
-                    gint row,
-                    gint col,
-                    GdkEventButton *event,
-                    gpointer d )
-{
-        SchedXactionDialog *sxd;
-        SchedXaction *sx;
-	GtkWidget *widget;
-       
-        sxd   = (SchedXactionDialog*)d;
-
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_EDIT_BUTTON );
-	gtk_widget_set_sensitive(widget, TRUE);
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_DELETE_BUTTON );
-	gtk_widget_set_sensitive(widget, TRUE);
-
-        if ( event == NULL ) {
-                /* it could be a keypress */
-                return;
-        }
-
-        switch ( event->type ) {
-        case GDK_2BUTTON_PRESS:
-                sx = (SchedXaction*)gtk_clist_get_row_data( clist, row );
-                gnc_ui_scheduled_xaction_editor_dialog_create( sxd, sx, FALSE );
-                break;
-        default:
-                /* noop */
-                break;
-        }
-}
-
-void
-row_unselect_handler( GtkCList *clist,
-                    gint row,
-                    gint col,
-                    GdkEventButton *event,
-                    gpointer d )
-{
-        SchedXactionDialog *sxd;
-	GtkWidget *widget;
-       
-        sxd   = (SchedXactionDialog*)d;
-
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_EDIT_BUTTON );
-	gtk_widget_set_sensitive(widget, FALSE);
-	widget = glade_xml_get_widget( sxd->gxml, SX_LIST_DELETE_BUTTON );
-	gtk_widget_set_sensitive(widget, FALSE);
-}
-
-static
-void
-schedXact_populate( SchedXactionDialog *sxd )
-{
-        GList *sxList;
-        GtkCList *sx_clist;
-        int i;
-
-        sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
-        g_list_foreach( sxList, putSchedXactionInDialog, sxd );
-
-        sx_clist = GTK_CLIST( glade_xml_get_widget( sxd->gxml,
-                                                    SX_LIST ) );
-        for ( i=0; i<3; i++ ) {
-                gtk_clist_set_column_auto_resize( sx_clist, i, TRUE );
-        }
-}
-
-static
-gint
-sxed_close_event( GtkDialog *dlg, gpointer ud )
-{
-        SchedXactionEditorDialog *sxed = (SchedXactionEditorDialog*)ud;
-
-        /* We've already processed the SX, likely because of "ok" being
-         * clicked. */
-        if ( sxed->sx == NULL ) {
-          return FALSE;
-        }
-
-        if ( ! sxed_confirmed_cancel( sxed ) ) {
-                return TRUE;
-        }
-        return FALSE;
-}
-
-static
-void
-gnc_sxed_get_widgets( SchedXactionEditorDialog *sxed )
-{
-        GtkWidget *w;
-
-        w = glade_xml_get_widget( sxed->gxml, SXED_NAME_ENTRY );
-        sxed->nameEntry = GTK_EDITABLE(w);
-        w = glade_xml_get_widget( sxed->gxml, SXED_LAST_OCCUR_LABEL );
-        sxed->lastOccurLabel = GTK_LABEL(w);
-        w = glade_xml_get_widget( sxed->gxml, AUTOCREATE_OPT );
-        sxed->autocreateOpt = GTK_TOGGLE_BUTTON(w);
-        w = glade_xml_get_widget( sxed->gxml, NOTIFY_OPT );
-        sxed->notifyOpt = GTK_TOGGLE_BUTTON(w);
-        w = glade_xml_get_widget( sxed->gxml, ADVANCE_OPT );
-        sxed->advanceOpt = GTK_TOGGLE_BUTTON(w);
-        w = glade_xml_get_widget( sxed->gxml, ADVANCE_DAYS_SPIN );
-        sxed->advanceSpin = GTK_SPIN_BUTTON(w);
-        w = glade_xml_get_widget( sxed->gxml, REMIND_OPT );
-        sxed->remindOpt = GTK_TOGGLE_BUTTON(w);
-        w = glade_xml_get_widget( sxed->gxml, REMIND_DAYS_SPIN );
-        sxed->remindSpin = GTK_SPIN_BUTTON(w);
-
-        w = glade_xml_get_widget( sxed->gxml, "rb_enddate" );
-        sxed->optEndDate = GTK_TOGGLE_BUTTON(w);
-
-        w = glade_xml_get_widget( sxed->gxml, "rb_noend" );
-        sxed->optEndNone = GTK_TOGGLE_BUTTON(w);
-
-        w = glade_xml_get_widget( sxed->gxml, "rb_num_occur" );
-        sxed->optEndCount = GTK_TOGGLE_BUTTON(w);
-
-        w = glade_xml_get_widget( sxed->gxml, END_SPIN );
-        sxed->endCountSpin = GTK_ENTRY(w);
-
-        w = glade_xml_get_widget( sxed->gxml, REMAIN_SPIN );
-        sxed->endRemainSpin = GTK_ENTRY(w);
-
-}
-
-SchedXactionEditorDialog *
-gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
-                                               SchedXaction *sx,
-                                               gboolean newSX )
-{
-        SchedXactionEditorDialog *sxed;
-        GtkWidget *button;
-        int i;
-        GList *dlgExists = NULL;
-
-        static struct widgetSignalCallback {
-                char     *name;
-                char     *signal;
-                void     (*fn)();
-                gpointer objectData;
-        } widgets[] = {
-                { "ok_button",      "clicked", editor_ok_button_clicked,     NULL },
-                { "cancel_button",  "clicked", editor_cancel_button_clicked, NULL },
-                { "help_button",    "clicked", editor_help_button_clicked,   NULL },
-
-                { "rb_noend",       "toggled", endgroup_rb_toggled,          GINT_TO_POINTER(END_NEVER_OPTION) },
-                { "rb_enddate",     "toggled", endgroup_rb_toggled,          GINT_TO_POINTER(END_DATE_OPTION) },
-                { "rb_num_occur",   "toggled", endgroup_rb_toggled,          GINT_TO_POINTER(NUM_OCCUR_OPTION) },
-
-                { REMAIN_SPIN ,     "value-changed", sxed_excal_update_adapt, NULL },
-
-                { AUTOCREATE_OPT,   "toggled", autocreate_toggled,           NULL },
-                { ADVANCE_OPT,      "toggled", advance_toggle,               (gpointer)ADVANCE_DAYS_SPIN },
-                { REMIND_OPT,       "toggled", advance_toggle,               (gpointer)REMIND_DAYS_SPIN },
-
-                { NULL,             NULL,      NULL,                         NULL }
-        };
-
-        dlgExists = gnc_find_gui_components( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
-                                             editor_component_sx_equality,
-                                             sx );
-        if ( dlgExists != NULL ) {
-                DEBUG( "dialog already exists; using that one." );
-                sxed = (SchedXactionEditorDialog*)dlgExists->data;
-                gtk_window_present( GTK_WINDOW(sxed->dialog) );
-                g_list_free( dlgExists );
-                return sxed;
-        }
-
-        sxed         = g_new0( SchedXactionEditorDialog, 1 );
-        sxed->gxml   = gnc_glade_xml_new( SX_GLADE_FILE,
-                                        SX_EDITOR_GLADE_NAME );
-        sxed->dialog = glade_xml_get_widget( sxed->gxml, SX_EDITOR_GLADE_NAME );
-
-        sxed->sxd    = sxd;
-        sxed->sx     = sx;
-        sxed->newsxP = newSX;
-        /* Setup dense-cal local mark storage */
-        {
-                sxed->cal_marks = g_new0( GDate*, EX_CAL_NUM_MONTHS * 31 );
-                for( i=0; i<(EX_CAL_NUM_MONTHS * 31); i++ ) {
-                        sxed->cal_marks[i] = g_date_new();
-                }
-                sxed->markId = -1;
-        }
-
-        /* Setup the end-date GNC widget */
-        {
-                GtkWidget *endDateBox =
-                        glade_xml_get_widget( sxed->gxml, END_DATE_BOX );
-                sxed->endDateEntry =
-                        GNC_DATE_EDIT(gnc_date_edit_new( time(NULL),
-                                                         FALSE, FALSE ));
-                gtk_widget_show(GTK_WIDGET(sxed->endDateEntry));
-                g_signal_connect( sxed->endDateEntry,
-                                  "date-changed",
-                                  G_CALLBACK( sxed_excal_update_adapt ),
-                                  sxed );
-                gtk_box_pack_start( GTK_BOX(endDateBox),
-                                    GTK_WIDGET(sxed->endDateEntry),
-                                    TRUE, TRUE, 0 );
-        }
-
-        /* NOTE: this must occur before processing the widget list, defined
-         * above, so the gpointers stored with the advance_ and remind_opts
-         * are correct. */
-        gnc_sxed_get_widgets( sxed );
-
-        gnc_register_gui_component( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
-                                    NULL, /* no refresh handler */
-                                    sxed_close_handler,
-                                    sxed );
-
-        g_signal_connect( sxed->dialog, "close",
-                          G_CALLBACK(sxed_close_event), sxed );
-        g_signal_connect( sxed->dialog, "destroy",
-                          G_CALLBACK(scheduledxaction_editor_dialog_destroy),
-                          sxed );
-
-        for ( i=0; widgets[i].name != NULL; i++ ) {
-                button = glade_xml_get_widget( sxed->gxml, widgets[i].name );
-                if ( widgets[i].objectData != NULL ) {
-                        g_object_set_data( G_OBJECT(button), "whichOneAmI",
-					   widgets[i].objectData );
-                }
-                g_signal_connect( button, widgets[i].signal,
-                                  G_CALLBACK( widgets[i].fn ), sxed );
-        }
-
-        /* For some reason the Glade-specified sensitivity settings are not
-         * being honored... ? */
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->notifyOpt), FALSE );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->advanceSpin), FALSE );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->remindSpin), FALSE );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->endCountSpin), FALSE );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->endRemainSpin), FALSE );
-
-        gtk_editable_set_editable( GTK_EDITABLE(sxed->advanceSpin), TRUE );
-        gtk_editable_set_editable( GTK_EDITABLE(sxed->remindSpin), TRUE );
-
-	/* Allow resize */
-        gtk_window_set_resizable (GTK_WINDOW(sxed->dialog), TRUE);
-
-	gnc_restore_window_size(SXED_GCONF_SECTION, GTK_WINDOW(sxed->dialog));
-
-        /* create the frequency-selection macrowidget and example
-         * [dense-]calendar. */
-        schedXact_editor_create_freq_sel( sxed );
-        /* create the template-transaction ledger window */
-        schedXact_editor_create_ledger( sxed );
-        /* populate */
-        schedXact_editor_populate( sxed );
-
-	/* Do not call show_all here. Screws up the gtkuimanager code */
-        gtk_widget_show(sxed->dialog);
-
-	/* Refresh the cal and the ledger */
-	gtk_widget_queue_resize( GTK_WIDGET( sxed->example_cal ) );
-        gnc_ledger_display_refresh( sxed->ledger );
-
-        return sxed;
-}
-
-static
-void
-gnc_sxed_record_size( SchedXactionEditorDialog *sxed )
-{
-	gnc_save_window_size( SXED_GCONF_SECTION, GTK_WINDOW(sxed->dialog) );
-}
-
-static
-void
-schedXact_editor_create_freq_sel( SchedXactionEditorDialog *sxed )
-{
-        GtkBox *b;
-
-        b = GTK_BOX(glade_xml_get_widget( sxed->gxml, "gncfreq_hbox" ));
-        sxed->gncfreq =
-                GNC_FREQUENCY( gnc_frequency_new( xaccSchedXactionGetFreqSpec(sxed->sx),
-                                                  xaccSchedXactionGetStartDate(sxed->sx) ) );
-        g_assert( sxed->gncfreq );
-        g_signal_connect( sxed->gncfreq, "changed",
-                          G_CALLBACK(gnc_sxed_freq_changed),
-                          sxed );
-        gtk_container_add( GTK_CONTAINER(b), GTK_WIDGET(sxed->gncfreq) );
-
-        b = GTK_BOX(glade_xml_get_widget( sxed->gxml, "example_cal_hbox" ));
-        sxed->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new());
-        g_assert( sxed->example_cal );
-        gnc_dense_cal_set_num_months( sxed->example_cal, EX_CAL_NUM_MONTHS );
-        gnc_dense_cal_set_months_per_col( sxed->example_cal, EX_CAL_MO_PER_COL );
-        gtk_container_add( GTK_CONTAINER(b), GTK_WIDGET(sxed->example_cal) );
-	gtk_widget_show( GTK_WIDGET(sxed->example_cal) );
-}
-
-static
-void
-schedXact_editor_create_ledger( SchedXactionEditorDialog *sxed )
-{
-        SplitRegister *splitreg;
-        GtkWidget *main_vbox;
-
-	/* Create the ledger */
-        /* THREAD-UNSAFE */
-        sxed->sxGUIDstr = g_strdup( guid_to_string(
-                                        xaccSchedXactionGetGUID(sxed->sx) ) );
-        sxed->ledger = gnc_ledger_display_template_gl( sxed->sxGUIDstr );
-        splitreg = gnc_ledger_display_get_split_register( sxed->ledger );
-
-	/* First the embedded window */
-        main_vbox = glade_xml_get_widget( sxed->gxml, "register_vbox" );
-	sxed->embed_window =
-	  gnc_embedded_window_new("SXWindowActions",
-                                  gnc_sxed_menu_entries,
-                                  gnc_sxed_menu_n_entries,
-                                  "gnc-sxed-window-ui.xml",
-                                  sxed->dialog,
-                                  FALSE, /* no accelerators */
-                                  sxed);
-	gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET(sxed->embed_window),
-			    TRUE, TRUE, 0);
-
-	/* Now create the register plugin page. */
-	sxed->plugin_page = gnc_plugin_page_register_new_ledger (sxed->ledger);
-	gnc_plugin_page_set_ui_description (sxed->plugin_page,
-					    "gnc-sxed-window-ui-full.xml");
-	gnc_plugin_page_register_set_options (sxed->plugin_page,
-					      NULL, NULL,
-					      NUM_LEDGER_LINES_DEFAULT, FALSE );
-	gnc_embedded_window_open_page (sxed->embed_window, sxed->plugin_page);
-
-        /* configure... */
-        /* don't use double-line */
-        gnc_split_register_config(splitreg,
-                                  splitreg->type, splitreg->style,
-                                  FALSE);
-        gnc_split_register_set_auto_complete(splitreg, FALSE);
-
-        /* don't show present/future divider [by definition, not necessary] */
-        gnc_split_register_show_present_divider( splitreg, FALSE );
-}
-
-static
-void
-schedXact_editor_populate( SchedXactionEditorDialog *sxed )
-{
-        char *name;
-        time_t tmpDate;
-        SplitRegister *splitReg;
-        struct tm *tmpTm;
-        GDate *gd;
-        gint daysInAdvance;
-        gboolean autoCreateState, notifyState;
-
-        name = xaccSchedXactionGetName(sxed->sx);
-        if ( name != NULL ) {
-                gtk_entry_set_text( GTK_ENTRY(sxed->nameEntry), name  );
-        }
-        {
-                gd = xaccSchedXactionGetLastOccurDate( sxed->sx );
-                if ( g_date_valid( gd ) ) {
-                        gchar dateBuf[ MAX_DATE_LENGTH+1 ];
-                        qof_print_gdate( dateBuf,MAX_DATE_LENGTH, gd );
-                        gtk_label_set_text( sxed->lastOccurLabel, dateBuf );
-                } else {
-                        gtk_label_set_text( sxed->lastOccurLabel, _( "(never)" ) );
-                }
-                gd = NULL;
-        }
-
-        gd = xaccSchedXactionGetEndDate( sxed->sx );
-        if ( g_date_valid( gd ) ) {
-                gtk_toggle_button_set_active( sxed->optEndDate, TRUE );
-                /* fill in date data. */
-                tmpTm = g_new0( struct tm, 1 );
-                g_date_to_struct_tm( gd, tmpTm );
-                tmpDate = mktime( tmpTm );
-                g_free( tmpTm );
-                gnc_date_edit_set_time( sxed->endDateEntry, tmpDate );
-
-                set_endgroup_toggle_states( sxed, END_DATE );
-        } else if ( xaccSchedXactionHasOccurDef( sxed->sx ) ) {
-                gint numOccur = xaccSchedXactionGetNumOccur( sxed->sx );
-                gint numRemain = xaccSchedXactionGetRemOccur( sxed->sx );
-
-                gtk_toggle_button_set_active( sxed->optEndCount, TRUE );
-
-		gtk_spin_button_set_value ( GTK_SPIN_BUTTON(sxed->endCountSpin), numOccur );
-		gtk_spin_button_set_value ( GTK_SPIN_BUTTON(sxed->endRemainSpin), numRemain );
-
-                set_endgroup_toggle_states( sxed, END_OCCUR );
-        } else {
-                gtk_toggle_button_set_active( sxed->optEndNone, TRUE );
-                set_endgroup_toggle_states( sxed, END_NEVER );
-        }
-
-        /* Do auto-create/notify setup */
-        if ( sxed->newsxP ) {
-                autoCreateState =
-		  gnc_gconf_get_bool( SXED_GCONF_SECTION, KEY_CREATE_AUTO, NULL );
-                notifyState =
-		  gnc_gconf_get_bool( SXED_GCONF_SECTION, KEY_NOTIFY, NULL );
-        } else {
-                xaccSchedXactionGetAutoCreate( sxed->sx,
-                                               &autoCreateState,
-                                               &notifyState );
-        }
-        gtk_toggle_button_set_active( sxed->autocreateOpt, autoCreateState );
-        if ( ! autoCreateState ) {
-                notifyState = FALSE;
-        }
-        gtk_toggle_button_set_active( sxed->notifyOpt, notifyState );
-
-
-        /* Do days-in-advance-to-create widget[s] setup. */
-        if ( sxed->newsxP ) {
-                daysInAdvance =
-		  gnc_gconf_get_float( SXED_GCONF_SECTION, KEY_CREATE_DAYS, NULL );
-        } else {
-                daysInAdvance =
-                        xaccSchedXactionGetAdvanceCreation( sxed->sx );
-        }
-        if ( daysInAdvance != 0 ) {
-                gtk_toggle_button_set_active( sxed->advanceOpt, TRUE );
-                gtk_spin_button_set_value( sxed->advanceSpin,
-                                           (gfloat)daysInAdvance );
-        }
-
-        /* Do days-in-advance-to-remind widget[s] setup. */
-        if ( sxed->newsxP ) {
-                daysInAdvance =
-		  gnc_gconf_get_float( SXED_GCONF_SECTION, KEY_REMIND_DAYS, NULL );
-        } else {
-                daysInAdvance =
-                        xaccSchedXactionGetAdvanceReminder( sxed->sx );
-        }
-        if ( daysInAdvance != 0 ) {
-                gtk_toggle_button_set_active( sxed->remindOpt, TRUE );
-                gtk_spin_button_set_value( sxed->remindSpin,
-                                           (gfloat)daysInAdvance );
-        }
-
-        if ( sxed->newsxP ) {
-                gnc_sx_set_instance_count( sxed->sx, 1 );
-        }
-
-        /* populate the ledger */
-        { 
-                /* create the split list */
-                GList        *splitList;
-
-                splitList = xaccSchedXactionGetSplits( sxed->sx );
-                if ( splitList != NULL ) {
-                        splitReg = gnc_ledger_display_get_split_register
-                          ( sxed->ledger );
-                        gnc_split_register_load(splitReg, splitList, NULL );
-                } /* otherwise, use the existing stuff. */
-        }
-
-        /* Update the example cal */
-        gnc_sxed_update_cal( sxed );
-}
-
-static
-void
-set_endgroup_toggle_states( SchedXactionEditorDialog *sxed, EndType type )
-{
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->endDateEntry),   (type == END_DATE) );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->endCountSpin),  (type == END_OCCUR) );
-        gtk_widget_set_sensitive( GTK_WIDGET(sxed->endRemainSpin), (type == END_OCCUR) );
-}
-
-static
-void
-new_button_clicked( GtkButton *b, gpointer d )
-{
-        SchedXactionDialog        *sxd;
-        FreqSpec *fs;
-        GDate *gd;
-        SchedXaction        *tmpSX =
-                xaccSchedXactionMalloc( gnc_get_current_book ());
-        SchedXactionEditorDialog *sxed;
-
-        /* Give decent initial FreqSpec for SX */
-        fs = xaccSchedXactionGetFreqSpec( tmpSX );
-        gd = g_date_new();
-        g_date_set_time_t( gd, time(NULL) );
-        xaccFreqSpecSetMonthly( fs, gd, 1 );
-        xaccFreqSpecSetUIType ( fs, UIFREQ_MONTHLY );
-        g_date_free( gd );
-        
-        sxd = (SchedXactionDialog*)d;
-        sxed = gnc_ui_scheduled_xaction_editor_dialog_create( sxd, tmpSX,
-                                                              TRUE /* newSX */ );
-}
-
-static
-void
-edit_button_clicked( GtkButton *b, gpointer d )
-{
-        GList *sel;
-        GtkCList *cl;
-        int row;
-        SchedXactionDialog *sxd;
-        SchedXaction *sx;
-        SchedXactionEditorDialog *sxed;
-
-        sxd = (SchedXactionDialog*)d;
-        cl = GTK_CLIST(glade_xml_get_widget( sxd->gxml, SX_LIST ));
-        for( sel = cl->selection; sel; sel = g_list_next(sel) ) {
-                row = GPOINTER_TO_INT(sel->data);
-                /* get the clist row for this listitem */
-                sx = (SchedXaction*)gtk_clist_get_row_data( cl, row );
-                /* get the object UD */
-                sxed = gnc_ui_scheduled_xaction_editor_dialog_create( sxd, sx, FALSE );
-        }
-}
-
-static void
-delete_button_clicked( GtkButton *b, gpointer d )
-{
-        GNCBook *book;
-        GtkCList *cl;
-        GList *sel, *sxList, *beingEditedList, *l;
-        SchedXactionDialog *sxd;
-        char *beingEditedMessage =
-          _( "The following transactions are presently being edited; "
-             "are you sure you want to delete them?" );
-        char *confirmMessage =
-          _( "Delete the selected Scheduled Transactions?" );
-        GString  *realConfDelOpenMsg, *realConfDeleteMsg;
-        SchedXaction *sx;
-        gboolean destroyOpenedResult = FALSE;
-
-        sxd = (SchedXactionDialog*)d;
-
-        cl = GTK_CLIST(glade_xml_get_widget( sxd->gxml, SX_LIST ));
-        sel = cl->selection;
-
-        if ( !sel ) {
-                return;
-        }
-
-        realConfDeleteMsg = g_string_new( confirmMessage );
-        realConfDelOpenMsg = g_string_new( beingEditedMessage );
-        beingEditedList = NULL;
-        for ( ; sel ; sel = sel->next ) {
-                sx = (SchedXaction*)gtk_clist_get_row_data( cl, GPOINTER_TO_INT(sel->data));
-                g_string_append_printf( realConfDeleteMsg, "\n\"%s\"",
-                                        xaccSchedXactionGetName( sx ) );
-                if ( (l = gnc_find_gui_components( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
-                                                   editor_component_sx_equality,
-                                                   sx )) ) {
-                        beingEditedList = g_list_append( beingEditedList, (gpointer)l );
-                        g_string_append_printf( realConfDelOpenMsg, "\n\"%s\"",
-                                                xaccSchedXactionGetName( sx ) );
-                }
-        }
-
-        if ( g_list_length( beingEditedList ) > 0 ) {
-                /* Figure out the user's disposition [toward the opened
-                 * transactions], but if it's true, don't act on it until
-                 * they confirm they actually want to do the deletion
-                 * generically.  If it's false, cleanup and return. */
-                if ( ! (destroyOpenedResult =
-                        gnc_verify_dialog( sxd->dialog, FALSE, "%s",
-					   realConfDelOpenMsg->str )) ) {
-                        for ( l = beingEditedList; l; l = l->next ) {
-                                g_list_free( (GList*)l->data );
-                        }
-                        g_list_free( beingEditedList );
-                        goto cleanupStrings;
-                        return; /* unreachable, but clearer. */
-                }
-        }
-
-        if ( gnc_verify_dialog( sxd->dialog, FALSE, "%s",
-				realConfDeleteMsg->str ) ) {
-                /* Close the being-edited transactions. */
-                if ( destroyOpenedResult ) {
-                        GList *component;
-                        for ( l = beingEditedList; l; l = l->next ) {
-                                SplitRegister *reg;
-                                component = (GList*)l->data;
-                                /* We'd like to force the cancellation of
-                                 * ledger/other changes, here. */
-                                reg = gnc_ledger_display_get_split_register(
-                                        ((SchedXactionEditorDialog*)component
-                                         ->data)
-                                        ->ledger );
-                                gnc_split_register_cancel_cursor_trans_changes(
-                                        reg );
-                                editor_cancel_button_clicked(
-                                        NULL,
-                                        (SchedXactionEditorDialog*)component
-                                        ->data );
-                                g_list_free( component );
-                        }
-                        g_list_free( beingEditedList );
-                }
-
-                /* Now, actually do the deletions... */
-                book = gnc_get_current_book ();
-                sxList = gnc_book_get_schedxactions( book );
-                for ( sel = cl->selection; sel; sel = sel->next ) {
-                        SxRuntimeInfo *sxri;
-                        SxRuntimeInfo **p_sxri = &sxri;
-                        gpointer unused;
-                        gboolean foundP;
-
-                        sx = (SchedXaction*)gtk_clist_get_row_data( cl, GPOINTER_TO_INT(sel->data));
-                        sxList = g_list_remove( sxList, (gpointer)sx );
-                        gnc_book_set_schedxactions( book, sxList );
-
-                        foundP = g_hash_table_lookup_extended( sxd->sxData, sx,
-                                                               &unused,
-                                                               (gpointer*)p_sxri );
-                        g_assert( foundP );
-                        if ( sxri->markTag != -1 ) {
-                                gnc_dense_cal_mark_remove( sxd->gdcal, sxri->markTag );
-                        }
-                        g_hash_table_remove( sxd->sxData, sx );
-                        xaccSchedXactionFree( sx );
-                }
-
-                gtk_clist_freeze( cl );
-                /* Remove the selected and deleted rows from the clist in
-                 * reverse order so each index is valid. */
-                sel = g_list_copy( cl->selection );
-                sel = g_list_reverse( sel );
-                gtk_clist_unselect_all( cl );
-                for ( ; sel; sel = sel->next ) {
-                        gtk_clist_remove( cl, GPOINTER_TO_INT(sel->data) );
-                }
-                g_list_free( sel );
-                sel = NULL;
-                gtk_clist_thaw( cl );
-        }
-
- cleanupStrings:
-        g_string_free( realConfDeleteMsg, TRUE );
-        g_string_free( realConfDelOpenMsg, TRUE );
-}
-
-static
-void
-endgroup_rb_toggled( GtkButton *b, gpointer d )
-{
-        /* figure out which one */
-        SchedXactionEditorDialog *sxed;
-        gint id;
-
-        sxed = (SchedXactionEditorDialog*)d;
-        id = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(b), "whichOneAmI" ));
-
-        switch (id) {
-        case END_NEVER_OPTION:
-                set_endgroup_toggle_states( sxed, END_NEVER );
-                break;
-        case END_DATE_OPTION:
-                set_endgroup_toggle_states( sxed, END_DATE );
-                break;
-        case NUM_OCCUR_OPTION:
-                set_endgroup_toggle_states( sxed, END_OCCUR );
-                break;
-        default:
-                g_error( "Unknown id %d", id );
-                break;
-        }
-
-        gnc_sxed_update_cal( sxed );
-}
-
-/**
- * This is a copy of more complex code from dialog-sxsincelast.c.  They
- * should probably be combined into a single useful function somewhere.
- **/
-static
-void
-generate_instances( SchedXaction *sx,
-                    GDate *end, GList **instanceList )
-{
-        GDate gd, *gdToReturn;
-        void *seqStateData;
-
-        /* Process valid next instances */
-        seqStateData = gnc_sx_create_temporal_state( sx );
-        gd = xaccSchedXactionGetNextInstance( sx, seqStateData );
-        while ( g_date_valid(&gd)
-                && g_date_compare( &gd, end ) <= 0 ) {
-
-                gdToReturn = g_date_new();
-                *gdToReturn = gd;
-                *instanceList = g_list_append( *instanceList, gdToReturn );
-
-                gnc_sx_incr_temporal_state( sx, seqStateData );
-                gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
-        }
-        gnc_sx_destroy_temporal_state( seqStateData );
-        seqStateData = NULL;
-}
-
-static
-void
-_gnc_sxd_free_dates( gpointer data, gpointer user_data )
-{
-        g_date_free( (GDate*)data );
-}
-
-static
-SxRuntimeInfo*
-_new_sx_runtime_info( SchedXaction *sx )
-{
-        SxRuntimeInfo *sxri;
-
-        sxri = g_new0( SxRuntimeInfo, 1 );
-        sxri->sx      = sx;
-        sxri->row     = -1;
-        sxri->markTag = -1;
-        return sxri;
-}
-
-static
-void
-putSchedXactionInDialog( gpointer data, gpointer user_data )
-{
-        SchedXaction *sx;
-        SchedXactionDialog *sxd;
-        GtkCList *clist;
-        char *text[3];
-        GString *freqStr;
-        GString *nextDate;
-        int i;
-        GDate *nextInstDate = NULL, *calEndDate;
-        int instArraySize;
-        GDate **instArray;
-        GList *instList;
-        gpointer unused;
-        SxRuntimeInfo *sxri = NULL;
-        SxRuntimeInfo **p_sxri = &sxri;
-        gboolean foundP;
-        gint gdcMarkTag;
-        gint row;
-
-        sx = (SchedXaction*)data;
-        sxd = (SchedXactionDialog*)user_data;
-
-        freqStr = g_string_new( "" );
-        nextDate = g_string_new( "" );
-
-        xaccFreqSpecGetFreqStr( xaccSchedXactionGetFreqSpec(sx), freqStr );
-
-        calEndDate = g_date_new_dmy( 1,
-                                     gnc_dense_cal_get_month(sxd->gdcal),
-                                     gnc_dense_cal_get_year(sxd->gdcal) );
-        g_date_add_months( calEndDate,
-                           gnc_dense_cal_get_num_months(sxd->gdcal) );
-
-        instList = NULL;
-        generate_instances( sx, calEndDate, &instList );
-        g_date_free( calEndDate );
-
-        if ( instList == NULL ) {
-                /* This was a bug [#90326]; while we do want to generate
-                 * instances within the visible calendar range, we also want
-                 * to generate the first, next SX instance regardless of the
-                 * calendar range.  Thus, if the generate_instances above
-                 * returns nothing, double-check with the SX. */
-                nextInstDate = g_date_new();
-                *nextInstDate = xaccSchedXactionGetNextInstance( sx, NULL );
-                if ( g_date_valid( nextInstDate ) ) {
-                        instList = g_list_append( instList,
-                                                  (gpointer)nextInstDate );
-                }
-        }
-
-        if ( instList == NULL ) {
-                g_string_printf( nextDate, _("Not scheduled") );
-        } else {
-                char tmpBuf[ MAX_DATE_LENGTH+1 ];
-                char dowBuf[ 25 ]; /* <- FIXME: appropriate length? */
-                nextInstDate = (GDate*)instList->data;
-                qof_print_gdate( tmpBuf, MAX_DATE_LENGTH, nextInstDate );
-                g_date_strftime( dowBuf, 25, "%A", nextInstDate );
-                g_string_printf( nextDate, "%s (%s)", tmpBuf, dowBuf );
-        }
-
-        /* Add markings to GncDenseCal */
-        gdcMarkTag = -1;
-        if ( instList != NULL ) {
-                GList *l;
-                FreqSpec *fs;
-                GString *freqDesc;
-
-                instArraySize = g_list_length( instList );
-                instArray = g_new0( GDate*, instArraySize );
-                for ( i=0, l=instList; l; l = l->next ) {
-                        instArray[i++] = (GDate*)l->data;
-                }
-                freqDesc = g_string_sized_new(64);
-                fs = xaccSchedXactionGetFreqSpec(sx);
-                xaccFreqSpecGetFreqStr(fs, freqDesc );
-                gdcMarkTag = gnc_dense_cal_mark( sxd->gdcal,
-                                                 instArraySize, instArray,
-                                                 xaccSchedXactionGetName(sx),
-                                                 freqDesc->str );
-                g_string_free( freqDesc, TRUE );
-                g_free( instArray );
-                g_list_foreach( instList, _gnc_sxd_free_dates, NULL );
-                g_list_free( instList );
-                nextInstDate = NULL;
-        }
-
-        foundP = g_hash_table_lookup_extended( sxd->sxData,
-                                               (gpointer)sx,
-                                               &unused,
-                                               (gpointer*)p_sxri );
-        if ( ! foundP )
-        {
-                // new SX -- create runtime storage for it
-                sxri = _new_sx_runtime_info( sx );
-                sxri->markTag = gdcMarkTag;
-        }
-        else
-        {
-                // existing SX; remove it's 
-                if ( sxri->markTag != -1 ) {
-                        gnc_dense_cal_mark_remove( sxd->gdcal, sxri->markTag );
-                        sxri->markTag = gdcMarkTag;
-                }
-        }
-
-
-        text[0] = xaccSchedXactionGetName( sx );
-        text[1] = freqStr->str;
-        text[2] = nextDate->str;
-
-        clist = GTK_CLIST( glade_xml_get_widget( sxd->gxml, SX_LIST ) );
-        gtk_clist_freeze( clist );
-
-        row = gtk_clist_find_row_from_data( clist, (gpointer)sx );
-        if ( sxri->row == -1 ) {
-                /* new item to be inserted */
-                sxri->row = gtk_clist_append( clist, text );
-                gtk_clist_set_row_data( clist, sxri->row, sx );
-        } else {
-                for ( i=0; i<3; i++ ) {
-                        gtk_clist_set_text( clist, sxri->row, i, text[i] );
-                }
-        }
-        gtk_clist_sort( clist );
-        gtk_clist_thaw( clist );
-        g_hash_table_insert( sxd->sxData, (gpointer)sx, (gpointer)sxri );
-        sxri = NULL;
-
-        g_string_free( freqStr,  TRUE );
-        g_string_free( nextDate, TRUE );
-}
-
-/********************************************************************\
- * gnc_register_check_close                                         *
- *                                                                  *
- * Args:   regData - the data struct for this register              *
- * Return: none                                                     *
-\********************************************************************/
-static void
-gnc_sxed_reg_check_close(SchedXactionEditorDialog *sxed)
-{
-        gboolean pending_changes;
-        SplitRegister *reg;
-        const char *message =
-                _("The current template transaction "
-                  "has been changed. "
-                  "Would you like to record the changes?");
-        
-        reg = gnc_ledger_display_get_split_register (sxed->ledger);
-        pending_changes = gnc_split_register_changed (reg);
-        if (!pending_changes) {
-                return;
-        }
-
-        if (gnc_verify_dialog(sxed->dialog, TRUE, message)) {
-                Transaction *trans;
-                trans = gnc_split_register_get_current_trans( reg );
-                if ( !gnc_split_register_save( reg, TRUE ) )
-                        return;
-                
-                gnc_split_register_redraw( reg );
-        } else {
-                gnc_split_register_cancel_cursor_trans_changes (reg);
-        }
-}
-
-static gboolean
-editor_component_sx_equality( gpointer find_data,
-                              gpointer user_data )
-{
-        return ( (SchedXaction*)find_data
-                 == ((SchedXactionEditorDialog*)user_data)->sx );
-}
-
-static
-void
-gnc_sxd_row_click_handler( GtkCList *clist,
-                           gint col,
-                           gpointer ud )
-{
-        SchedXactionDialog *sxd = (SchedXactionDialog*)ud;
-
-        if ( col == sxd->currentSortCol ) {
-                g_assert( sxd->currentSortType == GTK_SORT_ASCENDING
-                          || sxd->currentSortType == GTK_SORT_DESCENDING );
-                switch ( sxd->currentSortType ) {
-                case GTK_SORT_ASCENDING:
-                        sxd->currentSortType = GTK_SORT_DESCENDING;
-                        break;
-                case GTK_SORT_DESCENDING:
-                        sxd->currentSortType = GTK_SORT_ASCENDING;
-                        break;
-                default:
-                        PERR( "Unknown current sort type %d",
-                              sxd->currentSortType );
-                }
-                /* By defn, the current sort_compare method is correct. */
-                gtk_clist_set_sort_column( clist, col );
-                gtk_clist_set_sort_type( clist, sxd->currentSortType );
-                gtk_clist_sort( clist );
-                return;
-        }
-
-        sxd->currentSortCol = col;
-        gnc_sxd_set_sort_compare( clist, sxd->currentSortCol );
-        sxd->currentSortType = GTK_SORT_ASCENDING;
-        gtk_clist_set_sort_column( clist, sxd->currentSortCol );
-        gtk_clist_set_sort_type( clist, sxd->currentSortType );
-        gtk_clist_sort( clist );
-}
-
-static
-gint
-gnc_sxd_clist_compare_sx_name( GtkCList *cl, gconstpointer a, gconstpointer b )
-{
-        SchedXaction *sxa, *sxb;
-
-        sxa = (SchedXaction*)(((GtkCListRow*)a)->data);
-        sxb = (SchedXaction*)(((GtkCListRow*)b)->data);
-        g_assert( sxa || sxb );
-        if ( !sxa ) {
-                return 1;
-        }
-        if ( !sxb ) {
-                return -1;
-        }
-        return strcmp( xaccSchedXactionGetName( sxa ),
-                       xaccSchedXactionGetName( sxb ) );
-}
-
-static
-gint
-gnc_sxd_clist_compare_sx_freq( GtkCList *cl,
-                               gconstpointer a,
-                               gconstpointer b )
-{
-        SchedXaction *sxa, *sxb;
-
-        g_assert( a || b );
-        if ( !a ) return 1;
-        if ( !b ) return -1;
-        sxa = (SchedXaction*)((GtkCListRow*)a)->data;
-        sxb = (SchedXaction*)((GtkCListRow*)b)->data;
-        g_assert( sxa || sxb );
-        if ( !sxa ) return 1;
-        if ( !sxb ) return -1;
-        return gnc_freq_spec_compare( xaccSchedXactionGetFreqSpec( sxa ),
-                                      xaccSchedXactionGetFreqSpec( sxb ) );
-}
-
-static
-gint
-gnc_sxd_clist_compare_sx_next_occur( GtkCList *cl,
-                                     gconstpointer a,
-                                     gconstpointer b )
-{
-        SchedXaction *sxa, *sxb;
-        GDate gda, gdb;
-
-        sxa = (SchedXaction*)((GtkCListRow*)a)->data;
-        sxb = (SchedXaction*)((GtkCListRow*)b)->data;
-
-        g_assert( sxa || sxb );
-        if ( !sxa ) {
-                return 1;
-        }
-        if ( !sxb ) {
-                return -1;
-        }
-        g_assert( sxa && sxb );
-
-        gda = xaccSchedXactionGetNextInstance( sxa, NULL );
-        gdb = xaccSchedXactionGetNextInstance( sxb, NULL );
-
-        if ( ! ( g_date_valid(&gda) && g_date_valid(&gdb) ) ) {
-                return 0;
-        }
-        if ( !g_date_valid(&gda) ) {
-                return 1;
-        }
-        if ( !g_date_valid(&gdb) ) {
-                return -1;
-        }
-        return g_date_compare( &gda, &gdb );
-}
-
-
-static
-void
-gnc_sxd_set_sort_compare( GtkCList *cl, gint col )
-{
-        gint (*fn)( GtkCList *, gconstpointer, gconstpointer );
-
-        fn = NULL;
-        switch ( col ) {
-        case 0: /* SX name */
-                fn = gnc_sxd_clist_compare_sx_name;
-                break;
-        case 1: /* SX frequency */
-                fn = gnc_sxd_clist_compare_sx_freq;
-                break;
-        case 2: /* next-occur date */
-                fn = gnc_sxd_clist_compare_sx_next_occur;
-                break;
-        default: /* ?? */
-                DEBUG( "invalid column value %d", col );
-                g_assert( FALSE );
-        }
-        gtk_clist_set_compare_func( cl, NULL );
-        gtk_clist_set_compare_func( cl, fn );
-}
-
-typedef enum { NO_END, DATE_END, COUNT_END } END_TYPE;
-
-static
-void
-gnc_sxed_update_cal( SchedXactionEditorDialog *sxed )
-{
-        int i;
-        FreqSpec *fs;
-        GDate d;
-        END_TYPE endType;
-        GDate endDate;
-        int numRemain;
-
-        endType = NO_END;
-        numRemain = -1;
-        /* figure out the end restriction */
-        if ( gtk_toggle_button_get_active( sxed->optEndDate ) ) {
-                time_t tt;
-                struct tm *tmpTm;
-                endType = DATE_END;
-                tt = gnc_date_edit_get_date( sxed->endDateEntry );
-                tmpTm = g_new0( struct tm, 1 );
-                *tmpTm = *(localtime( &tt ));
-                g_date_set_day( &endDate, tmpTm->tm_mday );
-                g_date_set_month( &endDate, tmpTm->tm_mon+1 );
-                g_date_set_year( &endDate, tmpTm->tm_year + 1900 );
-                g_free( tmpTm );
-        } else if ( gtk_toggle_button_get_active( sxed->optEndNone ) ) {
-                endType = NO_END;
-        } else if ( gtk_toggle_button_get_active( sxed->optEndCount ) ) {
-                endType = COUNT_END;
-		numRemain =
-		  gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(sxed->endRemainSpin) );
-
-        } else {
-                g_assert( FALSE );
-        }
-
-        if ( sxed->markId != -1 ) {
-                gnc_dense_cal_mark_remove( sxed->example_cal, sxed->markId );
-                sxed->markId = -1;
-        }
-
-        fs = xaccFreqSpecMalloc( gnc_get_current_book() );
-        gnc_frequency_save_state( sxed->gncfreq, fs, &d );
-        g_date_subtract_days( &d, 1 );
-        xaccFreqSpecGetNextInstance( fs, &d, &d );
-
-        /* Deal with the fact that this SX may have been run before [the
-         * calendar should only show upcoming instances]... */
-        {
-                GDate *lastInst;
-
-                lastInst = xaccSchedXactionGetLastOccurDate( sxed->sx );
-                if ( g_date_valid( lastInst )
-                     && g_date_valid( &d )
-                     && g_date_compare( lastInst, &d ) != 0 ) {
-                        d = *lastInst;
-                        xaccFreqSpecGetNextInstance( fs, &d, &d );
-                }
-        }
-
-        if ( !g_date_valid( &d ) ) {
-                /* Nothing to do. */
-                xaccFreqSpecFree( fs );
-                return;
-        }
-
-        i = 0;
-        gnc_dense_cal_set_month( sxed->example_cal, g_date_get_month( &d ) );
-        gnc_dense_cal_set_year(  sxed->example_cal, g_date_get_year( &d ) );
-        while ( (i < EX_CAL_NUM_MONTHS * 31)
-                && g_date_valid( &d )
-                /* Restrict based on end date */
-                && ( endType == NO_END
-                     || ( endType == DATE_END
-                          && g_date_compare( &d, &endDate ) <= 0 )
-                     || ( endType == COUNT_END
-                          && i < numRemain ) ) ) {
-                *(sxed->cal_marks[i++]) = d;
-                xaccFreqSpecGetNextInstance( fs, &d, &d );
-        }
-        if ( i <= 0 ) {
-                xaccFreqSpecFree( fs );
-                return;
-        }
-
-        { 
-                gchar *name;
-                GString *info;
-
-                name = gtk_editable_get_chars( sxed->nameEntry, 0, -1 );
-                if ( strlen( name ) == 0 ) {
-                        g_free(name);
-                        name = NULL;
-                }
-                info = g_string_sized_new( 16 );
-                xaccFreqSpecGetFreqStr( fs, info );
-                sxed->markId = gnc_dense_cal_mark( sxed->example_cal, i,
-                                                   sxed->cal_marks,
-                                                   name, info->str );
-                gtk_widget_queue_draw( GTK_WIDGET( sxed->example_cal ) );
-
-                g_string_free( info, TRUE );
-                if ( name != NULL )
-                {
-                        g_free( name );
-                }
-        }
-
-        xaccFreqSpecFree( fs );
-}
-
-static
-void
-gnc_sxed_freq_changed( GNCFrequency *gf, gpointer ud )
-{
-        gnc_sxed_update_cal( (SchedXactionEditorDialog*)ud );
-}
-
-static
-void
-sxed_excal_update_adapt( GtkObject *o, gpointer ud )
-{
-        gnc_sxed_update_cal( (SchedXactionEditorDialog*)ud );
-}
-
-void on_sx_check_toggled (GtkWidget *togglebutton, gpointer user_data);
-
-void
-on_sx_check_toggled (GtkWidget *togglebutton,
-		     gpointer user_data)
-{
-  GtkWidget *widget;
-  gboolean create; // , notify;
-
-  /* The gnc_glade_lookup_widget() function works because all of these
-   * widgets come from the same glade file. */
-  widget = gnc_glade_lookup_widget(togglebutton,
-	"gconf/dialogs/scheduled_trans/transaction_editor/create_auto");
-  create = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-  widget = gnc_glade_lookup_widget(togglebutton,
-	"gconf/dialogs/scheduled_trans/transaction_editor/notify");
-  gtk_widget_set_sensitive(widget, create);
-}
-
-typedef struct _acct_deletion_handler_data
-{
-  GList *affected_sxes;
-  GtkWidget *dialog;
-} acct_deletion_handler_data;
-
-static void
-_open_editors(GtkDialog *dialog, gint response_code, gpointer data)
-{
-  acct_deletion_handler_data *adhd = (acct_deletion_handler_data *)data;
-  gtk_widget_hide_all(adhd->dialog);
-  {
-    GList *sx_iter;
-    for (sx_iter = adhd->affected_sxes; sx_iter; sx_iter = sx_iter->next)
-    {
-      gnc_ui_scheduled_xaction_editor_dialog_create(NULL, 
-                                                    (SchedXaction*)sx_iter->data,
-                                                    FALSE);
-    }
-  }
-  g_list_free(adhd->affected_sxes);
-  gtk_widget_destroy(GTK_WIDGET(adhd->dialog));
-  g_free(adhd);
-}
-
-static void
-_sx_engine_event_handler(QofEntity *ent, QofEventId event_type, gpointer user_data, gpointer evt_data)
-{
-  Account *acct;
-  QofBook *book;
-  GList *affected_sxes;
-
-  if (!(event_type & QOF_EVENT_DESTROY))
-    return;
-  if (!GNC_IS_ACCOUNT(ent))
-    return;
-  acct = GNC_ACCOUNT(ent);
-  book = qof_instance_get_book(QOF_INSTANCE(acct));
-  affected_sxes = gnc_sx_get_sxes_referencing_account(book, acct);
-
-  if (g_list_length(affected_sxes) == 0)
-     return;
-
-  {
-    GList *sx_iter;
-    acct_deletion_handler_data *data;
-    GladeXML *xml;
-    GtkWidget *dialog;
-    GtkListStore *name_list;
-    GtkTreeView *list;
-    GtkTreeViewColumn *name_column;
-    GtkCellRenderer *renderer;
-
-    xml = gnc_glade_xml_new("sched-xact.glade", "Account Deletion");
-    dialog = glade_xml_get_widget(xml, "Account Deletion");
-    list = GTK_TREE_VIEW(glade_xml_get_widget(xml, "sx_list"));
-
-    data = (acct_deletion_handler_data*)g_new0(acct_deletion_handler_data, 1);
-    data->dialog = dialog;
-    data->affected_sxes = affected_sxes;
-    name_list = gtk_list_store_new(1, G_TYPE_STRING);
-    for (sx_iter = affected_sxes; sx_iter != NULL; sx_iter = sx_iter->next)
-    {
-      SchedXaction *sx;
-      GtkTreeIter iter;
-      gchar *sx_name;
-
-      sx = (SchedXaction*)sx_iter->data;
-      sx_name = xaccSchedXactionGetName(sx);
-      gtk_list_store_append(name_list, &iter);
-      gtk_list_store_set(name_list, &iter, 0, sx_name, -1);
-    }
-    gtk_tree_view_set_model(list, GTK_TREE_MODEL(name_list));
-    g_object_unref(G_OBJECT(name_list));
-
-    renderer = gtk_cell_renderer_text_new();
-    name_column = gtk_tree_view_column_new_with_attributes(_("Name"),
-                                                           renderer,
-                                                           "text", 0, NULL);
-    gtk_tree_view_append_column(list, name_column);
-
-    g_signal_connect(G_OBJECT(dialog), "response",
-                     G_CALLBACK(_open_editors), data);
-
-    gtk_widget_show_all(GTK_WIDGET(dialog));
-  }
-}
-
-void
-gnc_ui_sx_initialize (void)
-{
-  _sx_engine_event_handler_id = qof_event_register_handler(_sx_engine_event_handler, NULL);
-
-  gnc_hook_add_dangler(HOOK_BOOK_OPENED,
-		       (GFunc)gnc_sx_sxsincelast_book_opened, NULL);
-  gnc_preferences_add_page (SX_GLADE_FILE,
-			    "sx_prefs",
-			    _("Scheduled Transactions"));
-}

Deleted: gnucash/trunk/src/gnome/dialog-scheduledxaction.h
===================================================================
--- gnucash/trunk/src/gnome/dialog-scheduledxaction.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/dialog-scheduledxaction.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,67 +0,0 @@
-/********************************************************************\
- * dialog-scheduledxaction.h : dialogs for scheduled transactions   *
- * Copyright (C) 2001 Joshua Sled <jsled at asynchronous.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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-#ifndef DIALOG_SCHEDULEDXACTION_H
-#define DIALOG_SCHEDULEDXACTION_H
-
-#include "SchedXaction.h"
-
-#define DIALOG_SCHEDXACTION_CM_CLASS "dialog-scheduledtransactions"
-#define DIALOG_SCHEDXACTION_EDITOR_CM_CLASS "dialog-scheduledtransaction-editor"
-
-#define SXED_GCONF_SECTION "dialogs/scheduled_trans/transaction_editor"
-#define KEY_CREATE_AUTO	"create_auto"
-#define KEY_NOTIFY	"notify"
-#define KEY_CREATE_DAYS	"create_days"
-#define KEY_REMIND_DAYS	"remind_days"
-
-struct _SchedXactionDialog;
-struct _SchedXactionEditorDialog;
-
-typedef struct _SchedXactionDialog SchedXactionDialog;
-typedef struct _SchedXactionEditorDialog SchedXactionEditorDialog;
-
-SchedXactionDialog * gnc_ui_scheduled_xaction_dialog_create(void);
-void gnc_ui_scheduled_xaction_dialog_destroy(SchedXactionDialog *sxd);
-#ifdef __GTK_CLIST_H__
-void row_select_handler( GtkCList *clist, gint row, gint col,
-                         GdkEventButton *event, gpointer d );
-void row_unselect_handler( GtkCList *clist, gint row, gint col,
-                         GdkEventButton *event, gpointer d );
-#endif
-
-void gnc_sxd_list_refresh( SchedXactionDialog *sxd );
-
-SchedXactionEditorDialog *
-gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
-					       SchedXaction *sx,
-                                               gboolean newSX );
-
-void gnc_ui_scheduled_xaction_editor_dialog_destroy( SchedXactionEditorDialog *sxd );
-
-/**
- * Sets up a book opened hook.  The function called may open a "since
- * last run" dialog based upon the user's preferences.
- **/
-void gnc_ui_sx_initialize (void);
-
-#endif

Copied: gnucash/trunk/src/gnome/dialog-sx-editor.c (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c)

Copied: gnucash/trunk/src/gnome/dialog-sx-editor.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.h)

Modified: gnucash/trunk/src/gnome/dialog-sx-from-trans.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-sx-from-trans.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/dialog-sx-from-trans.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -25,26 +25,25 @@
 
 #include "config.h"
 
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include "glib-compat.h"
-
-#include "gnc-engine.h"
-#include "SX-book.h"
-#include "SX-book-p.h"
-#include "SX-ttinfo.h"
-#include "SchedXaction.h"
-#include "gnc-component-manager.h"
-#include "dialog-scheduledxaction.h"
+#include "dialog-sx-editor.h"
 #include "dialog-sx-from-trans.h"
 #include "dialog-utils.h"
+#include "glib-compat.h"
+#include "gnc-component-manager.h"
 #include "gnc-date-edit.h"
-#include "qof.h"
+#include "gnc-dense-cal-store.h"
+#include "gnc-dense-cal.h"
+#include "gnc-engine.h"
 #include "gnc-gconf-utils.h"
-#include "gnc-ui.h"
 #include "gnc-ui-util.h"
-#include "gnc-dense-cal.h"
+#include "gnc-ui.h"
+#include "qof.h"
+#include "SchedXaction.h"
+#include "SX-book.h"
+#include "SX-ttinfo.h"
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
 
 #define SX_GLADE_FILE "sched-xact.glade"
 #define SXFTD_DIALOG_GLADE_NAME "sx_from_real_trans"
@@ -78,11 +77,8 @@
 
 static void sxftd_destroy( GtkWidget *w, gpointer user_data );
 
-typedef enum { NEVER_END, END_ON_DATE, END_AFTER_N_OCCS, BAD_END } endType;
-
 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, 
@@ -97,11 +93,8 @@
   Transaction *trans;
   SchedXaction *sx;
 
+  GncDenseCalStore *dense_cal_model;
   GncDenseCal *example_cal;
-  /** Storage for the maximum possible number of marks we could put on the
-   *  calendar. */
-  GDate **cal_marks;
-  gint mark_id;
 
   GNCDateEdit *startDateGDE, *endDateGDE;
 
@@ -109,7 +102,7 @@
 
 typedef struct
 {
-  endType type;
+  gdcs_end_type type;
   GDate end_date;
   guint n_occurrences;
 } getEndTuple;
@@ -117,9 +110,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;
@@ -127,11 +117,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)
 {
@@ -144,7 +132,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 }
     };
   
@@ -370,20 +357,19 @@
 
   /* Setup the example calendar and related data structures. */
   {
-    int i;
+    int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31;
 
     w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME ));
-    sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new());
+    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)));
+    // gobject-2.10: g_object_ref_sink(sxfti->example_cal);
+    g_object_ref(G_OBJECT(sxfti->example_cal));
+    gtk_object_sink(GTK_OBJECT(sxfti->example_cal));
+
     g_assert( sxfti->example_cal );
     gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
     gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL );
     gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) );
-
-    sxfti->mark_id = -1;
-    sxfti->cal_marks = g_new0( GDate*, (SXFTD_EXCAL_NUM_MONTHS * 31) );
-    for ( i=0; i < SXFTD_EXCAL_NUM_MONTHS * 31; i++ ) {
-      sxfti->cal_marks[i] = g_date_new();
-    }
   }
 
   /* Setup the start and end dates as GNCDateEdits */
@@ -551,7 +537,7 @@
 sxftd_ok_clicked(SXFromTransInfo *sxfti)
 {
   QofBook *book;
-  GList *sx_list;
+  SchedXactions *sxes;
   guint sx_error = sxftd_compute_sx(sxfti);
 
   if (sx_error != 0
@@ -559,23 +545,14 @@
     PERR( "Error in sxftd_compute_sx after ok_clicked [%d]", sx_error );
   }
   else {
-    SchedXactionDialog *sxd;
-
     if ( sx_error == SXFTD_ERRNO_UNBALANCED_XACTION ) {
             gnc_error_dialog( gnc_ui_get_toplevel(), 
                               _( "The Scheduled Transaction is unbalanced. "
                                  "You are strongly encouraged to correct this situation." ) );
     }
     book = gnc_get_current_book ();
-    sx_list = gnc_book_get_schedxactions(book);
-    sx_list = g_list_append(sx_list, sxfti->sx);
-    gnc_book_set_schedxactions(book, sx_list);
-    sxd = (SchedXactionDialog*)
-            gnc_find_first_gui_component(
-                    DIALOG_SCHEDXACTION_CM_CLASS, NULL, NULL );
-    if ( sxd ) {
-      gnc_sxd_list_refresh( sxd );
-    }
+    sxes = gnc_book_get_schedxactions(book);
+    gnc_sxes_add_sx(sxes, sxfti->sx);
   }
 
   sxftd_close(sxfti, FALSE);
@@ -617,8 +594,7 @@
 sxftd_advanced_clicked(SXFromTransInfo *sxfti)
 {
   guint sx_error = sxftd_compute_sx(sxfti);
-  SchedXactionDialog *adv_dlg;
-  SchedXactionEditorDialog *adv_edit_dlg;
+  GncSxEditorDialog *adv_edit_dlg;
   GMainContext *context;
 
   if ( sx_error != 0
@@ -634,10 +610,8 @@
   context = g_main_context_default();
   while (g_main_context_iteration(context, FALSE));
 
-  adv_dlg = gnc_ui_scheduled_xaction_dialog_create();
   adv_edit_dlg =
-    gnc_ui_scheduled_xaction_editor_dialog_create(adv_dlg, 
-                                                  sxfti->sx,
+    gnc_ui_scheduled_xaction_editor_dialog_create(sxfti->sx,
                                                   TRUE /* newSX */);
   /* close ourself, since advanced editing entails us, and there are sync
    * issues otherwise. */
@@ -647,28 +621,21 @@
 static void
 sxftd_destroy( GtkWidget *w, gpointer user_data )
 {
-  int i;
   SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data;
 
-  for ( i=0; i<SXFTD_EXCAL_NUM_MONTHS*31; i++ ) {
-    g_date_free( sxfti->cal_marks[i] );
-  }
-  g_free( sxfti->cal_marks );
-    
   if ( sxfti->sx ) {
     xaccSchedXactionFree(sxfti->sx);
     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,
@@ -696,7 +663,6 @@
 	LEAVE(" ");
 }
 
-
 /**
  * Update the example calendar; make sure to take into account the end
  * specification.
@@ -707,11 +673,8 @@
   struct tm *tmpTm;
   time_t tmp_tt;
   GDate date, startDate;
-  unsigned int i;
   FreqSpec *fs;
   getEndTuple get;
-  gchar *name;
-  GString *info;
 
   fs = xaccFreqSpecMalloc( gnc_get_current_book() );
   get = sxftd_get_end_info( sxfti );
@@ -733,43 +696,27 @@
   xaccFreqSpecGetNextInstance( fs, &date, &date );
   startDate = date;
 
-  i = 0;
-  while ( (i < (SXFTD_EXCAL_NUM_MONTHS * 31))
-          && g_date_valid( &date )
-          /* Do checking against end restriction. */
-          && ( ( get.type == NEVER_END )
-               || ( get.type == END_ON_DATE
-                    && g_date_compare( &date, &(get.end_date) ) <= 0 )
-               || ( get.type == END_AFTER_N_OCCS
-                    && i < get.n_occurrences ) ) ) {
-
-    *sxfti->cal_marks[i++] = date;
-    xaccFreqSpecGetNextInstance( fs, &date, &date );
+  switch (get.type)
+  {
+  case NEVER_END:
+    gnc_dense_cal_store_update_no_end(sxfti->dense_cal_model, &startDate, fs);
+    break;
+  case END_ON_DATE:
+    gnc_dense_cal_store_update_date_end(sxfti->dense_cal_model, &startDate, fs, &get.end_date);
+    break;
+  case END_AFTER_N_OCCS:
+    gnc_dense_cal_store_update_count_end(sxfti->dense_cal_model, &startDate, fs, get.n_occurrences);
+    break;
+  default:
+    printf("unknown get.type [%d]\n", get.type);
+    break;
   }
-  /* remove old marks */
-  if ( sxfti->mark_id != -1 ) {
-    gnc_dense_cal_mark_remove( sxfti->example_cal, sxfti->mark_id );
-    sxfti->mark_id = -1;
-  }
-  if ( i > 0 ) {
-    GtkWidget *w;
-    gnc_dense_cal_set_month( sxfti->example_cal,
-                             g_date_get_month( &startDate ) );
-    gnc_dense_cal_set_year( sxfti->example_cal,
-                            g_date_get_year( &startDate ) );
-    w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY );
-    name = gtk_editable_get_chars( GTK_EDITABLE(w), 0, -1 );
-    info = g_string_sized_new( 16 );
-    xaccFreqSpecGetFreqStr( fs, info );
-    sxfti->mark_id =
-      gnc_dense_cal_mark( sxfti->example_cal,
-                          i, sxfti->cal_marks,
-                          name, info->str );
-    gtk_widget_queue_draw( GTK_WIDGET(sxfti->example_cal) );
-    g_free( name );
-    g_string_free( info, TRUE );
-  }
 
+  gnc_dense_cal_set_month( sxfti->example_cal,
+                           g_date_get_month( &startDate ) );
+  gnc_dense_cal_set_year( sxfti->example_cal,
+                          g_date_get_year( &startDate ) );
+
   xaccFreqSpecFree( fs );
 }
 
@@ -784,10 +731,6 @@
   sxftd_update_example_cal( sxfti );
 }
 
-
-/**
- *
- **/
 void
 gnc_sx_create_from_trans( Transaction *trans )
 {

Copied: gnucash/trunk/src/gnome/dialog-sx-since-last-run.c (from rev 15384, 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-15 01:57:07 UTC (rev 15384)
+++ gnucash/trunk/src/gnome/dialog-sx-since-last-run.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -0,0 +1,1105 @@
+/********************************************************************\
+ * dialog-sx-since-last-run.c : dialog for scheduled transaction    *
+ * since-last-run processing.                                       *
+ * Copyright (C) 2006 Joshua Sled <jsled at asynchronous.org>          *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of version 2 of the GNU General Public *
+ * License as published by the Free Software Foundation.            *
+ *                                                                  *
+ * 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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#include "config.h"
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glade/glade-xml.h>
+
+#include "dialog-utils.h"
+#include "gnc-exp-parser.h"
+#include "gnc-sx-instance-model.h"
+#include "dialog-sx-since-last-run.h"
+
+#include "gnc-ui-util.h"
+#include "Query.h"
+#include "QueryNew.h"
+#include "gnc-ledger-display.h"
+#include "gnc-plugin-page-register.h"
+#include "gnc-main-window.h"
+#include "gnc-component-manager.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-gui-query.h"
+
+// static QofLogModule log_module = GNC_MOD_GUI;
+
+#define GCONF_SECTION "dialogs/scheduled_trans/since_last_run"
+
+struct _GncSxSinceLastRunDialog
+{
+     GtkWidget *dialog;
+     GncSxSlrTreeModelAdapter *editing_model;
+     GtkTreeView *instance_view;
+     GtkToggleButton *review_created_txns_toggle;
+};
+
+/* ------------------------------------------------------------ */
+
+static GObjectClass *parent_class = NULL;
+
+struct _GncSxSlrTreeModelAdapter
+{
+     GObject parent;
+
+     /* protected: */
+     gulong updated_cb_id;
+     gboolean disposed;
+
+     GncSxInstanceModel *instances;
+     GtkTreeStore *real;
+};
+
+typedef struct _GncSxSlrTreeModelAdapterClass
+{
+     GObjectClass parent;
+} GncSxSlrTreeModelAdapterClass;
+
+GType gnc_sx_slr_tree_model_adapter_get_type(void);
+static void gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass);
+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);
+
+GncSxInstanceModel* gnc_sx_slr_tree_model_adapter_get_instance_model(GncSxSlrTreeModelAdapter *slr_model);
+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);
+/** @return null if the iter is not actually an GncSxInstance. **/
+GncSxInstance* gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
+static GncSxInstance* _gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth);
+/** @return false if the iter is not actaully an GncSxInstance's variable. **/
+gboolean gnc_sx_slr_model_get_instance_and_variable(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, GncSxInstance **instance_loc, GncSxVariable **var_loc);
+
+void gnc_sx_slr_model_change_instance_state(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxInstanceState new_state);
+void gnc_sx_slr_model_change_variable(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxVariable *variable, gnc_numeric *new_value);
+void gnc_sx_slr_model_effect_change(GncSxSlrTreeModelAdapter *model, gboolean auto_create_only, GList **created_transaction_guids, GList **creation_errors);
+
+GtkTreeModel* gnc_sx_get_slr_state_model(void);
+
+#define GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER	      (gnc_sx_slr_tree_model_adapter_get_type ())
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER(obj)	      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapter))
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
+#define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER(obj)	      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
+#define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
+
+/* ------------------------------------------------------------ */
+
+static void _show_created_transactions(GncSxSinceLastRunDialog *app_dialog, GList *created_txn_guids);
+
+static void dialog_response_cb(GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog *app_dialog);
+
+/* ------------------------------------------------------------ */
+
+static void
+_var_numeric_to_string(gnc_numeric *value, GString **str)
+{
+     *str = g_string_sized_new(5);
+     g_string_printf(*str, "%0.2f", gnc_numeric_to_double(*value));
+}
+
+/* ------------------------------------------------------------ */
+
+GType
+gnc_sx_slr_tree_model_adapter_get_type(void)
+{
+     static GType gsstma_type = 0;
+     if (gsstma_type == 0) {
+          static const GTypeInfo info = {
+               sizeof (GncSxSlrTreeModelAdapterClass),
+               NULL,   /* base_init */
+               NULL,   /* base_finalize */
+               (GClassInitFunc)gnc_sx_slr_tree_model_adapter_class_init,   /* class_init */
+               NULL,   /* class_finalize */
+               NULL,   /* class_data */
+               sizeof (GncSxSlrTreeModelAdapter),
+               0,      /* n_preallocs */
+               (GInstanceInitFunc)gnc_sx_slr_tree_model_adapter_init    /* instance_init */
+          };
+          static const GInterfaceInfo itreeModel_info = {
+               (GInterfaceInitFunc) gnc_sx_slr_tree_model_adapter_interface_init,    /* interface_init */
+               NULL,               /* interface_finalize */
+               NULL                /* interface_data */
+          };
+
+          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 gsstma_type;
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass)
+{
+     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
+gsslrtma_get_flags(GtkTreeModel *tree_model)
+{
+     return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
+}
+
+static gint
+gsslrtma_get_n_columns(GtkTreeModel *tree_model)
+{
+     return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
+}
+
+static GType
+gsslrtma_get_column_type(GtkTreeModel *tree_model, gint index)
+{
+     return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), index);
+}
+
+static gboolean
+gsslrtma_get_iter(GtkTreeModel *tree_model,
+                GtkTreeIter *iter,
+                GtkTreePath *path)
+{
+     return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
+}
+
+static GtkTreePath*
+gsslrtma_get_path(GtkTreeModel *tree_model,
+                GtkTreeIter *iter)
+{
+     return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gsslrtma_get_value(GtkTreeModel *tree_model,
+                 GtkTreeIter *iter,
+                 gint column,
+                 GValue *value)
+{
+     gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
+}
+
+static gboolean
+gsslrtma_iter_next(GtkTreeModel *tree_model,
+                 GtkTreeIter *iter)
+{
+     return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gboolean
+gsslrtma_iter_children(GtkTreeModel *tree_model,
+                     GtkTreeIter *iter,
+                     GtkTreeIter *parent)
+{
+     return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
+}
+
+static gboolean
+gsslrtma_iter_has_child(GtkTreeModel *tree_model,
+                      GtkTreeIter *iter)
+{
+     return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gint
+gsslrtma_iter_n_children(GtkTreeModel *tree_model,
+                       GtkTreeIter *iter)
+{
+     return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gboolean
+gsslrtma_iter_nth_child(GtkTreeModel *tree_model,
+                      GtkTreeIter *iter,
+                      GtkTreeIter *parent,
+                      gint n)
+{
+     return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
+}
+
+static gboolean
+gsslrtma_iter_parent(GtkTreeModel *tree_model,
+                   GtkTreeIter *iter,
+                   GtkTreeIter *child)
+{
+     return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
+}
+
+static void
+gsslrtma_ref_node(GtkTreeModel *tree_model,
+                GtkTreeIter *iter)
+{
+     gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gsslrtma_unref_node(GtkTreeModel *tree_model,
+                  GtkTreeIter *iter)
+{
+     gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data)
+{
+     GtkTreeModelIface *tree_model = (GtkTreeModelIface*)g_iface;
+     tree_model->get_flags = gsslrtma_get_flags;
+     tree_model->get_n_columns = gsslrtma_get_n_columns;
+     tree_model->get_column_type = gsslrtma_get_column_type;
+     tree_model->get_iter = gsslrtma_get_iter;
+     tree_model->get_path = gsslrtma_get_path;
+     tree_model->get_value = gsslrtma_get_value;
+     tree_model->iter_next = gsslrtma_iter_next;
+     tree_model->iter_children = gsslrtma_iter_children;
+     tree_model->iter_has_child = gsslrtma_iter_has_child;
+     tree_model->iter_n_children = gsslrtma_iter_n_children;
+     tree_model->iter_nth_child = gsslrtma_iter_nth_child;
+     tree_model->iter_parent = gsslrtma_iter_parent;
+     tree_model->ref_node = gsslrtma_ref_node;
+     tree_model->unref_node = gsslrtma_unref_node;
+}
+
+static void
+gsslrtma_proxy_row_changed(GtkTreeModel *treemodel,
+                         GtkTreePath *arg1,
+                         GtkTreeIter *arg2,
+                         gpointer user_data)
+{
+     g_signal_emit_by_name(user_data, "row-changed", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_row_deleted(GtkTreeModel *treemodel,
+                         GtkTreePath *arg1,
+                         gpointer user_data)
+{
+     g_signal_emit_by_name(user_data, "row-deleted", arg1);
+}
+
+static void
+gsslrtma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
+                                     GtkTreePath *arg1,
+                                     GtkTreeIter *arg2,
+                                     gpointer user_data)
+{
+     g_signal_emit_by_name(user_data, "row-has-child-toggled", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_row_inserted(GtkTreeModel *treemodel,
+                            GtkTreePath *arg1,
+                            GtkTreeIter *arg2,
+                            gpointer user_data)
+{
+     g_signal_emit_by_name(user_data, "row-inserted", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_rows_reordered(GtkTreeModel *treemodel,
+                              GtkTreePath *arg1,
+                              GtkTreeIter *arg2,
+                              gpointer arg3,
+                              gpointer user_data)
+{
+     g_signal_emit_by_name(user_data, "rows-reordered", arg1, arg2, arg3);
+}
+
+// model columns
+enum {
+     SLR_MODEL_COL_NAME = 0,
+     SLR_MODEL_COL_INSTANCE_STATE,
+     SLR_MODEL_COL_VARAIBLE_VALUE,
+     SLR_MODEL_COL_INSTANCE_VISIBILITY,
+     SLR_MODEL_COL_VARIABLE_VISIBILITY,
+     SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
+};
+
+static void
+gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
+{
+     GncSxSlrTreeModelAdapter *adapter = GNC_SX_SLR_TREE_MODEL_ADAPTER(instance);
+     // columns:    thing-name, instance-state, variable-value, instance-visible, variable-visible, instance_state_sensitivity
+     // at depth=0: <sx>,       N/A,            N/A,            N/A               N/A,              N/A
+     // at depth=1: <instance>, <state>,        N/A,            <valid>,          N/A,              <valid>
+     // at depth=2: <variable>, N/A,            <value>,        N/A,              <valid>,          N/A
+     adapter->real = gtk_tree_store_new(6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+
+     g_signal_connect(adapter->real, "row-changed", G_CALLBACK(gsslrtma_proxy_row_changed), adapter);
+     g_signal_connect(adapter->real, "row-deleted", G_CALLBACK(gsslrtma_proxy_row_deleted), adapter);
+     g_signal_connect(adapter->real, "row-has-child-toggled", G_CALLBACK(gsslrtma_proxy_row_has_child_toggled), adapter);
+     g_signal_connect(adapter->real, "row-inserted", G_CALLBACK(gsslrtma_proxy_row_inserted), adapter);
+     g_signal_connect(adapter->real, "rows-reordered", G_CALLBACK(gsslrtma_proxy_rows_reordered), adapter);
+}
+
+/* @@fixme: i18n. **/
+/* @@fixme: non-staticize. **/
+static char* gnc_sx_instance_state_names[] = {
+     ("Ignored"),
+     ("Postponed"),
+     ("To-Create"),
+     ("Reminder"),
+     ("Created"),
+     NULL
+};
+
+static GtkTreeModel* _singleton_slr_state_model = NULL;
+
+GtkTreeModel*
+gnc_sx_get_slr_state_model(void)
+{
+     if (_singleton_slr_state_model == NULL)
+     {
+          int i;
+          GtkTreeIter iter;
+
+          _singleton_slr_state_model = GTK_TREE_MODEL(gtk_list_store_new(1, G_TYPE_STRING));
+          for (i = 0; i != SX_INSTANCE_STATE_CREATED; i++)
+          {
+               gtk_list_store_insert_with_values(GTK_LIST_STORE(_singleton_slr_state_model),
+                                                 &iter,
+                                                 SX_INSTANCE_STATE_MAX_STATE + 1,
+                                                 0, gnc_sx_instance_state_names[i], -1);
+          }
+     }
+     return _singleton_slr_state_model;
+}
+
+static void
+_consume_excess_rows(GtkTreeStore *store, int last_index, GtkTreeIter *parent_iter, GtkTreeIter *maybe_invalid_iter)
+{
+     if (last_index == -1)
+     {
+          // try to get whatever was there beforehand, if it exists
+          if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(store), maybe_invalid_iter, parent_iter))
+               return;
+     }
+     else
+     {
+          // increment the iter, or bail out.
+          if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store), maybe_invalid_iter))
+               return;
+     }
+
+     // consume until we're done.
+     while (gtk_tree_store_remove(store, maybe_invalid_iter));
+}
+
+
+static void
+gsslrtma_populate_tree_store(GncSxSlrTreeModelAdapter *model)
+{
+     GtkTreeIter sx_tree_iter;
+     GList *sx_iter;
+     int instances_index = -1;
+
+     for (sx_iter = model->instances->sx_instance_list; sx_iter != NULL; sx_iter = sx_iter->next)
+     {
+          GncSxInstances *instances = (GncSxInstances*)sx_iter->data;
+          FreqSpec *fs;
+          GString *frequency_str;
+          char last_occur_date_buf[MAX_DATE_LENGTH+1];
+          char next_occur_date_buf[MAX_DATE_LENGTH+1];
+
+          frequency_str = g_string_sized_new(32);
+          fs = xaccSchedXactionGetFreqSpec(instances->sx);
+          xaccFreqSpecGetFreqStr(fs, frequency_str);
+
+          {
+               GDate *last_occur = xaccSchedXactionGetLastOccurDate(instances->sx);
+               if (last_occur == NULL || !g_date_valid(last_occur))
+               {
+                    g_stpcpy(last_occur_date_buf, "never");
+               }
+               else
+               {
+                    qof_print_gdate(last_occur_date_buf,
+                                    MAX_DATE_LENGTH,
+                                    last_occur);
+               }
+          }
+
+          qof_print_gdate(next_occur_date_buf, MAX_DATE_LENGTH, &instances->next_instance_date);
+
+          if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &sx_tree_iter, NULL, ++instances_index))
+          {
+               gtk_tree_store_append(model->real, &sx_tree_iter, NULL);
+          }
+          gtk_tree_store_set(model->real, &sx_tree_iter,
+                             SLR_MODEL_COL_NAME, xaccSchedXactionGetName(instances->sx),
+                             SLR_MODEL_COL_INSTANCE_STATE, NULL,
+                             SLR_MODEL_COL_VARAIBLE_VALUE, NULL,
+                             SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
+                             SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
+                             SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
+                             -1);
+          g_string_free(frequency_str, TRUE);
+
+          // Insert instance information
+          {
+               GList *inst_iter;
+               GtkTreeIter inst_tree_iter;
+               char instance_date_buf[MAX_DATE_LENGTH+1];
+               int instance_index = -1;
+
+               for (inst_iter = instances->list; inst_iter != NULL; inst_iter = inst_iter->next)
+               {
+                    GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
+                    qof_print_gdate(instance_date_buf, MAX_DATE_LENGTH, &inst->date);
+
+                    if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &inst_tree_iter, &sx_tree_iter, ++instance_index))
+                    {
+                         gtk_tree_store_append(model->real, &inst_tree_iter, &sx_tree_iter);
+                    }
+                    gtk_tree_store_set(model->real, &inst_tree_iter,
+                                       SLR_MODEL_COL_NAME, instance_date_buf,
+                                       SLR_MODEL_COL_INSTANCE_STATE, gnc_sx_instance_state_names[inst->state],
+                                       SLR_MODEL_COL_VARAIBLE_VALUE, NULL,
+                                       SLR_MODEL_COL_INSTANCE_VISIBILITY, TRUE,
+                                       SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
+                                       SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, inst->state != SX_INSTANCE_STATE_CREATED,
+                                       -1);
+
+                    // Insert variable information
+                    {
+                         GList *vars = NULL, *var_iter;
+                         GtkTreeIter var_tree_iter;
+                         gint visible_variable_index = -1;
+
+                         vars = gnc_sx_instance_get_variables(inst);
+                         for (var_iter = vars; var_iter != NULL; var_iter = var_iter->next)
+                         {
+                              GncSxVariable *var = (GncSxVariable*)var_iter->data;
+                              GString *tmp_str;
+
+                              if (!var->editable)
+                                   continue;
+
+                              if (gnc_numeric_check(var->value) == GNC_ERROR_OK)
+                              {
+                                   _var_numeric_to_string(&var->value, &tmp_str);
+                              }
+                              else
+                              {
+                                   tmp_str = g_string_new("(need value)");
+                              }
+
+                              if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real),
+                                                                 &var_tree_iter, &inst_tree_iter,
+                                                                 ++visible_variable_index))
+                              {
+                                   gtk_tree_store_append(model->real, &var_tree_iter, &inst_tree_iter);
+                              }
+                              gtk_tree_store_set(model->real, &var_tree_iter,
+                                                 SLR_MODEL_COL_NAME, var->name,
+                                                 SLR_MODEL_COL_INSTANCE_STATE, NULL,
+                                                 SLR_MODEL_COL_VARAIBLE_VALUE, tmp_str->str,
+                                                 SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
+                                                 SLR_MODEL_COL_VARIABLE_VISIBILITY, TRUE,
+                                                 SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE
+                                                 -1);
+                              g_string_free(tmp_str, TRUE);
+                         }
+                         g_list_free(vars);
+
+                         _consume_excess_rows(model->real, visible_variable_index, &inst_tree_iter, &var_tree_iter);
+                    }
+               }
+               
+               // if there are more instance iters, remove
+               _consume_excess_rows(model->real, instance_index, &sx_tree_iter, &inst_tree_iter);
+          }
+     }
+     _consume_excess_rows(model->real, instances_index, NULL, &sx_tree_iter);
+}
+
+GncSxInstanceModel*
+gnc_sx_slr_tree_model_adapter_get_instance_model(GncSxSlrTreeModelAdapter *slr_model)
+{
+     return slr_model->instances;
+}
+
+GncSxInstances*
+gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
+{
+     return _gnc_sx_slr_tree_model_adapter_get_sx_instances(model, iter, TRUE);
+}
+
+static GncSxInstances*
+_gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
+{
+     GtkTreePath *path;
+     gint *indices, index;
+     path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
+     if (check_depth && gtk_tree_path_get_depth(path) != 1)
+     {
+          gtk_tree_path_free(path);
+          return NULL;
+     }
+     indices = gtk_tree_path_get_indices(path);
+     index = indices[0];
+     gtk_tree_path_free(path);
+
+     return (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
+}
+
+GncSxInstance*
+gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
+{
+     return _gnc_sx_slr_model_get_instance(model, iter, TRUE);
+}
+
+static GncSxInstance*
+_gnc_sx_slr_model_get_instance(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
+{
+     GtkTreePath *path;
+     gint *indices, instances_index, instance_index;
+     GncSxInstances *instances;
+     path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
+     if (check_depth && gtk_tree_path_get_depth(path) != 2)
+     {
+          gtk_tree_path_free(path);
+          return NULL;
+     }
+     indices = gtk_tree_path_get_indices(path);
+     instances_index = indices[0];
+     instance_index = indices[1];
+     gtk_tree_path_free(path);
+
+     instances = (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, instances_index);
+     if (instance_index < 0 || instance_index >= g_list_length(instances->list))
+     {
+          return NULL;
+     }
+
+     return (GncSxInstance*)g_list_nth_data(instances->list, instance_index);
+}
+
+gboolean
+gnc_sx_slr_model_get_instance_and_variable(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, GncSxInstance **instance_loc, GncSxVariable **var_loc)
+{
+     GtkTreePath *path;
+     gint *indices, variable_index;
+     GncSxInstance *instance;
+     GList *variables;
+
+     instance = _gnc_sx_slr_model_get_instance(model, iter, FALSE);
+     if (instance == NULL)
+     {
+          return FALSE;
+     }
+     variables = gnc_sx_instance_get_variables(instance);
+
+     path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
+     if (gtk_tree_path_get_depth(path) != 3)
+     {
+          gtk_tree_path_free(path);
+          return FALSE;
+     }
+     indices = gtk_tree_path_get_indices(path);
+     variable_index = indices[2];
+     gtk_tree_path_free(path);
+
+     if (variable_index < 0 || variable_index >= g_list_length(variables))
+     {
+          g_list_free(variables);
+          return FALSE;
+     }
+
+     if (instance_loc != NULL)
+     {
+          *instance_loc = instance;
+     }
+
+     if (var_loc != NULL)
+     {
+          // *var_loc = (GncSxVariable*)g_list_nth_data(variables, variable_index);
+          GList *list_iter = variables;
+          for (; list_iter != NULL; list_iter = list_iter->next)
+          {
+               GncSxVariable *var = (GncSxVariable*)list_iter->data;
+               if (!var->editable)
+                    continue;
+               if (variable_index-- == 0)
+               {
+                    *var_loc = var;
+                    break;
+               }
+          }
+     }
+
+     g_list_free(variables);
+     return TRUE;
+}
+
+void
+gnc_sx_slr_model_change_instance_state(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxInstanceState new_state)
+{
+     // @fixme: pop this out a level.
+     gnc_sx_instance_model_change_instance_state(model->instances, instance, new_state);
+}
+
+/**
+ * Special-case list indexing that only refers to "editable" variables. :(
+ **/
+static gint
+_variable_list_index(GList *variables, GncSxVariable *variable)
+{
+     gint index = 0;
+     for (; variables != NULL; variables = variables->next)
+     {
+          GncSxVariable *var = (GncSxVariable*)variables->data;
+          if (!var->editable)
+               continue;
+          if (variable == var)
+               return index;
+          index++;
+     }
+     return -1;
+}
+
+static GtkTreePath*
+_get_path_for_variable(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxVariable *variable)
+{
+     GList *variables;
+     int indices[3];
+     GtkTreePath *path;
+
+     indices[0] = g_list_index(model->instances->sx_instance_list, instance->parent);
+     if (indices[0] == -1)
+          return NULL;
+     indices[1] = g_list_index(instance->parent->list, instance);
+     if (indices[1] == -1)
+          return NULL;
+     variables = gnc_sx_instance_get_variables(instance);
+     indices[2] = _variable_list_index(variables, variable);
+     g_list_free(variables);
+     if (indices[2] == -1)
+          return NULL;
+     path = gtk_tree_path_new_from_indices(indices[0], indices[1], indices[2], -1);
+     return path;
+}
+
+void
+gnc_sx_slr_model_change_variable(GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxVariable *variable, gnc_numeric *new_value)
+{
+     gnc_sx_instance_model_set_variable(model->instances, instance, variable, new_value);
+}
+
+static void
+gsslrtma_added_cb(GncSxInstanceModel *instances, SchedXaction *added_sx, gpointer user_data)
+{
+     GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data); 
+     // this is wasteful, but fine.
+     gsslrtma_populate_tree_store(model);
+}
+
+static void
+gsslrtma_updated_cb(GncSxInstanceModel *instances, SchedXaction *updated_sx, gpointer user_data)
+{
+     GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data); 
+     gnc_sx_instance_model_update_sx_instances(instances, updated_sx);
+     gsslrtma_populate_tree_store(model);
+}
+
+static void
+gsslrtma_removing_cb(GncSxInstanceModel *instances, SchedXaction *to_remove_sx, gpointer user_data)
+{
+     GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data); 
+     GtkTreeIter tree_iter;
+     GList *iter;
+     int index = 0;
+     // get index, create path, remove
+     for (iter = instances->sx_instance_list; iter != NULL; iter = iter->next, index++)
+     {
+          GncSxInstances *instances = (GncSxInstances*)iter->data;
+          if (instances->sx == to_remove_sx)
+               break;
+     }
+     if (iter == NULL)
+          return; // couldn't find sx in our model, which is weird.
+     if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(model->real), &tree_iter, NULL, index))
+          return; // perr(couldn't get something that should exist.
+     gtk_tree_store_remove(model->real, &tree_iter);
+
+     gnc_sx_instance_model_remove_sx_instances(instances, to_remove_sx);
+}
+
+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), "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;
+}
+
+void
+gnc_sx_sxsincelast_book_opened(void)
+{
+     GncSxInstanceModel *inst_model;
+     GncSxSummary summary;
+
+     if (!gnc_gconf_get_bool(GCONF_SECTION, "show_at_file_open", NULL))
+          return;
+
+     inst_model = gnc_sx_get_current_instances();
+     gnc_sx_instance_model_summarize(inst_model, &summary);
+     gnc_sx_summary_print(&summary);
+     gnc_sx_instance_model_effect_change(inst_model, TRUE, NULL, NULL);
+
+     if (summary.need_dialog)
+     {
+          gnc_ui_sx_since_last_run_dialog(inst_model);
+     }
+     else
+     {
+          if (summary.num_auto_create_no_notify_instances != 0)
+          {
+               gnc_info_dialog
+                    (NULL,
+                     ngettext 
+                     ("There are no Scheduled Transactions to be entered at this time. "
+                      "(%d transaction automatically created)",
+                      "There are no Scheduled Transactions to be entered at this time. "
+                      "(%d transactions automatically created)",
+                      summary.num_auto_create_no_notify_instances),
+                     summary.num_auto_create_no_notify_instances);
+          }
+     }
+     g_object_unref(G_OBJECT(inst_model));
+}
+
+void
+gnc_ui_sxsincelast_dialog_create(void)
+{
+     GncSxInstanceModel *model = gnc_sx_get_current_instances();
+     gnc_sx_instance_model_effect_change(model, TRUE, NULL, NULL);
+     gnc_ui_sx_since_last_run_dialog(model);
+     g_object_unref(G_OBJECT(model));
+}
+
+static void
+instance_state_changed_cb(GtkCellRendererText *cell,
+                          const gchar *path,
+                          const gchar *value,
+                          GncSxSinceLastRunDialog *dialog)
+{
+     GtkTreeIter tree_iter;
+     GncSxInstance *inst;
+     int i;
+     GncSxInstanceState new_state;
+     
+     for (i = 0; i < SX_INSTANCE_STATE_CREATED; i++)
+     {
+          if (strcmp(value, gnc_sx_instance_state_names[i]) == 0)
+               break;
+     }
+     if (i == SX_INSTANCE_STATE_CREATED)
+     {
+          printf("unknown value [%s]\n", value);
+          return;
+     }
+     new_state = i;
+
+     if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
+     {
+          printf("unknown path [%s]\n", path);
+          return;
+     }
+
+     inst = gnc_sx_slr_model_get_instance(dialog->editing_model, &tree_iter);
+     if (inst == NULL)
+     {
+          printf("invalid path [%s]\n", path);
+          return;
+     }
+
+     gnc_sx_slr_model_change_instance_state(dialog->editing_model, inst, new_state);
+}
+
+static void
+variable_value_changed_cb(GtkCellRendererText *cell,
+                          const gchar *path,
+                          const gchar *value,
+                          GncSxSinceLastRunDialog *dialog)
+{
+     GncSxVariable *var;
+     GncSxInstance *inst;
+     GtkTreeIter tree_iter;
+     gnc_numeric parsed_num;
+     char *endStr = NULL;
+
+     printf("variable to [%s] at path [%s]\n", value, path);
+     if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
+     {
+          printf("invalid path [%s]\n", path);
+          return;
+     }
+
+     if (!gnc_sx_slr_model_get_instance_and_variable(dialog->editing_model, &tree_iter, &inst, &var))
+     {
+          printf("path [%s] doesn't correspond to a valid variable\n", path);
+          return;
+     }
+
+     if (!xaccParseAmount(value, TRUE, &parsed_num, &endStr)
+         || gnc_numeric_check(parsed_num) != GNC_ERROR_OK)
+     {
+          printf("@@fixme: better parse error handling\n");
+          // @fixme: set location (back) to "(need value)"
+          return;
+     }
+     gnc_sx_slr_model_change_variable(dialog->editing_model, inst, var, &parsed_num);
+}
+
+GncSxSinceLastRunDialog*
+gnc_ui_sx_since_last_run_dialog(GncSxInstanceModel *sx_instances)
+{
+     GncSxSinceLastRunDialog *dialog;
+     GladeXML *glade;
+
+     dialog = g_new0(GncSxSinceLastRunDialog, 1);
+     glade = gnc_glade_xml_new("sched-xact.glade", "since-last-run-dialog");
+     dialog->dialog = glade_xml_get_widget(glade, "since-last-run-dialog");
+
+     dialog->editing_model = gnc_sx_slr_tree_model_adapter_new(sx_instances);
+     // gobject-2.10: g_object_ref_sink(G_OBJECT(dialog->editing_model));
+     g_object_ref(G_OBJECT(dialog->editing_model));
+     gtk_object_sink(GTK_OBJECT(dialog->editing_model));
+     
+     {
+          GtkPaned *paned;
+
+          paned = GTK_PANED(glade_xml_get_widget(glade, "paned"));
+          gtk_paned_set_position(paned, 240);
+     }
+
+     dialog->review_created_txns_toggle = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade, "review_txn_toggle"));
+     
+     {
+          GtkCellRenderer *renderer;
+          GtkTreeViewColumn *col;
+          
+          dialog->instance_view = GTK_TREE_VIEW(glade_xml_get_widget(glade, "instance_view"));
+          gtk_tree_view_set_model(dialog->instance_view, GTK_TREE_MODEL(dialog->editing_model));
+
+          renderer = gtk_cell_renderer_text_new();
+          col = gtk_tree_view_column_new_with_attributes("SX, Instance, Variable", renderer,
+                                                         "text", SLR_MODEL_COL_NAME,
+                                                         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(),
+                       "text-column", 0,
+                       "has-entry", FALSE,
+                       "editable", TRUE,
+                       NULL);
+          g_signal_connect(G_OBJECT(renderer),
+                           "edited",
+                           G_CALLBACK(instance_state_changed_cb),
+                           dialog);
+          col = gtk_tree_view_column_new_with_attributes("Instance State", renderer,
+                                                         "text", SLR_MODEL_COL_INSTANCE_STATE,
+                                                         "visible", SLR_MODEL_COL_INSTANCE_VISIBILITY,
+                                                         // you might think only "sensitive" is required to
+                                                         // control the ability of the combo box to select
+                                                         // a new state, but you'd be wrong.
+                                                         "editable", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
+                                                         "sensitive", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
+                                                         NULL);
+          gtk_tree_view_append_column(dialog->instance_view, col);
+
+          
+          renderer = gtk_cell_renderer_text_new();
+          g_object_set(G_OBJECT(renderer),
+                       "editable", TRUE,
+                       NULL);
+          g_signal_connect(G_OBJECT(renderer),
+                           "edited",
+                           G_CALLBACK(variable_value_changed_cb),
+                           dialog);
+          col = gtk_tree_view_column_new_with_attributes("Variable Value", renderer,
+                                                         "text", SLR_MODEL_COL_VARAIBLE_VALUE,
+                                                         "visible", SLR_MODEL_COL_VARIABLE_VISIBILITY,
+                                                         NULL);
+          gtk_tree_view_append_column(dialog->instance_view, col);
+
+          gtk_tree_view_expand_all(dialog->instance_view);
+     }
+
+     g_signal_connect(G_OBJECT(dialog->dialog), "response", G_CALLBACK(dialog_response_cb), dialog);
+     
+     gtk_widget_show_all(dialog->dialog);
+
+     return dialog;
+}
+
+static void
+_show_created_transactions(GncSxSinceLastRunDialog *app_dialog, GList *created_txn_guids)
+{
+     GNCLedgerDisplay *ledger;
+     GncPluginPage *page;
+     Query *book_query, *guid_query, *query;
+     GList *guid_iter;
+
+     book_query = xaccMallocQuery();
+     guid_query = xaccMallocQuery();
+     xaccQuerySetBook(book_query, gnc_get_current_book());
+     for (guid_iter = created_txn_guids; guid_iter != NULL; guid_iter = guid_iter->next)
+     {
+          xaccQueryAddGUIDMatch(guid_query, (GUID*)guid_iter->data, GNC_ID_TRANS, QUERY_OR);
+     }
+     query = xaccQueryMerge(book_query, guid_query, QUERY_AND);
+
+     // inspired by dialog-find-transactions:do_find_cb:
+     ledger = gnc_ledger_display_query(query, SEARCH_LEDGER, REG_STYLE_JOURNAL);
+     gnc_ledger_display_refresh(ledger);
+     page = gnc_plugin_page_register_new_ledger(ledger);
+     g_object_set(G_OBJECT(page), "page-name", _("Created Transactions"), NULL);
+     gnc_main_window_open_page(NULL, page);
+
+     xaccFreeQuery(query);
+     xaccFreeQuery(book_query);
+     xaccFreeQuery(guid_query);
+}
+
+static GList*
+gnc_sx_slr_model_check_variables(GncSxSlrTreeModelAdapter *editing_model)
+{
+     return gnc_sx_instance_model_check_variables(editing_model->instances);
+}
+
+static void
+dialog_response_cb(GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog *app_dialog)
+{
+     GList *created_txns = NULL;
+     switch (response_id)
+     {
+     case GTK_RESPONSE_OK:
+          // @@fixme validate current state(GError *errs);
+          // - instance state constraints
+          // - required variable binding
+          // - ability to create transactions
+          {
+               GList *unbound_variables;
+               unbound_variables = gnc_sx_slr_model_check_variables(app_dialog->editing_model);
+               printf("%d variables unbound\n", g_list_length(unbound_variables));
+               if (g_list_length(unbound_variables) > 0)
+               {
+                    // focus first variable
+                    GncSxVariableNeeded *first_unbound;
+                    GtkTreePath *variable_path;
+                    GtkTreeViewColumn *variable_col;
+                    gint variable_view_column = 2;
+                    gboolean start_editing = TRUE;
+
+                    first_unbound = (GncSxVariableNeeded*)unbound_variables->data;
+                    variable_path = _get_path_for_variable(app_dialog->editing_model, first_unbound->instance, first_unbound->variable);
+                    variable_col = gtk_tree_view_get_column(app_dialog->instance_view, variable_view_column);
+
+                    gtk_tree_view_set_cursor(app_dialog->instance_view, variable_path, variable_col, start_editing);
+
+                    gtk_tree_path_free(variable_path);
+                    g_list_foreach(unbound_variables, (GFunc)g_free, NULL);
+                    g_list_free(unbound_variables);
+                    return;
+               }
+          }
+          gnc_suspend_gui_refresh();
+          gnc_sx_slr_model_effect_change(app_dialog->editing_model, FALSE, &created_txns, NULL);
+          gnc_resume_gui_refresh();
+          if (gtk_toggle_button_get_active(app_dialog->review_created_txns_toggle)
+              && g_list_length(created_txns) > 0)
+          {
+               _show_created_transactions(app_dialog, created_txns);
+          }
+          g_list_free(created_txns);
+          created_txns = NULL;
+          /* FALLTHROUGH */
+     case GTK_RESPONSE_CANCEL: 
+     case GTK_RESPONSE_DELETE_EVENT:
+          gtk_widget_destroy(GTK_WIDGET(dialog));
+          g_object_unref(G_OBJECT(app_dialog->editing_model));
+          app_dialog->editing_model = NULL;
+          break;
+     default:
+          printf("unknown response id [%d]\n", response_id);
+          g_assert_not_reached();
+          break;
+     }
+}
+
+/**
+ * @param auto_create_only Will only affect auto-create transactions; the
+ * rest of the state will be left alone.
+ **/
+void
+gnc_sx_slr_model_effect_change(GncSxSlrTreeModelAdapter *model,
+                               gboolean auto_create_only,
+                               GList **created_transaction_guids,
+                               GList **creation_errors)
+{
+     g_signal_handler_block(model->instances, model->updated_cb_id);
+     gnc_sx_instance_model_effect_change(model->instances, auto_create_only, created_transaction_guids, creation_errors);
+     g_signal_handler_unblock(model->instances, model->updated_cb_id);
+}
+

Copied: gnucash/trunk/src/gnome/dialog-sx-since-last-run.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.h)

Deleted: gnucash/trunk/src/gnome/dialog-sxsincelast.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-sxsincelast.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/dialog-sxsincelast.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,4030 +0,0 @@
-/********************************************************************\
- * dialog-sxsincelast.c - "since last run" dialog.                  *
- * Copyright (c) 2001,2002 Joshua Sled <jsled at asynchronous.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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-/**
- * . Page 1: reminders list
- *   . backed by: sxsld->reminderList
- * . Page 2: auto-create notify ledger
- *   . backed by: sxsld->autoCreateList
- * . Page 3: to-create variable bindings
- *   . backed by: sxsld->toCreateData [s/Data/List/]
- * . Page 4: created ledger
- *   . backed by: sxsld->createdList
- * . Page 5: obsolete list
- *   . backed by: sxsld->toRemoveList
- *
- * Detail regarding 'back' processing support.
- * . reminders
- *   . selected
- *     . <standard policy>
- *   . unselected
- *     . if auto-created   : delete
- *     . if to-create      : remove
- * . auto-create           : display
- * . to-create variable bindings
- *   . if bindings changed : reeval/fill credit/debit cells
- *   . if made incomplete  : delete transaction
- * . created               : display
- * . obsolete              : select status [easy]
- **/
-
-#include "config.h"
-
-#include <gnome.h>
-#include <glib.h>
-#include <glib/gi18n.h>
-#include "glib-compat.h"
-#include <limits.h>
-
-#include "Account.h"
-#include "Group.h"
-#include "Query.h"
-#include "QueryNew.h"
-#include "SchedXaction.h"
-#include "Transaction.h"
-#include "Scrub.h"
-#include "SX-book.h"
-#include "SX-book-p.h"
-#include "dialog-utils.h"
-#include "finvar.h"
-#include "gnc-date.h"
-#include "gnc-component-manager.h"
-#include "gnc-engine.h"
-#include "gnc-exp-parser.h"
-#include "gnc-embedded-window.h"
-#include "gnc-gconf-utils.h"
-#include "gnc-main-window.h"
-#include "gnc-numeric.h"
-#include "gnc-plugin-page.h"
-#include "gnc-plugin-page-register.h"
-#include "gnc-ui-util.h"
-#include "gnc-ui.h"
-#include "gnc-gui-query.h"
-#include "split-register.h"
-#include "gnc-ledger-display.h"
-#include "gnucash-sheet.h"
-#include "gnc-split-reg.h"
-
-#include "dialog-sxsincelast.h"
-#include "dialog-scheduledxaction.h"
-
-#ifdef HAVE_LANGINFO_D_FMT
-#include <langinfo.h>
-#endif
-
-#define DIALOG_SXSINCELAST_CM_CLASS "dialog-sxsincelast"
-#define DIALOG_SXSINCELAST_REMIND_CM_CLASS "dialog-sxsincelast-remind"
-#define DIALOG_SXSINCELAST_OBSOLETE_CM_CLASS "dialog-sxsincelast-obsolete"
-
-#define DIALOG_SXSINCELAST_GLADE_NAME "Since Last Run Druid"
-#define SXSLD_DRUID_GLADE_NAME "sincelast_druid"
-#define SXSLD_WIN_PREFIX "sx_sincelast_win"
-#define GCONF_SECTION "dialogs/scheduled_trans/since_last_run"
-
-#define SINCELAST_DRUID   "sincelast_druid"
-#define WHAT_TO_DO_PG "what_to_do"
-#define REMINDERS_PG "reminders_page"
-#define AUTO_CREATE_NOTIFY_PG "auto_create_notify_page"
-#define TO_CREATE_PG "to_create_page"
-#define CREATED_PG "created_page"
-#define OBSOLETE_PG "obsolete_page"
-#define COMMIT_PG "commit_page"
-
-#define SX_OBSOLETE_CLIST "sx_obsolete_clist"
-#define TO_CREATE_LIST "to_create_list"
-#define REMINDER_LIST  "reminders_list"
-#define SX_GLADE_FILE "sched-xact.glade"
-
-#define TO_CREATE_STATUS "to_create_status"
-
-#define SELECT_ALL_BUTTON "select_all_button"
-#define UNSELECT_ALL_BUTTON "unselect_all_button"
-#define OK_BUTTON "ok_button"
-#define CANCEL_BUTTON "cancel_button"
-#define VARIABLE_TABLE "variables_table"
-#define AUTO_CREATE_VBOX "ac_vbox"
-#define TO_CREATE_TXN_VBOX "to_create_txn_vbox"
-#define CREATED_VBOX "created_vbox"
-#define WHAT_TO_DO_VBOX "what_to_do_vbox"
-#define WHAT_TO_DO_PROGRESS "creation_progress"
-#define SX_DISPOSITION_OPT "disposition_opt"
-
-#define TO_CREATE_LIST_WIDTH 2
-#define REMINDER_LIST_WIDTH  3
-#define SX_OBSOLETE_CLIST_WIDTH 3
-
-#define COERCE_VOID_TO_GBOOLEAN(x) ((gboolean)(*#x))
-
-#define IGNORE_TEXT         "Ignored"
-#define POSTPONE_TEXT       "Postponed"
-#define READY_TEXT          "Ready to create"
-#define NEEDS_BINDINGS_TEXT "Needs values for variables"
-
-static QofLogModule log_module = GNC_MOD_SX;
-
-/**
- * Directions for {forward,back}-page determining.
- * @see gnc_sxsld_get_appropriate_page
- **/
-typedef enum {
-        FORWARD, BACK
-} Direction;
-
-/**
- * The states a to-be-created SX can be in...
- * SX_TO_CREATE : The SX is ready to be created, depending on variable-binding
- *               requirements.
- * SX_IGNORE   : Drop the SX on the floor forever.
- * SX_POSTPONE : Bring this SX up in the future, but we're not going to
- *               create it right now.
- * SX_[MAX_STATE] : The maximum real value.
- * SX_UNDEF     : Only used for prevState, to indicate that we haven't
- *               processed this instance, yet.
- **/
-typedef enum {
-        SX_TO_CREATE,
-        SX_IGNORE,
-        SX_POSTPONE,
-        SX_MAX_STATE,
-        SX_UNDEF
-} ToCreateState;
-
-typedef struct toCreateTuple_ {
-        SchedXaction *sx;
-        GList /* <toCreateInstance*> */ *instanceList;
-} toCreateTuple;
-
-typedef struct toCreateInstance_ {
-        GDate *date;
-        GHashTable *varBindings;
-        void *sxStateData;
-        GtkCTreeNode *node;
-        toCreateTuple *parentTCT;
-        /* A list of the GUIDs of transactions generated from this TCI [if
-         * any]; this will always be a subset of the
-         * sxsld->createdTxnGUIDList. */
-        GList /* <GUID*> */ *createdTxnGUIDs;
-        gboolean dirty;
-        /** How this was, originally -- for revert processing. **/
-        ToCreateState origState;
-        /** How the user would currently like to process this instance
-         * [within the druid]. */
-        ToCreateState state;
-        /** How we've previously processed this instance [within the druid]. */
-        ToCreateState prevState;
-} toCreateInstance;
-
-/**
- * A tuple of an SX and any upcoming reminders.
- **/
-typedef struct reminderTuple_ {
-        SchedXaction *sx;
-        GList /* <reminderInstanceTuple*> */ *instanceList;
-} reminderTuple;
-
-/**
- * An reminder instance of the containing SX.
- **/
-typedef struct reminderInstanceTuple_ {
-        GDate        *endDate;
-        GDate        *occurDate;
-        void    *sxStateData;
-        gboolean isSelected;
-        reminderTuple *parentRT;
-        toCreateInstance *resultantTCI;
-} reminderInstanceTuple;
-
-typedef struct toDeleteTuple_ {
-        SchedXaction *sx;
-        GDate *endDate;
-        gboolean isSelected;
-} toDeleteTuple;
-
-typedef struct creation_helper_userdata_ {
-        /* the to-create tuple */
-        toCreateInstance *tci;
-        /* a pointer to a GList to append the GUIDs of newly-created
-         * Transactions to, or NULL */
-        GList **createdGUIDs;
-        /* a pointer to a GList<GString*> of error-messages encountered while
-         * creating the transactions. **/
-        GList **creation_errors;
-} createData;
-
-/**
- * The since-last-run dialog is a Gnome Druid which steps through the various
- * parts of scheduled transaction since-last-run processing; these parts are:
- *
- * 1. Display and select SX reminders for creation
- * 2. Show/allow editing of auto-created + notification-request SXes
- * 3. Show to-create SXes, allowing variable binding
- * 4. Show created SXes, allowing editing
- * 5. Allow deletion of any obsolete SXes
- *
- * Pages which aren't relevant are skipped; this is handled in the 'prep'
- * signal handler: e.g., a since-last dialog with only obsolete SXes would go
- * through the 'prep' methods of all it's pages to reach the Obsolete page.
- **/
-typedef struct _sxSinceLastData {
-        GtkWidget *sincelast_window;
-        GnomeDruid *sincelast_druid;
-        GladeXML *gxml;
-
-        GtkProgressBar *prog;
-        GtkStatusbar *toCreateFormula;
-        guint formulaCtxId;
-        GtkStatusbar *toCreateStatus;
-        guint statusCtxId;
-
-        /* The currently-selected to-create instance. */
-        toCreateInstance *curSelTCI;
-
-        /* Multi-stage processing-related stuff... */
-        GList /* <toCreateTuple*> */ *autoCreateList;
-        GList /* <toCreateTuple*> */ *toCreateList;
-        GList /* <reminderTuple*> */ *reminderList;
-        GList /* <toDeleteTuple*> */ *toRemoveList;
-
-        /********** "Cancel"-related stuff... **********/
-        
-        /** A HashTable of SX mapped to initial temporal data. */
-        GHashTable /* <SchedXaction*,void*> */ *sxInitStates;
-
-        /** The list of the GUIDs of _all_ transactions we've created. */
-        GList /* <GUID*> */            *createdTxnGUIDList;
-
-        /* The count of selected reminders. */
-        gint remindSelCount;
-
-        /* The count of auto-created transactions. */
-        gint autoCreatedCount;
-
-	GncEmbeddedWindow   *ac_window;
-	GncPluginPage       *ac_register;
-        GNCLedgerDisplay    *ac_ledger;
-
-	GncEmbeddedWindow   *created_window;
-	GncPluginPage       *created_register;
-        GNCLedgerDisplay    *created_ledger;
-
-	GncEmbeddedWindow   *to_create_window;
-	GncPluginPage       *to_create_register;
-        GNCLedgerDisplay    *to_create_ledger;
-
-} sxSinceLastData;
-
-static void sxsincelast_init( sxSinceLastData *sxsld );
-static void create_autoCreate_ledger( sxSinceLastData *sxsld );
-static void create_created_ledger( sxSinceLastData *sxsld );
-static void create_to_create_ledger( sxSinceLastData *sxsld );
-static void gnc_sxsld_commit_ledgers( sxSinceLastData *sxsld );
-
-#if 0
-static void sxsld_jump_to_real_txn( GtkAction *action, sxSinceLastData *sxsld );
-#endif
-
-static gint sxsincelast_populate( sxSinceLastData *sxsld );
-static void sxsincelast_druid_cancelled( GnomeDruid *druid, gpointer ud );
-static void sxsincelast_close_handler( gpointer ud );
-
-static GnomeDruidPage* gnc_sxsld_get_appropriate_page( sxSinceLastData *sxsdl,
-                                                       GnomeDruidPage *from,
-                                                       Direction dir );
-static gboolean gnc_sxsld_wtd_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_remind_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_tocreate_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_autocreate_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_created_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_obsolete_appr( sxSinceLastData *sxsld );
-static gboolean gnc_sxsld_commit_appr( sxSinceLastData *sxsld );
-
-static void sxsincelast_entry_changed( GtkEditable *e, gpointer ud );
-static void sxsincelast_destroy( GtkObject *o, gpointer ud );
-static void sxsincelast_save_size( sxSinceLastData *sxsld );
-static void create_transactions_on(SchedXaction *sx,
-                                   GDate *gd,
-                                   toCreateInstance *tci,
-                                   GList **createdGUIDs,
-                                   GList **creation_errors);
-static gint create_each_transaction_helper( Transaction *t, void *d );
-/* External for what reason ... ? */
-void sxsl_get_sx_vars( SchedXaction *sx, GHashTable *varHash );
-static void hash_to_sorted_list( GHashTable *hashTable, GList **gl );
-static void andequal_numerics_set( gpointer key,
-                                   gpointer value,
-                                   gpointer data );
-/* External for bad reasons, I think...? */
-void print_vars_helper( gpointer key,
-                        gpointer value,
-                        gpointer user_data );
-static void clean_sincelast_data( sxSinceLastData *sxsld );
-static void clean_variable_table( sxSinceLastData *sxsld );
-
-static void process_auto_create_list(GList *, sxSinceLastData *sxsld, GList **creation_errors);
-static void add_to_create_list_to_gui( GList *, sxSinceLastData *sxsld );
-static void add_reminders_to_gui( GList *, sxSinceLastData *sxsld );
-static void add_dead_list_to_gui( GList *, sxSinceLastData *sxsld );
-static void processSelectedReminderList( GList *, sxSinceLastData * );
-
-static void sxsincelast_tc_row_sel( GtkCTree *ct,
-                                    GList *nodelist,
-                                    gint column,
-                                    gpointer user_data);
-
-static void sxsincelast_tc_row_unsel( GtkCTree *ct,
-                                      GList *nodelist,
-                                      gint column,
-                                      gpointer user_data);
-
-static void sxsld_remind_row_toggle( GtkCTree *ct, GList *node,
-                                     gint column, gpointer user_data );
-static void sxsld_obsolete_row_toggle( GtkCList *cl, gint row, gint col,
-                                       GdkEventButton *event, gpointer ud );
-
-static void sxsld_disposition_changed( GtkMenuShell *b, gpointer d );
-static void sxsld_set_sensitive_tci_controls( sxSinceLastData *sxsld,
-                                              gboolean sensitive );
-
-static void gnc_sxsld_revert_reminders( sxSinceLastData *sxsld,
-                                        GList *toRevertList );
-static gboolean processed_valid_reminders_listP( sxSinceLastData *sxsld );
-static void create_bad_reminders_msg( gpointer data, gpointer ud );
-static gboolean inform_or_add( sxSinceLastData *sxsld, reminderTuple *rt, gboolean okFlag,
-                               GList *badList, GList **goodList );
-
-static void sx_obsolete_select_all_clicked( GtkButton *button,
-                                            gpointer user_data );
-static void sx_obsolete_unselect_all_clicked( GtkButton *button,
-                                              gpointer user_data );
-
-static void gnc_sxsld_free_tci( toCreateInstance *tci );
-static void gnc_sxsld_free_toCreateTuple_list( GList *l );
-static void gnc_sxsld_free_sxState( gpointer key,
-                                    gpointer value,
-                                    gpointer userdata );
-static void gnc_sxsld_free_entry_numeric( GObject *o, gpointer ud );
-
-static gint sxsld_process_to_create_instance(sxSinceLastData *sxsld,
-                                             toCreateInstance *tci,
-                                             GList **creation_errors);
-static void sxsld_revert_to_create_txns( sxSinceLastData *sxsld,
-                                         toCreateInstance *tci );
-static gint sxsld_create_to_create_txns(sxSinceLastData *sxsld,
-                                        toCreateInstance *tci,
-                                        GList **creation_errors);
-static gint sxsld_get_future_created_txn_count( sxSinceLastData *sxsld );
-static void creation_errors_dialog(GList *creation_errors);
-static void creation_errors_free(GList *creation_errors);
-
-static GtkActionEntry gnc_sxsld_menu_entries [] =
-{
-	/* Toplevel */
-	{ "EditAction", NULL, N_("_Edit"), NULL, NULL, NULL },
-	{ "TransactionAction", NULL, N_("_Transaction"), NULL, NULL, NULL },
-	{ "ViewAction", NULL, N_("_View"), NULL, NULL, NULL },
-	{ "ActionsAction", NULL, N_("_Actions"), NULL, NULL, NULL },
-};
-static guint gnc_sxsld_menu_n_entries = G_N_ELEMENTS (gnc_sxsld_menu_entries);
-
-/**
- * Used to wrap for the book-open hook, where the book filename is given.
- **/
-void
-gnc_sx_sxsincelast_book_opened (void)
-{
-  gint ret;
-
-  if (!gnc_gconf_get_bool(GCONF_SECTION, "show_at_file_open", NULL))
-    return;
-
-  ret = gnc_ui_sxsincelast_dialog_create();
-  if ( ret < 0 ) {
-    gnc_info_dialog
-      (NULL,
-       ngettext 
-       ("There are no Scheduled Transactions to be entered at this time. "
-        "(%d transaction automatically created)",
-        "There are no Scheduled Transactions to be entered at this time. "
-        "(%d transactions automatically created)",
-        -(ret)),
-       -(ret));
-  }
-}
-
-
-static gboolean
-show_handler (const char *class, gint component_id,
-              gpointer user_data, gpointer iter_data)
-{
-        GtkWidget *window = user_data;
-
-        if (!window)
-                return(FALSE);
-        gtk_window_present (GTK_WINDOW(window));
-        return(TRUE);
-}
-
-/**
- * @return The magnitude of the return value is the number of auto-created,
- * no-notification scheduled transactions created.  This value is positive if
- * there are additionally other SXes which need user interaction and the
- * Druid has been displayed, or negative if there are not, and no Druid
- * window was realized.  In the case where there the dialog has been
- * displayed but no auto-create-no-notify transactions have been created,
- * INT_MAX [limits.h] is returned.  0 is treated as negative, with no
- * transactions created and no dialog displayed.  The caller can use this
- * value as appropriate to inform the user.
- *
- * [e.g., for book-open-hook: do nothing; for menu-selection: display an info
- *  dialog stating there's nothing to do.]
- **/
-gint
-gnc_ui_sxsincelast_dialog_create()
-{
-        int autoCreateCount;
-        sxSinceLastData        *sxsld;
-
-        if (gnc_forall_gui_components (DIALOG_SXSINCELAST_CM_CLASS,
-                                       show_handler, NULL))
-                return 0;
-
-
-        sxsld = g_new0( sxSinceLastData, 1 );
-
-        sxsld->toCreateList = sxsld->reminderList = sxsld->toRemoveList = NULL;
-        sxsld->sxInitStates = g_hash_table_new( g_direct_hash, g_direct_equal );
-
-        autoCreateCount = sxsincelast_populate( sxsld );
-        if ( autoCreateCount <= 0 ) {
-                g_free( sxsld );
-                return autoCreateCount;
-        }
-
-        sxsld->gxml = gnc_glade_xml_new( SX_GLADE_FILE,
-                                         DIALOG_SXSINCELAST_GLADE_NAME );
-        sxsld->sincelast_window =
-                glade_xml_get_widget( sxsld->gxml,
-                                      DIALOG_SXSINCELAST_GLADE_NAME );
-        sxsld->sincelast_druid =
-                GNOME_DRUID( glade_xml_get_widget( sxsld->gxml,
-                                                   SXSLD_DRUID_GLADE_NAME ) );
-        sxsincelast_init( sxsld );
-        return autoCreateCount;
-}
-
-static void 
-clist_set_all_cols_autoresize( GtkCList *cl, guint n_cols )
-{
-        guint col;
-        for( col = 0; col< n_cols; col++ ) {
-                gtk_clist_set_column_auto_resize (cl, col, TRUE);
-        }
-        return;
-}
-
-typedef struct {
-        char *name;
-        char *signal;
-        void (*handlerFn)();
-} widgetSignalHandlerTuple;
-
-typedef struct {
-        char     *pageName;
-        void     (*prepareHandlerFn)();
-        gboolean (*backHandlerFn)();
-        gboolean (*nextHandlerFn)();
-        void     (*finishHandlerFn)();
-        gboolean (*cancelHandlerFn)();
-} druidSignalHandlerTuple;
-   
-static void
-dialog_widgets_attach_handlers(GladeXML *dialog_xml, 
-                               widgetSignalHandlerTuple *handler_info, 
-                               sxSinceLastData *sxsld)
-{
-        int i;
-        GtkWidget *w;
-
-        for (i = 0; handler_info[i].name != NULL; i++)
-        {
-                w = glade_xml_get_widget(dialog_xml, handler_info[i].name);
-                g_signal_connect( G_OBJECT(w), handler_info[i].signal, 
-				  G_CALLBACK(handler_info[i].handlerFn),
-				  sxsld);
-        }
-}
-
-static void
-druid_pages_attach_handlers( GladeXML *dialog_xml,
-                             druidSignalHandlerTuple *handler_info,
-                             sxSinceLastData *sxsld )
-{
-        int i;
-        GtkWidget *w;
-
-        for(i = 0; handler_info[i].pageName != NULL; i++)
-        {
-                w = glade_xml_get_widget(dialog_xml, handler_info[i].pageName);
-                if ( handler_info[i].prepareHandlerFn ) {
-                        g_signal_connect( G_OBJECT(w), "prepare",
-					  G_CALLBACK(handler_info[i].
-						     prepareHandlerFn),
-					  sxsld);
-                }
-                if ( handler_info[i].backHandlerFn ) {
-                        g_signal_connect( G_OBJECT(w), "back",
-					  G_CALLBACK(handler_info[i].
-						     backHandlerFn),
-					  sxsld);
-                }
-                if ( handler_info[i].nextHandlerFn ) {
-                        g_signal_connect( G_OBJECT(w), "next",
-					  G_CALLBACK(handler_info[i].
-						     nextHandlerFn),
-					  sxsld);
-                }
-                if ( handler_info[i].finishHandlerFn ) {
-                        g_signal_connect( G_OBJECT(w), "finish",
-					  G_CALLBACK(handler_info[i].
-						     finishHandlerFn),
-					  sxsld);
-                }
-                if ( handler_info[i].cancelHandlerFn ) {
-                        g_signal_connect( G_OBJECT(w), "cancel",
-					  G_CALLBACK(handler_info[i].
-						     cancelHandlerFn),
-					  sxsld);
-                }
-        }
-}
-
-static void
-sxsincelast_druid_cancelled( GnomeDruid *druid, gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        gtk_widget_hide( sxsld->sincelast_window );
-        sxsincelast_close_handler( sxsld );
-}
-
-/**
- * Using the specified direction, gets the next appropriate page.  Returns
- * NULL if there is no approrpiate page to go to.
- **/
-static
-GnomeDruidPage*
-gnc_sxsld_get_appropriate_page( sxSinceLastData *sxsld,
-                                GnomeDruidPage *from,
-                                Direction dir )
-{
-        static struct {
-                gchar *pageName;
-                gboolean (*pageAppropriate)( sxSinceLastData *sxsld );
-        } pages[] = {
-                { WHAT_TO_DO_PG,         gnc_sxsld_wtd_appr },
-                { REMINDERS_PG,          gnc_sxsld_remind_appr },
-                { AUTO_CREATE_NOTIFY_PG, gnc_sxsld_autocreate_appr },
-                { TO_CREATE_PG,          gnc_sxsld_tocreate_appr },
-                { CREATED_PG,            gnc_sxsld_created_appr },
-                { OBSOLETE_PG,           gnc_sxsld_obsolete_appr },
-                { COMMIT_PG,             gnc_sxsld_commit_appr },
-                { NULL,                  NULL }
-        };
-        int modifier;
-        int cur;
-        GtkWidget *pg;
-
-        pg = NULL;
-        /* get the current page index via lame linear search. */
-        for ( cur = 0; pages[cur].pageName != NULL; cur++ ) {
-                pg = glade_xml_get_widget( sxsld->gxml, pages[cur].pageName );
-                if ( GTK_WIDGET(from) == pg ) {
-                        break;
-                }
-        }
-        g_assert( pages[cur].pageName != NULL );
-
-        modifier = ( dir == FORWARD ? 1 : -1 );
-        /* Find the approrpriate "next" page; start trying the first possible
-         * "next" page. */
-        cur += modifier;
-        while ( cur >= 0
-                && pages[cur].pageName != NULL
-                && !(*pages[cur].pageAppropriate)( sxsld ) ) {
-                cur += modifier;
-        }
-
-        if ( cur < 0
-             || pages[cur].pageName == NULL ) {
-                return NULL;
-        }
-        return GNOME_DRUID_PAGE( glade_xml_get_widget( sxsld->gxml,
-                                                       pages[cur].pageName ) );
-}
-
-static
-gboolean
-gnc_sxsld_wtd_appr( sxSinceLastData *sxsld )
-{
-        /* It's never appropriate to return here. */
-        return FALSE;
-}
-
-static
-gboolean
-gnc_sxsld_remind_appr( sxSinceLastData *sxsld )
-{
-        return (g_list_length( sxsld->reminderList ) != 0);
-}
-
-static
-gboolean
-gnc_sxsld_tocreate_appr( sxSinceLastData *sxsld )
-{
-        return (g_list_length( sxsld->toCreateList ) != 0);
-}
-
-static
-gboolean
-gnc_sxsld_autocreate_appr( sxSinceLastData *sxsld )
-{
-        return (sxsld->autoCreatedCount > 0);
-}
-
-static
-gboolean
-gnc_sxsld_created_appr( sxSinceLastData *sxsld )
-{
-        return ((g_list_length(sxsld->createdTxnGUIDList)
-                 - sxsld->autoCreatedCount) > 0);
-}
-
-static
-gboolean
-gnc_sxsld_obsolete_appr( sxSinceLastData *sxsld )
-{
-        return (g_list_length( sxsld->toRemoveList ) != 0);
-}
-
-static
-gboolean
-gnc_sxsld_commit_appr( sxSinceLastData *sxsld )
-{
-	/* Always show this page */
-        return TRUE;
-}
-
-static
-gboolean
-gen_back( GnomeDruidPage *druid_page,
-          gpointer arg1, gpointer ud )
-{
-        GnomeDruidPage *gdp;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        if ( !(gdp = gnc_sxsld_get_appropriate_page( sxsld, druid_page, BACK )) ) {
-                DEBUG( "No appropriate page to go to." );
-                return TRUE;
-        }
-        gnome_druid_set_page( sxsld->sincelast_druid, gdp );
-        return TRUE;
-}
-
-static
-gboolean
-gen_next( GnomeDruidPage *druid_page,
-          gpointer arg1, gpointer ud )
-{
-        GnomeDruidPage *gdp;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        if ( !(gdp = gnc_sxsld_get_appropriate_page( sxsld, druid_page, FORWARD )) ) {
-                DEBUG( "No appropriate page to go to." );
-                return TRUE;
-        }
-        gnome_druid_set_page( sxsld->sincelast_druid, gdp );
-        return TRUE;
-}
-
-static void
-whattodo_prep( GnomeDruidPage *druid_page,
-               gpointer arg1, gpointer ud )
-{
-}
-
-static
-void 
-reminders_prep( GnomeDruidPage *druid_page,
-                gpointer arg1, gpointer ud )
-{
-        GtkWidget *w;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        w = glade_xml_get_widget( sxsld->gxml, REMINDER_LIST );
-        gtk_clist_freeze( GTK_CLIST(w) );
-        gtk_clist_clear( GTK_CLIST(w) );
-        add_reminders_to_gui( sxsld->reminderList, sxsld );
-        gtk_clist_thaw( GTK_CLIST(w) );
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-        /* FIXME: this isn't quite right; see the comment in
-         * sxsld_remind_row_toggle */
-        gnome_druid_set_show_finish( sxsld->sincelast_druid,
-                                     !gnc_sxsld_get_appropriate_page( sxsld,
-                                                                      druid_page,
-                                                                      FORWARD ) );
-}
-
-static
-gboolean 
-reminders_next( GnomeDruidPage *druid_page,
-                gpointer arg1, gpointer ud )
-{
-        GnomeDruidPage *gdp;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        if ( !processed_valid_reminders_listP( sxsld ) ) {
-                return TRUE;
-        }
-        if ( !(gdp = gnc_sxsld_get_appropriate_page( sxsld,
-                                                     druid_page,
-                                                     FORWARD )) ) {
-                DEBUG( "no valid page to switch to" );
-                return TRUE;
-        }
-        gnome_druid_set_page( sxsld->sincelast_druid, gdp );
-        return TRUE;
-}
-
-static
-gboolean 
-reminders_back( GnomeDruidPage *druid_page,
-                gpointer arg1, gpointer ud )
-{
-        GnomeDruidPage *gdp;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        if ( !processed_valid_reminders_listP( sxsld ) ) {
-                return TRUE;
-        }
-        if ( !(gdp = gnc_sxsld_get_appropriate_page( sxsld, 
-                                                     druid_page,
-                                                     BACK )) ) {
-                DEBUG( "no valid page to switch to" );
-                return TRUE;
-        }
-        gnome_druid_set_page( sxsld->sincelast_druid, gdp );
-        return TRUE;
-}
-
-static
-gboolean
-created_back( GnomeDruidPage *druid_page,
-              gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)ud;
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->created_ledger),
-                TRUE );
-        return gen_back( druid_page, arg1, ud );
-}
-
-static
-gboolean
-created_next( GnomeDruidPage *druid_page,
-              gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)ud;
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->created_ledger),
-                TRUE );
-        return gen_next( druid_page, arg1, ud );
-}
-
-static
-void
-created_prep( GnomeDruidPage *druid_page,
-               gpointer arg1, gpointer ud )
-{
-        GList *tctList, *tciList, *guidList;
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-        Query *bookQuery, *guidQuery, *q;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        bookQuery = xaccMallocQuery();
-        guidQuery = xaccMallocQuery();
-        xaccQuerySetBook( bookQuery, gnc_get_current_book() );
-        /* Create the appropriate query for the Created ledger; go through
-         * the to-create list's instances and add all the created Txn
-         * GUIDs. */
-        for ( tctList = sxsld->toCreateList;
-              tctList;
-              tctList = tctList->next ) {
-                tct = (toCreateTuple*)tctList->data;
-                for ( tciList = tct->instanceList;
-                      tciList;
-                      tciList = tciList->next ) {
-                        tci = (toCreateInstance*)tciList->data;
-                        for ( guidList = tci->createdTxnGUIDs;
-                              guidList;
-                              guidList = guidList->next ) {
-                                xaccQueryAddGUIDMatch( guidQuery,
-                                                       (GUID*)guidList->data,
-                                                       GNC_ID_TRANS,
-                                                       QUERY_OR );
-                        }
-                }
-        }
-        q = xaccQueryMerge( bookQuery, guidQuery, QUERY_AND );
-        gnc_suspend_gui_refresh();
-        gnc_ledger_display_set_query( sxsld->created_ledger, q );
-        gnc_ledger_display_refresh( sxsld->created_ledger );
-        gnc_resume_gui_refresh();
-        xaccFreeQuery( q );
-        xaccFreeQuery( bookQuery );
-        xaccFreeQuery( guidQuery );
-
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-
-        if ( !gnc_sxsld_get_appropriate_page( sxsld,
-                                              druid_page,
-                                              FORWARD ) ) {
-                gnome_druid_set_show_finish( sxsld->sincelast_druid, TRUE );
-        }
-}
-
-static void
-obsolete_prep( GnomeDruidPage *druid_page,
-               gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-        add_dead_list_to_gui( sxsld->toRemoveList, sxsld );
-
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-}
-
-static void
-commit_prep( GnomeDruidPage *druid_page,
-	     gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-}
-
-static
-gboolean
-auto_create_back( GnomeDruidPage *druid_page,
-                  gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)ud;
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->ac_ledger),
-                TRUE );
-        return gen_back( druid_page, arg1, ud );
-}
-
-static
-gboolean
-auto_create_next( GnomeDruidPage *druid_page,
-                  gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)ud;
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->ac_ledger),
-                TRUE );
-        return gen_next( druid_page, arg1, ud );
-}
-
-static
-void
-auto_create_prep( GnomeDruidPage *druid_page,
-                  gpointer arg1, gpointer ud )
-{
-        GList *tctList, *tciList, *guidList;
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-        Query *bookQuery, *guidQuery, *q;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        bookQuery = xaccMallocQuery();
-        guidQuery = xaccMallocQuery();
-        xaccQuerySetBook( bookQuery, gnc_get_current_book() );
-        /* Create the appropriate query for the auto-create-notify ledger; go
-         * through the auto-create list's instances and add all the created
-         * Txn GUIDs. */
-        for ( tctList = sxsld->autoCreateList;
-              tctList;
-              tctList = tctList->next ) {
-                gboolean unused, notifyState;
-
-                tct = (toCreateTuple*)tctList->data;
-                xaccSchedXactionGetAutoCreate( tct->sx, &unused, &notifyState );
-                if ( !notifyState ) {
-                        continue;
-                }
-
-                for ( tciList = tct->instanceList;
-                      tciList;
-                      tciList = tciList->next ) {
-                        tci = (toCreateInstance*)tciList->data;
-                        for ( guidList = tci->createdTxnGUIDs;
-                              guidList;
-                              guidList = guidList->next ) {
-                                xaccQueryAddGUIDMatch( guidQuery,
-                                                       (GUID*)guidList->data,
-                                                       GNC_ID_TRANS,
-                                                       QUERY_OR );
-                        }
-                }
-        }
-        q = xaccQueryMerge( bookQuery, guidQuery, QUERY_AND );
-        gnc_suspend_gui_refresh();
-        gnc_ledger_display_set_query( sxsld->ac_ledger, q );
-        gnc_ledger_display_refresh( sxsld->ac_ledger );
-        gnc_resume_gui_refresh();
-        xaccFreeQuery( q );
-        xaccFreeQuery( bookQuery );
-        xaccFreeQuery( guidQuery );
-
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-
-        if ( !gnc_sxsld_get_appropriate_page( sxsld,
-                                              druid_page,
-                                              FORWARD ) ) {
-                gnome_druid_set_show_finish( sxsld->sincelast_druid, TRUE );
-        }
-}
-
-static
-void
-to_create_prep( GnomeDruidPage *druid_page,
-                gpointer arg1, gpointer ud )
-{
-        GtkWidget *w;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        w = glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST );
-        gtk_clist_freeze( GTK_CLIST(w) );
-        gtk_clist_clear( GTK_CLIST(w) );
-        clean_variable_table( sxsld );
-        add_to_create_list_to_gui( sxsld->toCreateList, sxsld );
-        gtk_clist_thaw( GTK_CLIST(w) );
-        
-        gnome_druid_set_buttons_sensitive(
-                sxsld->sincelast_druid,
-                ( gnc_sxsld_get_appropriate_page( sxsld,
-                                                  druid_page,
-                                                  BACK )
-                  != NULL ),
-                TRUE, TRUE, TRUE );
-        /* Setup next/finish button based on the number of ready-to-go
-         * to-create transactions */
-        gnome_druid_set_show_finish(
-                sxsld->sincelast_druid,
-                ( (sxsld_get_future_created_txn_count(sxsld)
-                   - sxsld->autoCreatedCount) == 0 ) );
-}
-
-static
-void
-sxsld_revert_to_create_txns( sxSinceLastData *sxsld,
-                             toCreateInstance *tci )
-{
-        GList *l = NULL;
-        
-        gnc_suspend_gui_refresh();
-        for ( l = tci->createdTxnGUIDs;
-              l; l = l->next ) {
-                Transaction *t;
-                t = xaccTransLookup( (GUID*)l->data,
-                                     gnc_get_current_book() );
-                g_assert( t );
-                xaccTransBeginEdit( t );
-                xaccTransDestroy( t );
-                xaccTransCommitEdit( t );
-
-                /* Remove from master list, too. */
-                sxsld->createdTxnGUIDList =
-                        g_list_remove(
-                                sxsld->createdTxnGUIDList,
-                                l->data );
-        }
-        g_list_free( tci->createdTxnGUIDs );
-        tci->createdTxnGUIDs = NULL;
-        gnc_resume_gui_refresh();
-}
-
-/**
- * @return The count of created transactions.
- **/
-static
-gint
-sxsld_create_to_create_txns(sxSinceLastData *sxsld,
-                            toCreateInstance *tci,
-                            GList **creation_errors)
-{
-        gint toRet = 0;
-        GList *l = NULL;
-        GList *created = NULL;
-
-        /* Don't process instances we've already created transactions for
-         * [list_length > 0], which haven't otherwise changed [!dirty]. */
-        if ( g_list_length( tci->createdTxnGUIDs ) != 0 ) {
-                /* If we've created it and the variables
-                 * haven't changed, skip it. */
-                if ( ! tci->dirty ) {
-                        return toRet;
-                }
-                /* Otherwise, destroy the transactions and
-                 * re-create them below. */
-
-                /* FIXME: this would be better if we could
-                 * re-used the existing txns we've already
-                 * gone through the pain of creating. */
-                sxsld_revert_to_create_txns( sxsld, tci );
-        }
-
-        create_transactions_on(tci->parentTCT->sx,
-                               tci->date,
-                               tci,
-                               &created,
-                               creation_errors);
-        tci->dirty = FALSE;
-
-        /* Add to the Query for that register. */
-        for ( l = created; l; l = l->next ) {
-                tci->createdTxnGUIDs =
-                        g_list_append( tci->createdTxnGUIDs,
-                                       (GUID*)l->data );
-                toRet++;
-        }
-        sxsld->createdTxnGUIDList =
-                g_list_concat( sxsld->createdTxnGUIDList, created );
-        return toRet;
-}
-
-/**
- * Do the correct thing for the given toCreateInstance, taking into account
- * what we've done to it before [tci->prevState].  That is: if we previously
- * processed the instance as to-create/as-scheduled, and now we're postponing
- * it, we should remove the previously-created transactions and now add the
- * instance to the postponed list.  See the code for full details on the
- * policy here.
- *
- * @return The count of created transactions.
- **/
-static
-gint
-sxsld_process_to_create_instance(sxSinceLastData *sxsld,
-                                 toCreateInstance *tci,
-                                 GList **creation_errors)
-{
-        gint toRet = 0;
-
-        /* Undo the previous work. */
-        switch ( tci->prevState ) {
-        case SX_IGNORE:
-                switch ( tci->state ) {
-                case SX_IGNORE:
-                        /* Keep ignoring. */
-                        break;
-                case SX_POSTPONE:
-                        /* remove from postponed list. */
-                        gnc_sx_remove_defer_instance( tci->parentTCT->sx,
-                                                      tci->sxStateData );
-                        break;
-                case SX_TO_CREATE:
-                        /* del prev txns. */
-                        sxsld_revert_to_create_txns( sxsld, tci );
-                        break;
-                default:
-                        g_assert( FALSE );
-                }
-                break;
-        case SX_POSTPONE:
-                if ( tci->state != SX_POSTPONE ) {
-                        /* remove from postponed list. */
-                        gnc_sx_remove_defer_instance( tci->parentTCT->sx,
-                                                      tci->sxStateData );
-                }
-                break;
-        case SX_TO_CREATE:
-                if ( tci->state != SX_TO_CREATE ) {
-                        /* del prev txns. */
-                        sxsld_revert_to_create_txns( sxsld, tci );
-                }
-                break;
-        case SX_UNDEF:
-                /* Fine; do nothing. */
-                break;
-        default:
-                g_assert( FALSE );
-                break;
-        }
-
-        /* Now, process the currently-requested state. */
-        switch ( tci->state ) {
-        case SX_IGNORE:
-                /* Fine ... just ignore it. */
-                break;
-        case SX_POSTPONE:
-                if ( tci->prevState == SX_POSTPONE ) {
-                        break;
-                }
-                /* add to the postponed list. */
-                { 
-                        char tmpBuf[ MAX_DATE_LENGTH+1 ];
-                        qof_print_gdate( tmpBuf, MAX_DATE_LENGTH, tci->date );
-                        DEBUG( "Adding defer instance on %s for %s",
-                               tmpBuf,
-                               xaccSchedXactionGetName( tci->parentTCT->sx ) );
-                }
-                gnc_sx_add_defer_instance( tci->parentTCT->sx, tci->sxStateData );
-                break;
-        case SX_TO_CREATE:
-                /* Go ahead and create... */
-                toRet = sxsld_create_to_create_txns(sxsld, tci, creation_errors);
-                break;
-        default:
-                g_assert( FALSE );
-                break;
-        }
-
-        tci->prevState = tci->state;
-
-        /* Increment the SX state regardless of what happens above.  The last
-         * generated SX instance is the new final state of the SX in all
-         * cases [ignored, postponed or created]. */
-        {
-                gint tmp;
-                GDate *last_occur;
-                SchedXaction *sx;
-
-                sx = tci->parentTCT->sx;
-
-                /* Only set the last-occur-date, instance count and remaining
-                 * occurances if this instance is later than presently-last
-                 * definition in the SX; no matter what happens in the SX
-                 * dialog, the last instance processed sets the last-occur
-                 * date [and other params] to its instance date [and other
-                 * params]. */
-                last_occur = xaccSchedXactionGetLastOccurDate( sx );
-                /* If we don't have anything to do, then just return. */
-                if ( g_date_valid( last_occur )
-                     && g_date_compare( last_occur, tci->date ) > 0 ) {
-                        return toRet;
-                }
-                xaccSchedXactionSetLastOccurDate( sx, tci->date );
-
-                /* Handle an interesting corner case of postponing or
-                 * ignoring the first instance. We only want to incrment the
-                 * counters for newly-discovered-as-to-be-created SXes.
-                 */
-                if ( tci->origState == SX_UNDEF ) {
-                        tmp = gnc_sx_get_instance_count( sx, NULL );
-                        gnc_sx_set_instance_count( sx, tmp+1 );
-                        if ( xaccSchedXactionHasOccurDef( sx ) ) {
-                                tmp = xaccSchedXactionGetRemOccur(sx);
-                                xaccSchedXactionSetRemOccur( sx, tmp-1 );
-                        }
-                }
-        }
-
-        return toRet;
-}
-
-static
-gboolean
-sxsld_process_to_create_page( sxSinceLastData *sxsld )
-{
-        GtkCTree *ct;
-        GList *tcList, *tcInstList, *creation_errors;
-        gboolean allVarsBound;
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-
-        ct = GTK_CTREE( glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST ) );
-
-        /* First: check to make sure all TCTs are 'ready' [and return if not].
-         * Second: create the entries based on the variable bindings. */
-        tcList = sxsld->toCreateList;
-        if ( tcList == NULL ) {
-                DEBUG( "No transactions to create..." );
-                return FALSE;
-        }
-
-        for ( ; tcList ; tcList = tcList->next ) {
-                tct = (toCreateTuple*)tcList->data;
-                for ( tcInstList = tct->instanceList;
-                      tcInstList;
-                      tcInstList = tcInstList->next ) {
-                        tci = (toCreateInstance*)tcInstList->data;
-
-                        if ( tci->state == SX_IGNORE
-                             || tci->state == SX_POSTPONE ) {
-                                continue;
-                        }
-
-                        allVarsBound = TRUE;
-                        g_hash_table_foreach( tci->varBindings,
-                                              andequal_numerics_set,
-                                              &allVarsBound );
-                        if ( !allVarsBound ) {
-                                char tmpBuf[ MAX_DATE_LENGTH+1 ];
-                                qof_print_gdate( tmpBuf, MAX_DATE_LENGTH, tci->date );
-                                /* FIXME: this should be better-presented to the user. */
-                                DEBUG( "SX %s on date %s still has unbound variables.",
-                                       xaccSchedXactionGetName(tci->parentTCT->sx), tmpBuf );
-                                gtk_ctree_select( ct, tci->node );
-                                return TRUE;
-                        }
-                }
-        }
-
-        /* At this point we can assume there are to-create transactions and
-         * either the instances are being postponed/ignored, or all variables
-         * are bound. */
-
-        tcList = sxsld->toCreateList;
-        g_assert( tcList != NULL );
-
-        creation_errors = NULL;
-        gnc_suspend_gui_refresh();
-        for ( ; tcList ; tcList = tcList->next ) {
-                tct = (toCreateTuple*)tcList->data;
-
-                for ( tcInstList = tct->instanceList;
-                      tcInstList;
-                      tcInstList = tcInstList->next ) {
-
-                        tci = (toCreateInstance*)tcInstList->data;
-                        sxsld_process_to_create_instance(sxsld, tci, &creation_errors);
-                }
-        }
-        gnc_resume_gui_refresh();
-        if (g_list_length(creation_errors) > 0)
-        {
-                creation_errors_dialog(creation_errors);
-                creation_errors_free(creation_errors);
-        }
-        return FALSE;
-}
-
-static
-gboolean
-to_create_next( GnomeDruidPage *druid_page,
-                gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-        GnomeDruidPage *nextPg;
-
-        sxsld = (sxSinceLastData*)ud;
-
-        /* Do the actual work processing the page. */
-        if ( sxsld_process_to_create_page( sxsld ) ) {
-                return TRUE;
-        }
-
-        /* Figure out the next page, now, given the changes we've made above.
-         * This will get us a fix for Bug#95734. */
-        nextPg = gnc_sxsld_get_appropriate_page( sxsld,
-                                                 GNOME_DRUID_PAGE( druid_page ),
-                                                 FORWARD );
-        /* We've made the "adjust buttons on disposition-change" fix
-         * which will make this assertion true. */
-        g_assert( nextPg != NULL );
-        gnome_druid_set_page( sxsld->sincelast_druid, nextPg );
-
-        return TRUE;
-}
-
-static void
-gnc_sxsld_finish( GnomeDruidPage *druid_page,
-                  gpointer arg1, gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-        GList *sxList, *toDelPtr, *elt;
-        GtkCList *cl;
-        gint row;
-        toDeleteTuple *tdt;
-
-        gtk_widget_hide( sxsld->sincelast_window );
-
-        gnc_sxsld_commit_ledgers( sxsld );
-
-        /* If we're finishing from the to-create page, then process the page
-         * contents. */
-        if ( druid_page ==
-             GNOME_DRUID_PAGE( glade_xml_get_widget( sxsld->gxml,
-                                                     TO_CREATE_PG ) ) ) {
-                DEBUG( "Stopped on to-create-pg" );
-                sxsld_process_to_create_page( sxsld );
-        }
-
-        /* Deal with the selected obsolete list elts. */
-        cl = GTK_CLIST( glade_xml_get_widget( sxsld->gxml,
-                                              SX_OBSOLETE_CLIST ) );
-
-        if ( g_list_length( cl->selection ) > 0 ) {
-                SchedXactionDialog *sxd;
-                sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
-
-                gnc_suspend_gui_refresh();
-                for ( toDelPtr = cl->selection;
-                      toDelPtr;
-                      toDelPtr = toDelPtr->next ) {
-
-                        row = GPOINTER_TO_INT(toDelPtr->data);
-                        tdt = (toDeleteTuple*)gtk_clist_get_row_data( cl, row );
-                        elt = g_list_find( sxList, tdt->sx );
-                        sxList = g_list_remove_link( sxList, elt );
-
-                        xaccSchedXactionFree( (SchedXaction*)elt->data );
-                }
-                gnc_resume_gui_refresh();
-
-                gnc_book_set_schedxactions( gnc_get_current_book(), sxList );
-
-                sxd = (SchedXactionDialog*)
-                        gnc_find_first_gui_component(
-                                DIALOG_SCHEDXACTION_CM_CLASS, NULL, NULL );
-                if ( sxd ) {
-                        gnc_sxd_list_refresh( sxd );
-                }
-        }
-
-        sxsincelast_close_handler( sxsld );
-}
-
-static void
-restore_sx_temporal_state( gpointer key,
-                           gpointer value,
-                           gpointer user_data )
-{
-        SchedXaction *sx;
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)user_data;
-
-        sx = (SchedXaction*)key;
-        gnc_sx_revert_to_temporal_state( sx, (void*)value );
-}
-
-static gboolean 
-cancel_check( GnomeDruidPage *druid_page,
-              gpointer arg1, gpointer ud )
-{
-        GList *l;
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-        char *lastrun_cancel_check_msg =
-          _( "Canceling the Since-Last-Run dialog "
-             "will revert all changes. "
-             "Are you sure you want to lose all "
-             "Scheduled Transaction changes?" );
-
-        /* FIXME: This may now be a bug, as we might have changed the SX
-         * states. */
-        if ( g_list_length( sxsld->createdTxnGUIDList ) == 0 ) {
-                /* There's nothing to cancel, so just do so... */
-                return FALSE;
-        }
-
-        if ( !gnc_verify_dialog( sxsld->sincelast_window, TRUE,
-                                 lastrun_cancel_check_msg ) ) {
-                return TRUE;
-        }
-
-        /* Cancel policy:
-         * . deleted SXes
-         *   . reborn
-         * . created transactions
-         *   . deleted
-         *   . SXes reset
-         * . auto-created transactions
-         *   . deleted
-         *   . SXes reset
-         * . reminders -> created
-         *   . Trans deleted
-         *   . SXes reset
-         * SXes reset [we use the temporal-state-data to take care of this]
-         *   . end_date || num_remain_instances
-         *   . last_occur_date
-         */
-
-        gnc_suspend_gui_refresh();
-
-        /* destroy created transactions */
-        if ( g_list_length( sxsld->createdTxnGUIDList ) > 0 ) {
-                Transaction *t = NULL;
-                for ( l = sxsld->createdTxnGUIDList; l; l = l->next ) {
-                        t = xaccTransLookup( (GUID*)l->data,
-                                             gnc_get_current_book() );
-                        /* we used to assert, but since we allow the user a
-                         * register, they may have deleted 't' from their
-                         * view.  Thus, if we can't find it, don't die; fixes
-                         * Bug#103182. */
-                        if ( t != NULL )
-                        {
-                          xaccTransBeginEdit( t );
-                          xaccTransDestroy( t );
-                          xaccTransCommitEdit( t );
-                          t = NULL;
-                        }
-                }
-        }
-
-        /* Remove postponed SXes from their postponed lists, unless they were
-         * originally postponed. */
-        {
-                GList *tcList, *tciList;
-                toCreateTuple *tct;
-                toCreateInstance *tci;
-
-                for ( tcList = sxsld->toCreateList;
-                      tcList;
-                      tcList = tcList->next ) {
-                        tct = (toCreateTuple*)tcList->data;
-                        for ( tciList = tct->instanceList;
-                              tciList;
-                              tciList = tciList->next ) {
-                                tci = (toCreateInstance*)tciList->data;
-                                if ( tci->prevState == SX_POSTPONE
-                                     && tci->origState    != SX_POSTPONE ) {
-                                        /* Any valid [non-null] 'prevState !=
-                                         * SX_POSTPONE' sx temporal state
-                                         * pointers will be destroyed at the
-                                         * destruction of the dialog [the
-                                         * non-cancel case], so if we need to
-                                         * deal with those here, we should do
-                                         * so.
-                                         */
-                                        gnc_sx_remove_defer_instance( tct->sx, tci->sxStateData );
-                                        gnc_sx_destroy_temporal_state( tci->sxStateData );
-                                        tci->sxStateData = NULL;
-                                }
-                        }
-                }
-        }
-
-        /* Restore the temporal state of all SXes. 
-         * This is in sxInitStates [a bunch of opaque void *'s ... which
-         * should be freed when we're done to prevent a memory leak.] */
-        g_hash_table_foreach( sxsld->sxInitStates,
-                              restore_sx_temporal_state,
-                              (gpointer)sxsld );
-        /* This will get destroyed when the dialog is, which will happen
-         * shortly after this return. */
-
-        gnc_resume_gui_refresh();
-        return FALSE;
-}
-
-
-static void
-sxsincelast_init( sxSinceLastData *sxsld )
-{
-        GtkWidget *w;
-        GObject *o;
-        GnomeDruidPage *nextPage;
-        GList *creation_errors;
-        int i;
-        static widgetSignalHandlerTuple widgets[] = {
-                { SINCELAST_DRUID, "cancel",  sxsincelast_druid_cancelled },
-
-                { REMINDER_LIST, "tree-select-row",   sxsld_remind_row_toggle },
-                { REMINDER_LIST, "tree-unselect-row", sxsld_remind_row_toggle },
-                
-                { TO_CREATE_LIST, "tree-select-row",   sxsincelast_tc_row_sel },
-                { TO_CREATE_LIST, "tree-unselect-row", sxsincelast_tc_row_unsel },
-
-                { SX_OBSOLETE_CLIST, "select-row",   sxsld_obsolete_row_toggle },
-                { SX_OBSOLETE_CLIST, "unselect-row", sxsld_obsolete_row_toggle },
-
-                { SELECT_ALL_BUTTON,   "clicked",
-                  sx_obsolete_select_all_clicked },
-                { UNSELECT_ALL_BUTTON, "clicked",
-                  sx_obsolete_unselect_all_clicked },
-
-                { NULL, NULL, NULL }
-        };
-
-        static druidSignalHandlerTuple pages[] = {
-                { WHAT_TO_DO_PG,
-                  whattodo_prep, NULL, NULL,
-                  NULL, cancel_check },
-
-                { REMINDERS_PG,
-                  reminders_prep, reminders_back, reminders_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { AUTO_CREATE_NOTIFY_PG,
-                  auto_create_prep, auto_create_back, auto_create_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { TO_CREATE_PG,
-                  to_create_prep, gen_back, to_create_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { CREATED_PG,
-                  created_prep, created_back, created_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { OBSOLETE_PG,
-                  obsolete_prep, gen_back, gen_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { COMMIT_PG,
-                  commit_prep, gen_back, gen_next,
-                  gnc_sxsld_finish, cancel_check },
-
-                { NULL, NULL, NULL, NULL, NULL, NULL }
-        };
-
-        static const struct optionMenuTuple {
-                char *name;
-                void (*fn)();
-        } optionMenus[] = {
-                { SX_DISPOSITION_OPT, sxsld_disposition_changed },
-                { NULL, NULL }
-        };
-
-
-        gnc_register_gui_component( DIALOG_SXSINCELAST_CM_CLASS,
-                                    NULL,
-                                    sxsincelast_close_handler,
-                                    sxsld->sincelast_window );
-
-        g_signal_connect( G_OBJECT(sxsld->sincelast_window), "destroy",
-			  G_CALLBACK( sxsincelast_destroy ), sxsld );
-
-        dialog_widgets_attach_handlers(sxsld->gxml, widgets, sxsld);
-        druid_pages_attach_handlers( sxsld->gxml, pages, sxsld );
-
-        /* gnc-init the option menu[s]. */
-        for ( i=0; optionMenus[i].name != NULL; i++ ) {
-                w = glade_xml_get_widget( sxsld->gxml, optionMenus[i].name );
-                gnc_option_menu_init( w );
-                o = G_OBJECT(gtk_option_menu_get_menu(GTK_OPTION_MENU(w)));
-                g_signal_connect( o, "selection-done",
-				  G_CALLBACK( optionMenus[i].fn ),
-				  sxsld );
-        }
-
-        /* set all to-create clist columns to auto-resize. */
-        w = glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST );
-        clist_set_all_cols_autoresize(GTK_CLIST(w), TO_CREATE_LIST_WIDTH);
-        w = glade_xml_get_widget( sxsld->gxml, REMINDER_LIST );
-        clist_set_all_cols_autoresize(GTK_CLIST(w), REMINDER_LIST_WIDTH);
-        w = glade_xml_get_widget( sxsld->gxml, SX_OBSOLETE_CLIST );
-        clist_set_all_cols_autoresize(GTK_CLIST(w), SX_OBSOLETE_CLIST_WIDTH);
-
-        sxsld->prog = GTK_PROGRESS_BAR(glade_xml_get_widget( sxsld->gxml,
-                                                             WHAT_TO_DO_PROGRESS ));
-
-        sxsld->toCreateStatus =
-                GTK_STATUSBAR(
-                        glade_xml_get_widget( sxsld->gxml, TO_CREATE_STATUS ) );
-        sxsld->statusCtxId =
-                gtk_statusbar_get_context_id( sxsld->toCreateStatus,
-                                              /* Sure, we're overusing this
-                                               * string, but I don't see why
-                                               * the Statusbar even
-                                               * cares... */
-                                              TO_CREATE_STATUS );
-
-	/* The last druid page is blank without this call. */
-        gtk_widget_show_all( sxsld->sincelast_window );
-
-        create_autoCreate_ledger( sxsld );
-        create_created_ledger( sxsld );
-        create_to_create_ledger( sxsld );
-
-	gnc_restore_window_size(GCONF_SECTION, GTK_WINDOW(sxsld->sincelast_window));
-
-	/* Do not call show_all here. Screws up the gtkuimanager code */
-        gtk_widget_show( sxsld->sincelast_window );
-
-        creation_errors = NULL;
-        process_auto_create_list(sxsld->autoCreateList, sxsld, &creation_errors);
-        if (g_list_length(creation_errors) > 0)
-        {
-                creation_errors_dialog(creation_errors);
-                creation_errors_free(creation_errors);
-        }
-
-        w = glade_xml_get_widget( sxsld->gxml, WHAT_TO_DO_PG );
-        nextPage = gnc_sxsld_get_appropriate_page( sxsld,
-                                                   GNOME_DRUID_PAGE(w),
-                                                   FORWARD );
-
-        /* If there's nowhere to go, then we shouldn't have been started at
-         * all [ie., ..._populate should have returned FALSE]. */
-        g_assert( nextPage );
-
-        gnome_druid_set_page( sxsld->sincelast_druid, nextPage );
-}
-
-static
-void
-sxsincelast_save_size( sxSinceLastData *sxsld )
-{
-  gnc_save_window_size( GCONF_SECTION, GTK_WINDOW(sxsld->sincelast_window) );
-}
-
-static void
-generate_instances(SchedXaction *sx,
-                   GDate *end,
-                   GDate *reminderEnd,
-                   GList **instanceList,
-                   GList **reminderList,
-                   GList **deadList)
-{
-        GDate gd;
-        toCreateInstance *tci;
-        reminderTuple *rt;
-        reminderInstanceTuple *rit;
-        void *seqStateData;
-
-        g_assert( g_date_valid(end) );
-        g_assert( g_date_valid(reminderEnd) );
-
-        g_date_clear(&gd, 1);
-
-        /* Process valid next instances. */
-        seqStateData = gnc_sx_create_temporal_state( sx );
-        //gd = xaccSchedXactionGetNextInstance( sx, seqStateData );
-        gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
-        while ( g_date_valid(&gd)
-                && g_date_compare( &gd, end ) <= 0 ) {
-
-                tci = g_new0( toCreateInstance, 1 );
-
-                tci->dirty     = FALSE;
-                tci->date      = g_date_new();
-                *tci->date     = gd;
-                tci->origState = SX_UNDEF;
-                tci->state     = SX_TO_CREATE;
-                tci->prevState = SX_UNDEF;
-                tci->sxStateData =
-                        gnc_sx_clone_temporal_state( seqStateData );
-                *instanceList  = g_list_append( *instanceList, tci );
-
-                gnc_sx_incr_temporal_state( sx, seqStateData );
-                gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
-        }
-
-        /* Process reminder instances or add to dead list [if we have one] */
-        if ( g_date_valid( &gd ) ) {
-                rt = g_new0( reminderTuple, 1 );
-                rt->sx = sx;
-                rt->instanceList = NULL;
-                while ( g_date_valid(&gd)
-                        && g_date_compare( &gd, reminderEnd ) <= 0 ) {
-
-                        rit = g_new0( reminderInstanceTuple, 1 );
-                        rit->endDate     = g_date_new();
-                        *rit->endDate    = *end;
-                        rit->occurDate   = g_date_new();
-                        *rit->occurDate  = gd;
-                        rit->isSelected  = FALSE;
-                        rit->parentRT    = rt;
-                        rit->sxStateData =
-                                gnc_sx_clone_temporal_state( seqStateData );
-                        rt->instanceList = g_list_append( rt->instanceList, rit );
-
-                        gnc_sx_incr_temporal_state( sx, seqStateData );
-                        gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
-                }
-                if ( rt->instanceList != NULL ) {
-                        *reminderList = g_list_append( *reminderList, rt );
-                } else {
-                        g_free( rt );
-                }
-                rt = NULL;
-        } else if ( deadList ) {
-                toDeleteTuple *tdt;
-
-                tdt = g_new0( toDeleteTuple, 1 );
-                tdt->sx = sx;
-                tdt->endDate = g_date_new();
-                *tdt->endDate = gd;
-                *deadList = g_list_append( *deadList, tdt );
-        } /* else { this else intentionally left blank: drop the SX on the
-           * floor at this point. } */
-
-        gnc_sx_destroy_temporal_state( seqStateData );
-        seqStateData = NULL;
-}
-
-static void
-_free_varBindings_hash_elts( gpointer key, gpointer value, gpointer data )
-{
-        g_assert( key );
-        g_free( key );
-        if ( value ) 
-                g_free( value );
-}
-
-static void
-process_auto_create_list(GList *autoCreateList, sxSinceLastData *sxsld, GList **creation_errors)
-{
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-        GList *instances;
-
-        gnc_suspend_gui_refresh();
-
-        for ( ; autoCreateList ; autoCreateList = autoCreateList->next ) {
-                tct = (toCreateTuple*)autoCreateList->data;
-                
-                for ( instances = tct->instanceList;
-                      instances;
-                      instances = instances->next ) {
-                        tci = (toCreateInstance*)instances->data;
-                        sxsld->autoCreatedCount +=
-                                sxsld_process_to_create_instance( sxsld, tci, creation_errors );
-                }
-        }
-        gnc_resume_gui_refresh();
-}
-
-static
-void
-add_to_create_list_to_gui( GList *toCreateList, sxSinceLastData *sxsld )
-{
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-        GtkCTree *ct;
-        GtkCTreeNode *sxNode;
-        GtkCTreeNode *firstToBeProcessedRow;
-        char *rowText[ TO_CREATE_LIST_WIDTH ];
-        GList *insts;
-
-        ct = GTK_CTREE( glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST ) );
-
-        firstToBeProcessedRow = NULL;
-        for ( ; toCreateList ; toCreateList = toCreateList->next ) {
-                tct = (toCreateTuple*)toCreateList->data;
-
-                rowText[0] = xaccSchedXactionGetName( tct->sx );
-                rowText[1] = "";
-
-                sxNode = gtk_ctree_insert_node( ct, NULL, NULL,
-                                                rowText,
-                                                0, NULL, NULL, NULL, NULL,
-                                                FALSE, TRUE );
-
-                for ( insts = tct->instanceList;
-                      insts;
-                      insts = insts->next ) {
-                        gboolean allVarsBound = FALSE;
-
-                        tci = (toCreateInstance*)insts->data;
-                
-                        /* tct->{sx,date} are already filled in. */
-                        if ( ! tci->varBindings ) {
-                                tci->varBindings = g_hash_table_new( g_str_hash,
-                                                                     g_str_equal );
-
-                                sxsl_get_sx_vars( tci->parentTCT->sx,
-                                                  tci->varBindings );
-                        }
-
-                        rowText[0] = g_new0( char, MAX_DATE_LENGTH+1 );
-                        qof_print_gdate( rowText[0], MAX_DATE_LENGTH, tci->date );
-                        
-
-                        switch ( tci->state ) {
-                        case SX_TO_CREATE:
-                            allVarsBound = TRUE;
-                            g_hash_table_foreach( tci->varBindings,
-                                                  andequal_numerics_set,
-                                                  &allVarsBound );
-                            rowText[1] = ( allVarsBound
-                                           ? _( "Ready to create" ) /* READY_TEXT */ 
-                                           : _( "Needs values for variables" ) /* NEEDS_BINDINGS_TEXT */
-                                    );
-                            break;
-                        case SX_IGNORE:
-                            rowText[1] = _( "Ignored" ) /* IGNORE_TEXT */ ;
-                            break;
-                        case SX_POSTPONE:
-                            rowText[1] = _( "Postponed" ) /* POSTPONE_TEXT */ ;
-                            break;
-                        default:
-                            g_assert( FALSE );
-                        }
-                                
-                        tci->node = gtk_ctree_insert_node( ct, sxNode, NULL,
-                                                           rowText,
-                                                           0, NULL, NULL, NULL, NULL,
-                                                           TRUE, FALSE );
-                        if ( !allVarsBound && !firstToBeProcessedRow ) {
-                                firstToBeProcessedRow = tci->node;
-                        }
-                        gtk_ctree_node_set_row_data( ct, tci->node, tci );
-                        g_free( rowText[0] );
-                }
-        }
-
-        /* Setup the first thing to be processed, or disable controls. */
-        if ( firstToBeProcessedRow ) {
-                gtk_ctree_select( ct, firstToBeProcessedRow );
-                sxsld_set_sensitive_tci_controls( sxsld, TRUE );
-        } else {
-                sxsld_set_sensitive_tci_controls( sxsld, FALSE );
-        }
-}
-
-static
-void
-add_reminders_to_gui( GList *reminderList, sxSinceLastData *sxsld )
-{
-        GtkCTree *ctree;
-        GtkCTreeNode *sxNode, *instNode;
-        char *rowText[REMINDER_LIST_WIDTH];
-        reminderTuple *rt;
-        GList *instances;
-        reminderInstanceTuple *rit;
-        FreqSpec *fs;
-        GString *freqSpecStr;
-
-        ctree = GTK_CTREE( glade_xml_get_widget( sxsld->gxml,
-                                                 REMINDER_LIST ) );
-
-        for ( ; reminderList; reminderList = reminderList->next ) {
-                rt = (reminderTuple*)reminderList->data;
-
-                rowText[0] = xaccSchedXactionGetName( rt->sx );
-                fs = xaccSchedXactionGetFreqSpec( rt->sx );
-                freqSpecStr = g_string_sized_new( 16 );
-                xaccFreqSpecGetFreqStr( fs, freqSpecStr );
-                rowText[1] = freqSpecStr->str;
-                rowText[2] = ""; /* Days Away */
-                sxNode = gtk_ctree_insert_node( ctree, NULL, NULL, rowText,
-                                                0, /* spacing */
-                                                NULL, NULL, NULL, NULL, /* pixmaps */
-                                                FALSE, /* leafP */
-                                                TRUE ); /* expandedP */
-                g_string_free( freqSpecStr, TRUE );
-
-                /* The SX node itself isn't selectable; only the
-                 * instances. */
-                gtk_ctree_node_set_selectable( ctree, sxNode, FALSE );
-                for ( instances = rt->instanceList;
-                      instances;
-                      instances = instances->next ) {
-                        rit = (reminderInstanceTuple*)instances->data;
-
-                        rowText[0] = g_new0( gchar, MAX_DATE_LENGTH+1 );
-                        qof_print_gdate( rowText[0], MAX_DATE_LENGTH, rit->occurDate );
-                        rowText[1] = "";
-                        rowText[2] = g_new0( gchar, 5 ); /* FIXME: appropriate size? */
-                        sprintf( rowText[2], "%d",
-                                 (g_date_get_julian(rit->occurDate)
-                                  - g_date_get_julian(rit->endDate)) );
-
-                        instNode = gtk_ctree_insert_node( ctree, sxNode, NULL,
-                                                          rowText,
-                                                          0, NULL, NULL, NULL, NULL,
-                                                          TRUE, TRUE );
-                        gtk_ctree_node_set_row_data( ctree,
-                                                     instNode,
-                                                     (gpointer)rit );
-                        g_signal_handlers_block_by_func( G_OBJECT(ctree),
-                                                         sxsld_remind_row_toggle,
-                                                         sxsld ); 
-                        if ( rit->isSelected ) {
-                                gtk_ctree_select( ctree, instNode );
-                        }
-                        g_signal_handlers_unblock_by_func( G_OBJECT(ctree),
-                                                           sxsld_remind_row_toggle,
-                                                           sxsld );
-                        g_free( rowText[0] );
-                        g_free( rowText[2] );
-                }
-        }
-}
-
-static void
-add_dead_list_to_gui(GList *removeList, sxSinceLastData *sxsld)
-{
-        GtkCList *cl;
-        char *rowtext[3];
-        int row;
-        GString *tmp_str;
-        toDeleteTuple *tdt;
-        FreqSpec *fs;
-        cl = GTK_CLIST( glade_xml_get_widget( sxsld->gxml,
-                                              SX_OBSOLETE_CLIST ));
-
-        tmp_str = g_string_new(NULL);
-        rowtext[2] = g_strdup( _("Obsolete") );
-
-        gtk_clist_freeze( cl );
-        gtk_clist_clear( cl );
-        g_signal_handlers_block_by_func( G_OBJECT(cl),
-                                         sxsld_obsolete_row_toggle,
-                                         sxsld );
-
-        for ( row = 0; removeList;
-              row++, removeList = removeList->next ) {
-                tdt = (toDeleteTuple*)removeList->data;
-
-                rowtext[0] = xaccSchedXactionGetName( tdt->sx );
-
-                fs = xaccSchedXactionGetFreqSpec( tdt->sx );
-                xaccFreqSpecGetFreqStr( fs, tmp_str );
-                /* XXX are we leaking memory here, by not 
-                 * freeing previous rrowtext[1] ?? */
-                rowtext[1] = tmp_str->str;
-
-                gtk_clist_insert( cl, row, rowtext );
-                gtk_clist_set_row_data( cl, row, tdt );
-                if ( tdt->isSelected ) {
-                        gtk_clist_select_row( cl, row, 0 );
-                }
-        }
-        g_signal_handlers_unblock_by_func( G_OBJECT(cl),
-                                           sxsld_obsolete_row_toggle,
-                                           sxsld );
-        gtk_clist_thaw( cl );
-
-        g_string_free(tmp_str, TRUE);
-        g_free(rowtext[2]);
-}
-
-/**
- * Moves the selected reminders to the appropriate [auto-create or to-create]
- * sections of the since-last-run dialog.
- **/
-static void
-processSelectedReminderList( GList *goodList, sxSinceLastData *sxsld )
-{
-        GList *list = NULL;
-        GList **containingList;
-        reminderInstanceTuple *rit;
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-        gboolean autoCreateOpt, notifyOpt;
-
-        tct = NULL;
-        for ( ; goodList ; goodList = goodList->next ) {
-                rit = (reminderInstanceTuple*)goodList->data;
-
-                /* skip over reminders we've already created [in the
-                 * past]. */
-                if ( rit->resultantTCI )
-                        continue;
-
-                xaccSchedXactionGetAutoCreate( rit->parentRT->sx,
-                                               &autoCreateOpt, &notifyOpt );
-                containingList = ( autoCreateOpt
-                                   ? &sxsld->autoCreateList
-                                   : &sxsld->toCreateList );
-                for ( list = *containingList;
-                      list;
-                      list = list->next ) {
-                        tct = (toCreateTuple*)list->data;
-                        /* Find any already-existing toCreateTuples to add to...*/
-                        if ( tct->sx == rit->parentRT->sx ) {
-                                break;
-                        }
-                }
-                if ( !list ) {
-                        tct = g_new0( toCreateTuple, 1 );
-                        tct->sx = rit->parentRT->sx;
-                        *containingList =
-                                g_list_append( *containingList, tct );
-                }
-
-                tci = g_new0( toCreateInstance, 1 );
-                tci->dirty       = FALSE;
-                tci->parentTCT   = tct;
-                tci->date        = g_date_new();
-                *tci->date       = *rit->occurDate;
-                tci->state       = SX_TO_CREATE;
-                tci->prevState   = SX_UNDEF;
-                tci->origState   = SX_UNDEF;
-                tci->varBindings = NULL;
-                tci->node        = NULL;
-                tci->sxStateData = rit->sxStateData;
-                
-                tct->instanceList =
-                        g_list_append( tct->instanceList, tci );
-                
-                /* special auto-create-opt processing; process it now. */
-                if ( autoCreateOpt ) {
-                        GList *creation_errors = NULL;
-                        list = NULL;
-                        list = g_list_append( list, tct );
-                        process_auto_create_list( list, sxsld, &creation_errors );
-                        list = NULL;
-                }
-
-                /* save the resultant just-created TCI in the RIT in case
-                 * things change later. */
-                rit->resultantTCI = tci;
-        }
-}
-
-/**
- * @see gnc_ui_sxsincelast_dialog_create for the return value definition.
- **/
-static
-gint
-sxsincelast_populate( sxSinceLastData *sxsld )
-{
-        int toRet = 0;
-        gboolean onlyNoNotify = TRUE;
-        GList *sxList, *instanceList, *l, **containingList;
-        SchedXaction *sx;
-        GDate end, endPlusReminders;
-        gint daysInAdvance;
-        gboolean autocreateState, notifyState;
-        toCreateTuple *tct;
-        toCreateInstance *tci;
-
-        instanceList = NULL;
-        sxList = gnc_book_get_schedxactions( gnc_get_current_book () );
-
-        if ( sxList == NULL ) {
-                DEBUG( "No scheduled transactions to populate." );
-                return toRet;
-        }
-
-        for ( ; sxList; sxList = sxList->next ) {
-                sx = (SchedXaction*)sxList->data;
-                
-                /* Store initial state of SX. */
-                if ( g_hash_table_lookup( sxsld->sxInitStates, sx )
-                     != NULL ) {
-                        PERR( "Why are we able to find a SX initial state "
-                              "hash entry for something we're seeing for "
-                              "the first time?" );
-                        return toRet;
-                }
-                {
-                        void *sx_state;
-                        sx_state = gnc_sx_create_temporal_state( sx );
-                        g_hash_table_insert( sxsld->sxInitStates,
-                                             sx, sx_state );
-                        sx_state = NULL;
-                }
-
-		g_date_set_time_t( &end, time(NULL) );
-                daysInAdvance = xaccSchedXactionGetAdvanceCreation( sx );
-                g_date_add_days( &end, daysInAdvance );
-                
-                endPlusReminders = end;
-                daysInAdvance = xaccSchedXactionGetAdvanceReminder(sx);
-                g_date_add_days(&endPlusReminders, daysInAdvance);
-
-                /* Handle postponed instances.
-                 *
-                 * Postponed instances, by definition, are always at the
-                 * front of the instance list.  As well, they're always valid
-                 * instances [not reminders]. */
-
-                /* FIXME: postponed instances _may_ create an obsolete
-                 * instance. */
-                {
-                        GList *postponed, *l;
-
-                        postponed = gnc_sx_get_defer_instances( sx );
-
-                        for ( l = postponed; l; l = l->next ) {
-                                onlyNoNotify = FALSE;
-
-                                tci = g_new0( toCreateInstance, 1 );
-                                tci->sxStateData = (void*)l->data;
-                                tci->date        = g_date_new();
-                                *tci->date       =
-                                        xaccSchedXactionGetNextInstance(
-                                                sx, tci->sxStateData );
-                                tci->dirty       = FALSE;
-                                tci->state       = SX_POSTPONE;
-                                tci->prevState   = SX_POSTPONE;
-                                tci->origState   = SX_POSTPONE;
-
-                                instanceList = g_list_append( instanceList, tci );
-                                tci = NULL;
-                        }
-                        
-                }
-
-                generate_instances(sx,
-                                   &end,
-                                   &endPlusReminders,
-                                   &instanceList,
-                                   &sxsld->reminderList,
-                                   &sxsld->toRemoveList);
-
-                if (instanceList == NULL)
-                        continue;
-
-                xaccSchedXactionGetAutoCreate(sx, &autocreateState, &notifyState);
-                /* Figure out the appropriate list to place the new TCT on. */
-                containingList = ( autocreateState
-                                   ? &sxsld->autoCreateList
-                                   : &sxsld->toCreateList );
-
-                tct = g_new0( toCreateTuple, 1 );
-                tct->sx = sx;
-                for ( l = instanceList ; l; l = l->next ) {
-
-                        /* only count the no-notify txns for this. */
-                        if ( autocreateState && !notifyState ) {
-                                onlyNoNotify &= (!notifyState);
-                                toRet++;
-                        }
-
-                        tci = (toCreateInstance*)l->data;
-                        tci->parentTCT = tct;
-                        
-                        tct->instanceList =
-                                g_list_append( tct->instanceList, tci );
-                }
-
-                g_list_free( instanceList );
-                instanceList = NULL;
-
-                /* abstractly place the TCT onto the afore-determined list. */
-                *containingList = g_list_append( *containingList, tct );
-        }
-
-        /* Return appropriately. */
-        {
-                gboolean stuffToDo = 
-                        ( g_list_length( sxsld->toRemoveList )    > 0
-                          || g_list_length( sxsld->reminderList ) > 0
-                          || g_list_length( sxsld->toCreateList ) > 0 );
-                if ( onlyNoNotify && !stuffToDo ) {
-                        toRet = -(toRet);
-                }
-
-                if ( toRet == 0
-                     && ( stuffToDo
-                          || g_list_length( sxsld->autoCreateList ) > 0 ) ) {
-                        toRet = INT_MAX;
-                }
-        }
-
-        /* if we're about to return a negative value [indicating only
-         * auto-create no-notify txns], then actually create them. */
-        if ( toRet < 0 ) {
-                GList *creation_errors = NULL;
-                process_auto_create_list( sxsld->autoCreateList, sxsld, &creation_errors );
-                if (g_list_length(creation_errors) > 0)
-                {
-                        creation_errors_dialog(creation_errors);
-                        creation_errors_free(creation_errors);
-                }
-        }
-
-        return toRet;
-}
-
-static void
-sxsincelast_close_handler( gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-        
-        gtk_widget_hide( sxsld->sincelast_window );
-        sxsincelast_save_size( sxsld );
-        gtk_widget_destroy( sxsld->sincelast_window );
-        /* The data will be cleaned up in the destroy handler. */
-}
-
-static void
-andequal_numerics_set( gpointer key, gpointer value, gpointer data )
-{
-        gboolean *allVarsBound = data;
-        if ( strcmp( (gchar*)key, "i" ) == 0 ) {
-                return;
-        }
-        *allVarsBound &= (value != NULL);
-}
-
-static void
-sxsincelast_entry_changed( GtkEditable *e, gpointer ud )
-{
-        sxSinceLastData *sxsld;
-        gchar *varName;
-        toCreateInstance *tci;
-        gchar *entryText;
-        gnc_numeric *num, *ourNum;
-        GHashTable *dummyVarHash;
-        static const int MSG_BUF_LEN = 127;
-        char msgBuf[MSG_BUF_LEN+1];
-
-        sxsld = (sxSinceLastData*)ud;
-
-        tci = (toCreateInstance*)g_object_get_data( G_OBJECT(e), "tci" );
-        g_assert( tci == sxsld->curSelTCI );
-
-        varName = (gchar*)g_object_get_data( G_OBJECT(e), "varName" );
-        num = (gnc_numeric*)g_object_get_data( G_OBJECT(e), "numeric" );
-        entryText = gtk_editable_get_chars( e, 0, -1 );
-        dummyVarHash = g_hash_table_new( NULL, NULL );
-        /* FIXME?: Should be using xaccParseAmount instead of
-         * parser_parse_separate_vars? */
-        gtk_statusbar_pop( sxsld->toCreateStatus, sxsld->statusCtxId );
-
-        if ( !gnc_exp_parser_parse_separate_vars( entryText, num,
-                                                  NULL, dummyVarHash ) ) {
-                num = NULL;
-                if ( entryText != NULL
-                     && strlen(entryText) > 0 ) {
-                        snprintf( msgBuf, MSG_BUF_LEN,
-                                  "error parsing entry near \"%s\"", entryText );
-                        gtk_statusbar_push( sxsld->toCreateStatus,
-                                            sxsld->statusCtxId,
-                                            msgBuf );
-                }
-        } else if ( g_hash_table_size( dummyVarHash ) != 0 ) {
-                num = NULL;
-                snprintf( msgBuf, MSG_BUF_LEN,
-                          "No new variables allowed in "
-                          "expression \"%s\"", entryText );
-                gtk_statusbar_push( sxsld->toCreateStatus,
-                                    sxsld->statusCtxId,
-                                    msgBuf );
-        } else if ( gnc_numeric_check( *num ) != GNC_ERROR_OK ) {
-                snprintf( msgBuf, MSG_BUF_LEN,
-                          "Entry \"%s\" is not "
-                          "parseable", entryText );
-                gtk_statusbar_push( sxsld->toCreateStatus,
-                                    sxsld->statusCtxId,
-                                    msgBuf );
-                num = NULL;
-        } else {
-                snprintf( msgBuf, MSG_BUF_LEN,
-                          "%f", gnc_numeric_to_double( *num ) );
-                gtk_statusbar_push( sxsld->toCreateStatus,
-                                    sxsld->statusCtxId,
-                                    msgBuf );
-        }
-
-        g_hash_table_foreach( dummyVarHash,
-                              _free_varBindings_hash_elts,
-                              NULL );
-        g_hash_table_destroy( dummyVarHash );
-
-        {
-                gpointer maybeKey, maybeValue;
-                
-                ourNum = NULL;
-                if ( num ) {
-                        ourNum = g_new0( gnc_numeric, 1 );
-                        *ourNum = *num;
-                }
-                if ( g_hash_table_lookup_extended( tci->varBindings, varName,
-                                                   &maybeKey, &maybeValue ) ) {
-                        g_hash_table_remove( tci->varBindings, maybeKey );
-                        /* only if not null. */
-                        if ( maybeValue ) {
-                                g_free( maybeValue );
-                        }
-                }
-                g_hash_table_insert( tci->varBindings, varName, ourNum );
-                tci->dirty = TRUE;
-        }
-
-        
-        {
-                GtkCTree *ct;
-                gboolean allVarsBound = TRUE;
-
-                /* If there are no un-bound variables, then set the 'ready-to-go'
-                   flag to 'y'. */
-                g_hash_table_foreach( tci->varBindings,
-                                      andequal_numerics_set,
-                                      &allVarsBound );
-                ct = GTK_CTREE(glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST ));
-                gtk_ctree_node_set_text( ct, tci->node, 1,
-                                         ( allVarsBound
-                                           ? _( READY_TEXT )
-                                           : _( NEEDS_BINDINGS_TEXT ) ) );
-        }
-}
-
-static void
-sxsincelast_destroy( GtkObject *o, gpointer ud )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-
-        /* appropriate place to destroy data structures */
-        clean_sincelast_data( sxsld );
-
-        gnc_embedded_window_close_page(sxsld->ac_window, sxsld->ac_register);
-        gtk_widget_destroy(GTK_WIDGET(sxsld->ac_window));
-        sxsld->ac_window = NULL;
-        sxsld->ac_register = NULL;
-        sxsld->ac_ledger = NULL;
-
-        gnc_embedded_window_close_page(sxsld->created_window,
-                                       sxsld->created_register);
-        gtk_widget_destroy(GTK_WIDGET(sxsld->created_window));
-        sxsld->created_window = NULL;
-        sxsld->created_register = NULL;
-        sxsld->created_ledger = NULL;
-
-        gnc_embedded_window_close_page(sxsld->to_create_window,
-                                       sxsld->to_create_register);
-        gtk_widget_destroy(GTK_WIDGET(sxsld->to_create_window));
-        sxsld->to_create_window = NULL;
-        sxsld->to_create_register = NULL;
-        sxsld->to_create_ledger = NULL;
-
-        gnc_unregister_gui_component_by_data( DIALOG_SXSINCELAST_CM_CLASS,
-                                              sxsld->sincelast_window );
-
-        g_free( sxsld );
-}
-
-/**
- * Used to copy the varBinding GHashTable.
- **/
-static
-void
-gnc_sxsl_copy_ea_hash( gpointer key,
-                       gpointer value,
-                       gpointer user_data )
-{
-        gchar *name = (gchar*)key;
-        gnc_numeric *val = (gnc_numeric*)value;
-        gnc_numeric *newVal;
-        GHashTable *table = (GHashTable*)user_data;
-
-        newVal = g_new0( gnc_numeric, 1 );
-        *newVal = gnc_numeric_error( -2 );
-        if ( val )
-                *newVal = *val;
-
-        g_assert( name );
-
-        g_hash_table_insert( table,
-                             (gpointer)g_strdup( name ),
-                             (gpointer)newVal );
-}
-
-static
-void
-gnc_sxsl_del_vars_table_ea( gpointer key,
-                            gpointer value,
-                            gpointer user_data )
-{
-        g_assert( key );
-        if ( key )
-                g_free( (gchar*)key );
-        if ( value )
-                g_free( (gnc_numeric*)value );
-}
-
-static gint
-create_each_transaction_helper( Transaction *t, void *d )
-{
-        Transaction *newT;
-        GList *sList;
-        GList *osList;
-        Split *split;
-        kvp_frame *split_kvpf;
-        kvp_value *kvp_val;
-        gboolean errFlag;
-        createData *createUD;
-        toCreateInstance *tci;
-        gnc_commodity *first_cmdty = NULL;
-        GHashTable *actualVars;
-        gnc_numeric *varIValue;
-
-        errFlag = FALSE;
-
-        /* FIXME: In general, this should [correctly] deal with errors such
-           as not finding the approrpiate Accounts and not being able to
-           parse the formula|credit/debit strings. */
-
-        /* FIXME: when we copy the trans_onto_trans, we don't want to copy
-           the Split's kvp_frames... */
-
-        createUD = (createData*)d;
-        tci = createUD->tci;
-
-        newT = xaccMallocTransaction(gnc_get_current_book ());
-        xaccTransBeginEdit( newT );
-        /* the action and description/memo are in the template */
-        gnc_copy_trans_onto_trans( t, newT, FALSE, FALSE );
-
-        xaccTransSetDate( newT,
-                          g_date_get_day( tci->date ),
-                          g_date_get_month( tci->date ),
-                          g_date_get_year( tci->date ) );
-
-        /* the accounts and amounts are in the kvp_frames of the splits. */
-        osList = xaccTransGetSplitList( t );
-        sList = xaccTransGetSplitList( newT );
-        if ( (osList == NULL) || (sList == NULL) ) {
-                PERR( "\tseen transaction w/o splits. :(" );
-                xaccTransDestroy( newT );
-                xaccTransCommitEdit( newT );
-                return 13;
-        }
-
-        /* Setup the predefined variables for credit/debit formula
-         * processing. */
-        actualVars = g_hash_table_new( g_str_hash, g_str_equal );
-        if ( tci->varBindings != NULL ) {
-                g_hash_table_foreach( tci->varBindings,
-                                      gnc_sxsl_copy_ea_hash, actualVars );
-        }
-        varIValue = g_new0( gnc_numeric, 1 );
-        *varIValue =
-                gnc_numeric_create(
-                        gnc_sx_get_instance_count( tci->parentTCT->sx,
-                                                   tci->sxStateData ),
-                        1 );
-        /* It's really important that we strdup "i" here, so we can
-         * generically cleanup with a simple 'foreach' that blindly frees the
-         * keys, below. */
-        g_hash_table_insert( actualVars, g_strdup("i"), varIValue );
-
-        for ( ; sList && osList; sList = sList->next, osList = osList->next)
-        {
-                Account *acct;
-                gnc_commodity *split_cmdty = NULL;
-
-                split = (Split*)sList->data;
-
-                /* FIXME: Ick.  This assumes that the split lists will be
-                   ordered identically. :( I think it's fair to say they
-                   will, but I'd rather not have to count on it. --jsled */
-                split_kvpf = xaccSplitGetSlots( (Split*)osList->data );
-
-                /* from-transaction of splits */
-                /* This needs to be before the value setting [below] so the
-                 * balance calculations can work. */
-                {
-                        GUID                *acct_guid;
-                        /* contains the guid of the split's actual account. */
-                        kvp_val = kvp_frame_get_slot_path( split_kvpf,
-                                                           GNC_SX_ID,
-                                                           GNC_SX_ACCOUNT,
-                                                           NULL );
-                        if (kvp_val == NULL) {
-                                GString *err = g_string_new("");
-                                g_string_printf(err, "Null account kvp value for SX [%s], cancelling creation.",
-                                                xaccSchedXactionGetName(createUD->tci->parentTCT->sx));
-                                *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-                                errFlag = TRUE;
-                                break;
-                        }
-                        acct_guid = kvp_value_get_guid( kvp_val );
-                        acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
-                        if (acct == NULL)
-                        {
-                                const char *guidStr;
-                                GString *err;
-                                guidStr = guid_to_string((const GUID*)acct_guid);
-                                err = g_string_new("");
-                                g_string_printf(err, "Unknown account for guid [%s], cancelling SX [%s] creation.",
-                                                guidStr, xaccSchedXactionGetName(createUD->tci->parentTCT->sx));
-                                g_free((char*)guidStr);
-                                *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-                                errFlag = TRUE;
-                                break;
-                        }
-
-                        split_cmdty = xaccAccountGetCommodity(acct);
-                        if (first_cmdty == NULL)
-                        {
-                                first_cmdty = split_cmdty;
-                                xaccTransSetCurrency(newT, first_cmdty);
-                        }
-
-                        xaccAccountBeginEdit(acct);
-                        xaccAccountInsertSplit(acct, split);
-                }
-
-                /* credit/debit formulas */
-                {
-                        char *str, *parseErrorLoc;
-                        gnc_numeric credit_num, debit_num, final;
-                        int gncn_error;
-
-                        kvp_val = kvp_frame_get_slot_path( split_kvpf,
-                                                           GNC_SX_ID,
-                                                           GNC_SX_CREDIT_FORMULA,
-                                                           NULL);
-                        str = kvp_value_get_string( kvp_val );
-                        credit_num = gnc_numeric_create( 0, 1 );
-                        if (str != NULL && strlen(str) != 0) {
-                                if (!gnc_exp_parser_parse_separate_vars(str, &credit_num,
-                                                                        &parseErrorLoc,
-                                                                        actualVars))
-                                {
-                                        GString *err = g_string_new("");
-                                        g_string_printf(err, "Error parsing SX [%s] credit formula [%s] at [%s]: %s",
-                                                        xaccSchedXactionGetName(createUD->tci->parentTCT->sx),
-                                                        str, parseErrorLoc, gnc_exp_parser_error_string());
-                                        *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-                                        credit_num = gnc_numeric_create( 0, 1 );
-                                }
-                        }
-                        
-                        kvp_val = kvp_frame_get_slot_path( split_kvpf,
-                                                           GNC_SX_ID,
-                                                           GNC_SX_DEBIT_FORMULA,
-                                                           NULL);
-                        str = kvp_value_get_string( kvp_val );
-
-                        debit_num = gnc_numeric_create( 0, 1 );
-                        if (str != NULL && strlen(str) != 0) {
-                                if (!gnc_exp_parser_parse_separate_vars(str, &debit_num,
-                                                                        &parseErrorLoc,
-                                                                        actualVars))
-                                {
-                                        GString *err = g_string_new("");
-                                        g_string_printf(err, "Error parsing SX [%s] debit formula [%s] at [%s]: %s",
-                                                        xaccSchedXactionGetName(createUD->tci->parentTCT->sx),
-                                                        str, parseErrorLoc, gnc_exp_parser_error_string());
-                                        *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-                                        debit_num = gnc_numeric_create( 0, 1 );
-                                }
-
-                        }
-                        
-                        final = gnc_numeric_sub_fixed( debit_num, credit_num );
-                        
-                        gncn_error = gnc_numeric_check(final);
-                        if (gncn_error != GNC_ERROR_OK) {
-                                GString *err = g_string_new("");
-                                g_string_printf(err, "Error %d in SX [%s] final gnc_numeric value, using 0 instead.", 
-                                                gncn_error,
-                                                xaccSchedXactionGetName(createUD->tci->parentTCT->sx));
-                                *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-                                final = gnc_numeric_create(0, 1);
-                        }
-
-                        xaccSplitSetValue(split, final);
-                        if (! gnc_commodity_equal(split_cmdty, first_cmdty))
-                        {
-                                GString *exchange_rate_var_name = g_string_sized_new(16);
-                                gnc_numeric *exchange, amt;
-
-                                /*
-                                GNCPriceDB *price_db = gnc_pricedb_get_db(gnc_get_current_book());
-                                GNCPrice *price;
-
-                                price = gnc_pricedb_lookup_latest(price_db, first_cmdty, split_cmdty);
-                                if (price == NULL)
-                                {
-                                        price = gnc_pricedb_lookup_latest(price_db, split_cmdty, first_cmdty);
-                                        if (price == NULL)
-                                        {
-                                                GString *err = g_string_new("");
-                                                g_string_printf(err, "could not find pricedb entry for commodity-pair (%s, %s).",
-                                                                gnc_commodity_get_mnemonic(first_cmdty),
-                                                                gnc_commodity_get_mnemonic(split_cmdty));
-                                                exchange = gnc_numeric_create(1, 1);
-                                                *createUD->creation_errors = g_list_append(*createUD->creation_errors, err);
-
-                                        }
-                                        else
-                                        {
-                                                exchange = gnc_numeric_div(gnc_numeric_create(1,1),
-                                                                           gnc_price_get_value(price),
-                                                                           1000, GNC_HOW_RND_ROUND);
-                                        }
-                                }
-                                else
-                                {
-                                        exchange = gnc_price_get_value(price);
-                                }
-                                */
-
-                                g_string_printf(exchange_rate_var_name, "%s -> %s",
-                                                gnc_commodity_get_mnemonic(split_cmdty),
-                                                gnc_commodity_get_mnemonic(first_cmdty));
-                                exchange = (gnc_numeric*)g_hash_table_lookup(actualVars, exchange_rate_var_name->str);
-                                if (exchange == NULL)
-                                {
-                                        exchange = g_new0(gnc_numeric, 1);
-                                        *exchange = gnc_numeric_create(0, 1);
-                                }
-                                g_string_free(exchange_rate_var_name, TRUE);
-
-                                amt = gnc_numeric_mul(final, *exchange, 1000, GNC_HOW_RND_ROUND);
-                                xaccSplitSetAmount(split, amt);
-                        }
-                        xaccSplitScrub( split );
-                }
-                xaccAccountCommitEdit( acct );
-        }
-
-        /* Cleanup actualVars table. */
-        {
-                g_hash_table_foreach( actualVars,
-                                      gnc_sxsl_del_vars_table_ea,
-                                      NULL );
-                g_hash_table_destroy( actualVars );
-                actualVars = NULL;
-        }
-
-        if (errFlag) {
-                PERR("Some error in new transaction creation...");
-                xaccTransDestroy(newT);
-                xaccTransCommitEdit(newT);
-                return 13;
-        }
-
-        {
-                kvp_frame *txn_frame;
-                /* set a kvp-frame element in the transaction indicating and
-                 * pointing-to the SX this was created from. */
-                txn_frame = xaccTransGetSlots(newT);
-                kvp_frame_set_guid(txn_frame, "from-sched-xaction", 
-                                   xaccSchedXactionGetGUID(tci->parentTCT->sx));
-        }
-
-        xaccTransCommitEdit(newT);
-
-        if ( createUD->createdGUIDs != NULL ) {
-                *createUD->createdGUIDs =
-                        g_list_append( *(createUD->createdGUIDs),
-                                       (gpointer)xaccTransGetGUID(newT) );
-        }
-
-        return 0;
-}
-
-/**
- * This should be called with the dates in increasing order, or the last call
- * will set the last occur date incorrectly.
- **/
-static void
-create_transactions_on(SchedXaction *sx,
-                       GDate *gd,
-                       toCreateInstance *tci,
-                       GList **createdGUIDs,
-                       GList **creation_errors)
-{
-        createData createUD;
-        AccountGroup *ag;
-        Account *acct;
-        const char *id;
-
-        if (tci) {
-                g_assert(g_date_compare(gd, tci->date) == 0);
-        }
-
-        ag = gnc_book_get_template_group( gnc_get_current_book () );
-        id = guid_to_string( xaccSchedXactionGetGUID(sx) );
-        if ( !(ag && id) ) {
-                return;
-        }
-        /* This looks strange but it's right.  The account is
-           named after the guid string. */
-        acct = xaccGetAccountFromName( ag, id );
-        if (!acct) {
-                return;
-        }
-
-        createUD.tci = tci;
-        createUD.createdGUIDs = createdGUIDs;
-        createUD.creation_errors = creation_errors;
-        xaccAccountForEachTransaction(acct,
-                                      create_each_transaction_helper,
-                                      /*tct*/ &createUD);
-}
-
-static void
-_hashToList( gpointer key, gpointer value, gpointer user_data )
-{
-        *(GList**)user_data = g_list_append( *(GList**)user_data, key );
-}
-
-static void
-hash_to_sorted_list( GHashTable *hashTable, GList **gl )
-{
-        g_hash_table_foreach( hashTable, _hashToList, gl );
-        *gl = g_list_sort( *gl, g_str_equal );
-}
-
-static void
-clear_variable_numerics( gpointer key, gpointer value, gpointer data )
-{
-        g_free( (gnc_numeric*)value );
-        g_hash_table_insert( (GHashTable*)data, key, NULL );
-}
-
-static gint
-_get_vars_helper(Transaction *txn, void *var_hash_data)
-{
-        GHashTable *var_hash = (GHashTable*)var_hash_data;
-        GList *split_list;
-        kvp_frame *kvpf;
-        kvp_value *kvp_val;
-        Split *s;
-        char *str;
-        gnc_commodity *first_cmdty = NULL;
-
-        split_list = xaccTransGetSplitList(txn);
-
-        if ( split_list == NULL ) {
-                return 1;
-        }
-
-        for ( ; split_list ; split_list = split_list->next ) {
-                gnc_commodity *split_cmdty = NULL;
-                GUID *acct_guid;
-                Account *acct;
-
-                s = (Split*)split_list->data;
-                kvpf = xaccSplitGetSlots(s);
-                kvp_val = kvp_frame_get_slot_path(kvpf,
-                                                  GNC_SX_ID,
-                                                  GNC_SX_ACCOUNT,
-                                                  NULL);
-                acct_guid = kvp_value_get_guid( kvp_val );
-                acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
-                split_cmdty = xaccAccountGetCommodity(acct);
-                if (first_cmdty == NULL)
-                {
-                        first_cmdty = split_cmdty;
-                }
-                
-                if (! gnc_commodity_equal(split_cmdty, first_cmdty))
-                {
-                        gnc_numeric *tmp_num;
-                        GString *var_name = g_string_sized_new(16);
-                        g_string_printf(var_name, "%s -> %s",
-                                        gnc_commodity_get_mnemonic(split_cmdty),
-                                        gnc_commodity_get_mnemonic(first_cmdty));
-                        tmp_num = g_new0(gnc_numeric, 1);
-                        *tmp_num = gnc_numeric_create(0, 1);
-                        g_hash_table_insert(var_hash, g_strdup(var_name->str), tmp_num);
-                        g_string_free(var_name, TRUE);
-                }
-
-                // existing... ------------------------------------------
-                
-                kvp_val = kvp_frame_get_slot_path( kvpf,
-                                                   GNC_SX_ID,
-                                                   GNC_SX_CREDIT_FORMULA,
-                                                   NULL);
-                if ( kvp_val != NULL ) {
-                        str = kvp_value_get_string( kvp_val );
-                        if ( str && strlen(str) != 0 ) {
-                                parse_vars_from_formula( str, var_hash, NULL );
-                        }
-                }
-
-                kvp_val = kvp_frame_get_slot_path( kvpf,
-                                                   GNC_SX_ID,
-                                                   GNC_SX_DEBIT_FORMULA,
-                                                   NULL);
-                if ( kvp_val != NULL ) {
-                        str = kvp_value_get_string( kvp_val );
-                        if ( str && strlen(str) != 0 ) {
-                                parse_vars_from_formula( str, var_hash, NULL );
-                        }
-                }
-        }
-
-        return 0;
-}
-
-void
-sxsl_get_sx_vars( SchedXaction *sx, GHashTable *var_hash )
-{
-        AccountGroup *ag;
-        Account *acct;
-        const char *id;
-
-        ag = gnc_book_get_template_group( gnc_get_current_book () );
-        id = guid_to_string( xaccSchedXactionGetGUID(sx) );
-        /* Get account named after guid string. */
-        acct = xaccGetAccountFromName( ag, id );
-        xaccAccountForEachTransaction(acct,
-                                      _get_vars_helper,
-                                      var_hash);
-
-        g_hash_table_foreach( var_hash,
-                              clear_variable_numerics,
-                              (gpointer)var_hash );
-}
-
-static gboolean
-tct_table_entry_key_handle( GtkWidget *widget, GdkEventKey *event, gpointer ud )
-{
-        gnc_numeric *num;
-        GtkEntry *ent = NULL;
-        GString *str;
-
-        if ( (event->keyval != GDK_Tab)
-             && (event->keyval != GDK_ISO_Left_Tab) ) {
-                return FALSE;
-        }
-
-        /* First, deal with formulas in these cells, replacing their
-         * contents with the eval'd value. */
-        ent = GTK_ENTRY(widget);
-        num = (gnc_numeric*)g_object_get_data( G_OBJECT(ent), "numeric" );
-        str = g_string_new("");
-        g_string_printf( str, "%0.2f", gnc_numeric_to_double( *num ) );
-        gtk_entry_set_text( ent, str->str );
-        g_string_free( str, TRUE );
-
-        /* FIXME: Next, deal with tab-ordering in this page...
-         *
-         * if ( entry isn't last in table )
-         *    return (normal)FALSE
-         * if ( unfilled entry in this table exists )
-         *    change focus to unfilled entry
-         * if ( no more unfilled clist-rows )
-         *    return (normal)FALSE
-         * clist-select next unfilled row
-         *
-         * This doesn't deal with shift-tab very well ... 
-         * And there's a question of if the user will allow us to futz with
-         * their tab-ordering... though it's already pretty screwed up for the
-         * dynamically-changing-table anyways, so they probably won't mind
-         * too much... -- jsled
-         */
-
-        return FALSE;
-}
-
-static
-void
-sxsincelast_tc_row_sel( GtkCTree *ct,
-                        GList *nodelist,
-                        gint column,
-                        gpointer user_data)
-{
-        static const int NUM_COLS = 2;
-        static GtkAttachOptions sopts = GTK_SHRINK;
-        static GtkAttachOptions lxopts = GTK_EXPAND | GTK_FILL;
-        GtkTable *varTable;
-        int tableIdx;
-        GtkWidget *label, *entry;
-        GList *varList;
-        gint varHashSize;
-        GtkCTreeNode *node = GTK_CTREE_NODE( nodelist );
-
-        toCreateInstance *tci;
-        sxSinceLastData *sxsld;
-
-        /* FIXME: this should more gracefully deal with multiple 'row-select'
-         * signals from double/triple-clicks. */
-        sxsld = (sxSinceLastData*)user_data;
-
-        tci = (toCreateInstance*)gtk_ctree_node_get_row_data( ct, node );
-        if ( !tci )
-                return;
-
-        sxsld->curSelTCI = tci;
-        sxsld_set_sensitive_tci_controls( sxsld, TRUE );
-        /* set real sensitivity based on the state of the TCI; when we change
-         * the option menu selection here, it won't fire the selection-done
-         * handler, so we have to force it. */
-
-        {
-                GtkOptionMenu *optMenu;
-
-                optMenu = GTK_OPTION_MENU(
-                        glade_xml_get_widget( sxsld->gxml,
-                                              SX_DISPOSITION_OPT ) );
-                gtk_option_menu_set_history( optMenu,
-                                             sxsld->curSelTCI->state );
-                sxsld_disposition_changed( GTK_MENU_SHELL(
-                                                   gtk_option_menu_get_menu( optMenu ) ),
-                                           sxsld );
-        }
-
-        /* Setup the query for the to-create register to only show the
-         * transaction[s] associated with this lineitem. */
-        {
-                AccountGroup *ag;
-                Account *acct;
-                Query *q;
-                const gchar *sxGUIDstr;
-                SplitRegister *sr;
-
-                q = xaccMallocQuery();
-                xaccQuerySetBook( q, gnc_get_current_book() );
-                ag = gnc_book_get_template_group( gnc_get_current_book() );
-                sxGUIDstr = guid_to_string( xaccSchedXactionGetGUID( tci->parentTCT->sx ) );
-                acct = xaccGetAccountFromName( ag, sxGUIDstr );
-                g_assert( acct != NULL );
-                xaccQueryAddSingleAccountMatch( q, acct, QUERY_AND );
-          
-                gnc_suspend_gui_refresh();
-                gnc_ledger_display_set_query( sxsld->to_create_ledger, q );
-                sr = gnc_ledger_display_get_split_register( sxsld->to_create_ledger );
-                gnc_split_register_set_template_account( sr, acct );
-                gnc_ledger_display_refresh( sxsld->to_create_ledger );
-                gnc_resume_gui_refresh();
-        }
-
-        /* Get the count of variables; potentially remove the system-defined
-         * variables if they're present in the expression. */
-        varHashSize = g_hash_table_size( tci->varBindings );
-        {
-                gpointer *unusedKey, *unusedVal;
-                if ( g_hash_table_lookup_extended( tci->varBindings, "i",
-                                                   (gpointer)&unusedKey,
-                                                   (gpointer)&unusedVal ) ) {
-                        varHashSize -= 1;
-                }
-        }
-
-        if ( varHashSize == 0 ) {
-                return;
-        }
-
-        varList = NULL;
-        hash_to_sorted_list( tci->varBindings, &varList );
-        varTable = GTK_TABLE( glade_xml_get_widget( sxsld->gxml,
-                                                    VARIABLE_TABLE ) );
-        gtk_table_resize( varTable, varHashSize + 1, NUM_COLS );
-
-        tableIdx = 1;
-        for ( ; varList ; varList = varList->next ) {
-                gchar *varName;
-                GString *gstr;
-                const gchar *numValueStr;
-                gnc_numeric *numValue, *tmpNumValue;
-
-                varName = (gchar*)varList->data;
-                if ( strcmp( varName, "i" ) == 0 ) {
-                        continue;
-                }
-
-                gstr = g_string_sized_new(16);
-                g_string_printf( gstr, "%s: ", varName );
-                label = gtk_label_new( gstr->str );
-                gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_RIGHT );
-                g_string_free( gstr, TRUE );
-
-                entry = gtk_entry_new();
-                g_object_set_data( G_OBJECT(entry), "varName", varName );
-                g_object_set_data( G_OBJECT(entry), "tci", tci );
-                tmpNumValue = g_new0( gnc_numeric, 1 );
-                *tmpNumValue = gnc_numeric_create( 0, 1 );
-                g_object_set_data( G_OBJECT(entry), "numeric", tmpNumValue );
-                if ( tableIdx == varHashSize ) {
-                        /* Set a flag so we can know if we're the last row of
-                         * the table. */
-                        g_object_set_data( G_OBJECT(entry), "lastVisualElt",
-					   (gpointer)1 );
-                }
-
-                gtk_widget_set_size_request( entry, 64, -1 );
-                numValue = (gnc_numeric*)g_hash_table_lookup( tci->varBindings,
-                                                              varName );
-                if ( numValue != NULL ) {
-                        numValueStr =
-                                xaccPrintAmount( *numValue,
-                                                 gnc_default_print_info( FALSE ) );
-                        gtk_entry_set_text( GTK_ENTRY(entry), numValueStr );
-                }
-
-                /* fixme::2002.02.10 jsled testing */
-                g_signal_connect( entry, "key-press-event",
-				  G_CALLBACK( tct_table_entry_key_handle ),
-				  NULL );
-                g_signal_connect( entry, "changed",
-				  G_CALLBACK( sxsincelast_entry_changed ),
-				  sxsld );
-                g_signal_connect( entry, "destroy",
-				  G_CALLBACK(gnc_sxsld_free_entry_numeric),
-				  sxsld );
-
-                gtk_table_attach( varTable, label,
-                                  0, 1, tableIdx, tableIdx + 1,
-                                  lxopts, sopts, 0, 0 );
-                gtk_table_attach( varTable, entry,
-                                  1, 2, tableIdx, tableIdx + 1,
-                                  sopts, sopts, 0, 0 );
-                tableIdx += 1;
-        }
-
-        gtk_widget_show_all( GTK_WIDGET(varTable) );
-}
-
-static void
-clean_variable_table( sxSinceLastData *sxsld )
-{
-        GtkTable *table;
-        GList *children, *toFree, *l;
-        GtkTableChild *child;
-        
-        table = GTK_TABLE( glade_xml_get_widget( sxsld->gxml,
-                                                 VARIABLE_TABLE ) );
-        children = table->children;
-        g_assert( children );
-
-        toFree = NULL;
-        for( ; children ; children = children->next ) {
-                /* Destroy all children after the first [label-continaing]
-                   row... ie, leave the labels in place. */
-                child = (GtkTableChild*)children->data;
-                if ( child->top_attach > 0 ) {
-                        toFree = g_list_append( toFree, child->widget );
-                }
-        }
-
-        gtk_table_resize( table, 1, 2 );
-
-        for ( l = toFree; l; l = l->next ) {
-                gtk_widget_destroy( (GtkWidget*)l->data );
-        }
-        g_list_free( toFree );
-}
-
-static void
-sxsincelast_tc_row_unsel( GtkCTree *ct,
-                          GList *nodelist,
-                          gint column,
-                          gpointer user_data)
-{
-        sxSinceLastData *sxsld;
-
-        sxsld = (sxSinceLastData*)user_data;
-        clean_variable_table( sxsld );
-
-        sxsld->curSelTCI = NULL;
-
-        sxsld_set_sensitive_tci_controls( sxsld, FALSE );
-
-        {
-                Query *q;
-                q = xaccMallocQuery();
-                xaccQueryClear( q );
-                gnc_suspend_gui_refresh();
-                gnc_ledger_display_set_query( sxsld->to_create_ledger, q );
-                gnc_ledger_display_refresh( sxsld->to_create_ledger );
-                gnc_resume_gui_refresh();
-        }
-
-
-        /* we cleanup the gnc_numerics we allocated in the "destroy" signal
-         * handler of the entry [where we attached them] */
-}
-
-void
-print_vars_helper( gpointer key, gpointer value, gpointer user_data )
-{
-        DEBUG( "\"%s\" -> %.8x [%s]",
-               (gchar*)key, GPOINTER_TO_UINT(value),
-               gnc_numeric_to_string( *(gnc_numeric*)value ) );
-}
-
-int
-parse_vars_from_formula( const char *formula,
-                         GHashTable *varHash,
-                         gnc_numeric *result )
-{
-        gnc_numeric *num;
-        char *errLoc;
-        int toRet;
-
-        if ( result ) {
-                num = result;
-        } else {
-                num = g_new0( gnc_numeric, 1 );
-        }
-        
-        toRet = 0;
-        if ( ! gnc_exp_parser_parse_separate_vars( formula, num,
-                                                   &errLoc, varHash ) ) {
-                toRet = -1;
-        }
-
-        if ( !result ) {
-                g_free( num );
-        }
-        return toRet;
-}
-
-/**
- * The following makes me [jsled] somewhat sad, but it works... :I
- *
- * Basic problem: You can't create a SX instance if any after it have already
- * been created [e.g., if an SX has instances on d_0, d_1 and d_2, and you
- * create d_0 and d_2, then d_1 will never get created ... only d_3, d_4,
- * &c.]
- *
- * This code, then, makes sure that the user hasn't skipped a date...
- *
- * Code flow...
- * . If non-consecutive Reminders chosen, disallow.
- * . Else, for each selected reminder, add to to-create list.
- * . Dismiss dialog.
- *
- * While we're doing this, we handle any previously-selected, now-unselected
- * reminders.
- *
- * Returns TRUE if there are processed, valid reminders... FALSE otherwise.
- **/
-static gboolean
-processed_valid_reminders_listP( sxSinceLastData *sxsld )
-{
-        reminderTuple *rt;
-        reminderInstanceTuple *rit;
-        char *rtName;
-        gboolean overallOkFlag, okFlag, prevState;
-        GList *reminderList;
-        GList *reminderInstList;
-        GList *badList;
-        GList *badRecentRun;
-        GList *goodList;
-        GList *toRevertList;
-
-        rtName = NULL;
-        goodList = NULL;
-        overallOkFlag = TRUE;
-
-        okFlag = prevState = TRUE;
-        badList = badRecentRun = NULL;
-        rt = NULL;
-        toRevertList = NULL;
-
-        for ( reminderList = sxsld->reminderList;
-              reminderList;
-              reminderList = reminderList->next ) {
-
-                rt = (reminderTuple*)reminderList->data;
-                okFlag = prevState = TRUE;
-                badList = badRecentRun = NULL;
-                rtName = xaccSchedXactionGetName( rt->sx );
-
-                for ( reminderInstList = rt->instanceList;
-                      reminderInstList;
-                      reminderInstList = reminderInstList->next ) {
-                        rit = (reminderInstanceTuple*)reminderInstList->data;
-
-                        /* If we've previously created this RIT and now it's
-                         * not selected, then prepare to revert it
-                         * [later]. */
-                        if ( !rit->isSelected
-                             && rit->resultantTCI ) {
-                                toRevertList = g_list_append( toRevertList, rit );
-                        }
-
-                        if ( prevState ) {
-                                prevState = rit->isSelected;
-                                if ( !prevState ) {
-                                        badRecentRun = g_list_append( badRecentRun, rit );
-                                }
-                        } else {
-                                if ( rit->isSelected ) {
-                                        okFlag = FALSE;
-                                        if ( g_list_length( badRecentRun ) > 0 ) {
-                                                badList = g_list_concat( badList,
-                                                                         badRecentRun );
-                                                badRecentRun = NULL;
-                                        }
-                                } else {
-                                        badRecentRun =
-                                                g_list_append( badRecentRun, rit );
-                                }
-                        }
-                }
-                overallOkFlag &=
-                        inform_or_add( sxsld, rt, okFlag, badList, &goodList );
-                if ( badList ) {
-                        g_list_free( badList );
-                        badList = NULL;
-                }
-                if ( badRecentRun ) {
-                        g_list_free( badRecentRun );
-                        badRecentRun = NULL;
-                }
-        }
-
-        /* Handle implications of above logic. */
-        if ( !overallOkFlag ) {
-                g_list_free( goodList );
-                goodList = NULL;
-
-                g_list_free( toRevertList );
-                toRevertList = NULL;
-
-                return FALSE;
-        }
-
-        if ( g_list_length( goodList ) > 0 ) {
-                processSelectedReminderList( goodList, sxsld );
-                g_list_free( goodList );
-                goodList = NULL;
-        }
-
-        /* Revert the previously-created and now-unselected RITs. */
-        gnc_sxsld_revert_reminders( sxsld, toRevertList );
-        g_list_free( toRevertList );
-        toRevertList = NULL;
-
-        return TRUE;
-}
-
-
-/**
- * Remove the TCI from it's parent TCT, deleting any created transactions as
- * appropriate. Note: if after removing a TCIs from it's TCT and there are no
- * more instances in the TCT, then the TCT wouldn't have been created except
- * for us, and should be removed itself; we handle this as well.
- **/
-static
-void
-gnc_sxsld_revert_reminders( sxSinceLastData *sxsld,
-                            GList *toRevertList )
-{
-        reminderInstanceTuple *rit;
-        toCreateInstance *tci;
-        toCreateTuple *tct;
-        gboolean autoCreateState, notifyState;
-        GList *l, *m;
-
-        if ( !toRevertList ) {
-                return;
-        }
-
-        for ( l = toRevertList; l; l = l->next ) {
-                /* Navigate to the relevant objects. */
-                rit = (reminderInstanceTuple*)l->data;
-                g_assert( rit );
-                tci = rit->resultantTCI;
-                g_assert( tci );
-                tct = tci->parentTCT;
-                g_assert( tct );
-
-                tct->instanceList = g_list_remove( tct->instanceList, tci );
-
-                if ( g_list_length(tct->instanceList) == 0 ) {
-                        GList **correctList;
-                        /* if there are no instances, remove the TCT as
-                         * well. */
-                        xaccSchedXactionGetAutoCreate( rit->parentRT->sx,
-                                                       &autoCreateState,
-                                                       &notifyState );
-                        correctList = NULL;
-                        if ( autoCreateState ) {
-                                if ( notifyState ) {
-                                        correctList = &sxsld->autoCreateList;
-                                }
-                        } else {
-                                correctList = &sxsld->toCreateList;
-                        }
-
-                        if ( correctList ) 
-                                *correctList = g_list_remove( *correctList, tct );
-                }
-
-                /* destroy any created transactions. */
-                gnc_suspend_gui_refresh();
-                for ( m = tci->createdTxnGUIDs; m; m = m->next ) {
-                        Transaction *t;
-
-                        sxsld->createdTxnGUIDList =
-                                g_list_remove( sxsld->createdTxnGUIDList,
-                                               (GUID*)m->data );
-                        t = xaccTransLookup( (GUID*)m->data,
-                                             gnc_get_current_book() );
-                        g_assert( t );
-                        xaccTransBeginEdit(t);
-                        xaccTransDestroy(t);
-                        xaccTransCommitEdit(t);
-
-                }
-                gnc_resume_gui_refresh();
-
-                /* Free the now-dead TCI; this is buggy and causing
-                 * problems... */
-                gnc_sxsld_free_tci( tci );
-                rit->resultantTCI = NULL;
-        }
-}
-
-
-static void
-sxsld_remind_row_toggle( GtkCTree *ct, GList *node,
-                         gint column, gpointer user_data )
-{
-        GtkCTreeNode *ctn;
-        reminderInstanceTuple *rit;
-        sxSinceLastData *sxsld = (sxSinceLastData*)user_data;
-        GnomeDruidPage *thisPage, *nextPage;
-
-        ctn = GTK_CTREE_NODE( node );
-        rit = (reminderInstanceTuple*)gtk_ctree_node_get_row_data( ct, ctn );
-        if ( rit == NULL ) {
-                PERR( "We got called to toggle a row that "
-                      "we can't find data for..." );
-                return;
-        }
-        rit->isSelected = !rit->isSelected;
-
-        /* Deal with setting up a correct next/finish button for this
-         * page. */
-        sxsld->remindSelCount += ( rit->isSelected ? 1 : -1 );
-        thisPage = GNOME_DRUID_PAGE(glade_xml_get_widget( sxsld->gxml, REMINDERS_PG ));
-        nextPage = gnc_sxsld_get_appropriate_page( sxsld, thisPage, FORWARD );
-        if ( sxsld->remindSelCount == 0
-             || sxsld->remindSelCount == 1 ) {
-                /* If we don't have anywhere to go [read: there's only
-                 * reminders as of yet], and we've selected no reminders. */
-
-                /* FIXME: damnit, this won't work correctly as we really want
-                 * to incorporate the effect of changing the reminder
-                 * selections into this, too. */
-
-                gnome_druid_set_show_finish( sxsld->sincelast_druid,
-                                             ( !nextPage
-                                               && (sxsld->remindSelCount == 0) ) );
-
-        } /* else { This else intentionally left blank; if it's >1, then we
-           * handled the 'next/finish' button on the 0 -> 1 transition. } */
-}
-
-static
-void
-sxsld_obsolete_row_toggle( GtkCList *cl, gint row, gint col,
-                           GdkEventButton *event, gpointer ud )
-{
-        toDeleteTuple *tdt;
-
-        tdt = (toDeleteTuple*)gtk_clist_get_row_data( cl, row );
-        tdt->isSelected = !tdt->isSelected;
-}
-
-/**
- * @return the count of created transactions which would be true after
- * processing the currently-selected state of to-create transactions.  Note
- * that this includes auto-created transactions, which aren't shown in the
- * post-to-create review page.
- **/
-static
-gint
-sxsld_get_future_created_txn_count( sxSinceLastData *sxsld )
-{
-        GList *tctList, *tciList;
-        /* Get a reasonable initial count to modify below. */
-        gint toRet = g_list_length( sxsld->createdTxnGUIDList );
-
-        for ( tctList = sxsld->toCreateList;
-              tctList; tctList = tctList->next ) {
-
-                toCreateTuple *tct = (toCreateTuple*)tctList->data;
-
-                for ( tciList = tct->instanceList;
-                      tciList;
-                      tciList = tciList->next ) {
-
-                        GList *txnSet, *splitList;
-                        toCreateInstance *tci = (toCreateInstance*)tciList->data;
-
-                        if ( tci->state == tci->prevState ) {
-                                continue;
-                        }
-                        
-                        switch ( tci->state ) {
-                        case SX_TO_CREATE:
-                                /* We were postpone or ignore, before ... so
-                                 * add the new txns in. */
-
-                                /* Calculate the size of the transaction-list to be created. */
-                                txnSet = NULL;
-                                splitList = xaccSchedXactionGetSplits( tci->parentTCT->sx );
-                                for ( ; splitList; splitList = splitList->next ) {
-                                        Split *s = (Split*)splitList->data;
-                                        if ( g_list_find( txnSet, xaccSplitGetParent(s) ) == NULL ) {
-                                                txnSet = g_list_append( txnSet, (gpointer)s );
-                                        }
-                                }
-                                toRet += g_list_length( txnSet );
-                                g_list_free( txnSet );
-                                txnSet = NULL;
-                                break;
-                        case SX_IGNORE:
-                        case SX_POSTPONE:
-                                /* We were {postpone,ignore} or to-create,
-                                 * before, so either continue to ignore or
-                                 * subtract out the txns. */
-                                if ( tci->prevState != SX_TO_CREATE ) {
-                                        continue;
-                                }
-                                toRet -= g_list_length( tci->createdTxnGUIDs );
-                                break;
-                        case SX_UNDEF:
-                        case SX_MAX_STATE:
-                                g_assert( "We shouldn't see any of these." );
-                                break;
-                        }
-                }
-        }
-        g_assert( toRet >= 0 );
-        return toRet;
-}
-
-static
-void
-sxsld_disposition_changed( GtkMenuShell *b, gpointer d )
-{
-        sxSinceLastData *sxsld = (sxSinceLastData*)d;
-        ToCreateState newState;
-        gboolean newSensitivity;
-        GtkCTree *ct;
-        char *newCtreeText;
-
-        newState =
-                gnc_option_menu_get_active( 
-                        glade_xml_get_widget( sxsld->gxml,
-                                              SX_DISPOSITION_OPT ));
-        /* Change the state of the TCI */
-        //g_assert( sxsld->curSelTCI != NULL );
-        g_return_if_fail(sxsld->curSelTCI != NULL);
-
-        sxsld->curSelTCI->state = newState;
-
-        newSensitivity = TRUE;
-        newCtreeText = "FIXME";
-
-        switch ( newState ) {
-        case SX_TO_CREATE:
-                newSensitivity = TRUE;
-                {
-                        gboolean allVarsBound = TRUE;
-                        /* If there are no un-bound variables, then set the 'ready-to-go'
-                           flag to 'y'. */
-                        g_hash_table_foreach( sxsld->curSelTCI->varBindings,
-                                              andequal_numerics_set,
-                                              &allVarsBound );
-                        newCtreeText = ( allVarsBound
-                                         ? _( READY_TEXT )
-                                         : _( NEEDS_BINDINGS_TEXT ) );
-                }
-                break;
-        case SX_IGNORE:
-                newSensitivity = FALSE;
-                newCtreeText = _( IGNORE_TEXT );
-                break;
-        case SX_POSTPONE:
-                newSensitivity = FALSE;
-                newCtreeText = _( POSTPONE_TEXT );
-                break;
-        default:
-                g_assert( FALSE );
-                break;
-        }
-
-        gtk_widget_set_sensitive( glade_xml_get_widget( sxsld->gxml,
-                                                        VARIABLE_TABLE ),
-                                  newSensitivity );
-        ct = GTK_CTREE(glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST ));
-        gtk_ctree_node_set_text( ct, sxsld->curSelTCI->node, 1, newCtreeText );
-
-        /* set the 'next/finish' button appropraitely based on the new
-         * selection. */
-        gnome_druid_set_show_finish( sxsld->sincelast_druid,
-                                     ( ( sxsld_get_future_created_txn_count(sxsld)
-                                         - sxsld->autoCreatedCount )== 0 ) );
-}
-
-/**
- * Makes both the variable table and disposition selection [in]sensitive, as
- * specified.
- **/
-static
-void
-sxsld_set_sensitive_tci_controls( sxSinceLastData *sxsld,
-                                  gboolean sensitive )
-{
-        GtkWidget *w;
-        w = glade_xml_get_widget( sxsld->gxml, SX_DISPOSITION_OPT );
-        gtk_widget_set_sensitive( w, sensitive );
-        w = glade_xml_get_widget( sxsld->gxml, VARIABLE_TABLE );
-        gtk_widget_set_sensitive( w, sensitive );
-}
-
-static void
-create_bad_reminders_msg( gpointer data, gpointer ud )
-{
-        GString *msg;
-        reminderInstanceTuple *rit;
-        static char tmpBuf[ MAX_DATE_LENGTH+1 ];
-
-        rit = (reminderInstanceTuple*)data;
-        msg = (GString*)ud;
-        qof_print_gdate( tmpBuf, MAX_DATE_LENGTH, rit->occurDate );
-        g_string_append_printf( msg, tmpBuf );
-        g_string_append_printf( msg, "\n" );
-}
-
-static gboolean
-inform_or_add( sxSinceLastData *sxsld, reminderTuple *rt, gboolean okFlag,
-               GList *badList, GList **goodList )
-{
-        reminderInstanceTuple *rit;
-        GList *instances;
-        GString *userMsg;
-
-        userMsg = NULL;
-
-        if ( okFlag ) {
-                /* Add selected instances of this rt to
-                 * okay-to-add-to-toCreateList list. */
-                for ( instances = rt->instanceList;
-                      instances;
-                      instances = instances->next ) {
-                        rit = (reminderInstanceTuple*)instances->data;
-                        /* this isn't really all that efficient. */
-                        if ( rit->isSelected ) {
-                                *goodList = g_list_append( *goodList, rit );
-                        }
-                }
-        } else {
-                /* [Add to list for later] dialog issuance to user. */
-
-                userMsg = g_string_sized_new( 128 );
-                g_string_printf( userMsg,
-                                 "You cannot skip instances of "
-                                 "Scheduled Transactions. "
-                                 "The following instances of \"%s\" "
-                                 "must be selected as well:\n\n",
-                                 xaccSchedXactionGetName( rt->sx ) );
-                g_list_foreach( badList, create_bad_reminders_msg, userMsg );
-                gnc_error_dialog( sxsld->sincelast_window, userMsg->str );
-                g_string_free( userMsg, TRUE );
-        }
-
-        return okFlag;
-}
-
-static void
-sx_obsolete_select_all_clicked(GtkButton *button, gpointer user_data)
-{
-        sxSinceLastData* sxsld = user_data;
-  
-        GtkCList *ob_clist = GTK_CLIST(glade_xml_get_widget(sxsld->gxml, 
-                                                            SX_OBSOLETE_CLIST));
-        gtk_clist_select_all( ob_clist );
-}
-
-static void
-sx_obsolete_unselect_all_clicked(GtkButton *button, gpointer user_data)
-{
-        sxSinceLastData* sxsld = user_data;
-  
-        GtkCList *ob_clist = GTK_CLIST(glade_xml_get_widget(sxsld->gxml, 
-                                                            SX_OBSOLETE_CLIST));
-        gtk_clist_unselect_all( ob_clist );
-}
-
-static void
-create_autoCreate_ledger( sxSinceLastData *sxsld )
-{
-        SplitRegister *splitreg;
-        GtkWidget *vbox;
-        Query *q;
-
-        q = xaccMallocQuery();
-        xaccQuerySetBook (q, gnc_get_current_book ());
-        sxsld->ac_ledger = gnc_ledger_display_query( q,
-                                                     GENERAL_LEDGER,
-                                                     REG_STYLE_LEDGER );
-
-	/* First the embedded window */
-        vbox = glade_xml_get_widget( sxsld->gxml, AUTO_CREATE_VBOX );
-	sxsld->ac_window =
-	  gnc_embedded_window_new("SXWindowActions",
-				     gnc_sxsld_menu_entries,
-				     gnc_sxsld_menu_n_entries,
-				     "gnc-sxed-window-ui.xml",
-				     sxsld->sincelast_window,
-				     FALSE, /* no accelerators */
-				     sxsld);
-	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(sxsld->ac_window),
-			    TRUE, TRUE, 0);
-
-	/* Then the register in it */
-	sxsld->ac_register = gnc_plugin_page_register_new_ledger(sxsld->ac_ledger);
-	gnc_plugin_page_set_ui_description (sxsld->ac_register,
-					    "gnc-plugin-page-sxregister-ui.xml");
-	gnc_plugin_page_register_set_options (sxsld->ac_register,
-					      NULL, NULL, 4, FALSE);
-	gnc_embedded_window_open_page (sxsld->ac_window, sxsld->ac_register);
-
-	/* Now configure the register */
-        splitreg = gnc_ledger_display_get_split_register( sxsld->ac_ledger );
-        gnc_split_register_config(splitreg,
-                                  splitreg->type, splitreg->style,
-                                  FALSE);
-        gnc_split_register_show_present_divider( splitreg, FALSE );
-}
-
-static void
-create_created_ledger( sxSinceLastData *sxsld )
-{
-        SplitRegister *splitreg;
-        GtkWidget *vbox;
-        Query *q;
-
-        q = xaccMallocQuery();
-        xaccQuerySetBook (q, gnc_get_current_book ());
-        sxsld->created_ledger = gnc_ledger_display_query( q,
-                                                          GENERAL_LEDGER,
-                                                          REG_STYLE_LEDGER );
-
-	/* First the embedded window */
-        vbox = glade_xml_get_widget( sxsld->gxml, CREATED_VBOX );
-	sxsld->created_window =
-	  gnc_embedded_window_new("SXWindowActions",
-				  gnc_sxsld_menu_entries,
-				  gnc_sxsld_menu_n_entries,
-				  "gnc-sxed-window-ui.xml",
-				  sxsld->sincelast_window,
-				  FALSE, /* no accelerators */
-				  sxsld);
-	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(sxsld->created_window),
-			    TRUE, TRUE, 0);
-
-	/* Then the register in it */
-	sxsld->created_register = gnc_plugin_page_register_new_ledger(sxsld->created_ledger);
-	gnc_plugin_page_set_ui_description (sxsld->created_register,
-					    "gnc-plugin-page-sxregister-ui.xml");
-	gnc_plugin_page_register_set_options (sxsld->created_register,
-					      NULL, NULL, 4, FALSE);
-	gnc_embedded_window_open_page (sxsld->created_window, sxsld->created_register);
-
-	/* Now configure the register */
-        splitreg = gnc_ledger_display_get_split_register( sxsld->created_ledger );
-        gnc_split_register_config(splitreg,
-                                  splitreg->type, splitreg->style,
-                                  FALSE);
-        gnc_split_register_show_present_divider( splitreg, FALSE );
-}
-
-#if 0
-static
-void
-sxsld_jump_to_real_txn( GtkAction *action, sxSinceLastData *sxsld )
-{
-        SplitRegister *reg;
-	GNCSplitReg *gsr;
-        Account *account;
-        Account *leader;
-        Split *split;
-
-        reg = gnc_ledger_display_get_split_register(sxsld->to_create_ledger);
-	gsr = gnc_ledger_display_get_user_data(sxsld->to_create_ledger);
-
-        split = gnc_split_register_get_current_split (reg);
-        if (split == NULL)
-                return;
-
-        {
-                GUID *acct_guid;
-                kvp_frame *split_kvpf;
-                kvp_value *kvp_val;
-                
-                split_kvpf = xaccSplitGetSlots( split );
-                kvp_val = kvp_frame_get_slot_path( split_kvpf,
-                                                   GNC_SX_ID,
-                                                   GNC_SX_ACCOUNT,
-                                                   NULL );
-                if ( kvp_val == NULL ) {
-                        PERR( "Null kvp_val for account" );
-                }
-                acct_guid = kvp_value_get_guid( kvp_val );
-                account = xaccAccountLookup( acct_guid,
-                                             gnc_get_current_book ());
-        }
-        
-        if (account == NULL)
-                return;
-
-        leader = gnc_ledger_display_leader( gsr->ledger );
-
-        if (account == leader)
-        {
-                split = xaccSplitGetOtherSplit(split);
-                if (split == NULL)
-                        return;
-
-                account = xaccSplitGetAccount(split);
-                if (account == NULL)
-                        return;
-                if (account == leader)
-                        return;
-        }
-
-        {
-		GncPluginPage *new_page;
-                GNCSplitReg *gsr;
-
-		new_page = gnc_plugin_page_register_new (account, FALSE);
-		gnc_main_window_open_page (NULL, new_page);
-		gsr = gnc_plugin_page_register_get_gsr (new_page);
-		gnc_split_reg_jump_to_split(gsr, split);
-        }
-        
-        g_signal_stop_emission_by_name(gsr, "jump");
-}
-#endif
-
-static void
-create_to_create_ledger( sxSinceLastData *sxsld )
-{
-        SplitRegister *splitreg;
-        GtkWidget *vbox;
-        Query *q;
-
-        sxsld->to_create_ledger = gnc_ledger_display_template_gl( NULL );
-        q = xaccMallocQuery();
-        xaccQueryClear( q );
-        gnc_ledger_display_set_query( sxsld->to_create_ledger, q );
-
- 	/* First the embedded window */
-	vbox = glade_xml_get_widget( sxsld->gxml, TO_CREATE_TXN_VBOX );
-	sxsld->to_create_window =
-	  gnc_embedded_window_new("SXWindowActions",
-				  gnc_sxsld_menu_entries,
-				  gnc_sxsld_menu_n_entries,
-				  "gnc-sxed-to-create-window-ui.xml",
-				  sxsld->sincelast_window,
-				  FALSE, /* no accelerators */
-				  sxsld);
-	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(sxsld->to_create_window),
-			    TRUE, TRUE, 0);
-
-	/* Then the register in it */
-	sxsld->to_create_register = gnc_plugin_page_register_new_ledger(sxsld->to_create_ledger);
-	gnc_plugin_page_set_ui_description (sxsld->to_create_register,
-					    "gnc-sxed-to-create-window-ui.xml");
-	gnc_plugin_page_register_set_options(sxsld->to_create_register,
-                                             NULL, NULL, 4, TRUE);
-	gnc_embedded_window_open_page (sxsld->to_create_window, sxsld->to_create_register);
-
-	/* Now configure the register */
-        splitreg = gnc_ledger_display_get_split_register( sxsld->to_create_ledger );
-        gnc_split_register_config( splitreg, splitreg->type, splitreg->style,
-                                   FALSE );
-        gnc_split_register_show_present_divider( splitreg, FALSE );
-}
-
-static void
-clean_sincelast_data( sxSinceLastData *sxsld )
-{
-        GList *l, *m;
-
-        /* FIXME: handle the cloned state data for all the instance
-         * structures. */
-
-        /* Free the reminder list */
-        for ( l = sxsld->reminderList; l; l = l->next ) {
-                reminderTuple *rt;
-                reminderInstanceTuple *rit;
-
-                rt = (reminderTuple*)l->data;
-                for ( m = rt->instanceList; m; m = m->next ) {
-                        rit = (reminderInstanceTuple*)m->data;
-                        g_date_free( rit->endDate );
-                        g_date_free( rit->occurDate );
-                        g_free( rit );
-                }
-                g_list_free( rt->instanceList );
-                rt->instanceList = NULL;
-                g_free( rt );
-        }
-        g_list_free( sxsld->reminderList );
-
-        /* Free the auto-create and to-create lists */
-        gnc_sxsld_free_toCreateTuple_list( sxsld->autoCreateList );
-        g_list_free( sxsld->autoCreateList );
-        sxsld->autoCreateList = NULL;
-
-        gnc_sxsld_free_toCreateTuple_list( sxsld->toCreateList );
-        g_list_free( sxsld->toCreateList );
-        sxsld->toCreateList = NULL;
-
-        /* Free the to-remove list */
-        for ( l = sxsld->toRemoveList; l; l = l->next ) {
-                toDeleteTuple *tdt;
-
-                tdt = (toDeleteTuple*)l->data;
-                g_date_free( tdt->endDate );
-                tdt->endDate = NULL;
-
-                g_free( tdt );
-        }
-        g_list_free( sxsld->toRemoveList );
-        sxsld->toRemoveList = NULL;
-
-        /* free the created-txn-guid list */
-        g_list_free( sxsld->createdTxnGUIDList );
-        sxsld->createdTxnGUIDList = NULL;
-
-        /* Free the saved SX temporal states */
-        g_hash_table_foreach( sxsld->sxInitStates,
-                              gnc_sxsld_free_sxState,
-                              NULL );
-        g_hash_table_destroy( sxsld->sxInitStates );
-        sxsld->sxInitStates = NULL;
-
-}
-
-static
-void
-gnc_sxsld_free_tci( toCreateInstance *tci )
-{
-        if ( tci->date ) {
-                g_date_free(tci->date);
-                tci->date = NULL;
-        }
-
-        if ( tci->varBindings ) {
-                g_hash_table_foreach( tci->varBindings,
-                                      _free_varBindings_hash_elts,
-                                      NULL );
-                g_hash_table_destroy( tci->varBindings );
-                tci->varBindings = NULL;
-        }
-
-        /* Handling these original/previous/current-stated things is painful,
-         * but here's the rules...
-         *
-         * If we're not cancelling...
-         * . If ignored, destroy.
-         * . If postponed, DON'T destroy.
-         * . If to-create, destroy.
-         *
-         * If we are cancelling...
-         * . If ignored, destroy.
-         * . If postponed, destroy.
-         *   . UNLESS previously postponed
-         * . If to-create, destroy.
-         *
-         * So, we don't destroy postponed by default, and let the
-         * cancel-specific case handle that destruction [thus the
-         * valid-pointer check].
-         */
-        if ( tci->prevState      != SX_POSTPONE
-             && tci->origState   != SX_POSTPONE
-             && tci->sxStateData != NULL ) {
-                gnc_sx_destroy_temporal_state( tci->sxStateData );
-                tci->sxStateData = NULL;
-        }
-
-        tci->parentTCT = NULL;
-
-        if ( tci->createdTxnGUIDs ) {
-                g_list_free( tci->createdTxnGUIDs );
-                tci->createdTxnGUIDs = NULL;
-        }
-
-        g_free( tci );
-}
-
-/**
- * Frees a list of toCreateTuples, like the autoCreateList and
- * toCreateList.
- **/
-static
-void
-gnc_sxsld_free_toCreateTuple_list( GList *l )
-{
-        GList *m;
-        toCreateTuple *tct;
-
-        for ( ; l; l = l->next ) {
-                tct = (toCreateTuple*)l->data;
-                for ( m = tct->instanceList; m; m = m->next ) {
-                        gnc_sxsld_free_tci( (toCreateInstance*)m->data );
-                }
-                g_list_free( tct->instanceList );
-                tct->instanceList = NULL;
-                g_free( tct );
-        }
-}
-
-static
-void
-gnc_sxsld_free_sxState( gpointer key,
-                        gpointer value,
-                        gpointer userdata )
-{
-        gnc_sx_destroy_temporal_state( (void*)value );
-}
-
-static
-void
-gnc_sxsld_free_entry_numeric( GObject *o, gpointer ud )
-{
-        gnc_numeric *num;
-        num = (gnc_numeric*)g_object_get_data( o, "numeric" );
-        g_free( num );
-}
-
-static
-void
-gnc_sxsld_commit_ledgers( sxSinceLastData *sxsld )
-{
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->created_ledger),
-                TRUE );
-        gnc_split_register_save(
-                gnc_ledger_display_get_split_register(sxsld->ac_ledger),
-                TRUE );
-}
-
-static
-void
-_adderror(gpointer data, gpointer user_data)
-{
-        GString *dialog_text = (GString*)user_data;
-        g_string_append_printf(dialog_text, "- %s\n", ((GString*)data)->str);
-}
-
-static
-void
-creation_errors_dialog(GList *creation_errors)
-{
-        GString *dialog_text = g_string_new(_("The following errors were encountered while creating the Scheduled Transactions:\n"));
-        g_list_foreach(creation_errors, (GFunc)_adderror, dialog_text);
-        gnc_info_dialog(NULL, "%s", dialog_text->str);
-        g_string_free(dialog_text, TRUE);
-}
-
-static void
-_free_creation_errors(gpointer data, gpointer user_data_unused)
-{
-        g_string_free((GString*)data, TRUE);
-}
-
-static
-void
-creation_errors_free(GList *creation_errors)
-{
-        g_list_foreach(creation_errors, (GFunc)_free_creation_errors, NULL);
-        g_list_free(creation_errors);
-}

Deleted: gnucash/trunk/src/gnome/dialog-sxsincelast.h
===================================================================
--- gnucash/trunk/src/gnome/dialog-sxsincelast.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/dialog-sxsincelast.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,60 +0,0 @@
-/********************************************************************\
- * dialog-sxsincelast.h - SchedXaction "Since-Last-Run" dialog      *
- * Copyright (c) 2001 Joshua Sled <jsled at asynchronous.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, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-#ifndef DIALOG_SXSINCELAST_H
-#define DIALOG_SXSINCELAST_H
-
-/**
- * @return The magnitude of the return value is the number of auto-created,
- * no-notification scheduled transactions created.  This value is positive if
- * there are additionally other SXes which need user interaction and the
- * Druid has been displayed, or negative if there are not, and no Druid
- * window was realized.  In the case where there the dialog has been
- * displayed but no auto-create-no-notify transactions have been created,
- * INT_MAX [limits.h] is returned.  0 is treated as negative, with no
- * transactions created and no dialog displayed.  The caller can use this
- * value as appropriate to inform the user.
- *
- * [e.g., for book-open-hook: do nothing; for menu-selection: display an info
- *  dialog stating there's nothing to do.]
- **/
-gint gnc_ui_sxsincelast_dialog_create( void );
-void gnc_sx_sxsincelast_book_opened (void);
-
-/**
- * Returns the varaibles from the Splits of the given SchedXaction as the
- * keys of the given GHashTable.
- **/
-void sxsl_get_sx_vars( SchedXaction *sx, GHashTable *varHash );
-
-/**
- * Returns the variables from the given formula [free-form non-numeric
- * character strings] as the keys of the given GHashTable.
- * @param result can be NULL if you're not interested in the result
- **/
-int parse_vars_from_formula( const char *formula,
-                             GHashTable *varHash,
-                             gnc_numeric *result );
-
-void print_vars_helper( gpointer key, gpointer value, gpointer user_data );
-
-#endif // !defined(DIALOG_SXSINCELAST_H)

Modified: gnucash/trunk/src/gnome/druid-loan.c
===================================================================
--- gnucash/trunk/src/gnome/druid-loan.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/druid-loan.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -35,7 +35,6 @@
 
 #include "SchedXaction.h"
 #include "SX-book.h"
-#include "SX-book-p.h"
 #include "SX-ttinfo.h"
 #include "druid-utils.h"
 #include "gnc-book.h"
@@ -1982,7 +1981,8 @@
 ld_create_sx_from_tcSX( LoanDruidData *ldd, toCreateSX *tcSX )
 {
         SchedXaction *sx;
-        GList *ttxnList, *sxList;
+        SchedXactions *sxes;
+        GList *ttxnList;
 
         sx = xaccSchedXactionMalloc( gnc_get_current_book() );
         xaccSchedXactionSetName( sx, tcSX->name );
@@ -2003,9 +2003,8 @@
         xaccSchedXactionSetTemplateTrans( sx, ttxnList,
                                           gnc_get_current_book() );
 
-        sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
-        sxList = g_list_append( sxList, sx );
-        gnc_book_set_schedxactions( gnc_get_current_book(), sxList );
+        sxes = gnc_book_get_schedxactions(gnc_get_current_book());
+        gnc_sxes_add_sx(sxes, sx);
 
         g_list_free( ttxnList );
         ttxnList = NULL;

Modified: gnucash/trunk/src/gnome/glade/sched-xact.glade
===================================================================
--- gnucash/trunk/src/gnome/glade/sched-xact.glade	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/glade/sched-xact.glade	2007-01-19 23:45:45 UTC (rev 15399)
@@ -77,7 +77,7 @@
       </child>
 
       <child>
-	<widget class="GtkVBox" id="vbox105">
+	<widget class="GtkVBox" id="editor-vbox">
 	  <property name="visible">True</property>
 	  <property name="homogeneous">False</property>
 	  <property name="spacing">0</property>
@@ -2983,360 +2983,6 @@
   </child>
 </widget>
 
-<widget class="GtkDialog" id="Scheduled Transaction List">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Scheduled Transactions</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="default_width">640</property>
-  <property name="default_height">480</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox18">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">8</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area18">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="close_button">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-close</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">0</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="label847992">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">&lt;b&gt;Transactions&lt;/b&gt;</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">True</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkAlignment" id="alignment34">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xscale">1</property>
-	  <property name="yscale">1</property>
-	  <property name="top_padding">0</property>
-	  <property name="bottom_padding">0</property>
-	  <property name="left_padding">12</property>
-	  <property name="right_padding">0</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox123">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">12</property>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow1">
-		  <property name="visible">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <widget class="GtkCList" id="sched_xact_list">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="n_columns">3</property>
-		      <property name="column_widths">127,140,80</property>
-		      <property name="selection_mode">GTK_SELECTION_SINGLE</property>
-		      <property name="show_titles">True</property>
-		      <property name="shadow_type">GTK_SHADOW_IN</property>
-
-		      <child>
-			<widget class="GtkLabel" id="label847750">
-			  <property name="label" translatable="yes">Name</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_CENTER</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label847751">
-			  <property name="label" translatable="yes">Frequency</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_CENTER</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label847752">
-			  <property name="label" translatable="yes">Next Occurrence</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_CENTER</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkVButtonBox" id="vbuttonbox1">
-		  <property name="visible">True</property>
-		  <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
-		  <property name="spacing">10</property>
-
-		  <child>
-		    <widget class="GtkButton" id="new_button">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label">gtk-new</property>
-		      <property name="use_stock">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkButton" id="edit_button">
-		      <property name="visible">True</property>
-		      <property name="sensitive">False</property>
-		      <property name="can_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-
-		      <child>
-			<widget class="GtkAlignment" id="alignment24">
-			  <property name="visible">True</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xscale">0</property>
-			  <property name="yscale">0</property>
-			  <property name="top_padding">0</property>
-			  <property name="bottom_padding">0</property>
-			  <property name="left_padding">0</property>
-			  <property name="right_padding">0</property>
-
-			  <child>
-			    <widget class="GtkHBox" id="hbox179">
-			      <property name="visible">True</property>
-			      <property name="homogeneous">False</property>
-			      <property name="spacing">2</property>
-
-			      <child>
-				<widget class="GtkImage" id="image1">
-				  <property name="visible">True</property>
-				  <property name="stock">gtk-properties</property>
-				  <property name="icon_size">4</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				</widget>
-				<packing>
-				  <property name="padding">0</property>
-				  <property name="expand">False</property>
-				  <property name="fill">False</property>
-				</packing>
-			      </child>
-
-			      <child>
-				<widget class="GtkLabel" id="label847980">
-				  <property name="visible">True</property>
-				  <property name="label" translatable="yes">_Edit</property>
-				  <property name="use_underline">True</property>
-				  <property name="use_markup">False</property>
-				  <property name="justify">GTK_JUSTIFY_LEFT</property>
-				  <property name="wrap">False</property>
-				  <property name="selectable">False</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				</widget>
-				<packing>
-				  <property name="padding">0</property>
-				  <property name="expand">False</property>
-				  <property name="fill">False</property>
-				</packing>
-			      </child>
-			    </widget>
-			  </child>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkButton" id="delete_button">
-		      <property name="visible">True</property>
-		      <property name="sensitive">False</property>
-		      <property name="can_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label">gtk-delete</property>
-		      <property name="use_stock">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="label847993">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes"></property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="label847970">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">&lt;b&gt;Upcoming&lt;/b&gt;</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">True</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkAlignment" id="alignment35">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xscale">1</property>
-	  <property name="yscale">1</property>
-	  <property name="top_padding">0</property>
-	  <property name="bottom_padding">0</property>
-	  <property name="left_padding">12</property>
-	  <property name="right_padding">0</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="upcoming_cal_hbox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
 <widget class="GtkDialog" id="sx_from_real_trans">
   <property name="visible">True</property>
   <property name="title" translatable="yes">Make Scheduled Transaction</property>
@@ -6717,4 +6363,364 @@
   </child>
 </widget>
 
+<widget class="GtkWindow" id="sx list plugin page content">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">window1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+
+  <child>
+    <widget class="GtkVPaned" id="sx-list-vbox">
+      <property name="visible">True</property>
+      <property name="can_focus">True</property>
+      <property name="position">0</property>
+
+      <child>
+	<widget class="GtkVBox" id="vbox183">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label847992">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Transactions&lt;/b&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment34">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox123">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">12</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="scrolledwindow1">
+		      <property name="visible">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="sx_list">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="headers_visible">True</property>
+			  <property name="rules_hint">False</property>
+			  <property name="reorderable">True</property>
+			  <property name="enable_search">True</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="shrink">True</property>
+	  <property name="resize">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="upcoming mumble">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label847993">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label847970">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Upcoming&lt;/b&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment35">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="upcoming_cal_hbox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="shrink">True</property>
+	  <property name="resize">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="since-last-run-dialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Since Last Run...</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+  <property name="modal">False</property>
+  <property name="default_width">640</property>
+  <property name="default_height">480</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">True</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox25">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area25">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox182">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkVPaned" id="paned">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="position">240</property>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow21">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTreeView" id="instance_view">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="has_focus">True</property>
+		      <property name="headers_visible">True</property>
+		      <property name="rules_hint">False</property>
+		      <property name="reorderable">False</property>
+		      <property name="enable_search">True</property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="shrink">True</property>
+		  <property name="resize">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<placeholder/>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox179">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkFixed" id="fixed1">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="review_txn_toggle">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">_Review created transactions</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>

Modified: gnucash/trunk/src/gnome/gnc-plugin-basic-commands.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-basic-commands.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/gnc-plugin-basic-commands.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -41,8 +41,7 @@
 #include "dialog-chart-export.h"
 #include "dialog-fincalc.h"
 #include "dialog-find-transactions.h"
-#include "dialog-scheduledxaction.h"
-#include "dialog-sxsincelast.h"
+#include "dialog-sx-since-last-run.h"
 #include "dialog-totd.h"
 #include "druid-acct-period.h"
 #include "druid-loan.h"
@@ -55,6 +54,8 @@
 #include "gnc-window.h"
 #include "gnc-session.h"
 
+#include "gnc-plugin-page-sx-list.h"
+
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = GNC_MOD_GUI;
 
@@ -434,35 +435,50 @@
 static void
 gnc_main_window_cmd_actions_scheduled_transaction_editor (GtkAction *action, GncMainWindowActionData *data)
 {
-  gnc_ui_scheduled_xaction_dialog_create ();
+        GncPluginPage *page = gnc_plugin_page_sx_list_new();
+        gnc_main_window_open_page(NULL, page);
 }
 
 static void
 gnc_main_window_cmd_actions_since_last_run (GtkAction *action, GncMainWindowActionData *data)
 {
   GncMainWindow *window;
-  gint ret;
+  GncSxInstanceModel *sx_instances;
+  GncSxSummary summary;
   const char *nothing_to_do_msg =
     _( "There are no Scheduled Transactions to be entered at this time." );
 	
   g_return_if_fail (data != NULL);
 
   window = data->window;
-  ret = gnc_ui_sxsincelast_dialog_create ();
-  if ( ret == 0 ) {
-    gnc_info_dialog (GTK_WIDGET(&window->gtk_window), nothing_to_do_msg);
-  } else if ( ret < 0 ) {
-    gnc_info_dialog (GTK_WIDGET(&window->gtk_window), ngettext
-		     /* Translators: %d is the number of transactions. This is a
-			ngettext(3) message. */
-		     ("There are no Scheduled Transactions to be entered at this time. "
-		      "(%d transaction automatically created)",
-		      "There are no Scheduled Transactions to be entered at this time. "
-		      "(%d transactions automatically created)",
-		      -(ret)),
-		     -(ret));
-  } /* else { this else [>0 means dialog was created] intentionally left
-     * blank. } */	       
+  
+  sx_instances = gnc_sx_get_current_instances();
+  gnc_sx_instance_model_summarize(sx_instances, &summary);
+  gnc_sx_instance_model_effect_change(sx_instances, TRUE, NULL, NULL);
+  if (summary.need_dialog)
+  {
+    gnc_ui_sx_since_last_run_dialog(sx_instances);
+  }
+  else
+  {
+    if (summary.num_auto_create_no_notify_instances == 0)
+    {
+      gnc_info_dialog(GTK_WIDGET(&window->gtk_window), nothing_to_do_msg);
+    }
+    else
+    {
+      gnc_info_dialog(GTK_WIDGET(&window->gtk_window), ngettext
+                      /* Translators: %d is the number of transactions. This is a
+                         ngettext(3) message. */
+                      ("There are no Scheduled Transactions to be entered at this time. "
+                       "(%d transaction automatically created)",
+                       "There are no Scheduled Transactions to be entered at this time. "
+                       "(%d transactions automatically created)",
+                       summary.num_auto_create_no_notify_instances),
+                      summary.num_auto_create_no_notify_instances);
+    }
+  }
+  g_object_unref(G_OBJECT(sx_instances));
 }
 
 static void

Copied: gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c (from rev 15384, 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-15 01:57:07 UTC (rev 15384)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -0,0 +1,628 @@
+/* 
+ * gnc-plugin-page-sx-list.c
+ *
+ * Copyright (C) 2006 Josh Sled <jsled at asynchronous.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/* todo:
+ * - ui, actions, menus
+ * - icon
+ */
+
+/** @addtogroup ContentPlugins
+    @{ */
+/** @addtogroup GncPluginPageSxList A SX List Plugin Page
+    @{ */
+/** @brief Functions providing the SX List as a plugin page.
+    @author Josh Sled <jsled at asynchronous.org>
+*/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glade/glade-xml.h>
+#ifndef HAVE_GLIB26
+#include "gkeyfile.h"
+#endif
+#include "gnc-exp-parser.h"
+#include "gnc-engine.h"
+#include "Transaction.h"
+#include "Split.h"
+#include "gnc-commodity.h"
+#include "gnc-event.h"
+#include "gnc-dense-cal.h"
+#include "gnc-glib-utils.h"
+#include "gnc-icons.h"
+#include "gnc-plugin-page-sx-list.h"
+#include "gnc-sx-instance-model.h"
+#include "gnc-sx-instance-dense-cal-adapter.h"
+#include "gnc-sx-list-tree-model-adapter.h"
+#include "gnc-ui-util.h"
+#include "gnc-main-window.h"
+#include "dialog-utils.h"
+#include "gnc-component-manager.h"
+#include "SX-book.h"
+#include "gnc-book.h"
+#include "dialog-sx-editor.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+#define PLUGIN_PAGE_SX_LIST_CM_CLASS "plugin-page-sx-list"
+#define GCONF_SECTION "window/pages/sx_list"
+
+typedef struct GncPluginPageSxListPrivate
+{
+     gboolean disposed;
+
+     GtkWidget* widget;
+     gint gnc_component_id;
+
+     GladeXML* gxml;
+     GncSxInstanceDenseCalAdapter *dense_cal_model;
+     GncDenseCal* gdcal;
+
+     GncSxInstanceModel* instances;
+     GncSxListTreeModelAdapter* tree_model;
+     GtkTreeView* tree_view;
+} GncPluginPageSxListPrivate;
+
+#define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxListPrivate))
+
+static GObjectClass *parent_class = NULL;
+
+/************************************************************
+ *                        Prototypes                        *
+ ************************************************************/
+/* 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_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);
+static void gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
+static GncPluginPage *gnc_plugin_page_sx_list_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
+
+static void gppsl_row_activated_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data);
+
+/* Callbacks */
+static void gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page);
+static void gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page);
+static void gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page);
+
+/* Command callbacks */
+
+static GtkActionEntry gnc_plugin_page_sx_list_actions [] = {
+     { "SxListAction", NULL, N_("Scheduled"), NULL, NULL, NULL },
+     { "SxListNewAction", GNC_STOCK_NEW_ACCOUNT, N_("New"), NULL,
+       N_("Create a new scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new) },
+     { "SxListEditAction", GNC_STOCK_EDIT_ACCOUNT, N_("Edit"), NULL,
+       N_("Edit the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit) },
+     { "SxListDeleteAction", GNC_STOCK_DELETE_ACCOUNT, N_("Delete"), NULL,
+       N_("Delete the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_delete) },
+};
+/** The number of actions provided by this plugin. */
+static guint gnc_plugin_page_sx_list_n_actions = G_N_ELEMENTS (gnc_plugin_page_sx_list_actions);
+
+GType
+gnc_plugin_page_sx_list_get_type (void)
+{
+     static GType gnc_plugin_page_sx_list_type = 0;
+
+     if (gnc_plugin_page_sx_list_type == 0) {
+          static const GTypeInfo our_info = {
+               sizeof (GncPluginPageSxListClass),
+               NULL,
+               NULL,
+               (GClassInitFunc) gnc_plugin_page_sx_list_class_init,
+               NULL,
+               NULL,
+               sizeof (GncPluginPageSxList),
+               0,
+               (GInstanceInitFunc) gnc_plugin_page_sx_list_init
+          };
+		
+          gnc_plugin_page_sx_list_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
+                                                                 GNC_PLUGIN_PAGE_SX_LIST_NAME,
+                                                                 &our_info, 0);
+     }
+
+     return gnc_plugin_page_sx_list_type;
+}
+
+GncPluginPage *
+gnc_plugin_page_sx_list_new (void)
+{
+     GncPluginPageSxList *plugin_page;
+     plugin_page = g_object_new(GNC_TYPE_PLUGIN_PAGE_SX_LIST, NULL);
+     return GNC_PLUGIN_PAGE(plugin_page);
+}
+
+static void
+gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass)
+{
+     GObjectClass *object_class = G_OBJECT_CLASS(klass);
+     GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
+
+     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;
+     gnc_plugin_class->plugin_name     = GNC_PLUGIN_PAGE_SX_LIST_NAME;
+     gnc_plugin_class->create_widget   = gnc_plugin_page_sx_list_create_widget;
+     gnc_plugin_class->destroy_widget  = gnc_plugin_page_sx_list_destroy_widget;
+     gnc_plugin_class->save_page       = gnc_plugin_page_sx_list_save_page;
+     gnc_plugin_class->recreate_page   = gnc_plugin_page_sx_list_recreate_page;
+
+     g_type_class_add_private(klass, sizeof(GncPluginPageSxListPrivate));
+}
+
+static void
+gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page)
+{
+     GtkActionGroup *action_group;
+     GncPluginPageSxListPrivate *priv;
+     GncPluginPage *parent;
+
+     ENTER("page %p", plugin_page);
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
+
+     /* Init parent declared variables */
+     parent = GNC_PLUGIN_PAGE(plugin_page);
+     g_object_set(G_OBJECT(plugin_page),
+                  "page-name",      _("Scheduled Transactions"),
+                  "page-uri",       "default:",
+                  "ui-description", "gnc-plugin-page-sx-list-ui.xml",
+                  NULL);
+
+     /* change me when the system supports multiple books */
+     gnc_plugin_page_add_book(parent, gnc_get_current_book());
+
+     /* Create menu and toolbar information */
+     action_group =
+          gnc_plugin_page_create_action_group(parent,
+                                              "GncPluginPageSxListActions");
+     gtk_action_group_add_actions(action_group,
+                                  gnc_plugin_page_sx_list_actions,
+                                  gnc_plugin_page_sx_list_n_actions,
+                                  plugin_page);
+     /* gnc_plugin_init_short_names (action_group, toolbar_labels); */
+
+     LEAVE("page %p, priv %p, action group %p",
+           plugin_page, priv, action_group);
+}
+
+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;
+     
+     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));
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     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(" ");
+}
+
+/* Virtual Functions */
+static void
+gnc_plugin_page_sx_list_refresh_cb (GHashTable *changes, gpointer user_data)
+{
+     GncPluginPageSxList *page = user_data;
+     GncPluginPageSxListPrivate *priv;
+
+     g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(page));
+
+     /* We're only looking for forced updates here. */
+     if (changes)
+          return;
+
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     gtk_widget_queue_draw(priv->widget);
+}
+
+static void
+gnc_plugin_page_sx_list_close_cb (gpointer user_data)
+{
+     GncPluginPage *plugin_page;
+     GncPluginPageSxList *page;
+
+     plugin_page = GNC_PLUGIN_PAGE(user_data);
+     page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
+     gnc_main_window_close_page(plugin_page);
+}
+
+static void
+gppsl_selection_changed_cb(GtkTreeSelection *selection, gpointer user_data)
+{
+     GncPluginPage *page;
+     GtkAction *edit_action, *delete_action;
+     gboolean selection_state = TRUE;
+
+     page = GNC_PLUGIN_PAGE(user_data);
+     edit_action = gnc_plugin_page_get_action(page, "SxListEditAction");
+     delete_action = gnc_plugin_page_get_action(page, "SxListDeleteAction");
+     selection_state
+          = gtk_tree_selection_count_selected_rows(selection) == 0
+          ? FALSE
+          : TRUE;
+     gtk_action_set_sensitive(edit_action, selection_state);
+     gtk_action_set_sensitive(delete_action, selection_state);
+}
+
+static GtkWidget *
+gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
+{
+     GncPluginPageSxList *page;
+     GncPluginPageSxListPrivate *priv;
+
+     ENTER("page %p", plugin_page);
+     page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     if (priv->widget != NULL) {
+          LEAVE("widget = %p", priv->widget);
+          return priv->widget;
+     }
+
+     priv->gxml = gnc_glade_xml_new("sched-xact.glade", "sx-list-vbox");
+     priv->widget = glade_xml_get_widget(priv->gxml, "sx-list-vbox");
+
+     {
+          //gint half_way;
+          // half_way = plugin_page->notebook_page->allocation.height * 0.5;
+          // fixme; get a real value:
+          gtk_paned_set_position(GTK_PANED(priv->widget), 160);
+     }
+
+     {
+          GDate end;
+          g_date_clear(&end, 1);
+          g_date_set_time_t(&end, time(NULL));
+          g_date_add_years(&end, 1);
+          priv->instances = GNC_SX_INSTANCE_MODEL(gnc_sx_get_instances(&end));
+     }
+
+     {
+          GtkAction *edit_action, *delete_action;
+          edit_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListEditAction");
+          delete_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListDeleteAction");
+          gtk_action_set_sensitive(edit_action, FALSE);
+          gtk_action_set_sensitive(delete_action, FALSE);
+     }
+
+     {
+          GtkCellRenderer *renderer;
+          GtkTreeViewColumn *column;
+          GtkTreeSelection *selection;
+
+          priv->tree_model = gnc_sx_list_tree_model_adapter_new(priv->instances);
+          priv->tree_view = GTK_TREE_VIEW(glade_xml_get_widget(priv->gxml, "sx_list"));
+          gtk_tree_view_set_model(priv->tree_view, GTK_TREE_MODEL(priv->tree_model));
+          gtk_tree_view_set_headers_clickable(priv->tree_view, TRUE);
+
+          renderer = gtk_cell_renderer_text_new();
+          column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", SXLTMA_COL_NAME, NULL);
+          gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_NAME);
+          gtk_tree_view_append_column(priv->tree_view, column);
+
+          renderer = gtk_cell_renderer_text_new();
+          column = gtk_tree_view_column_new_with_attributes("Frequency", renderer, "text", SXLTMA_COL_FREQUENCY, NULL);
+          gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_FREQUENCY);
+          gtk_tree_view_append_column(priv->tree_view, column);
+
+          renderer = gtk_cell_renderer_text_new();
+          column = gtk_tree_view_column_new_with_attributes("Last Occur", renderer, "text", SXLTMA_COL_LAST_OCCUR, NULL);
+          gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_LAST_OCCUR);
+          gtk_tree_view_append_column(priv->tree_view, column);
+
+          renderer = gtk_cell_renderer_text_new();
+          column = gtk_tree_view_column_new_with_attributes("Next Occur", renderer, "text", SXLTMA_COL_NEXT_OCCUR, NULL);
+          gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_NEXT_OCCUR);
+          gtk_tree_view_append_column(priv->tree_view, column);
+
+          selection = gtk_tree_view_get_selection(priv->tree_view);
+          gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+          g_signal_connect(G_OBJECT(selection), "changed", (GCallback)gppsl_selection_changed_cb, (gpointer)page);
+
+          g_signal_connect(G_OBJECT(priv->tree_view), "row-activated", (GCallback)gppsl_row_activated_cb, (gpointer)page);
+     }
+
+     {
+          GtkWidget *w;
+
+          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)));
+          // gobject-2.10: g_object_ref_sink(G_OBJECT(priv->gdcal));
+	  g_object_ref(G_OBJECT(priv->gdcal));
+	  gtk_object_sink(GTK_OBJECT(priv->gdcal));
+          gnc_dense_cal_set_months_per_col(priv->gdcal, 4);
+          gnc_dense_cal_set_num_months(priv->gdcal, 12);
+
+          w = glade_xml_get_widget(priv->gxml, "upcoming_cal_hbox");
+          gtk_container_add(GTK_CONTAINER(w), GTK_WIDGET(priv->gdcal));
+          gtk_widget_show_all(w);
+     }
+
+     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)); */
+
+     return priv->widget;
+}
+
+static void
+gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
+{
+     GncPluginPageSxList *page;
+     GncPluginPageSxListPrivate *priv;
+
+     ENTER("page %p", plugin_page);
+     page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+
+     if (priv->widget) {
+          g_object_unref(G_OBJECT(priv->widget));
+          priv->widget = NULL;
+     }
+
+     if (priv->gnc_component_id) {
+          gnc_unregister_gui_component(priv->gnc_component_id);
+          priv->gnc_component_id = 0;
+     }
+
+     LEAVE("widget destroyed");
+}
+
+/**
+ * Save enough information about this page that it can be recreated next time
+ * the user starts gnucash.
+ * @param page The page to save.
+ * @param key_file A pointer to the GKeyFile data structure where the
+ * page information should be written.
+ * @param group_name The group name to use when saving data.
+ **/
+static void
+gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page,
+                                   GKeyFile *key_file,
+                                   const gchar *group_name)
+{
+     GncPluginPageSxList *page;
+     GncPluginPageSxListPrivate *priv;
+	
+     g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
+     g_return_if_fail(key_file != NULL);
+     g_return_if_fail(group_name != NULL);
+
+     ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
+           group_name);
+
+     page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+
+#if 0
+     gnc_tree_view_account_save(GNC_TREE_VIEW_ACCOUNT(priv->tree_view), 
+                                &priv->fd, key_file, group_name);
+#endif /* 0 */
+     LEAVE(" ");
+}
+
+/**
+ * Create a new sx list page based on the information saved during a previous
+ * instantiation of gnucash.
+ *  @param window The window where this page should be installed.
+ *  @param key_file A pointer to the GKeyFile data structure where the
+ *  page information should be read.
+ *  @param group_name The group name to use when restoring data.
+ **/
+static GncPluginPage *
+gnc_plugin_page_sx_list_recreate_page (GtkWidget *window,
+                                       GKeyFile *key_file,
+                                       const gchar *group_name)
+{
+     GncPluginPageSxList *page;
+     GncPluginPageSxListPrivate *priv;
+	
+     g_return_val_if_fail(key_file, NULL);
+     g_return_val_if_fail(group_name, NULL);
+     ENTER("key_file %p, group_name %s", key_file, group_name);
+
+     /* Create the new page. */
+     page = GNC_PLUGIN_PAGE_SX_LIST(gnc_plugin_page_sx_list_new());
+     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+
+     /* Install it now so we can them manipulate the created widget */
+     gnc_main_window_open_page(GNC_MAIN_WINDOW(window), GNC_PLUGIN_PAGE(page));
+
+#if 0
+     gnc_tree_view_account_restore(GNC_TREE_VIEW_ACCOUNT(priv->tree_view), 
+                                   &priv->fd, key_file, group_name);
+#endif /* 0 */
+     LEAVE(" ");
+     return GNC_PLUGIN_PAGE(page);
+}
+
+
+/* Callbacks */
+
+static SchedXaction*
+_sx_for_path(gpointer data, gpointer user_data)
+{
+     GtkTreeIter iter;
+     GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
+     gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, (GtkTreePath*)data);
+     return gnc_sx_list_tree_model_adapter_get_sx_instances(model, &iter)->sx;
+}
+
+static void
+gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page)
+{
+     FreqSpec *fs;
+     SchedXaction *new_sx;
+     gboolean new_sx_flag = TRUE;
+
+     new_sx = xaccSchedXactionMalloc(gnc_get_current_book());
+     /* Give decent initial FreqSpec for SX */
+     fs = xaccSchedXactionGetFreqSpec(new_sx);
+     {
+       GDate *now;
+       now = g_date_new();
+       g_date_set_time_t(now, time(NULL));
+       xaccFreqSpecSetMonthly(fs, now, 1);
+       xaccFreqSpecSetUIType(fs, UIFREQ_MONTHLY);
+       g_date_free(now);
+     }
+     gnc_ui_scheduled_xaction_editor_dialog_create(new_sx, new_sx_flag);
+}
+
+static void
+_edit_sx(gpointer data, gpointer user_data)
+{
+     gnc_ui_scheduled_xaction_editor_dialog_create((SchedXaction*)data, FALSE);
+}
+
+static void
+gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page)
+{
+     GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     GtkTreeSelection *selection;
+     GList *selected_paths, *to_edit;
+     GtkTreeModel *model;
+
+     selection = gtk_tree_view_get_selection(priv->tree_view);
+     selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
+     if (g_list_length(selected_paths) == 0)
+     {
+          PERR("no selection edit.");
+          return;
+     }
+
+     to_edit = gnc_g_list_map(selected_paths, (GncGMapFunc)_sx_for_path, model);
+     g_list_foreach(to_edit, (GFunc)_edit_sx, NULL);
+     g_list_free(to_edit);
+     g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
+     g_list_free(selected_paths);
+}
+
+static void
+gppsl_row_activated_cb(GtkTreeView *tree_view,
+                       GtkTreePath *path,
+                       GtkTreeViewColumn *column,
+                       gpointer user_data)
+{
+     GncPluginPageSxList *page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
+     GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     SchedXaction *sx = _sx_for_path(path, priv->tree_model);
+     gnc_ui_scheduled_xaction_editor_dialog_create(sx, FALSE);
+}
+
+
+static void
+_destroy_sx(gpointer data, gpointer user_data)
+{
+     SchedXactions *sxes;
+     SchedXaction *sx = (SchedXaction*)data;
+     GNCBook *book;
+     book = gnc_get_current_book();
+     sxes = gnc_book_get_schedxactions(book);
+     gnc_sxes_del_sx(sxes, sx);
+     xaccSchedXactionFree(sx);
+}
+
+static void
+gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page)
+{
+     GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
+     GtkTreeSelection *selection;
+     GList *selected_paths, *to_delete = NULL;
+     GtkTreeModel *model;
+
+     /* @@fixme -- add (suppressible?) confirmation dialog */
+     
+     selection = gtk_tree_view_get_selection(priv->tree_view);
+     selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
+     if (g_list_length(selected_paths) == 0)
+     {
+          PERR("no selection for delete.");
+          return;
+     }
+
+     to_delete = gnc_g_list_map(selected_paths, (GncGMapFunc)_sx_for_path, model);
+     {
+          GList *list;
+          for (list = to_delete; list != NULL; list = list->next)
+          {
+               DEBUG("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data));
+          }
+     }
+     g_list_foreach(to_delete, (GFunc)_destroy_sx, NULL);
+     g_list_free(to_delete);
+     g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
+     g_list_free(selected_paths);
+}
+
+/** @} */
+/** @} */

Copied: gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.h)

Modified: gnucash/trunk/src/gnome/gnc-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-split-reg.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/gnc-split-reg.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -5,7 +5,7 @@
  * Copyright (C) 1998 Rob Browning <rlb at cs.utexas.edu>              *
  * Copyright (C) 1999-2000 Dave Peticolas <dave at krondo.com>         *
  * Copyright (C) 2001 Gnumatic, Inc.                                *
- * Copyright (C) 2002 Joshua Sled <jsled at asynchronous.org>          *
+ * Copyright (C) 2002,2006 Joshua Sled <jsled at asynchronous.org>     *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -37,7 +37,7 @@
 #include "QueryNew.h"
 #include "SX-book.h"
 #include "dialog-account.h"
-#include "dialog-scheduledxaction.h"
+#include "dialog-sx-editor.h"
 #include "dialog-sx-from-trans.h"
 #include "gnc-component-manager.h"
 #include "gnc-date-edit.h"
@@ -1227,7 +1227,7 @@
         GList *sxElts;
         
         /* Get the correct SX */
-        for ( sxElts = gnc_book_get_schedxactions( gnc_get_current_book() );
+        for ( sxElts = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
               (!theSX) && sxElts;
               sxElts = sxElts->next ) {
           SchedXaction *sx = (SchedXaction*)sxElts->data;
@@ -1237,8 +1237,7 @@
         }
 
         if ( theSX ) {
-          SchedXactionDialog *sxd = gnc_ui_scheduled_xaction_dialog_create();
-          gnc_ui_scheduled_xaction_editor_dialog_create( sxd, theSX, FALSE );
+          gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
           return;
         }
       }

Copied: gnucash/trunk/src/gnome/gnc-sx-list-tree-model-adapter.c (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.c)

Copied: gnucash/trunk/src/gnome/gnc-sx-list-tree-model-adapter.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/gnc-sx-list-tree-model-adapter.h)

Modified: gnucash/trunk/src/gnome/top-level.c
===================================================================
--- gnucash/trunk/src/gnome/top-level.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/top-level.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -33,7 +33,7 @@
 #include "dialog-account.h"
 #include "dialog-commodity.h"
 #include "dialog-options.h"
-#include "dialog-scheduledxaction.h"
+#include "dialog-sx-editor.h"
 #include "dialog-transfer.h"
 #include "dialog-totd.h"
 #include "druid-hierarchy.h"

Modified: gnucash/trunk/src/gnome/ui/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome/ui/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome/ui/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -8,6 +8,7 @@
 	gnc-plugin-file-history-ui.xml \
 	gnc-plugin-register-ui.xml \
 	gnc-plugin-page-register-ui.xml \
+        gnc-plugin-page-sx-list-ui.xml \
 	gnc-plugin-page-sxregister-ui.xml \
 	gnc-sxed-to-create-window-ui.xml \
 	gnc-reconcile-window-ui.xml \

Copied: gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml (from rev 15384, gnucash/branches/sx-cleanup/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml)

Modified: gnucash/trunk/src/gnome-utils/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome-utils/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome-utils/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -49,6 +49,8 @@
   gnc-date-edit.c \
   gnc-date-format.c \
   gnc-dense-cal.c \
+  gnc-dense-cal-model.c \
+  gnc-dense-cal-store.c \
   gnc-druid-gnome.c \
   gnc-druid-provider-edge-gnome.c \
   gnc-druid-provider-file-gnome.c \
@@ -74,6 +76,7 @@
   gnc-period-select.c \
   gnc-query-list.c \
   gnc-splash.c \
+  gnc-sx-instance-dense-cal-adapter.c \
   gnc-tree-model.c \
   gnc-tree-model-account-types.c \
   gnc-tree-model-account.c \
@@ -117,6 +120,8 @@
   gnc-date-edit.h \
   gnc-date-format.h \
   gnc-dense-cal.h \
+  gnc-dense-cal-model.h \
+  gnc-dense-cal-store.h \
   gnc-druid-gnome-ui.h \
   gnc-embedded-window.h \
   gnc-file.h \
@@ -139,6 +144,7 @@
   gnc-period-select.h \
   gnc-query-list.h \
   gnc-splash.h \
+  gnc-sx-instance-dense-cal-adapter.h \
   gnc-tree-model.h \
   gnc-tree-model-account-types.h \
   gnc-tree-model-account.h \

Copied: gnucash/trunk/src/gnome-utils/gnc-dense-cal-model.c (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-model.c)

Copied: gnucash/trunk/src/gnome-utils/gnc-dense-cal-model.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-model.h)

Copied: gnucash/trunk/src/gnome-utils/gnc-dense-cal-store.c (from rev 15384, 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-15 01:57:07 UTC (rev 15384)
+++ gnucash/trunk/src/gnome-utils/gnc-dense-cal-store.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -0,0 +1,290 @@
+/*
+ * gnc-dense-cal-store.h
+ *
+ * Copyright (C) 2006 Joshua Sled <jsled at asynchronous.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <glib-object.h>
+#include "gnc-dense-cal.h"
+#include "gnc-dense-cal-model.h"
+#include "gnc-dense-cal-store.h"
+
+struct _GncDenseCalStore
+{
+     GObject parent;
+     
+     GDate start_date;
+     gdcs_end_type end_type;
+     GDate end_date;
+     gint n_occurrences;
+     gchar *name;
+     gchar *info;
+     int num_marks;
+     int num_real_marks; 
+     GDate **cal_marks;
+};
+
+struct _GncDenseCalStoreClass
+{
+     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);
+static gint gdcs_get_instance_count(GncDenseCalModel *model, guint tag);
+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;
+     iface->get_contained = gdcs_get_contained;
+     iface->get_name = gdcs_get_name;
+     iface->get_info = gdcs_get_info;
+     iface->get_instance_count = gdcs_get_instance_count;
+     iface->get_instance = gdcs_get_instance;
+}
+ 
+GType
+gnc_dense_cal_store_get_type(void)
+{
+     static GType type = 0;
+     if (type == 0)
+     {
+          static const GTypeInfo info = {
+               sizeof (GncDenseCalStoreClass),
+               NULL,   /* base_init */
+               NULL,   /* base_finalize */
+               (GClassInitFunc)gnc_dense_cal_store_class_init,   /* class_init */
+               NULL,   /* class_finalize */
+               NULL,   /* class_data */
+               sizeof(GncDenseCalStore),
+               0,      /* n_preallocs */
+               NULL    /* instance_init */
+          };
+          static const GInterfaceInfo iDenseCalModelInfo = {
+               (GInterfaceInitFunc)gnc_dense_cal_store_iface_init,
+               NULL, /* interface finalize */
+               NULL, /* interface data */
+          };
+          type = g_type_register_static(G_TYPE_OBJECT, "GncDenseCalStore", &info, 0);
+          g_type_add_interface_static(type,
+                                      GNC_TYPE_DENSE_CAL_MODEL,
+                                      &iDenseCalModelInfo);
+     }
+     return type;
+}
+
+GncDenseCalStore*
+gnc_dense_cal_store_new(int num_marks)
+{
+     GncDenseCalStore *model = g_object_new(GNC_TYPE_DENSE_CAL_STORE, NULL);
+     model->num_marks = num_marks;
+     model->cal_marks = g_new0(GDate*, num_marks);
+     {
+          int i = 0;
+          for (i = 0; i < model->num_marks; i++)
+          {
+               model->cal_marks[i] = g_date_new();
+          }
+     }
+     model->num_real_marks = 0;
+     g_date_clear(&model->start_date, 1);
+     g_date_set_time_t(&model->start_date, time(NULL));
+     model->end_type = NEVER_END;
+     g_date_clear(&model->end_date, 1);
+     g_date_set_time_t(&model->end_date, time(NULL));
+     model->n_occurrences = 0;
+     return model;
+}
+
+void
+gnc_dense_cal_store_clear(GncDenseCalStore *model)
+{
+     model->num_real_marks = 0;
+     g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
+}
+
+void
+gnc_dense_cal_store_update_name(GncDenseCalStore *model, gchar *name)
+{
+     if (model->name != NULL)
+     {
+          g_free(model->name);
+     }
+     model->name = g_strdup(name);
+     g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
+}
+
+void
+gnc_dense_cal_store_update_info(GncDenseCalStore *model, gchar *info)
+{
+     if (model->info != NULL)
+     {
+          g_free(model->info);
+     }
+     model->info = g_strdup(info);
+     g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
+}
+
+static void
+gdcs_generic_update(GncDenseCalStore *trans, GDate *start, FreqSpec *fs)
+{
+     int i;
+     GDate date;
+
+     date = *start;
+     /* go one day before what's in the box so we can get the correct start
+      * date. */
+     g_date_subtract_days(&date, 1);
+     xaccFreqSpecGetNextInstance(fs, &date, &date);
+
+     i = 0;
+     while ((i < trans->num_marks)
+            && g_date_valid(&date)
+            /* Do checking against end restriction. */
+            && ((trans->end_type == NEVER_END)
+                || (trans->end_type == END_ON_DATE
+                    && g_date_compare(&date, &trans->end_date) <= 0)
+                || (trans->end_type == END_AFTER_N_OCCS
+                    && i < trans->n_occurrences)))
+     {
+          *trans->cal_marks[i++] = date;
+          xaccFreqSpecGetNextInstance(fs, &date, &date);
+     }
+     trans->num_real_marks = (i-1);
+     g_signal_emit_by_name(trans, "update", GUINT_TO_POINTER(1));
+}
+
+void
+gnc_dense_cal_store_update_no_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs)
+{
+     model->end_type = NEVER_END;
+     gdcs_generic_update(model, start, fs);
+}
+
+void
+gnc_dense_cal_store_update_count_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, int num_occur)
+{
+     model->end_type = END_AFTER_N_OCCS;
+     model->n_occurrences = num_occur;
+     gdcs_generic_update(model, start, fs);
+}
+
+void
+gnc_dense_cal_store_update_date_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, GDate *end_date)
+{
+     model->end_type = END_ON_DATE;
+     model->end_date = *end_date;
+     gdcs_generic_update(model, start, fs);
+}
+
+static GList*
+gdcs_get_contained(GncDenseCalModel *model)
+{
+     GList *rtn = NULL;
+     rtn = g_list_append(rtn, GUINT_TO_POINTER(1));
+     return rtn;
+}
+
+static gchar*
+gdcs_get_name(GncDenseCalModel *model, guint tag)
+{
+     GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
+     // assert(tag == 1)
+     return mdl->name;
+}
+
+static gchar*
+gdcs_get_info(GncDenseCalModel *model, guint tag)
+{
+     GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
+     // assert(tag == 1)
+     return mdl->info;
+}
+
+static gint
+gdcs_get_instance_count(GncDenseCalModel *model, guint tag)
+{
+     GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
+     // assert(tag == 1)
+     return mdl->num_real_marks;
+}
+
+static void
+gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
+{
+     GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
+     // assert(tag == 1)
+     // assert 0 < instance_index < model->num_marks;
+     *date = *mdl->cal_marks[instance_index];
+}
+
+static void
+gnc_dense_cal_store_finalize(GObject *obj)
+{
+     int i;
+     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 (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);
+}

Copied: gnucash/trunk/src/gnome-utils/gnc-dense-cal-store.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/gnc-dense-cal-store.h)

Modified: gnucash/trunk/src/gnome-utils/gnc-dense-cal.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-dense-cal.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome-utils/gnc-dense-cal.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,6 +1,6 @@
 /********************************************************************\
  * gnc-dense-cal.c : a custom densely-dispalyed calendar widget     *
- * Copyright (C) 2002 Joshua Sled <jsled at asynchronous.org>          *
+ * Copyright (C) 2002,2006 Joshua Sled <jsled at asynchronous.org>     *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -22,28 +22,16 @@
 
 #include "config.h"
 
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
 #include "glib-compat.h"
-#include <math.h>
-
 #include "gnc-dense-cal.h"
-
-/* For PERR, only... */
+#include "gnc-dense-cal-model.h"
 #include "gnc-engine.h"
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <math.h>
 
 /**
- * Todo:
- * . marking
- *   . color-per-marker (configurable)
- *   X all-or-nothing
- * \ handle errors properly
- * X mouse-over -> "hottip"
- * X rotated month labels
- * X weeksPerCol -> monthsPerCol
- **/
-
-/**
  * Marking ...
  *
  * We want a facility to mark multiple days on the calendar.  This facility
@@ -84,16 +72,6 @@
 
 static const gchar* MARK_COLOR = "Yellow";
 
-static const gchar* MARKS_LOST_SIGNAL_NAME = "marks_lost";
-
-/* SIGNALS */
-enum gnc_dense_cal_signal_enum {
-  MARKS_LOST_SIGNAL,
-  LAST_SIGNAL
-};
-
-static guint gnc_dense_cal_signals[LAST_SIGNAL] = { 0 };
-
 static QofLogModule log_module = GNC_MOD_SX;
 
 static void gnc_dense_cal_class_init (GncDenseCalClass *class);
@@ -101,69 +79,72 @@
 static void gnc_dense_cal_finalize (GObject *object);
 static void gnc_dense_cal_dispose (GObject *object);
 static void gnc_dense_cal_realize (GtkWidget *widget);
-static void gnc_dense_cal_draw_to_buffer( GncDenseCal *dcal );
-static gint gnc_dense_cal_expose( GtkWidget      *widget,
-                                  GdkEventExpose *event );
+static void gnc_dense_cal_draw_to_buffer(GncDenseCal *dcal);
+static gint gnc_dense_cal_expose(GtkWidget      *widget,
+                                  GdkEventExpose *event);
 
-static void gdc_reconfig( GncDenseCal *dcal );
+static void gdc_reconfig(GncDenseCal *dcal);
 
-static void gdc_free_all_mark_data( GncDenseCal *dcal );
+static void gdc_free_all_mark_data(GncDenseCal *dcal);
 
-static void gnc_dense_cal_size_request( GtkWidget      *widget,
+static void gnc_dense_cal_size_request(GtkWidget      *widget,
                                         GtkRequisition *requisition);
-static void gnc_dense_cal_size_allocate( GtkWidget     *widget,
-                                         GtkAllocation *allocation );
-static gint gnc_dense_cal_motion_notify( GtkWidget      *widget,
-                                         GdkEventMotion *event );
-static gint gnc_dense_cal_button_press( GtkWidget *widget,
-                                        GdkEventButton *evt );
+static void gnc_dense_cal_size_allocate(GtkWidget     *widget,
+                                         GtkAllocation *allocation);
+static gint gnc_dense_cal_motion_notify(GtkWidget      *widget,
+                                         GdkEventMotion *event);
+static gint gnc_dense_cal_button_press(GtkWidget *widget,
+                                        GdkEventButton *evt);
 
-static inline int day_width_at( GncDenseCal *dcal, guint xScale );
-static inline int day_width( GncDenseCal *dcal );
-static inline int day_height_at( GncDenseCal *dcal, guint yScale );
-static inline int day_height( GncDenseCal *dcal );
-static inline int week_width_at( GncDenseCal *dcal, guint xScale );
-static inline int week_width( GncDenseCal *dcal );
-static inline int week_height_at( GncDenseCal *dcal, guint yScale );
-static inline int week_height( GncDenseCal *dcal );
-static inline int col_width_at( GncDenseCal *dcal, guint xScale );
-static inline int col_width( GncDenseCal *dcal );
+static inline int day_width_at(GncDenseCal *dcal, guint xScale);
+static inline int day_width(GncDenseCal *dcal);
+static inline int day_height_at(GncDenseCal *dcal, guint yScale);
+static inline int day_height(GncDenseCal *dcal);
+static inline int week_width_at(GncDenseCal *dcal, guint xScale);
+static inline int week_width(GncDenseCal *dcal);
+static inline int week_height_at(GncDenseCal *dcal, guint yScale);
+static inline int week_height(GncDenseCal *dcal);
+static inline int col_width_at(GncDenseCal *dcal, guint xScale);
+static inline int col_width(GncDenseCal *dcal);
 
-static inline int col_height( GncDenseCal *dcal );
-static inline int num_cols( GncDenseCal *dcal );
+static inline int col_height(GncDenseCal *dcal);
+static inline int num_cols(GncDenseCal *dcal);
 /**
  * Returns the total number of weeks to display in the calendar [irrespective
  * of columns/weeks-per-col].
  **/
-static inline int num_weeks( GncDenseCal *dcal );
+static inline int num_weeks(GncDenseCal *dcal);
 /**
  * Returns the number of weeks per column.  Note that this is the number of
  * weeks needed to display the longest column.
  **/
-static int num_weeks_per_col( GncDenseCal *dcal );
+static int num_weeks_per_col(GncDenseCal *dcal);
 
 /* hotspot calculation */
-static gint wheres_this( GncDenseCal *dcal, int x, int y );
+static gint wheres_this(GncDenseCal *dcal, int x, int y);
 
-static void recompute_x_y_scales( GncDenseCal *dcal );
-static void recompute_mark_storage( GncDenseCal *dcal );
-static void recompute_extents( GncDenseCal *dcal );
-static void populate_hover_window( GncDenseCal *dcal, gint doc );
+static void recompute_x_y_scales(GncDenseCal *dcal);
+static void recompute_mark_storage(GncDenseCal *dcal);
+static void recompute_extents(GncDenseCal *dcal);
+static void populate_hover_window(GncDenseCal *dcal, gint doc);
 
-static void month_coords( GncDenseCal *dcal, int monthOfCal, GList **outList );
-static void doc_coords( GncDenseCal *dcal, int dayOfCal,
-                        int *x1, int *y1, int *x2, int *y2 );
+static void month_coords(GncDenseCal *dcal, int monthOfCal, GList **outList);
+static void doc_coords(GncDenseCal *dcal, int dayOfCal,
+                        int *x1, int *y1, int *x2, int *y2);
 
+static void gdc_mark_add(GncDenseCal *dcal, guint tag, gchar *name, gchar *info, guint size, GDate **dateArray);
+static void gdc_mark_remove(GncDenseCal *dcal, guint mark_to_remove);
+
+static void gdc_add_tag_markings(GncDenseCal *cal, guint tag);
+static void gdc_add_markings(GncDenseCal *cal);
+static void gdc_remove_markings(GncDenseCal *cal);
+
 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];
@@ -177,10 +158,6 @@
 
         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)
@@ -189,8 +166,8 @@
     struct tm my_tm;
     int i;
     
-    memset( buf, 0, MONTH_NAME_BUFSIZE );
-    memset( &my_tm, 0, sizeof( struct tm ) );
+    memset(buf, 0, MONTH_NAME_BUFSIZE);
+    memset(&my_tm, 0, sizeof(struct tm));
     my_tm.tm_wday = wday;
     i = strftime (buf, MONTH_NAME_BUFSIZE-1, "%a", &my_tm);
     /* Wild hack to use only the first two letters */
@@ -198,1060 +175,1076 @@
     return buf;
 }
 
-
 GType
-gnc_dense_cal_get_type ()
+gnc_dense_cal_get_type()
 {
-        static GType dense_cal_type = 0;
+     static GType dense_cal_type = 0;
 
-        if (dense_cal_type == 0) {
-                static const GTypeInfo dense_cal_info = {
-                                sizeof (GncDenseCalClass),
-				NULL,
-				NULL,
-                                (GClassInitFunc) gnc_dense_cal_class_init,
-				NULL,
-				NULL,
-                                sizeof (GncDenseCal),
-				0,  /* n_preallocs */
-                                (GInstanceInitFunc) gnc_dense_cal_init,
-                                NULL
-		};
+     if (dense_cal_type == 0) {
+          static const GTypeInfo dense_cal_info = {
+               sizeof (GncDenseCalClass),
+               NULL,
+               NULL,
+               (GClassInitFunc) gnc_dense_cal_class_init,
+               NULL,
+               NULL,
+               sizeof (GncDenseCal),
+               0,
+               (GInstanceInitFunc) gnc_dense_cal_init,
+               NULL
+          };
 
-                dense_cal_type = g_type_register_static(GTK_TYPE_WIDGET,
-						"GncDenseCal",
-						&dense_cal_info, 0);
-        }
+          dense_cal_type = g_type_register_static(GTK_TYPE_WIDGET,
+                                                  "GncDenseCal",
+                                                  &dense_cal_info, 0);
+     }
 
-        return dense_cal_type;
+     return dense_cal_type;
 }
 
 static void
-gnc_dense_cal_class_init (GncDenseCalClass *klass)
+gnc_dense_cal_class_init(GncDenseCalClass *klass)
 {
-        GObjectClass *object_class;
-        GtkWidgetClass *widget_class;
+     GObjectClass *object_class;
+     GtkWidgetClass *widget_class;
 
-        object_class =  G_OBJECT_CLASS (klass);
-        widget_class = GTK_WIDGET_CLASS (klass);
+     object_class = G_OBJECT_CLASS (klass);
+     widget_class = GTK_WIDGET_CLASS (klass);
 
-        parent_class = g_type_class_peek_parent (klass);
+     parent_class = g_type_class_peek_parent (klass);
 
-        gnc_dense_cal_signals[MARKS_LOST_SIGNAL] =
-                g_signal_new (MARKS_LOST_SIGNAL_NAME,
-			      G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (GncDenseCalClass, marks_lost_cb),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
+     object_class->finalize = gnc_dense_cal_finalize;
+     object_class->dispose = gnc_dense_cal_dispose;
 
-        object_class->finalize = gnc_dense_cal_finalize;
-        object_class->dispose = gnc_dense_cal_dispose;
-
-        widget_class->realize = gnc_dense_cal_realize;
-        widget_class->expose_event = gnc_dense_cal_expose;
-        widget_class->size_request = gnc_dense_cal_size_request;
-        widget_class->size_allocate = gnc_dense_cal_size_allocate;
-        widget_class->motion_notify_event = gnc_dense_cal_motion_notify;
-        widget_class->button_press_event = gnc_dense_cal_button_press;
+     widget_class->realize = gnc_dense_cal_realize;
+     widget_class->expose_event = gnc_dense_cal_expose;
+     widget_class->size_request = gnc_dense_cal_size_request;
+     widget_class->size_allocate = gnc_dense_cal_size_allocate;
+     widget_class->motion_notify_event = gnc_dense_cal_motion_notify;
+     widget_class->button_press_event = gnc_dense_cal_button_press;
 }
 
 static void
-gnc_dense_cal_init (GncDenseCal *dcal)
+gnc_dense_cal_init(GncDenseCal *dcal)
 {
-        gboolean colorAllocSuccess;
+     gboolean colorAllocSuccess;
 
-        dcal->disposed = FALSE;
-        dcal->initialized = FALSE;
-        dcal->markData = NULL;
-        dcal->numMarks = 0;
-        dcal->marks = NULL;
-        dcal->lastMarkTag = 0;
+     dcal->disposed = FALSE;
+     dcal->initialized = FALSE;
+     dcal->markData = NULL;
+     dcal->numMarks = 0;
+     dcal->marks = NULL;
+     dcal->lastMarkTag = 0;
 
-        dcal->showPopup = FALSE;
+     dcal->showPopup = FALSE;
   
-        dcal->transPopup = GTK_WINDOW( gtk_window_new( GTK_WINDOW_POPUP ) );
-        {
-                GtkWidget *vbox, *hbox;
-                GtkWidget *l;
-                GtkCList *cl;
-                static gchar *CLIST_TITLES[2];
-		CLIST_TITLES[0] = _("Name");
-		CLIST_TITLES[1] = _("Frequency");
+     dcal->transPopup = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
+     {
+          GtkWidget *vbox, *hbox;
+          GtkWidget *l;
+          GtkListStore *tree_data;
+          GtkTreeView *tree_view;
 
-                vbox = gtk_vbox_new( FALSE, 5 );
-                hbox = gtk_hbox_new( FALSE, 5 );
+          vbox = gtk_vbox_new(FALSE, 5);
+          hbox = gtk_hbox_new(FALSE, 5);
 
-                l = gtk_label_new( _("Date: ") );
-                gtk_container_add( GTK_CONTAINER(hbox), l );
-                l = gtk_label_new( "YY/MM/DD" );
-                g_object_set_data( G_OBJECT(dcal->transPopup), "dateLabel", l );
-                gtk_container_add( GTK_CONTAINER(hbox), l );
-                gtk_container_add( GTK_CONTAINER(vbox), hbox );
+          l = gtk_label_new(_("Date: "));
+          gtk_container_add(GTK_CONTAINER(hbox), l);
+          l = gtk_label_new("YY/MM/DD");
+          g_object_set_data(G_OBJECT(dcal->transPopup), "dateLabel", l);
+          gtk_container_add(GTK_CONTAINER(hbox), l);
+          gtk_container_add(GTK_CONTAINER(vbox), hbox);
 
-                gtk_container_add( GTK_CONTAINER(vbox), gtk_hseparator_new() );
+          gtk_container_add(GTK_CONTAINER(vbox), gtk_hseparator_new());
 
-                cl = GTK_CLIST(gtk_clist_new_with_titles(2, (gchar**)CLIST_TITLES));
-                gtk_clist_set_column_auto_resize( cl, 0, TRUE );
-                gtk_clist_set_column_auto_resize( cl, 1, TRUE );
-                g_object_set_data( G_OBJECT(dcal->transPopup), "clist", cl );
-                gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(cl) );
+          tree_data = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+          tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_data)));
+          gtk_tree_view_insert_column_with_attributes(tree_view, -1, _("Name"), gtk_cell_renderer_text_new(), "text", 0, NULL);
+          gtk_tree_view_insert_column_with_attributes(tree_view, -1, _("Frequency"), gtk_cell_renderer_text_new(), "text", 1, NULL);
+          g_object_set_data(G_OBJECT(dcal->transPopup), "model", tree_data);
+          gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(tree_view));
 
-                gtk_container_add( GTK_CONTAINER(dcal->transPopup), vbox );
+          gtk_container_add(GTK_CONTAINER(dcal->transPopup), vbox);
 
-                gtk_widget_realize( GTK_WIDGET(dcal->transPopup) );
-        }
+          gtk_widget_realize(GTK_WIDGET(dcal->transPopup));
+     }
 
-        gdk_color_parse( MONTH_THIS_COLOR,  &dcal->weekColors[MONTH_THIS] );
-        gdk_color_parse( MONTH_THAT_COLOR,  &dcal->weekColors[MONTH_THAT] );
-        if ( gdk_colormap_alloc_colors( gdk_colormap_get_system(),
-                                        dcal->weekColors,
-                                        MAX_COLORS, TRUE, TRUE,
-                                        &colorAllocSuccess ) > 0 ) {
-                /* FIXME : handle [more] properly */
-                PERR( "Error allocating colors\n" );
-        }
+     gdk_color_parse(MONTH_THIS_COLOR,  &dcal->weekColors[MONTH_THIS]);
+     gdk_color_parse(MONTH_THAT_COLOR,  &dcal->weekColors[MONTH_THAT]);
+     if (gdk_colormap_alloc_colors(gdk_colormap_get_system(),
+                                   dcal->weekColors,
+                                   MAX_COLORS, TRUE, TRUE,
+                                   &colorAllocSuccess) > 0)
+     {
+          /* FIXME : handle [more] properly */
+          PERR("Error allocating colors\n");
+     }
+     
+     /* Deal with the various label sizes. */
+     {
+          gint i;
+          gint maxWidth, maxHeight, maxAscent, maxLBearing;
+          gint lbearing, rbearing, width, ascent, descent;
+          GtkStyle *style;
 
-        /* Deal with the various label sizes. */
-        {
-                gint i;
-                gint maxWidth, maxHeight, maxAscent, maxLBearing;
-                gint lbearing, rbearing, width, ascent, descent;
-		GtkStyle *style;
+          /* @FIXME: GNOME 2 port (rework the complete font code) */
+          style = gtk_widget_get_style(GTK_WIDGET(dcal));
 
-		/* FIXME GNOME 2 port (rework the complete font code) */
-                style = gtk_widget_get_style(GTK_WIDGET(dcal));
+          dcal->dayLabelFont = gtk_style_get_font(style);
+          gdk_font_ref(dcal->dayLabelFont);
+          g_assert(dcal->dayLabelFont);
 
-                dcal->dayLabelFont = gtk_style_get_font(style);
-                gdk_font_ref( dcal->dayLabelFont );
-                g_assert( dcal->dayLabelFont );
+          dcal->monthLabelFont = gtk_style_get_font(style);
+          g_assert(dcal->monthLabelFont);
+          gdk_font_ref(dcal->monthLabelFont);
 
-                dcal->monthLabelFont = gtk_style_get_font(style);
-                g_assert(dcal->monthLabelFont);
-                gdk_font_ref(dcal->monthLabelFont);
+          maxWidth = maxHeight = maxAscent = maxLBearing = 0;
+          for (i=0; i<12; i++)
+          {
+               gint w, h;
+               gdk_string_extents(dcal->monthLabelFont, month_name(i),
+                                   &lbearing, &rbearing, &width,
+                                   &ascent, &descent);
+               w = rbearing - lbearing + 1;
+               h = ascent + descent;
+               maxLBearing = MAX(maxLBearing, ABS(lbearing));
+               maxWidth = MAX(maxWidth, w);
+               maxHeight = MAX(maxHeight, h);
+               maxAscent = MAX(maxAscent, ascent);
+          }
+          dcal->label_width    = maxHeight + 1;
+          dcal->label_height   = maxWidth;
+          dcal->label_lbearing = maxLBearing;
+          dcal->label_ascent   = maxAscent;
+          dcal->needInitMonthLabels = TRUE;
+     }
 
-                maxWidth = maxHeight = maxAscent = maxLBearing = 0;
-                for ( i=0; i<12; i++ ) {
-                        gint w, h;
-                        gdk_string_extents( dcal->monthLabelFont, month_name(i),
-                                            &lbearing, &rbearing, &width,
-                                            &ascent, &descent );
-                        w = rbearing - lbearing + 1;
-                        h = ascent + descent;
-                        maxLBearing = MAX( maxLBearing, ABS(lbearing) );
-                        maxWidth = MAX( maxWidth, w );
-                        maxHeight = MAX( maxHeight, h );
-                        maxAscent = MAX( maxAscent, ascent );
-                }
-                dcal->label_width    = maxHeight + 1;
-                dcal->label_height   = maxWidth;
-                dcal->label_lbearing = maxLBearing;
-                dcal->label_ascent   = maxAscent;
-                dcal->needInitMonthLabels = TRUE;
-        }
+     dcal->month = G_DATE_JANUARY;
+     dcal->year  = 1970;
 
-        dcal->month = G_DATE_JANUARY;
-        dcal->year  = 1970;
+     dcal->numMonths = 12;
+     dcal->monthsPerCol = 3;
+     dcal->leftPadding = 2;
+     dcal->topPadding = 2;
 
-        dcal->numMonths = 12;
-        dcal->monthsPerCol = 3;
-        dcal->leftPadding = 2;
-        dcal->topPadding = 2;
+     {
+          GDate *now = g_date_new();
+          g_date_set_time_t(now, time(NULL));
+          gnc_dense_cal_set_month(dcal, g_date_get_month(now));
+          gnc_dense_cal_set_year(dcal, g_date_get_year(now));
+          g_date_free(now);
+     }
 
-        {
-                GDate *tmpDate;
+     recompute_extents(dcal);
+     recompute_mark_storage(dcal);
 
-                tmpDate = g_date_new();
-                g_date_set_time_t( tmpDate, time(NULL) );
-                gnc_dense_cal_set_month( dcal, g_date_get_month(tmpDate) );
-                gnc_dense_cal_set_year( dcal, g_date_get_year(tmpDate) );
-                g_date_free( tmpDate );
-        }
-
-        recompute_extents( dcal );
-        recompute_mark_storage( dcal );
-
-        /* Now that we're "sure" of our configuration, compute initial
-         * scaling factors; will be increased when we're allocated enough
-         * space to scale up. */
-        dcal->min_x_scale = dcal->x_scale =
-                MAX( gdk_string_width( dcal->monthLabelFont, "88" ),
-                     gdk_string_width( dcal->dayLabelFont, "88" ) + 2 );
-        dcal->min_y_scale = dcal->y_scale =
-                MAX( floor( (float)gdk_string_width( dcal->monthLabelFont,
-                                                     "XXX" )
-                            / 3.0 ),
-                     gdk_string_height( dcal->dayLabelFont, "88" ) + 2 );
-        dcal->dayLabelHeight = gdk_string_height( dcal->monthLabelFont, "88" );
-        dcal->initialized = TRUE;
+     /* Now that we're "sure" of our configuration, compute initial
+      * scaling factors; will be increased when we're allocated enough
+      * space to scale up. */
+     dcal->min_x_scale = dcal->x_scale =
+          MAX(gdk_string_width(dcal->monthLabelFont, "88"),
+              gdk_string_width(dcal->dayLabelFont, "88") + 2);
+     dcal->min_y_scale = dcal->y_scale =
+          MAX(floor((float)gdk_string_width(dcal->monthLabelFont,
+                                            "XXX")
+                    / 3.0),
+              gdk_string_height(dcal->dayLabelFont, "88") + 2);
+     dcal->dayLabelHeight = gdk_string_height(dcal->monthLabelFont, "88");
+     dcal->initialized = TRUE;
 }
 
 GtkWidget*
 gnc_dense_cal_new(void)
 {
-        GncDenseCal *dcal;
-        dcal = g_object_new(GNC_TYPE_DENSE_CAL, NULL, NULL);
+     GncDenseCal *dcal;
+     dcal = g_object_new(GNC_TYPE_DENSE_CAL, NULL);
+     return GTK_WIDGET(dcal);
+}
 
-        return GTK_WIDGET (dcal);
+GtkWidget*
+gnc_dense_cal_new_with_model(GncDenseCalModel *model)
+{
+     GncDenseCal *cal = GNC_DENSE_CAL(gnc_dense_cal_new());
+     gnc_dense_cal_set_model(cal, model);
+     return GTK_WIDGET(cal);
 }
 
 static void
-recompute_first_of_month_offset( GncDenseCal *dcal )
+recompute_first_of_month_offset(GncDenseCal *dcal)
 {
-        GDate *tmpDate;
+     GDate *tmpDate;
 
-        tmpDate = g_date_new_dmy( 1, dcal->month, dcal->year );
-        dcal->firstOfMonthOffset = g_date_get_weekday( tmpDate ) % 7;
-        g_date_free( tmpDate );
+     tmpDate = g_date_new_dmy(1, dcal->month, dcal->year);
+     dcal->firstOfMonthOffset = g_date_get_weekday(tmpDate) % 7;
+     g_date_free(tmpDate);
 }
 
 void
-gnc_dense_cal_set_month( GncDenseCal *dcal, GDateMonth mon )
+gnc_dense_cal_set_month(GncDenseCal *dcal, GDateMonth mon)
 {
-        dcal->month = mon;
-        recompute_first_of_month_offset( dcal );
-        recompute_extents( dcal );
-        if ( GTK_WIDGET_REALIZED( dcal ) ) {
-                recompute_x_y_scales( dcal );
-                gnc_dense_cal_draw_to_buffer( dcal );
-                gtk_widget_queue_draw( GTK_WIDGET(dcal) );
-        }
+     dcal->month = mon;
+     recompute_first_of_month_offset(dcal);
+     recompute_extents(dcal);
+     if (GTK_WIDGET_REALIZED(dcal))
+     {
+          recompute_x_y_scales(dcal);
+          gnc_dense_cal_draw_to_buffer(dcal);
+          gtk_widget_queue_draw(GTK_WIDGET(dcal));
+     }
 }
 
 void
-gnc_dense_cal_set_year( GncDenseCal *dcal, guint year )
+gnc_dense_cal_set_year(GncDenseCal *dcal, guint year)
 {
-        dcal->year = year;
-        recompute_first_of_month_offset( dcal );
-        recompute_extents( dcal );
-        if ( GTK_WIDGET_REALIZED( dcal ) ) {
-                recompute_x_y_scales( dcal );
-                gnc_dense_cal_draw_to_buffer( dcal );
-                gtk_widget_queue_draw( GTK_WIDGET(dcal) );
-        }
+     dcal->year = year;
+     recompute_first_of_month_offset(dcal);
+     recompute_extents(dcal);
+     if (GTK_WIDGET_REALIZED(dcal))
+     {
+          recompute_x_y_scales(dcal);
+          gnc_dense_cal_draw_to_buffer(dcal);
+          gtk_widget_queue_draw(GTK_WIDGET(dcal));
+     }
 }
 
 void
-gnc_dense_cal_set_num_months( GncDenseCal *dcal, guint num_months )
+gnc_dense_cal_set_num_months(GncDenseCal *dcal, guint num_months)
 {
-        dcal->numMonths = num_months;
-        recompute_extents( dcal );
-        recompute_mark_storage( dcal );
-        if ( GTK_WIDGET_REALIZED( dcal ) ) {
-                recompute_x_y_scales( dcal );
-                gnc_dense_cal_draw_to_buffer( dcal );
-                gtk_widget_queue_draw( GTK_WIDGET(dcal) );
-        }
+     dcal->numMonths = num_months;
+     recompute_extents(dcal);
+     recompute_mark_storage(dcal);
+     if (GTK_WIDGET_REALIZED(dcal))
+     {
+          recompute_x_y_scales(dcal);
+          gnc_dense_cal_draw_to_buffer(dcal);
+          gtk_widget_queue_draw(GTK_WIDGET(dcal));
+     }
 }
 
 void
-gnc_dense_cal_set_months_per_col( GncDenseCal *dcal, guint monthsPerCol )
+gnc_dense_cal_set_months_per_col(GncDenseCal *dcal, guint monthsPerCol)
 {
-        dcal->monthsPerCol = monthsPerCol;
-        recompute_x_y_scales(dcal);
+     dcal->monthsPerCol = monthsPerCol;
+     recompute_x_y_scales(dcal);
 }
 
 guint
-gnc_dense_cal_get_num_months( GncDenseCal *dcal )
+gnc_dense_cal_get_num_months(GncDenseCal *dcal)
 {
-        return dcal->numMonths;
+     return dcal->numMonths;
 }
 
 GDateMonth
-gnc_dense_cal_get_month( GncDenseCal *dcal )
+gnc_dense_cal_get_month(GncDenseCal *dcal)
 {
-        return dcal->month;
+     return dcal->month;
 }
 
 GDateYear
-gnc_dense_cal_get_year( GncDenseCal *dcal )
+gnc_dense_cal_get_year(GncDenseCal *dcal)
 {
-        return dcal->year;
+     return dcal->year;
 }
 
 static void
 gnc_dense_cal_dispose (GObject *object)
 {
-        int i;
-        GncDenseCal *dcal;
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GNC_IS_DENSE_CAL (object));
+     int i;
+     GncDenseCal *dcal;
+     g_return_if_fail(object != NULL);
+     g_return_if_fail(GNC_IS_DENSE_CAL(object));
 
-        dcal = GNC_DENSE_CAL(object);
+     dcal = GNC_DENSE_CAL(object);
 
-	if(dcal->disposed)
-		return;
+     if (dcal->disposed)
+          return;
+     dcal->disposed = TRUE;
 
-	dcal->disposed = TRUE;
+     if (GTK_WIDGET_REALIZED(dcal->transPopup))
+     {
+          gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
+          gtk_widget_destroy(GTK_WIDGET(dcal->transPopup));
+          dcal->transPopup = NULL;
+     }
 
-        if ( GTK_WIDGET_REALIZED( dcal->transPopup ) ) {
-                gtk_widget_hide( GTK_WIDGET(dcal->transPopup) );
-                gtk_widget_destroy( GTK_WIDGET(dcal->transPopup) );
-                dcal->transPopup = NULL;
-        }
+     if (dcal->drawbuf)
+     {
+          g_object_unref(dcal->drawbuf);
+          dcal->drawbuf = NULL;
+     }
 
-        if ( dcal->drawbuf ) {
-                g_object_unref( dcal->drawbuf );
-		dcal->drawbuf = NULL;
-	}
+     /* FIXME: we have a bunch of cleanup to do, here. */
+     /* monthLabelFont, dayLabelFont */
+     if (dcal->monthLabelFont)
+     {
+          gdk_font_unref(dcal->monthLabelFont);
+          dcal->monthLabelFont = NULL;
+     }
 
-        /* FIXME: we have a bunch of cleanup to do, here. */
-        /* monthLabelFont, dayLabelFont */
-        if ( dcal->monthLabelFont ) {
-		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++ ) {
-                	g_object_unref( dcal->monthLabels[i] );
-                	dcal->monthLabels[i] = NULL;
-		}
-        }
-        /* mark data */
-        gdc_free_all_mark_data( dcal );
+     if (dcal->dayLabelFont)
+     {
+          gdk_font_unref(dcal->dayLabelFont);
+          dcal->dayLabelFont = NULL;
+     }
 
-        if (G_OBJECT_CLASS (parent_class)->dispose)
-                (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+     /* month labels */
+     if (dcal->monthLabels[0])
+     {
+          for (i=0; i < 12; i++)
+          {
+               g_object_unref(dcal->monthLabels[i]);
+               dcal->monthLabels[i] = NULL;
+          }
+     }
+     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);
 }
 
 static void
 gnc_dense_cal_finalize (GObject *object)
 {
-        GncDenseCal *dcal;
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GNC_IS_DENSE_CAL (object));
+     GncDenseCal *dcal;
+     g_return_if_fail (object != NULL);
+     g_return_if_fail (GNC_IS_DENSE_CAL (object));
 
-        dcal = GNC_DENSE_CAL(object);
+     dcal = GNC_DENSE_CAL(object);
 
-        if (G_OBJECT_CLASS (parent_class)->finalize)
-                (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+     if (G_OBJECT_CLASS (parent_class)->finalize)
+          G_OBJECT_CLASS(parent_class)->finalize(object);
 }
 
 static void
 gnc_dense_cal_realize (GtkWidget *widget)
 {
-        GncDenseCal *dcal;
-        GdkWindowAttr attributes;
-        gint attributes_mask;
+     GncDenseCal *dcal;
+     GdkWindowAttr attributes;
+     gint attributes_mask;
 
-        g_return_if_fail (widget != NULL);
-        g_return_if_fail (GNC_IS_DENSE_CAL (widget));
+     g_return_if_fail(widget != NULL);
+     g_return_if_fail(GNC_IS_DENSE_CAL (widget));
 
-        GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-        dcal = GNC_DENSE_CAL (widget);
+     GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+     dcal = GNC_DENSE_CAL(widget);
 
-        attributes.x = widget->allocation.x;
-        attributes.y = widget->allocation.y;
-        attributes.width = widget->allocation.width;
-        attributes.height = widget->allocation.height;
-        attributes.wclass = GDK_INPUT_OUTPUT;
-        attributes.window_type = GDK_WINDOW_CHILD;
-        attributes.event_mask =
-                gtk_widget_get_events (widget)
-                | GDK_EXPOSURE_MASK
-                | GDK_BUTTON_PRESS_MASK
-                | GDK_BUTTON_RELEASE_MASK
-                | GDK_POINTER_MOTION_MASK
-                | GDK_POINTER_MOTION_HINT_MASK;
-        attributes.visual = gtk_widget_get_visual (widget);
-        attributes.colormap = gtk_widget_get_colormap (widget);
+     attributes.x = widget->allocation.x;
+     attributes.y = widget->allocation.y;
+     attributes.width = widget->allocation.width;
+     attributes.height = widget->allocation.height;
+     attributes.wclass = GDK_INPUT_OUTPUT;
+     attributes.window_type = GDK_WINDOW_CHILD;
+     attributes.event_mask =
+          gtk_widget_get_events(widget)
+          | GDK_EXPOSURE_MASK
+          | GDK_BUTTON_PRESS_MASK
+          | GDK_BUTTON_RELEASE_MASK
+          | GDK_POINTER_MOTION_MASK
+          | GDK_POINTER_MOTION_HINT_MASK;
+     attributes.visual = gtk_widget_get_visual(widget);
+     attributes.colormap = gtk_widget_get_colormap(widget);
 
-        attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+     attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
-        widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+     widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
 
-        widget->style = gtk_style_attach (widget->style, widget->window);
+     widget->style = gtk_style_attach(widget->style, widget->window);
 
-        gdk_window_set_user_data (widget->window, widget);
+     gdk_window_set_user_data(widget->window, widget);
 
-        gdc_reconfig( dcal );
+     gdc_reconfig(dcal);
 
-        gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+     gtk_style_set_background(widget->style, widget->window, GTK_STATE_ACTIVE);
 }
 
-static
-void
-gdc_reconfig( GncDenseCal *dcal )
+static void
+gdc_reconfig(GncDenseCal *dcal)
 {
-        GtkWidget *widget = GTK_WIDGET(dcal);
+     GtkWidget *widget = GTK_WIDGET(dcal);
 
-        if ( dcal->drawbuf ) {
-                g_object_unref( dcal->drawbuf );
-        }
-        dcal->drawbuf = gdk_pixmap_new( widget->window,
-                                        widget->allocation.width,
-                                        widget->allocation.height,
-                                        -1 );
-        gnc_dense_cal_draw_to_buffer( dcal );
+     if (dcal->drawbuf)
+          g_object_unref(dcal->drawbuf);
+     dcal->drawbuf = gdk_pixmap_new(widget->window,
+                                    widget->allocation.width,
+                                    widget->allocation.height,
+                                    -1);
+     gnc_dense_cal_draw_to_buffer(dcal);
 }
 
 static void 
-gnc_dense_cal_size_request( GtkWidget      *widget,
-                            GtkRequisition *requisition )
+gnc_dense_cal_size_request(GtkWidget *widget,
+                           GtkRequisition *requisition)
 {
-        GncDenseCal *dcal = GNC_DENSE_CAL(widget);
-        if ( !dcal->initialized ) {
-                PERR( "Uninitialized size request\n" );
-                requisition->width  = DENSE_CAL_DEFAULT_WIDTH;
-                requisition->height = DENSE_CAL_DEFAULT_HEIGHT;
-                return;
-        }
-        requisition->width =
-                (dcal->leftPadding * 2)
-                + (num_cols(dcal) * (col_width_at(dcal, dcal->min_x_scale)
-                                     + dcal->label_width))
-                + ((num_cols(dcal)-1) * COL_BORDER_SIZE);
-        requisition->height =
-                (dcal->topPadding * 2)
-                + MINOR_BORDER_SIZE
-                + dcal->dayLabelHeight
-                + (num_weeks_per_col(dcal)
-                   * week_height_at(dcal, dcal->min_y_scale));
+     GncDenseCal *dcal = GNC_DENSE_CAL(widget);
+     if (!dcal->initialized)
+     {
+          PERR("Uninitialized size request\n");
+          requisition->width  = DENSE_CAL_DEFAULT_WIDTH;
+          requisition->height = DENSE_CAL_DEFAULT_HEIGHT;
+          return;
+     }
+     requisition->width =
+          (dcal->leftPadding * 2)
+          + (num_cols(dcal)* (col_width_at(dcal, dcal->min_x_scale)
+                              + dcal->label_width))
+          + ((num_cols(dcal)-1) * COL_BORDER_SIZE);
+     requisition->height =
+          (dcal->topPadding * 2)
+          + MINOR_BORDER_SIZE
+          + dcal->dayLabelHeight
+          + (num_weeks_per_col(dcal)
+             * week_height_at(dcal, dcal->min_y_scale));
 }
 
 static void
-recompute_x_y_scales( GncDenseCal *dcal )
+recompute_x_y_scales(GncDenseCal *dcal)
 {
-        GtkWidget *widget;
-        int denom;
-        int width, height;
+     GtkWidget *widget;
+     int denom;
+     int width, height;
 
-        widget = GTK_WIDGET(dcal);
+     widget = GTK_WIDGET(dcal);
 
-        width = DENSE_CAL_DEFAULT_WIDTH;
-        height = DENSE_CAL_DEFAULT_HEIGHT;
-        if ( dcal->initialized ) {
-                width  = widget->allocation.width;
-                height = widget->allocation.height;
-        }
+     width = DENSE_CAL_DEFAULT_WIDTH;
+     height = DENSE_CAL_DEFAULT_HEIGHT;
+     if (dcal->initialized)
+     {
+          width  = widget->allocation.width;
+          height = widget->allocation.height;
+     }
 
-        /* FIXME: there's something slightly wrong in the x_scale computation that
-         * lets us draw larger than our area. */
-        denom = 7 * num_cols(dcal);
-        g_assert( denom != 0 );
-        dcal->x_scale = (gint)((width
-                                - (dcal->leftPadding * 2)
-                                - (num_cols(dcal) * ( (8 * MINOR_BORDER_SIZE)
-                                                      + dcal->label_width ))
-                                - ((num_cols(dcal)-1) * COL_BORDER_SIZE))
-                               / denom);
-        dcal->x_scale = MAX( dcal->x_scale, dcal->min_x_scale );
+     /* FIXME: there's something slightly wrong in the x_scale computation that
+      * lets us draw larger than our area. */
+     denom = 7 * num_cols(dcal);
+     g_assert(denom != 0);
+     dcal->x_scale = (gint)((width
+                             - (dcal->leftPadding * 2)
+                             - (num_cols(dcal) * ((8 * MINOR_BORDER_SIZE)
+                                                  + dcal->label_width))
+                             - ((num_cols(dcal)-1) * COL_BORDER_SIZE))
+                            / denom);
+     dcal->x_scale = MAX(dcal->x_scale, dcal->min_x_scale);
 
-        denom = num_weeks_per_col(dcal);
-        g_assert( denom != 0 );
-        dcal->y_scale = (gint)((height
-                                - (dcal->topPadding * 2)
-                                - MINOR_BORDER_SIZE
-                                - dcal->dayLabelHeight
-                                - (num_weeks_per_col(dcal)-1
-                                   * MINOR_BORDER_SIZE))
-                               / denom );
-        dcal->y_scale = MAX( dcal->y_scale, dcal->min_y_scale );
+     denom = num_weeks_per_col(dcal);
+     g_assert(denom != 0);
+     dcal->y_scale = (gint)((height
+                             - (dcal->topPadding * 2)
+                             - MINOR_BORDER_SIZE
+                             - dcal->dayLabelHeight
+                             - (num_weeks_per_col(dcal)-1
+                                * MINOR_BORDER_SIZE))
+                            / denom);
+     dcal->y_scale = MAX(dcal->y_scale, dcal->min_y_scale);
 }
 
 static void
-gdc_free_all_mark_data( GncDenseCal *dcal )
+gdc_free_all_mark_data(GncDenseCal *dcal)
 {
-        int i;
-        GList *l;
-        for ( i=0; i < dcal->numMarks; i++ ) {
-                /* Each of these just contains an elt of dcal->markData,
-                 * which we're about to free, below... */
-                g_list_free( dcal->marks[i] );
-        }
-        g_free( dcal->marks );
-        dcal->marks = NULL;
-        /* Remove the old mark data. */
-        for ( l = dcal->markData; l; l = l->next ) {
-                g_list_free( ((gdc_mark_data*)l->data)->ourMarks );
-                g_free( (gdc_mark_data*)l->data );
-        }
-        g_list_free( dcal->markData );
-        dcal->markData = NULL;
+     int i;
+     GList *l;
+     for (i=0; i < dcal->numMarks; i++)
+     {
+          /* Each of these just contains an elt of dcal->markData,
+           * which we're about to free, below... */
+          g_list_free(dcal->marks[i]);
+     }
+     g_free(dcal->marks);
+     dcal->marks = NULL;
+     /* Remove the old mark data. */
+     for (l = dcal->markData; l; l = l->next)
+     {
+          g_list_free(((gdc_mark_data*)l->data)->ourMarks);
+          g_free((gdc_mark_data*)l->data);
+     }
+     g_list_free(dcal->markData);
+     dcal->markData = NULL;
 }
 
 static void
-recompute_mark_storage( GncDenseCal *dcal )
+recompute_mark_storage(GncDenseCal *dcal)
 {
-        if ( dcal->marks == NULL ) {
-                goto createNew;
-        }
+     if (dcal->marks == NULL)
+          goto createNew;
+     gdc_free_all_mark_data(dcal);
 
-        gdc_free_all_mark_data( dcal );
  createNew:
-        dcal->numMarks = num_weeks(dcal) * 7;
-        dcal->marks = g_new0( GList*, dcal->numMarks );
-        g_signal_emit_by_name( dcal, MARKS_LOST_SIGNAL_NAME );
+     dcal->numMarks = num_weeks(dcal) * 7;
+     dcal->marks = g_new0(GList*, dcal->numMarks);
+     if (dcal->model)
+          gdc_add_markings(dcal);
 }
 
 static void
-recompute_extents( GncDenseCal *dcal )
+recompute_extents(GncDenseCal *dcal)
 {
-        GDate date;
-        gint start_week, end_week;
+     GDate date;
+     gint start_week, end_week;
 
-        g_date_clear( &date, 1 );
-        g_date_set_dmy( &date, 1, dcal->month, dcal->year );
-        start_week = g_date_get_sunday_week_of_year(&date);
-        g_date_add_months( &date, dcal->numMonths );
-        end_week = g_date_get_sunday_week_of_year(&date);
-        if ( g_date_get_year(&date) != dcal->year ) {
-                end_week += g_date_get_sunday_weeks_in_year( dcal->year );
-        }
-        dcal->num_weeks = end_week - start_week + 1;
+     g_date_clear(&date, 1);
+     g_date_set_dmy(&date, 1, dcal->month, dcal->year);
+     start_week = g_date_get_sunday_week_of_year(&date);
+     g_date_add_months(&date, dcal->numMonths);
+     end_week = g_date_get_sunday_week_of_year(&date);
+     if (g_date_get_year(&date) != dcal->year)
+          end_week += g_date_get_sunday_weeks_in_year(dcal->year);
+     dcal->num_weeks = end_week - start_week + 1;
 }
 
 static void
-gnc_dense_cal_size_allocate( GtkWidget     *widget,
-                             GtkAllocation *allocation )
+gnc_dense_cal_size_allocate(GtkWidget *widget,
+                            GtkAllocation *allocation)
 {
-        GncDenseCal *dcal;
+     GncDenseCal *dcal;
 
-        g_return_if_fail (widget != NULL);
-        g_return_if_fail (GNC_IS_DENSE_CAL (widget));
-        g_return_if_fail (allocation != NULL);
+     g_return_if_fail(widget != NULL);
+     g_return_if_fail(GNC_IS_DENSE_CAL (widget));
+     g_return_if_fail(allocation != NULL);
 
-        dcal = GNC_DENSE_CAL(widget);
+     dcal = GNC_DENSE_CAL(widget);
 
-        widget->allocation = *allocation;
+     widget->allocation = *allocation;
 
-        if (GTK_WIDGET_REALIZED (widget)) {
-                gdk_window_move_resize (widget->window,
-                                        allocation->x, allocation->y,
-                                        allocation->width,
-                                        allocation->height);
+     if (GTK_WIDGET_REALIZED(widget)) {
+          gdk_window_move_resize(widget->window,
+                                 allocation->x, allocation->y,
+                                 allocation->width,
+                                 allocation->height);
+          
+          /* We want to know how many px we can increase every day
+           * [width] or week [height]. */
+          recompute_x_y_scales(dcal);
 
-                /* We want to know how many px we can increase every day
-                 * [width] or week [height]. */
-                recompute_x_y_scales( dcal );
-
-                gdc_reconfig( dcal );
-        }
+          gdc_reconfig(dcal);
+     }
 }
 
 static void
-free_rect( gpointer data, gpointer ud )
+free_rect(gpointer data, gpointer ud)
 {
-        g_free( (GdkRectangle*)data );
+     g_free((GdkRectangle*)data);
 }
 
 static gint
-gnc_dense_cal_expose( GtkWidget *widget,
-                      GdkEventExpose *event )
+gnc_dense_cal_expose(GtkWidget *widget,
+                      GdkEventExpose *event)
 {
-        GncDenseCal *dcal;
-        GdkGC *gc;
+     GncDenseCal *dcal;
+     GdkGC *gc;
 
-        g_return_val_if_fail (widget != NULL, FALSE);
-        g_return_val_if_fail (GNC_IS_DENSE_CAL (widget), FALSE);
-        g_return_val_if_fail (event != NULL, FALSE);
+     g_return_val_if_fail(widget != NULL, FALSE);
+     g_return_val_if_fail(GNC_IS_DENSE_CAL(widget), FALSE);
+     g_return_val_if_fail(event != NULL, FALSE);
 
-        if (event->count > 0)
-                return FALSE;
+     if (event->count > 0)
+          return FALSE;
 
-        dcal = GNC_DENSE_CAL (widget);
-        gc = widget->style->fg_gc[ GTK_WIDGET_STATE(widget) ];
-        gdk_draw_drawable(GDK_DRAWABLE(widget->window),
-                          gc,
-                          GDK_DRAWABLE(dcal->drawbuf),
-                          0, 0, 0, 0,
-                          widget->allocation.width,
-                          widget->allocation.height);
+     dcal = GNC_DENSE_CAL(widget);
+     gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)];
+     gdk_draw_drawable(GDK_DRAWABLE(widget->window),
+                       gc,
+                       GDK_DRAWABLE(dcal->drawbuf),
+                       0, 0, 0, 0,
+                       widget->allocation.width,
+                       widget->allocation.height);
 
-        return FALSE;
+     return FALSE;
 }
 
 static void
-gnc_dense_cal_draw_to_buffer( GncDenseCal *dcal )
+gnc_dense_cal_draw_to_buffer(GncDenseCal *dcal)
 {
-        GtkWidget *widget;
-        gint i;
-        int maxWidth;
+     GtkWidget *widget;
+     gint i;
+     int maxWidth;
 
-        widget = &dcal->widget;
+     widget = &dcal->widget;
 
-        if ( ! dcal->drawbuf )
-                return;
+     if (!dcal->drawbuf)
+          return;
 
-        gdk_draw_rectangle (dcal->drawbuf,
-                            widget->style->white_gc,
-                            TRUE,
-                            0, 0,
-                            widget->allocation.width,
-                            widget->allocation.height);
+     gdk_draw_rectangle(dcal->drawbuf,
+                        widget->style->white_gc,
+                        TRUE,
+                        0, 0,
+                        widget->allocation.width,
+                        widget->allocation.height);
 
 
-        if ( dcal->needInitMonthLabels ) {
-                /* Create the month labels */
-                gint i;
-                GdkPixmap *tmpPix;
-                GdkImage *tmpImg;
-                GdkGC *gc;
-                GdkColor black;
+     if (dcal->needInitMonthLabels)
+     {
+          /* Create the month labels */
+          gint i;
+          GdkPixmap *tmpPix;
+          GdkImage *tmpImg;
+          GdkGC *gc;
+          GdkColor black;
 
-                gc = widget->style->fg_gc[widget->state];
-                tmpPix = gdk_pixmap_new( NULL,
-                                         dcal->label_height,
-                                         dcal->label_width,
-                                         gdk_visual_get_system()->depth );
-                black.pixel = gdk_rgb_xpixel_from_rgb(0);
-                for ( i=0; i<12; i++ ) {
-                        guint x,y;
-                        /* these are going to be rotated, so transpose width
-                         * and height */
-                        dcal->monthLabels[i] =
-                                gdk_pixmap_new( widget->window,
-                                                dcal->label_width,
-                                                dcal->label_height, -1 );
-                        gdk_draw_rectangle( dcal->monthLabels[i],
-                                            widget->style->white_gc,
-                                            TRUE, 0, 0,
-                                            dcal->label_width,
-                                            dcal->label_height );
+          gc = widget->style->fg_gc[widget->state];
+          tmpPix = gdk_pixmap_new(NULL,
+                                  dcal->label_height,
+                                  dcal->label_width,
+                                  gdk_visual_get_system()->depth);
+          black.pixel = gdk_rgb_xpixel_from_rgb(0);
+          for (i=0; i<12; i++)
+          {
+               guint x,y;
+               /* these are going to be rotated, so transpose width
+                * and height */
+               dcal->monthLabels[i] =
+                    gdk_pixmap_new(widget->window,
+                                   dcal->label_width,
+                                   dcal->label_height, -1);
+               gdk_draw_rectangle(dcal->monthLabels[i],
+                                  widget->style->white_gc,
+                                  TRUE, 0, 0,
+                                  dcal->label_width,
+                                  dcal->label_height);
 
-                        gdk_draw_rectangle( tmpPix,
-                                            widget->style->white_gc,
-                                            TRUE, 0, 0,
-                                            dcal->label_height,
-                                            dcal->label_width );
+               gdk_draw_rectangle(tmpPix,
+                                  widget->style->white_gc,
+                                  TRUE, 0, 0,
+                                  dcal->label_height,
+                                  dcal->label_width);
 
-                        gdk_draw_string( tmpPix, dcal->monthLabelFont, gc,
-                                         dcal->label_lbearing,
-                                         dcal->label_ascent,
-                                         month_name(i) );
+               gdk_draw_string(tmpPix, dcal->monthLabelFont, gc,
+                               dcal->label_lbearing,
+                               dcal->label_ascent,
+                               month_name(i));
 
-                        tmpImg = gdk_image_get( tmpPix, 0, 0,
-                                                dcal->label_height,
-                                                dcal->label_width );
+               tmpImg = gdk_image_get(tmpPix, 0, 0,
+                                      dcal->label_height,
+                                      dcal->label_width);
 
-                        /* now, (transpose the pixel matrix)==(do a 90-degree
-                         * counter-clockwise rotation) */
-                        for ( x=0; x < dcal->label_height; x++ ) {
-                                for ( y=0; y < dcal->label_width; y++ ) {
-                                        if ( gdk_image_get_pixel( tmpImg, x, y )
-                                             != black.pixel ) {
-                                                continue;
-                                        }
-                                        gdk_draw_point( dcal->monthLabels[i],
-                                                        gc, y,
-                                                        dcal->label_height - x );
-                                }
-                        }
-                        gdk_image_destroy( tmpImg );
-                }
-                dcal->needInitMonthLabels = FALSE;
-        }
+               /* now, (transpose the pixel matrix)==(do a 90-degree
+                * counter-clockwise rotation) */
+               for (x=0; x < dcal->label_height; x++)
+               {
+                    for (y=0; y < dcal->label_width; y++)
+                    {
+                         if (gdk_image_get_pixel(tmpImg, x, y) != black.pixel)
+                              continue;
+                         gdk_draw_point(dcal->monthLabels[i],
+                                        gc, y,
+                                        dcal->label_height - x);
+                    }
+               }
+               gdk_image_destroy(tmpImg);
+          }
+          dcal->needInitMonthLabels = FALSE;
+     }
 
-        /* Fill in alternating month colors. */
-        {
-                gint i;
-                GdkGC *gc;
-                GdkRectangle *rect;
-                GList *mcList, *mcListIter;
+     /* Fill in alternating month colors. */
+     {
+          gint i;
+          GdkGC *gc;
+          GdkRectangle *rect;
+          GList *mcList, *mcListIter;
 
-                gc = gdk_gc_new( dcal->widget.window );
-                gdk_gc_copy( gc, widget->style->fg_gc[GTK_WIDGET_STATE(widget)] );
+          gc = gdk_gc_new(dcal->widget.window);
+          gdk_gc_copy(gc, widget->style->fg_gc[GTK_WIDGET_STATE(widget)]);
 
-                /* reset all of the month position offsets. */
-                for ( i=0; i<12; i++ ) {
-                        dcal->monthPositions[i].x = dcal->monthPositions[i].y = -1;
-                }
+          /* reset all of the month position offsets. */
+          for (i=0; i<12; i++)
+          {
+               dcal->monthPositions[i].x = dcal->monthPositions[i].y = -1;
+          }
 
-                /* Paint the weeks for the upcoming N months. */
-                for ( i=0; i < dcal->numMonths; i++ ) {
-                        gdk_gc_set_foreground( gc, &dcal->weekColors[ i % 2 ] );
+          /* Paint the weeks for the upcoming N months. */
+          for (i=0; i < dcal->numMonths; i++)
+          {
+               gdk_gc_set_foreground(gc, &dcal->weekColors[ i % 2 ]);
 
-                        mcList = NULL;
-                        month_coords( dcal, i, &mcList );
-                        dcal->monthPositions[i].x = 
-                                floor(i/dcal->monthsPerCol)
-                                * (col_width(dcal) + COL_BORDER_SIZE);
-                        dcal->monthPositions[i].y = ((GdkRectangle*)mcList->next->data)->y;
-                        for ( mcListIter = mcList; mcListIter;
-                              mcListIter = mcListIter->next ) {
-                                rect = (GdkRectangle*)mcListIter->data;
-                                gdk_draw_rectangle( dcal->drawbuf, gc,
-                                                    TRUE, rect->x, rect->y,
-                                                    rect->width - 2, rect->height );
-                        }
-                        g_list_foreach( mcList, free_rect, NULL );
-                        g_list_free( mcList );
-                }
+               mcList = NULL;
+               month_coords(dcal, i, &mcList);
+               dcal->monthPositions[i].x
+                    = floor(i/dcal->monthsPerCol)
+                    * (col_width(dcal) + COL_BORDER_SIZE);
+               dcal->monthPositions[i].y = ((GdkRectangle*)mcList->next->data)->y;
+               for (mcListIter = mcList; mcListIter != NULL; mcListIter = mcListIter->next)
+               {
+                    rect = (GdkRectangle*)mcListIter->data;
+                    gdk_draw_rectangle(dcal->drawbuf, gc,
+                                       TRUE, rect->x, rect->y,
+                                       rect->width - 2, rect->height);
+               }
+               g_list_foreach(mcList, free_rect, NULL);
+               g_list_free(mcList);
+          }
 
-                gdk_gc_destroy( gc );
-        }
+          gdk_gc_destroy(gc);
+     }
 
-        /* Hilight the marked days. */
-        {
-                int i;
-                int x1, x2, y1, y2;
-                GdkColor markColor, black;
-                GList *l;
-                gdc_mark_data *gdcmd;
+     /* Hilight the marked days. */
+     {
+          int i;
+          int x1, x2, y1, y2;
+          GdkColor markColor, black;
 
-                gdk_color_parse( MARK_COLOR, &markColor );
-                gdk_colormap_alloc_color( gdk_colormap_get_system(), &markColor, TRUE, TRUE );
-                gdk_color_black( gdk_colormap_get_system(), &black );
+          gdk_color_parse(MARK_COLOR, &markColor);
+          gdk_colormap_alloc_color(gdk_colormap_get_system(), &markColor, TRUE, TRUE);
+          gdk_color_black(gdk_colormap_get_system(), &black);
 
-                /* FIXME: use a different GC for this */
-                gdk_gc_set_foreground( widget->style->fg_gc[widget->state], &markColor );
-                for ( i=0; i<dcal->numMarks; i++ ) {
-                        for ( l = dcal->marks[i]; l ; l = l->next ) {
-                                gdcmd = (gdc_mark_data*)l->data;
-                                doc_coords( dcal, i, &x1, &y1, &x2, &y2 );
-                                gdk_draw_rectangle( dcal->drawbuf,
-                                                    widget->style->fg_gc[widget->state],
-                                                    TRUE, x1, y1, (x2-x1), (y2-y1) );
-                        }
-                }
-                gdk_gc_set_foreground( widget->style->fg_gc[widget->state], &black );
-        }
+          /* FIXME: use a different GC for this */
+          gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &markColor);
+          for (i=0; i<dcal->numMarks; i++)
+          {
+               if (dcal->marks[i] != NULL)
+               {
+                    doc_coords(dcal, i, &x1, &y1, &x2, &y2);
+                    gdk_draw_rectangle(dcal->drawbuf,
+                                       widget->style->fg_gc[widget->state],
+                                       TRUE, x1, y1, (x2-x1), (y2-y1));
+               }
+          }
+          gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &black);
+     }
 
-        for ( i=0; i < num_cols(dcal); i++ ) {
-                gint x, y, w, h;
-                gint j;
+     for (i=0; i < num_cols(dcal); i++)
+     {
+          gint x, y, w, h;
+          gint j;
 
-                dcal->dayLabelHeight = gdk_string_height( dcal->monthLabelFont, "S" );
+          dcal->dayLabelHeight = gdk_string_height(dcal->monthLabelFont, "S");
 
-                x = dcal->leftPadding
-                        + ( i * (col_width(dcal)+COL_BORDER_SIZE) )
-                        + dcal->label_width;
-                y = dcal->topPadding + dcal->dayLabelHeight;
-                w = col_width(dcal) - COL_BORDER_SIZE - dcal->label_width - 2;
-                h = col_height(dcal);
+          x = dcal->leftPadding
+               + (i * (col_width(dcal)+COL_BORDER_SIZE))
+               + dcal->label_width;
+          y = dcal->topPadding + dcal->dayLabelHeight;
+          w = col_width(dcal) - COL_BORDER_SIZE - dcal->label_width - 2;
+          h = col_height(dcal);
 
-                /* draw the outside border [inside the month labels] */
-                gdk_draw_rectangle( dcal->drawbuf,
+          /* draw the outside border [inside the month labels] */
+          gdk_draw_rectangle(dcal->drawbuf,
+                             widget->style->fg_gc[widget->state],
+                             FALSE, x, y, w, h);
+          /* draw the week seperations */
+          for (j=0; j < num_weeks_per_col(dcal); j++)
+          {
+               gint wy = y + (j * week_height(dcal));
+               gdk_draw_line(dcal->drawbuf,
+                             widget->style->fg_gc[widget->state],
+                             x,     wy,
+                             x + w, wy);
+          }
+
+          /* draw the day seperations */
+          for (j=1; j<7; j++)
+          {
+               gint dx = x + (j * day_width(dcal));
+               gdk_draw_line(dcal->drawbuf,
+                             widget->style->fg_gc[widget->state],
+                             dx, y,
+                             dx, y + col_height(dcal));
+          }
+
+          /* draw the day labels */
+          maxWidth = gdk_string_width(dcal->monthLabelFont, "88");
+          if (dcal->x_scale > maxWidth)
+          {
+               for (j=0; j<7; j++)
+               {
+                    gint dx = x
+                         + (j * day_width(dcal))
+                         + (day_width(dcal)/2)
+                         - (gdk_string_width(dcal->monthLabelFont,
+                                             day_label(j)) / 2);
+                    gint dy = y - 2;
+                    gdk_draw_string(dcal->drawbuf,
+                                    dcal->monthLabelFont,
                                     widget->style->fg_gc[widget->state],
-                                    FALSE, x, y, w, h );
-                /* draw the week seperations */
-                {
-                        for ( j=0; j < num_weeks_per_col(dcal); j++ ) {
-                                gint wy = y + (j * week_height(dcal));
-                                gdk_draw_line( dcal->drawbuf,
-                                               widget->style->fg_gc[widget->state],
-                                               x,     wy,
-                                               x + w, wy );
-                        }
-                }
-                /* draw the day seperations */
-                {
-                        for ( j=1; j<7; j++ ) {
-                                gint dx = x + (j * day_width(dcal));
-                                gdk_draw_line( dcal->drawbuf,
-                                               widget->style->fg_gc[widget->state],
-                                               dx, y,
-                                               dx, y + col_height(dcal) );
-                        }
-                }
-                /* draw the day labels */
-                maxWidth = gdk_string_width( dcal->monthLabelFont, "88" );
-                if ( dcal->x_scale > maxWidth ) {
-                        for ( j=0; j<7; j++ ) {
-                                gint dx = x
-                                        + (j * day_width(dcal))
-                                        + (day_width(dcal)/2)
-                                        - ( gdk_string_width(dcal->monthLabelFont,
-                                                             day_label(j)) / 2 );
-                                gint dy = y - 2;
-                                gdk_draw_string( dcal->drawbuf,
-                                                 dcal->monthLabelFont,
-                                                 widget->style->fg_gc[widget->state],
-                                                 dx, dy, day_label(j) );
-                        }
-                }
-        }
+                                    dx, dy, day_label(j));
+               }
+          }
+     }
 
-        /* Try some pixmap copying for the month labels. */
-        {
-                gint i, idx;
+     /* Try some pixmap copying for the month labels. */
+     {
+          gint i, idx;
 
-                for ( i=0; i<12; i++ ) {
-                        if ( dcal->monthPositions[i].x == -1 ) {
-                                break;
-                        }
-                        idx = (dcal->month - 1 + i) % 12;
-                        gdk_draw_drawable(GDK_DRAWABLE(dcal->drawbuf),
-                                          widget->style->fg_gc[widget->state],
-                                          GDK_DRAWABLE(dcal->monthLabels[idx]),
-                                          0, 0,
-                                          dcal->leftPadding
-                                          + dcal->monthPositions[i].x,
-                                          dcal->monthPositions[i].y,
-                                          dcal->label_width, dcal->label_height);
-                }
-        }
+          for (i=0; i<12; i++)
+          {
+               if (dcal->monthPositions[i].x == -1)
+                    break;
+               idx = (dcal->month - 1 + i) % 12;
+               gdk_draw_drawable(GDK_DRAWABLE(dcal->drawbuf),
+                                 widget->style->fg_gc[widget->state],
+                                 GDK_DRAWABLE(dcal->monthLabels[idx]),
+                                 0, 0,
+                                 dcal->leftPadding
+                                 + dcal->monthPositions[i].x,
+                                 dcal->monthPositions[i].y,
+                                 dcal->label_width, dcal->label_height);
+          }
+     }
 
-        /* Try the per-day strings [dates] */
-        {
-                GDate d, eoc;
-                gint doc;
-                gchar dayNumBuf[3];
-                gint numW, numH;
-                gint x1, y1, x2, y2, w, h;
+     /* Try the per-day strings [dates] */
+     {
+          GDate d, eoc;
+          gint doc;
+          gchar dayNumBuf[3];
+          gint numW, numH;
+          gint x1, y1, x2, y2, w, h;
 
-                g_date_set_dmy( &d, 1, dcal->month, dcal->year );
-                eoc = d;
-                g_date_add_months( &eoc, dcal->numMonths );
-                for ( doc = 0; g_date_get_julian(&d) < g_date_get_julian(&eoc);
-                      g_date_add_days( &d, 1 ), doc++ ) {
-                        doc_coords( dcal, doc, &x1, &y1, &x2, &y2 );
-                        memset( dayNumBuf, 0, 3 );
-                        snprintf( dayNumBuf, 3, "%d", g_date_get_day( &d ) );
-                        numW = gdk_string_width( dcal->dayLabelFont, dayNumBuf );
-                        numH = gdk_string_height( dcal->dayLabelFont, dayNumBuf );
-                        w = (x2 - x1)+1;
-                        h = (y2 - y1)+1;
-                        gdk_draw_string( dcal->drawbuf,
-                                         dcal->dayLabelFont,
-                                         widget->style->fg_gc[widget->state],
-                                         x1 + (w/2) - (numW/2),
-                                         y1 + (h/2) + (numH/2),
-                                         dayNumBuf );
-                }
-        }
+          g_date_set_dmy(&d, 1, dcal->month, dcal->year);
+          eoc = d;
+          g_date_add_months(&eoc, dcal->numMonths);
+          for (doc = 0; g_date_get_julian(&d) < g_date_get_julian(&eoc); g_date_add_days(&d, 1), doc++)
+          {
+               doc_coords(dcal, doc, &x1, &y1, &x2, &y2);
+               memset(dayNumBuf, 0, 3);
+               snprintf(dayNumBuf, 3, "%d", g_date_get_day(&d));
+               numW = gdk_string_width(dcal->dayLabelFont, dayNumBuf);
+               numH = gdk_string_height(dcal->dayLabelFont, dayNumBuf);
+               w = (x2 - x1)+1;
+               h = (y2 - y1)+1;
+               gdk_draw_string(dcal->drawbuf,
+                               dcal->dayLabelFont,
+                               widget->style->fg_gc[widget->state],
+                               x1 + (w/2) - (numW/2),
+                               y1 + (h/2) + (numH/2),
+                               dayNumBuf);
+          }
+     }
 
-        {
-                GdkRectangle update_rect;
-                update_rect.x = 0;
-                update_rect.y = 0;
-                update_rect.width  = widget->allocation.width;
-                update_rect.height = widget->allocation.height;
-                gtk_widget_draw( GTK_WIDGET(dcal),
-                                 &update_rect );
-        }
-
+     {
+          GdkRectangle update_rect;
+          update_rect.x = 0;
+          update_rect.y = 0;
+          update_rect.width  = widget->allocation.width;
+          update_rect.height = widget->allocation.height;
+          gtk_widget_draw(GTK_WIDGET(dcal), &update_rect);
+     }
 }
 
 static void
-populate_hover_window( GncDenseCal *dcal, gint doc )
+populate_hover_window(GncDenseCal *dcal, gint doc)
 {
-        GtkWidget *w;
-        GDate *date;
-        static const int MAX_STRFTIME_BUF_LEN = 64;
-        gchar strftimeBuf[MAX_STRFTIME_BUF_LEN];
+     GtkWidget *w;
+     GDate *date;
+     static const int MAX_STRFTIME_BUF_LEN = 64;
+     gchar strftimeBuf[MAX_STRFTIME_BUF_LEN];
 
-        if ( doc >= 0 ) {
-                GObject *o;
-                GtkCList *cl;
-                GList *l;
-                gchar *rowText[2];
-                gint row = 0;
-                gdc_mark_data *gdcmd;
+     if (doc >= 0)
+     {
+          GObject *o;
+          GtkListStore *model;
+          GList *l;
 
-                w = GTK_WIDGET( g_object_get_data( G_OBJECT(dcal->transPopup),
-						   "dateLabel" ) );
-                date = g_date_new_dmy( 1, dcal->month, dcal->year );
-                g_date_add_days( date, doc );
-		/* Note: the ISO date format (%F or equivalently
-		 * %Y-%m-%d) is not a good idea here since many
-		 * locales will want to use a very different date
-		 * format. Please leave the specification of the date
-		 * format up to the locale and use %x here.  */
-                g_date_strftime( strftimeBuf, MAX_STRFTIME_BUF_LEN-1, "%x", date );
-                gtk_label_set_text( GTK_LABEL(w), strftimeBuf );
+          w = GTK_WIDGET(g_object_get_data(G_OBJECT(dcal->transPopup), "dateLabel"));
+          date = g_date_new_dmy(1, dcal->month, dcal->year);
+          g_date_add_days(date, doc);
+          /* Note: the ISO date format (%F or equivalently
+           * %Y-%m-%d) is not a good idea here since many
+           * locales will want to use a very different date
+           * format. Please leave the specification of the date
+           * format up to the locale and use %x here.  */
+          g_date_strftime(strftimeBuf, MAX_STRFTIME_BUF_LEN-1, "%x", date);
+          gtk_label_set_text(GTK_LABEL(w), strftimeBuf);
 
-                o = G_OBJECT(dcal->transPopup);
-                cl = GTK_CLIST( g_object_get_data(o, "clist" ) );
-                gtk_clist_clear( cl );
-                for ( l = dcal->marks[doc]; l; l = l->next ) {
-                        gdcmd = (gdc_mark_data*)l->data;
-                        rowText[0] = ( gdcmd->name ? gdcmd->name : _("(unnamed)") );
-                        rowText[1] = gdcmd->info;
-                        gtk_clist_insert( cl, row++, rowText );
-                }
+          o = G_OBJECT(dcal->transPopup);
+          model = GTK_LIST_STORE(g_object_get_data(o, "model"));
+          gtk_list_store_clear(model);
+          for (l = dcal->marks[doc]; l; l = l->next)
+          {
+               GtkTreeIter iter;
+               gdc_mark_data *gdcmd;
 
-                // FIXME: free 'date'?
-        }
+               gdcmd = (gdc_mark_data*)l->data;
+               gtk_list_store_insert(model, &iter, INT_MAX);
+               gtk_list_store_set(model, &iter, 0, (gdcmd->name ? gdcmd->name : _("(unnamed)")), 1, gdcmd->info, -1);
+          }
+
+          g_date_free(date);
+     }
 }
 
 static gint
-gnc_dense_cal_button_press( GtkWidget *widget,
-                            GdkEventButton *evt )
+gnc_dense_cal_button_press(GtkWidget *widget,
+                            GdkEventButton *evt)
 {
-        gint doc;
-        GncDenseCal *dcal = GNC_DENSE_CAL(widget);
+     gint doc;
+     GncDenseCal *dcal = GNC_DENSE_CAL(widget);
 
-        doc = wheres_this( dcal, evt->x, evt->y );
-        dcal->showPopup = ~(dcal->showPopup);
-        if ( dcal->showPopup && doc >= 0 ) {
-                // Do the move twice in case the WM is ignoring the first one
-                // because the window hasn't been shown, yet.  The WM is free
-                // to ignore our move and place windows according to it's own
-                // strategy, but hopefully it'll listen to us.  Certainly the
-                // second move after show_all'ing the window should do the
-                // trick with a bit of flicker.
-                gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root+5, evt->y_root+5);
-                populate_hover_window( dcal, doc );
-                gtk_widget_show_all( GTK_WIDGET(dcal->transPopup) );
-                gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root+5, evt->y_root+5);
-        } else {
-                gtk_widget_hide( GTK_WIDGET(dcal->transPopup) );
-        }
-        return FALSE;
+     doc = wheres_this(dcal, evt->x, evt->y);
+     dcal->showPopup = ~(dcal->showPopup);
+     if (dcal->showPopup && doc >= 0)
+     {
+          // Do the move twice in case the WM is ignoring the first one
+          // because the window hasn't been shown, yet.  The WM is free
+          // to ignore our move and place windows according to it's own
+          // strategy, but hopefully it'll listen to us.  Certainly the
+          // second move after show_all'ing the window should do the
+          // trick with a bit of flicker.
+          gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root+5, evt->y_root+5);
+          populate_hover_window(dcal, doc);
+          gtk_widget_show_all(GTK_WIDGET(dcal->transPopup));
+          gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root+5, evt->y_root+5);
+     }
+     else
+     {
+          gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
+     }
+     return FALSE;
 }
 
 static gint
-gnc_dense_cal_motion_notify( GtkWidget      *widget,
-                             GdkEventMotion *event )
+gnc_dense_cal_motion_notify(GtkWidget *widget,
+                            GdkEventMotion *event)
 {
-        GncDenseCal *dcal;
-        gint doc;
-        int unused;
-        int x_root_offset, y_root_offset;
-        GdkModifierType unused2;
+     GncDenseCal *dcal;
+     gint doc;
+     int unused;
+     int x_root_offset, y_root_offset;
+     GdkModifierType unused2;
 
-        dcal = GNC_DENSE_CAL(widget);
-        if ( ! dcal->showPopup )
-                return FALSE;
+     dcal = GNC_DENSE_CAL(widget);
+     if (!dcal->showPopup)
+          return FALSE;
 
-        x_root_offset = event->x_root;
-        y_root_offset = event->y_root;
+     x_root_offset = event->x_root;
+     y_root_offset = event->y_root;
 
-        /* As per http://www.gtk.org/tutorial/sec-eventhandling.html */
-        if ( event->is_hint ) {
-                gdk_window_get_pointer( event->window, &unused, &unused, &unused2 );
-        }
-        gdk_window_move( GTK_WIDGET(dcal->transPopup)->window,
-                         x_root_offset+5, y_root_offset+5 );
-        doc = wheres_this( dcal, event->x, event->y );
-        if ( doc >= 0 ) {
-                populate_hover_window( dcal, doc );
-                gtk_widget_show_all( GTK_WIDGET(dcal->transPopup) );
-        } else {
-                gtk_widget_hide( GTK_WIDGET(dcal->transPopup) );
-        }
-        return TRUE;
+     /* As per http://www.gtk.org/tutorial/sec-eventhandling.html */
+     if (event->is_hint)
+          gdk_window_get_pointer(event->window, &unused, &unused, &unused2);
+     gdk_window_move(GTK_WIDGET(dcal->transPopup)->window,
+                     x_root_offset+5, y_root_offset+5);
+     doc = wheres_this(dcal, event->x, event->y);
+     if (doc >= 0)
+     {
+          populate_hover_window(dcal, doc);
+          gtk_widget_show_all(GTK_WIDGET(dcal->transPopup));
+     }
+     else
+     {
+          gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
+     }
+     return TRUE;
 }
 
 static inline int
-day_width_at( GncDenseCal *dcal, guint xScale )
+day_width_at(GncDenseCal *dcal, guint xScale)
 {
-        return xScale + MINOR_BORDER_SIZE;
+     return xScale + MINOR_BORDER_SIZE;
 }
 
 static inline int
-day_width( GncDenseCal *dcal )
+day_width(GncDenseCal *dcal)
 {
-        return day_width_at( dcal, dcal->x_scale );
+     return day_width_at(dcal, dcal->x_scale);
 }
 
 static inline int
-day_height_at( GncDenseCal *dcal, guint yScale )
+day_height_at(GncDenseCal *dcal, guint yScale)
 {
-        return yScale + MINOR_BORDER_SIZE;
+     return yScale + MINOR_BORDER_SIZE;
 }
 
 static inline int
-day_height( GncDenseCal *dcal )
+day_height(GncDenseCal *dcal)
 {
-        return day_height_at( dcal, dcal->y_scale );
+     return day_height_at(dcal, dcal->y_scale);
 }
 
 static inline int
-week_width_at( GncDenseCal *dcal, guint xScale )
+week_width_at(GncDenseCal *dcal, guint xScale)
 {
-        return day_width_at(dcal, xScale) * 7;
+     return day_width_at(dcal, xScale) * 7;
 }
 
 static inline int
-week_width( GncDenseCal *dcal )
+week_width(GncDenseCal *dcal)
 {
-        return week_width_at( dcal, dcal->x_scale );
+     return week_width_at(dcal, dcal->x_scale);
 }
 
 static inline int
-week_height_at( GncDenseCal *dcal, guint yScale )
+week_height_at(GncDenseCal *dcal, guint yScale)
 {
-        return day_height_at(dcal, yScale);
+     return day_height_at(dcal, yScale);
 }
 
 static inline int
-week_height( GncDenseCal *dcal )
+week_height(GncDenseCal *dcal)
 {
-        return week_height_at(dcal, dcal->y_scale);
+     return week_height_at(dcal, dcal->y_scale);
 }
 
 static inline int
-col_width_at( GncDenseCal *dcal, guint xScale )
+col_width_at(GncDenseCal *dcal, guint xScale)
 {
-        return (week_width_at(dcal, xScale)
-                + dcal->label_width
-                + COL_BORDER_SIZE);
+     return (week_width_at(dcal, xScale)
+             + dcal->label_width
+             + COL_BORDER_SIZE);
 }
 
 static inline int
-col_width( GncDenseCal *dcal )
+col_width(GncDenseCal *dcal)
 {
-        return col_width_at( dcal, dcal->x_scale );
+     return col_width_at(dcal, dcal->x_scale);
 }
 
 static inline int
-col_height( GncDenseCal *dcal )
+col_height(GncDenseCal *dcal)
 {
-        return week_height(dcal)
-                * num_weeks_per_col(dcal);
+     return week_height(dcal) * num_weeks_per_col(dcal);
 }
 
 static inline int
-num_cols( GncDenseCal *dcal )
+num_cols(GncDenseCal *dcal)
 {
-        return ceil( (float)dcal->numMonths / (float)dcal->monthsPerCol );
+     return ceil((float)dcal->numMonths / (float)dcal->monthsPerCol);
 }
 
 static inline int
-num_weeks( GncDenseCal *dcal )
+num_weeks(GncDenseCal *dcal)
 {
-        /* FIXME: calculate, remove 'recompute_extents' */
-        return dcal->num_weeks;
+     return dcal->num_weeks;
 }
 
 static
-int num_weeks_per_col( GncDenseCal *dcal )
+int num_weeks_per_col(GncDenseCal *dcal)
 {
-        int num_weeks_toRet, numCols, i;
-        GDate *start,*end;
-        int startWeek, endWeek;
+     int num_weeks_toRet, numCols, i;
+     GDate *start,*end;
+     int startWeek, endWeek;
 
-        start = g_date_new();
-        end = g_date_new();
+     start = g_date_new();
+     end = g_date_new();
 
-        num_weeks_toRet = 0;
-        numCols = num_cols(dcal);
+     num_weeks_toRet = 0;
+     numCols = num_cols(dcal);
 
-        for ( i=0; i<numCols; i++ ) {
-                g_date_set_dmy( start, 1,
-                                ((dcal->month - 1 +
-                                  (i * dcal->monthsPerCol)) % 12)
-                                + 1,
-                                dcal->year + floor((dcal->month - 1
-                                                    + (i*dcal->monthsPerCol))
-                                                   / 12) );
-                *end = *start;
-                /* Add the smaller of (the number of months in the
-                 * calendar-display, minus the number of months shown in the
-                 * previous columns) or (the number of months in a column) */
-                g_date_add_months( end, MIN( dcal->numMonths,
-                                             MIN( dcal->monthsPerCol,
-                                                  dcal->numMonths
-                                                  - ((i-1)
-                                                     * dcal->monthsPerCol) ) ) );
-                g_date_subtract_days( end, 1 );
-                startWeek = g_date_get_sunday_week_of_year( start );
-                endWeek = g_date_get_sunday_week_of_year( end );
-                if ( endWeek < startWeek ) {
-                        endWeek += g_date_get_sunday_weeks_in_year( g_date_get_year(start) );
-                }
-                num_weeks_toRet = MAX( num_weeks_toRet, (endWeek - startWeek)+1 );
-        }
-        return num_weeks_toRet;
+     for (i=0; i<numCols; i++)
+     {
+          g_date_set_dmy(start, 1,
+                         ((dcal->month - 1
+                           + (i * dcal->monthsPerCol)) % 12)
+                         + 1,
+                         dcal->year + floor((dcal->month - 1
+                                             + (i*dcal->monthsPerCol))
+                                            / 12));
+          *end = *start;
+          /* Add the smaller of (the number of months in the
+           * calendar-display, minus the number of months shown in the
+           * previous columns) or (the number of months in a column) */
+          g_date_add_months(end, MIN(dcal->numMonths,
+                                     MIN(dcal->monthsPerCol,
+                                         dcal->numMonths
+                                         - ((i-1)
+                                            * dcal->monthsPerCol))));
+          g_date_subtract_days(end, 1);
+          startWeek = g_date_get_sunday_week_of_year(start);
+          endWeek = g_date_get_sunday_week_of_year(end);
+          if (endWeek < startWeek)
+          {
+               endWeek += g_date_get_sunday_weeks_in_year(g_date_get_year(start));
+          }
+          num_weeks_toRet = MAX(num_weeks_toRet, (endWeek - startWeek)+1);
+     }
+     return num_weeks_toRet;
 }
 
 /**
@@ -1261,167 +1254,171 @@
  * size of the month.
  **/
 static void
-month_coords( GncDenseCal *dcal, int monthOfCal, GList **outList )
+month_coords(GncDenseCal *dcal, int monthOfCal, GList **outList)
 {
-        gint weekRow, colNum, previousMonthsInCol, monthOffset;
-        gint start;
-        GDate *startD, *endD;
-        GdkRectangle *rect;
-        gint startWk, endWk;
+     gint weekRow, colNum, previousMonthsInCol, monthOffset;
+     gint start;
+     GDate *startD, *endD;
+     GdkRectangle *rect;
+     gint startWk, endWk;
 
-        if ( monthOfCal > dcal->numMonths ) {
-                return;
-        }
-        colNum = floor(monthOfCal / dcal->monthsPerCol);
-        monthOffset = colNum * dcal->monthsPerCol;
-        previousMonthsInCol = MAX( 0, (monthOfCal % dcal->monthsPerCol) );
+     if (monthOfCal > dcal->numMonths)
+          return;
 
-        startD = g_date_new();
-        endD = g_date_new();
-        // FIXME: clean these up?
+     colNum = floor(monthOfCal / dcal->monthsPerCol);
+     monthOffset = colNum * dcal->monthsPerCol;
+     previousMonthsInCol = MAX(0, (monthOfCal % dcal->monthsPerCol));
 
-        /* Calculate the number of weeks in the column before the month we're
-         * interested in. */
-        weekRow = 0;
-        if ( previousMonthsInCol > 0 ) {
-                g_date_set_dmy( startD, 1,
-                                ((dcal->month - 1 + monthOffset) % 12) + 1,
-                                dcal->year + floor((dcal->month-1+monthOffset)/12) );
-                /* get the week of the top of the column */
-                startWk = g_date_get_sunday_week_of_year( startD );
-                /* get the week of the end of the previous months */
-                *endD = *startD;
-                g_date_add_months( endD, previousMonthsInCol );
-                g_date_subtract_days( endD, 1 );
-                endWk = g_date_get_sunday_week_of_year( endD );
-                if ( endWk < startWk ) {
-                        endWk += g_date_get_sunday_weeks_in_year( g_date_get_year(startD) );
-                }
-                /* determine how many weeks are before the month we're
-                 * interested in. */
-                weekRow = endWk - startWk;
-                if ( g_date_get_weekday(endD) == G_DATE_SATURDAY ) {
-                        weekRow++;
-                }
-        }
+     startD = g_date_new();
+     endD = g_date_new();
+     // FIXME: clean these up?
 
-        g_date_set_dmy( startD, 1,
-                        ((dcal->month - 1 + monthOfCal) % 12) + 1,
-                        dcal->year + floor((dcal->month-1+monthOfCal)/12) );
-        *endD = *startD;
-        g_date_add_months( endD, 1 );
-        g_date_subtract_days( endD, 1 );
-        /* Get the first week. */
-        {
-                start = g_date_get_weekday( startD ) % 7;
-                rect = g_new0( GdkRectangle, 1 );
-                rect->x = dcal->leftPadding
-                        + MINOR_BORDER_SIZE
-                        + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
-                        + dcal->label_width
-                        + (start * day_width(dcal));
-                rect->y = dcal->topPadding
-                        + dcal->dayLabelHeight
-                        + MINOR_BORDER_SIZE
-                        + (weekRow * week_height(dcal) );
-                rect->width = (7 - start) * day_width(dcal);
-                rect->height = week_height(dcal);
-                *outList = g_list_append(*outList, (gpointer)rect );
-                rect = NULL;
-        }
+     /* Calculate the number of weeks in the column before the month we're
+      * interested in. */
+     weekRow = 0;
+     if (previousMonthsInCol > 0)
+     {
+          g_date_set_dmy(startD, 1,
+                         ((dcal->month - 1 + monthOffset) % 12) + 1,
+                         dcal->year + floor((dcal->month-1+monthOffset)/12));
+          /* get the week of the top of the column */
+          startWk = g_date_get_sunday_week_of_year(startD);
+          /* get the week of the end of the previous months */
+          *endD = *startD;
+          g_date_add_months(endD, previousMonthsInCol);
+          g_date_subtract_days(endD, 1);
+          endWk = g_date_get_sunday_week_of_year(endD);
+          if (endWk < startWk)
+          {
+               endWk += g_date_get_sunday_weeks_in_year(g_date_get_year(startD));
+          }
+          /* determine how many weeks are before the month we're
+           * interested in. */
+          weekRow = endWk - startWk;
+          if (g_date_get_weekday(endD) == G_DATE_SATURDAY)
+          {
+               weekRow++;
+          }
+     }
 
-        /* Get the middle weeks. */
-        {
-                gint i, weekStart, weekEnd;
+     g_date_set_dmy(startD, 1,
+                    ((dcal->month - 1 + monthOfCal) % 12) + 1,
+                    dcal->year + floor((dcal->month-1+monthOfCal)/12));
+     *endD = *startD;
+     g_date_add_months(endD, 1);
+     g_date_subtract_days(endD, 1);
+     /* Get the first week. */
+     {
+          start = g_date_get_weekday(startD) % 7;
+          rect = g_new0(GdkRectangle, 1);
+          rect->x = dcal->leftPadding
+               + MINOR_BORDER_SIZE
+               + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
+               + dcal->label_width
+               + (start * day_width(dcal));
+          rect->y = dcal->topPadding
+               + dcal->dayLabelHeight
+               + MINOR_BORDER_SIZE
+               + (weekRow * week_height(dcal));
+          rect->width = (7 - start) * day_width(dcal);
+          rect->height = week_height(dcal);
+          *outList = g_list_append(*outList, (gpointer)rect);
+          rect = NULL;
+     }
 
-                weekStart = g_date_get_sunday_week_of_year(startD)+1;
-                weekEnd = g_date_get_sunday_week_of_year(endD);
-                for ( i=weekStart; i<weekEnd; i++ ) {
-                        rect = g_new0( GdkRectangle, 1 );
-                        rect->x = dcal->leftPadding
-                                + MINOR_BORDER_SIZE
-                                + dcal->label_width
-                                + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
-                        rect->y = dcal->topPadding
-                                + dcal->dayLabelHeight
-                                + MINOR_BORDER_SIZE
-                                + ((weekRow + (i-weekStart) + 1) * week_height(dcal));
-                        rect->width  = week_width(dcal);
-                        rect->height = week_height(dcal);
+     /* Get the middle weeks. */
+     {
+          gint i, weekStart, weekEnd;
 
-                        *outList = g_list_append( *outList, (gpointer)rect );
-                        rect = NULL;
-                }
-        }
+          weekStart = g_date_get_sunday_week_of_year(startD)+1;
+          weekEnd = g_date_get_sunday_week_of_year(endD);
+          for (i=weekStart; i<weekEnd; i++) {
+               rect = g_new0(GdkRectangle, 1);
+               rect->x = dcal->leftPadding
+                    + MINOR_BORDER_SIZE
+                    + dcal->label_width
+                    + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
+               rect->y = dcal->topPadding
+                    + dcal->dayLabelHeight
+                    + MINOR_BORDER_SIZE
+                    + ((weekRow + (i-weekStart) + 1) * week_height(dcal));
+               rect->width  = week_width(dcal);
+               rect->height = week_height(dcal);
+
+               *outList = g_list_append(*outList, (gpointer)rect);
+               rect = NULL;
+          }
+     }
         
-        /* Get the last week. */
-        {
-                rect = g_new0( GdkRectangle, 1 );
-                rect->x = dcal->leftPadding
-                        + MINOR_BORDER_SIZE
-                        + dcal->label_width
-                        + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
-                rect->y = dcal->topPadding
-                        + MINOR_BORDER_SIZE
-                        + dcal->dayLabelHeight
-                        + ((weekRow
-                            + (g_date_get_sunday_week_of_year(endD)
-                               - g_date_get_sunday_week_of_year(startD)))
-                           * week_height(dcal));
-                rect->width = ((g_date_get_weekday(endD) % 7)+1) * day_width(dcal);
-                rect->height = week_height(dcal);
+     /* Get the last week. */
+     {
+          rect = g_new0(GdkRectangle, 1);
+          rect->x = dcal->leftPadding
+               + MINOR_BORDER_SIZE
+               + dcal->label_width
+               + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
+          rect->y = dcal->topPadding
+               + MINOR_BORDER_SIZE
+               + dcal->dayLabelHeight
+               + ((weekRow
+                   + (g_date_get_sunday_week_of_year(endD)
+                      - g_date_get_sunday_week_of_year(startD)))
+                  * week_height(dcal));
+          rect->width = ((g_date_get_weekday(endD) % 7)+1) * day_width(dcal);
+          rect->height = week_height(dcal);
 
-                *outList = g_list_append( *outList, (gpointer)rect );
-                rect = NULL;
-        }
+          *outList = g_list_append(*outList, (gpointer)rect);
+          rect = NULL;
+     }
 }
 
 /* FIXME: make this more like month_coords */
 static void
-doc_coords( GncDenseCal *dcal, int dayOfCal,
-            int *x1, int *y1, int *x2, int *y2 )
+doc_coords(GncDenseCal *dcal, int dayOfCal,
+           int *x1, int *y1, int *x2, int *y2)
 {
-        GDate d;
-        gint docMonth;
-        gint d_week_of_cal, top_of_col_week_of_cal;
-        gint colNum, dayCol, weekRow;
+     GDate d;
+     gint docMonth;
+     gint d_week_of_cal, top_of_col_week_of_cal;
+     gint colNum, dayCol, weekRow;
 
-        /* FIXME: add range checks */
-        g_date_set_dmy( &d, 1, dcal->month, dcal->year );
-        g_date_add_days( &d, dayOfCal );
-        docMonth = g_date_get_month( &d );
-        if ( g_date_get_year( &d ) != dcal->year ) {
-                docMonth += 12;
-        }
-        colNum  = floor( (float)(docMonth - dcal->month) / (float)dcal->monthsPerCol );
-        dayCol  = g_date_get_weekday( &d ) % 7;
-        d_week_of_cal = g_date_get_sunday_week_of_year( &d );
-        g_date_set_dmy( &d, 1, dcal->month, dcal->year );
-        g_date_add_months( &d, (colNum * dcal->monthsPerCol) );
-        top_of_col_week_of_cal = g_date_get_sunday_week_of_year( &d );
-        if ( d_week_of_cal < top_of_col_week_of_cal ) {
-                d_week_of_cal +=
-                        g_date_get_sunday_weeks_in_year( dcal->year );
-        }
-        weekRow = d_week_of_cal - top_of_col_week_of_cal;
+     /* FIXME: add range checks */
+     g_date_set_dmy(&d, 1, dcal->month, dcal->year);
+     g_date_add_days(&d, dayOfCal);
+     docMonth = g_date_get_month(&d);
+     if (g_date_get_year(&d) != dcal->year)
+     {
+          docMonth += 12;
+     }
+     colNum  = floor((float)(docMonth - dcal->month) / (float)dcal->monthsPerCol);
+     dayCol  = g_date_get_weekday(&d) % 7;
+     d_week_of_cal = g_date_get_sunday_week_of_year(&d);
+     g_date_set_dmy(&d, 1, dcal->month, dcal->year);
+     g_date_add_months(&d, (colNum * dcal->monthsPerCol));
+     top_of_col_week_of_cal = g_date_get_sunday_week_of_year(&d);
+     if (d_week_of_cal < top_of_col_week_of_cal)
+     {
+          d_week_of_cal += g_date_get_sunday_weeks_in_year(dcal->year);
+     }
+     weekRow = d_week_of_cal - top_of_col_week_of_cal;
 
-        /* top-left corner */
-        /* FIXME: this has the math to make the mark-cells come out right,
-         * which it shouldn't. */
-        *x1 = dcal->leftPadding
-                + MINOR_BORDER_SIZE
-                + dcal->label_width
-                + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
-                + (dayCol * day_width(dcal))
-                + (day_width(dcal)/4);
-        *y1 = dcal->topPadding
-                + MINOR_BORDER_SIZE
-                + dcal->dayLabelHeight
-                + (weekRow * week_height(dcal))
-                + (day_height(dcal)/4);
+     /* top-left corner */
+     /* FIXME: this has the math to make the mark-cells come out right,
+      * which it shouldn't. */
+     *x1 = dcal->leftPadding
+          + MINOR_BORDER_SIZE
+          + dcal->label_width
+          + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
+          + (dayCol * day_width(dcal))
+          + (day_width(dcal)/4);
+     *y1 = dcal->topPadding
+          + MINOR_BORDER_SIZE
+          + dcal->dayLabelHeight
+          + (weekRow * week_height(dcal))
+          + (day_height(dcal)/4);
 
-        *x2 = *x1 + (day_width(dcal)/2);
-        *y2 = *y1 + (day_height(dcal)/2);
+     *x2 = *x1 + (day_width(dcal)/2);
+     *y2 = *y1 + (day_height(dcal)/2);
 }
 
 /**
@@ -1429,211 +1426,325 @@
  * '-1' if invalid.
  **/
 static gint
-wheres_this( GncDenseCal *dcal, int x, int y )
+wheres_this(GncDenseCal *dcal, int x, int y)
 {
-        gint colNum, weekRow, dayCol, dayOfCal;
-        GDate d, startD;
+     gint colNum, weekRow, dayCol, dayOfCal;
+     GDate d, startD;
 
-        x -= dcal->leftPadding;
-        y -= dcal->topPadding;
+     x -= dcal->leftPadding;
+     y -= dcal->topPadding;
 
-        if ( (x < 0) || (y < 0) ) {
-	    /* DEBUG( "x(%d) or y(%d) < 0", x, y ); */
-                return -1;
-        }
-        if ( (x >= GTK_WIDGET(dcal)->allocation.width)
-             || (y >= GTK_WIDGET(dcal)->allocation.height) ) {
-	    /*DEBUG( "x(%d) > allocation.width(%d) or y(%d) > allocation->height(%d)",
-	      x, y,
-	      GTK_WIDGET(dcal)->allocation.width,
-	      GTK_WIDGET(dcal)->allocation.height );*/
-                return -1;
-        }
+     if ((x < 0) || (y < 0))
+     {
+          /* DEBUG("x(%d) or y(%d) < 0", x, y); */
+          return -1;
+     }
+     if ((x >= GTK_WIDGET(dcal)->allocation.width)
+         || (y >= GTK_WIDGET(dcal)->allocation.height))
+     {
+          /*DEBUG("x(%d) > allocation.width(%d) or y(%d) > allocation->height(%d)",
+            x, y,
+            GTK_WIDGET(dcal)->allocation.width,
+            GTK_WIDGET(dcal)->allocation.height);*/
+          return -1;
+     }
 
-        /* "outside of displayed table" check */
-        if ( x >= (num_cols(dcal) * (col_width(dcal) + COL_BORDER_SIZE)) ) {
-	    /*DEBUG( "x(%d) > ( col_width(%d) * num_cols(%d) )",
-	      x, col_width(dcal), num_cols(dcal) );*/
-                return -1;
-        }
-        if ( y >= col_height(dcal) ) {
-	    /*DEBUG( "y(%d) > col_height(%d)",
-	      y, col_height(dcal) );*/
-                return -1;
-        }
+     /* "outside of displayed table" check */
+     if (x >= (num_cols(dcal) * (col_width(dcal) + COL_BORDER_SIZE)))
+     {
+          /*DEBUG("x(%d) > (col_width(%d) * num_cols(%d))",
+            x, col_width(dcal), num_cols(dcal));*/
+          return -1;
+     }
+     if (y >= col_height(dcal))
+     {
+          /*DEBUG("y(%d) > col_height(%d)",
+            y, col_height(dcal));*/
+          return -1;
+     }
         
-        /* coords -> year-relative-values */
-        colNum = floor( x / (col_width(dcal)+COL_BORDER_SIZE) );
+     /* coords -> year-relative-values */
+     colNum = floor(x / (col_width(dcal)+COL_BORDER_SIZE));
+     
+     x %= (col_width(dcal)+COL_BORDER_SIZE);
+     x -= dcal->label_width;
+     if (x < 0)
+     {
+          /* DEBUG("X is over the label.");*/
+          return -1;
+     }
+     if (x >= day_width(dcal) * 7)
+     {
+          /*DEBUG("X is in the col_border space.");*/
+          return -1;
+     }
 
-        x %= (col_width(dcal)+COL_BORDER_SIZE);
-        x -= dcal->label_width;
-        if ( x < 0 ) {
-	    /* DEBUG( "X is over the label." );*/
-	    return -1;
-        }
-        if ( x >= day_width(dcal) * 7 ) {
-	    /*DEBUG( "X is in the col_border space." );*/
-	    return -1;
-        }
+     y -= dcal->dayLabelHeight;
+     if (y < 0)
+     {
+          /*DEBUG("Y is over the label.");*/
+          return -1;
+     }
 
-        y -= dcal->dayLabelHeight;
-        if ( y < 0 ) {
-	    /*DEBUG( "Y is over the label." );*/
-	    return -1;
-        }
+     dayCol = floor((float)x / (float)day_width(dcal));
+     weekRow = floor((float)y / (float)week_height(dcal));
 
-        dayCol = floor( (float)x / (float)day_width(dcal) );
-        weekRow = floor( (float)y / (float)week_height(dcal) );
+     g_date_set_dmy(&startD, 1, dcal->month, dcal->year);
+     d = startD;
+     g_date_add_months(&d, (colNum * dcal->monthsPerCol));
+     dayCol -= (g_date_get_weekday(&d) % 7);
+     if (weekRow == 0)
+     {
+          if (dayCol < 0)
+          {
+               /*DEBUG("Before the beginning of the first month.");*/
+               return -1;
+          }
+     }
+     g_date_add_days(&d, dayCol + (weekRow * 7));
 
-        g_date_set_dmy( &startD, 1, dcal->month, dcal->year );
-        d = startD;
-        g_date_add_months( &d, (colNum * dcal->monthsPerCol) );
-        dayCol -= (g_date_get_weekday(&d) % 7);
-        if ( weekRow == 0 ) {
-                if ( dayCol < 0 ) {
-		    /*DEBUG( "Before the beginning of the first month." );*/
-                        return -1;
-                }
-        }
-        g_date_add_days( &d, dayCol + (weekRow * 7) );
+     /* Check to make sure we're within the column's displayed range. */
+     {
+          GDate ccd;
+          g_date_set_dmy(&ccd, 1, dcal->month, dcal->year);
+          g_date_add_months(&ccd, (colNum+1) * dcal->monthsPerCol);
+          if (g_date_get_julian(&d) >= g_date_get_julian(&ccd))
+          {
+               /*DEBUG("%d outside of column range [%d]",
+                 g_date_get_julian(&d), g_date_get_julian(&ccd));*/
+               return -1;
+          }
+     }
 
-        /* Check to make sure we're within the column's displayed range. */
-        {
-                GDate ccd;
-                g_date_set_dmy( &ccd, 1, dcal->month, dcal->year );
-                g_date_add_months( &ccd, (colNum+1) * dcal->monthsPerCol );
-                if ( g_date_get_julian(&d) >= g_date_get_julian(&ccd) ) {
-		    /*DEBUG( "%d outside of column range [%d]",
-		      g_date_get_julian(&d), g_date_get_julian(&ccd) );*/
-                        return -1;
-                }
-        }
+     dayOfCal = g_date_get_julian(&d) - g_date_get_julian(&startD);
 
-        dayOfCal = g_date_get_julian(&d) - g_date_get_julian(&startD);
+     /* one more check before returning... */
+     g_date_subtract_months(&d, dcal->numMonths);
+     if (g_date_get_julian(&d) >= g_date_get_julian(&startD))
+     {
+          /* we're past the end of the displayed calendar, thus -1 */
+          DEBUG("%d >= %d", g_date_get_julian(&d), g_date_get_julian(&startD));
+          return -1;
+     }
 
-        /* one more check before returning... */
-        g_date_subtract_months( &d, dcal->numMonths );
-        if ( g_date_get_julian(&d) >= g_date_get_julian(&startD) ) {
-                /* we're past the end of the displayed calendar, thus -1 */
-                DEBUG( "%d >= %d",
-                       g_date_get_julian( &d ), g_date_get_julian( &startD ) );
-                return -1;
-        }
-
-        return dayOfCal;
+     return dayOfCal;
 }
 
 static gint
-gdc_get_doc_offset( GncDenseCal *dcal, GDate *d )
+gdc_get_doc_offset(GncDenseCal *dcal, GDate *d)
 {
-        gint toRet;
-        /* soc == start-of-calendar */
-        GDate soc;
+     gint toRet;
+     /* soc == start-of-calendar */
+     GDate soc;
 
-        g_date_set_dmy( &soc, 1, dcal->month, dcal->year );
-        /* ensure not before calendar start. */
-        if ( g_date_get_julian(d) < g_date_get_julian(&soc) ) {
-                return -1;
-        }
-        /* do computation here, since we're going to change the
-         * start-of-calendar date. */
-        toRet = g_date_get_julian(d) - g_date_get_julian(&soc);
-        /* ensure not after end of visible calendar. */
-        g_date_add_months( &soc, dcal->numMonths );
-        if ( g_date_get_julian(d) > g_date_get_julian(&soc) ) {
-                return -1;
-        }
-        /* return pre-computed value. */
-        return toRet;
+     g_date_clear(&soc, 1);
+     g_date_set_dmy(&soc, 1, dcal->month, dcal->year);
+     /* ensure not before calendar start. */
+     if (g_date_get_julian(d) < g_date_get_julian(&soc))
+          return -1;
+     /* do computation here, since we're going to change the
+      * start-of-calendar date. */
+     toRet = g_date_get_julian(d) - g_date_get_julian(&soc);
+     /* ensure not after end of visible calendar. */
+     g_date_add_months(&soc, dcal->numMonths);
+     if (g_date_get_julian(d) > g_date_get_julian(&soc))
+          return -1;
+     /* return pre-computed value. */
+     return toRet;
 }
 
+static void
+gdc_add_tag_markings(GncDenseCal *cal, guint tag)
+{
+     gchar *name, *info;
+     gint num_marks, idx;
+     GDate **dates;
+
+     // copy the values into the old marking function.
+     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++)
+     {
+          dates[idx] = g_date_new();
+          gnc_dense_cal_model_get_instance(cal->model, tag, idx, dates[idx]);
+     }
+
+     gdc_mark_add(cal, tag, name, info, num_marks, dates);
+
+     for (idx = 0; idx < num_marks; idx++)
+     {
+          g_date_free(dates[idx]);
+     }
+     g_free(dates);
+}
+
+static void
+gdc_add_markings(GncDenseCal *cal)
+{
+     GList *tags;
+     tags = gnc_dense_cal_model_get_contained(cal->model);
+     for (; tags != NULL; tags = tags->next)
+     {
+          guint tag = GPOINTER_TO_UINT(tags->data);
+          gdc_add_tag_markings(cal, tag);
+     }
+}
+
+static void
+gdc_remove_markings(GncDenseCal *cal)
+{
+     GList *tags;
+     tags = gnc_dense_cal_model_get_contained(cal->model);
+     for (; tags != NULL; tags = tags->next)
+     {
+          guint tag = GPOINTER_TO_UINT(tags->data);
+          gdc_mark_remove(cal, tag);
+     }
+}
+
+static void
+gdc_model_added_cb(GncDenseCalModel *model, guint added_tag, gpointer user_data)
+{
+     GncDenseCal *cal = GNC_DENSE_CAL(user_data);
+     printf("gdc_model_added_cb update\n");
+     gdc_add_tag_markings(cal, added_tag);
+} 
+
+static void
+gdc_model_update_cb(GncDenseCalModel *model, guint update_tag, gpointer user_data)
+{
+     GncDenseCal *cal = GNC_DENSE_CAL(user_data);
+     printf("gdc_model_update_cb update for tag [%d]\n", update_tag);
+     gdc_mark_remove(cal, update_tag);
+     gdc_add_tag_markings(cal, update_tag);
+}
+
+static void
+gdc_model_removing_cb(GncDenseCalModel *model, guint remove_tag, gpointer user_data)
+{
+     GncDenseCal *cal = GNC_DENSE_CAL(user_data);
+     printf("gdc_model_removing_cb update [%d]\n", remove_tag);
+     gdc_mark_remove(cal, remove_tag);
+}
+
+void
+gnc_dense_cal_set_model(GncDenseCal *cal, GncDenseCalModel *model)
+{
+     if (cal->model != NULL)
+     {
+          gdc_remove_markings(cal);
+          g_object_unref(G_OBJECT(cal->model));
+          cal->model = NULL;
+     }
+     cal->model = 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);
+
+     gdc_add_markings(cal);
+}
+
 /**
  * Marks the given array of GDate*s on the calendar with the given name.
  **/
-guint
-gnc_dense_cal_mark( GncDenseCal *dcal,
-                    guint size, GDate **dateArray,
-                    gchar *name, gchar *info )
+static void
+gdc_mark_add(GncDenseCal *dcal,
+             guint tag,
+             gchar *name,
+             gchar *info,
+             guint size,
+             GDate **dateArray)
 {
-        guint i;
-	gint doc;
-        gdc_mark_data *newMark;
-        GDate *d;
+     guint i;
+     gint doc;
+     gdc_mark_data *newMark;
+     GDate *d;
 
-        if ( size == 0 ) {
-                PERR( "0 size not allowed\n" );
-                return -1;
-        }
+     if (size == 0)
+     {
+          PERR("0 size not allowed\n");
+          return;
+     }
 
-        newMark = g_new0( gdc_mark_data, 1 );
-        newMark->name = NULL;
-        if ( name ) {
-                newMark->name = g_strdup(name);
-        }
-        newMark->info = NULL;
-        if ( info ) {
-                newMark->info = g_strdup(info);
-        }
-        newMark->tag = dcal->lastMarkTag++;
-        newMark->ourMarks = NULL;
+     newMark = g_new0(gdc_mark_data, 1);
+     newMark->name = NULL;
+     if (name)
+          newMark->name = g_strdup(name);
+     newMark->info = NULL;
+     if (info)
+          newMark->info = g_strdup(info);
+     newMark->tag = tag;
+     newMark->ourMarks = NULL;
+     printf("saving mark with tag [%d]\n", newMark->tag);
 
-        for ( i=0; i<size; i++ ) {
-                d = dateArray[i];
-                doc = gdc_get_doc_offset( dcal, d );
-                if ( doc < 0 ) {
-                        continue;
-                }
-                if ( doc >= dcal->numMarks ) {
-                        /* It's not going to get any better, so just
-                         * stop processing. */
-                        break;
-                }
-		dcal->marks[doc] = g_list_append( dcal->marks[doc], newMark );
-                newMark->ourMarks = g_list_append( newMark->ourMarks,
-                                                   GINT_TO_POINTER(doc) );
-        }
-        dcal->markData = g_list_append( dcal->markData, (gpointer)newMark );
-        gnc_dense_cal_draw_to_buffer( dcal );
-        gtk_widget_queue_draw( GTK_WIDGET( dcal ) );
-        return newMark->tag;
+     for (i=0; i<size; i++)
+     {
+          d = dateArray[i];
+          doc = gdc_get_doc_offset(dcal, d);
+          if (doc < 0)
+               continue;
+          if (doc >= dcal->numMarks)
+          {
+               /* It's not going to get any better, so just
+                * stop processing. */
+               break;
+          }
+          dcal->marks[doc] = g_list_append(dcal->marks[doc], newMark);
+          newMark->ourMarks = g_list_append(newMark->ourMarks,
+                                            GINT_TO_POINTER(doc));
+     }
+     dcal->markData = g_list_append(dcal->markData, (gpointer)newMark);
+     gnc_dense_cal_draw_to_buffer(dcal);
+     gtk_widget_queue_draw(GTK_WIDGET(dcal));
 }
 
-void
-gnc_dense_cal_mark_remove( GncDenseCal *dcal, guint markToRemove )
+static void
+gdc_mark_remove(GncDenseCal *dcal, guint mark_to_remove)
 {
-        GList *l, *calMarkL;
-        gint doc;
-        gdc_mark_data *gdcmd;
+     GList *iter, *calendar_marks;
+     gint day_of_cal;
+     gdc_mark_data *mark_data;
 
-        /* Ignore non-realistic marks */
-        if ( (gint)markToRemove == -1 ) {
-                DEBUG( "markToRemove = -1" );
-                return;
-        }
+     /* Ignore non-realistic marks */
+     if ((gint)mark_to_remove == -1)
+     {
+          DEBUG("mark_to_remove = -1");
+          return;
+     }
 
-        gdcmd = NULL;
-        for ( l = dcal->markData; l; l=l->next ) {
-                gdcmd = (gdc_mark_data*)l->data;
-                if ( gdcmd->tag == markToRemove )
-                        break;
-        }
-        g_assert( l != NULL );
-        if ( l == NULL ) {
-                DEBUG( "l == null" );
-                return;
-        }
-        g_assert( gdcmd != NULL );
+     mark_data = NULL;
+     for (iter = dcal->markData; iter != NULL; iter = iter->next)
+     {
+          mark_data = (gdc_mark_data*)iter->data;
+          if (mark_data->tag == mark_to_remove)
+               break;
+     }
+     if (iter == NULL)
+     {
+          DEBUG("couldn't find tag [%d]", mark_to_remove);
+          return;
+     }
+     if (mark_data == NULL)
+     {
+          DEBUG("mark_data == null");
+          return;
+     }
 
-        l = NULL;
-        for ( calMarkL = gdcmd->ourMarks;
-              calMarkL;
-              calMarkL = calMarkL->next ) {
-                doc = GPOINTER_TO_INT(calMarkL->data);
-                dcal->marks[doc] = g_list_remove( dcal->marks[doc], gdcmd );
-        }
-        g_list_free( gdcmd->ourMarks );
-        dcal->markData = g_list_remove( dcal->markData, gdcmd );
-        g_free( gdcmd );
-        gnc_dense_cal_draw_to_buffer( dcal );
-        gtk_widget_queue_draw( GTK_WIDGET(dcal) );
+     for (calendar_marks = mark_data->ourMarks; calendar_marks != NULL; calendar_marks = calendar_marks->next)
+     {
+          day_of_cal = GPOINTER_TO_INT(calendar_marks->data);
+          dcal->marks[day_of_cal] = g_list_remove(dcal->marks[day_of_cal], mark_data);
+     }
+     g_list_free(mark_data->ourMarks);
+     dcal->markData = g_list_remove(dcal->markData, mark_data);
+     g_free(mark_data);
+     gnc_dense_cal_draw_to_buffer(dcal);
+     gtk_widget_queue_draw(GTK_WIDGET(dcal));
 }

Modified: gnucash/trunk/src/gnome-utils/gnc-dense-cal.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-dense-cal.h	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome-utils/gnc-dense-cal.h	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,14 +1,11 @@
-#ifndef _DENSECAL_H_
-#define _DENSECAL_H_
-
 /********************************************************************\
  * gnc-dense-cal.h : a custom densely-dispalyed calendar widget     *
- * Copyright (C) 2002 Joshua Sled <jsled at asynchronous.org>          *
+ * Copyright (C) 2002,2006 Joshua Sled <jsled at asynchronous.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.              *
+ * published by the Free Software Foundation, under version 2 of    *
+ * the License.                                                     *
  *                                                                  *
  * This program is distributed in the hope that it will be useful,  *
  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
@@ -23,14 +20,17 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
-#include <gdk/gdk.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkwidget.h>
+#ifndef _GNC_DENSE_CAL_H
+#define _GNC_DENSE_CAL_H
+
+#include "config.h"
+
+#include <FreqSpec.h>
 #include <glib.h>
+#include "gnc-dense-cal-model.h"
+#include <gtk/gtk.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
 
 #define GNC_TYPE_DENSE_CAL          (gnc_dense_cal_get_type ()) 
 #define GNC_DENSE_CAL(obj)          GTK_CHECK_CAST (obj, gnc_dense_cal_get_type (), GncDenseCal)
@@ -40,92 +40,97 @@
 typedef struct _GncDenseCal        GncDenseCal;
 typedef struct _GncDenseCalClass   GncDenseCalClass;
 
-typedef struct _gdc_month_coords {
-        gint x, y;
+typedef struct _gdc_month_coords
+{
+     gint x, y;
 } gdc_month_coords;
 
-enum GDC_COLORS {
-  MONTH_THIS = 0,
-  MONTH_THAT,
-  MAX_COLORS
+enum GDC_COLORS
+{
+     MONTH_THIS = 0,
+     MONTH_THAT,
+     MAX_COLORS
 };
 
 struct _GncDenseCal
 {
-        GtkWidget widget;
+     GtkWidget widget;
 
-        GdkPixmap *drawbuf;
+     GdkPixmap *drawbuf;
 
-        gboolean initialized;
+     gboolean initialized;
 
-        gboolean showPopup;
-        GtkWindow *transPopup;
+     gboolean showPopup;
+     GtkWindow *transPopup;
 
-        gint min_x_scale;
-        gint min_y_scale;
+     gint min_x_scale;
+     gint min_y_scale;
 
-        gint x_scale;
-        gint y_scale;
+     gint x_scale;
+     gint y_scale;
 
-        gint numMonths;
-        gint monthsPerCol;
-        gint num_weeks; /* computed */
+     gint numMonths;
+     gint monthsPerCol;
+     gint num_weeks; /* computed */
 
-        GDateMonth month;
-        gint year;
-        gint firstOfMonthOffset;
+     GDateMonth month;
+     gint year;
+     gint firstOfMonthOffset;
 
-        gint leftPadding;
-        gint topPadding;
+     gint leftPadding;
+     gint topPadding;
 
-        gboolean needInitMonthLabels;
-        gdc_month_coords monthPositions[12];
-        GdkFont *monthLabelFont;
-        GdkFont *dayLabelFont;
-        GdkPixmap *monthLabels[12];
+     gboolean needInitMonthLabels;
+     gdc_month_coords monthPositions[12];
+     GdkFont *monthLabelFont;
+     GdkFont *dayLabelFont;
+     GdkPixmap *monthLabels[12];
 
-        GdkColor weekColors[MAX_COLORS];
+     GdkColor weekColors[MAX_COLORS];
 
-        guint label_lbearing;
-        guint label_ascent;
-        guint label_width;
-        guint label_height;
-        guint dayLabelHeight;
+     guint label_lbearing;
+     guint label_ascent;
+     guint label_width;
+     guint label_height;
+     guint dayLabelHeight;
 
-        guint lastMarkTag;
+     GncDenseCalModel *model;
 
-        /**
-         * A GList of gdc_mark_data structs, one for each active/valid markTag.
-         **/
-        GList *markData;
-        int numMarks;
-        /* array of GList*s of per-cell markings. */
-        GList **marks;
+     guint lastMarkTag;
 
-	int disposed; /* private */
+     /**
+      * A GList of gdc_mark_data structs, one for each active/valid markTag.
+      **/
+     GList *markData;
+     int numMarks;
+     /* array of GList*s of per-cell markings. */
+     GList **marks;
+
+     int disposed; /* private */
 };
 
 struct _GncDenseCalClass
 {
-        GtkWidgetClass parent_class;
-        void (*marks_lost_cb)( GncDenseCal *dcal, gpointer user_data );
+     GtkWidgetClass parent_class;
 };
 
-typedef struct _gdc_mark_data {
-        gchar *name;
-        gchar *info;
-        guint tag;
-        /* GdkColor markStyle; */
-        /**
-         * A GList of the dcal->marks indexes containing this mark.
-         **/
-        GList *ourMarks;
+typedef struct _gdc_mark_data
+{
+     gchar *name;
+     gchar *info;
+     guint tag;
+     /**
+      * A GList of the dcal->marks indexes containing this mark.
+      **/
+     GList *ourMarks;
 } gdc_mark_data;
 
 GtkWidget*     gnc_dense_cal_new                    (void);
+GtkWidget*     gnc_dense_cal_new_with_model         (GncDenseCalModel *model);
 GType          gnc_dense_cal_get_type               (void);
 
-void gnc_dense_cal_set_month( GncDenseCal *dcal, GDateMonth mon );
+void gnc_dense_cal_set_model(GncDenseCal *cal, GncDenseCalModel *model);
+void gnc_dense_cal_set_month(GncDenseCal *dcal, GDateMonth mon);
 /**
  * @param year Julian year: 2000 = 2000AD.
  **/
@@ -137,13 +142,6 @@
 GDateMonth gnc_dense_cal_get_month( GncDenseCal *dcal );
 GDateYear gnc_dense_cal_get_year( GncDenseCal *dcal );
 
-guint gnc_dense_cal_mark( GncDenseCal *dcal,
-                          guint size, GDate **daysArray,
-                          gchar *name, gchar *info );
-void gnc_dense_cal_mark_remove( GncDenseCal *dcal, guint markToRemove );
+G_END_DECLS
 
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _DENSECAL_H_ */
+#endif /* _GNC_DENSE_CAL_H */

Modified: gnucash/trunk/src/gnome-utils/gnc-frequency.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-frequency.c	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome-utils/gnc-frequency.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -638,12 +638,12 @@
         gint tmpInt;
         int i;
         GDate gd;
-        time_t tmpTimeT;
+        time_t start_tt;
 
-        tmpTimeT = gnc_date_edit_get_date( gf->startDate );
+        start_tt = gnc_date_edit_get_date( gf->startDate );
         if ( NULL != outDate ) 
         {
-                g_date_set_time_t( outDate, tmpTimeT );
+                g_date_set_time_t( outDate, start_tt );
         }
 
         if (NULL == fs) return;
@@ -656,7 +656,7 @@
         gnc_suspend_gui_refresh();
 
         g_date_clear (&gd, 1);
-        g_date_set_time_t( &gd, tmpTimeT );
+        g_date_set_time_t( &gd, start_tt );
 
         /*uift = xaccFreqSpecGetUIType( fs );*/
         uift = PAGES[page].uiFTVal;
@@ -667,6 +667,7 @@
                 /* hmmm... shouldn't really be allowed. */
                 break;
         case UIFREQ_ONCE:
+                xaccFreqSpecSetOnceDate(fs, &gd);
                 xaccFreqSpecSetUIType( fs, uift );
                 break;
         case UIFREQ_DAILY:
@@ -771,8 +772,8 @@
                 o = glade_xml_get_widget( gf->gxml, "semimonthly_second" );
                 day = gtk_combo_box_get_active( GTK_COMBO_BOX(o) )+1;
                 tmpFS = xaccFreqSpecMalloc(gnc_get_current_book ());
-                tmpTimeT = gnc_date_edit_get_date( gf->startDate );
-                g_date_set_time_t( &gd, tmpTimeT );
+                start_tt = gnc_date_edit_get_date( gf->startDate );
+                g_date_set_time_t( &gd, start_tt );
                 g_date_to_struct_tm( &gd, &stm);
                 if ( day >= stm.tm_mday ) {
                         /* next month */
@@ -788,15 +789,19 @@
         }
         case UIFREQ_MONTHLY:
         {
-                struct tm stm;
                 o = glade_xml_get_widget( gf->gxml, "monthly_spin" );
                 tmpInt = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(o));
-                g_date_to_struct_tm( &gd, &stm);
 
                 o = glade_xml_get_widget( gf->gxml, "monthly_day" );
                 day = gtk_combo_box_get_active( GTK_COMBO_BOX(o) ) + 1;
-                stm.tm_mday = day;
-                g_date_set_time_t( &gd, mktime( &stm ) );
+                g_date_set_time_t(&gd, time(NULL));
+                g_date_set_month(&gd, 1);
+                g_date_set_day(&gd, day);
+                {
+                     gchar buf[128];
+                     g_date_strftime(buf, 127, "%c", &gd);
+                     printf("monthly date [%s]\n", buf);
+                }
                 xaccFreqSpecSetMonthly( fs, &gd, tmpInt );
                 xaccFreqSpecSetUIType( fs, uift );
                 break;

Copied: gnucash/trunk/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c)

Copied: gnucash/trunk/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h)


Property changes on: gnucash/trunk/src/gnome-utils/test
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
.deps
.libs
test-link-module
test-gnc-dialog
test-gnc-recurrence
semantic.cache
TAGS
*.exe

   + Makefile
Makefile.in
.deps
.libs
test-link-module
test-gnc-dialog
test-gnc-recurrence
test-sx
semantic.cache
TAGS
*.exe


Modified: gnucash/trunk/src/gnome-utils/test/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome-utils/test/Makefile.am	2007-01-19 11:49:26 UTC (rev 15398)
+++ gnucash/trunk/src/gnome-utils/test/Makefile.am	2007-01-19 23:45:45 UTC (rev 15399)
@@ -1,5 +1,5 @@
 TESTS =  \
-  test-link-module test-load-module
+  test-link-module test-load-module test-sx
 
 # The following tests are nice, but have absolutely no place in an
 # automated testing system.
@@ -26,29 +26,30 @@
   $(shell ${top_srcdir}/src/gnc-test-env --no-exports ${GNC_TEST_DEPS})
 
 check_PROGRAMS = \
-  test-link-module test-gnc-recurrence test-gnc-dialog
+  test-link-module test-gnc-recurrence test-gnc-dialog test-sx
 
 INCLUDES= \
   -I${top_srcdir}/src \
   -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/engine/test-core \
   -I${top_srcdir}/src/gnome-utils \
   -I${top_srcdir}/src/gnc-module \
   -I${top_srcdir}/src/app-utils \
+  -I${top_srcdir}/src/test-core \
   ${GLIB_CFLAGS} ${GUILE_INCS} ${GNOME_CFLAGS} ${GLADE_CFLAGS} ${QOF_CFLAGS}
 
-test_gnc_recurrence_SOURCES=test-gnc-recurrence.c
-test_gnc_recurrence_LDADD = ${GNOME_LIBS} \
+LDADD = \
+  ${GNOME_LIBS} \
   ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
   ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
-  ${top_builddir}/src/engine/libgncmod-engine.la
+  ${top_builddir}/src/engine/libgncmod-engine.la \
+  ${top_builddir}/src/engine/test-core/libgncmod-test-engine.la \
+  ${top_builddir}/src/test-core/libgncmod-test.la
 
-test_gnc_dialog_LDADD = ${GNOME_LIBS} \
-  ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
-  ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
-  ${top_builddir}/src/engine/libgncmod-engine.la
+test_gnc_recurrence_SOURCES=test-gnc-recurrence.c
 
 test_link_module_SOURCES=test-link-module.c
-test_link_module_LDADD= \
+test_link_module_LDADD = \
   ${GUILE_LIBS} \
   ${top_builddir}/src/gnc-module/libgnc-module.la
 

Copied: gnucash/trunk/src/gnome-utils/test/test-sx.c (from rev 15384, gnucash/branches/sx-cleanup/src/gnome-utils/test/test-sx.c)
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome-utils/test/test-sx.c	2007-01-15 01:57:07 UTC (rev 15384)
+++ gnucash/trunk/src/gnome-utils/test/test-sx.c	2007-01-19 23:45:45 UTC (rev 15399)
@@ -0,0 +1,82 @@
+#include "config.h"
+#include <glib.h>
+#include "qof.h"
+#include "gnc-engine.h"
+#include "gnc-sx-instance-model.h"
+#include "gnc-sx-instance-dense-cal-adapter.h"
+#include "gnc-dense-cal.h"
+#include "gnc-dense-cal-model.h"
+
+#include "test-stuff.h"
+#include "test-engine-stuff.h"
+
+static void
+_removing(GObject *obj, SchedXaction *removing, gpointer unused_user_data)
+{
+     gnc_sx_instance_model_remove_sx_instances(GNC_SX_INSTANCE_MODEL(obj), removing);
+}
+
+static void
+setup_default_handlers(GncSxInstanceModel *model)
+{
+     g_signal_connect(model, "removing", (GCallback)_removing, NULL);
+}
+
+static void
+test()
+{
+     GDate *start, *end;
+     GncSxInstanceModel *model;
+     GncSxInstanceDenseCalAdapter *dense_cal_model;
+     GncDenseCal *cal;
+     SchedXaction *foo, *bar;
+
+     start = g_date_new();
+     g_date_clear(start, 1);
+     g_date_set_time_t(start, time(NULL));
+
+     end = g_date_new();
+     g_date_clear(end, 1);
+     g_date_set_time_t(end, time(NULL));
+     g_date_add_years(end, 1);
+     
+     foo = add_daily_sx("foo", start, NULL, NULL);
+
+     model = gnc_sx_get_instances(end);
+     setup_default_handlers(model);
+
+     do_test(g_list_length(model->sx_instance_list) == 1, "1 instances");
+
+     dense_cal_model = gnc_sx_instance_dense_cal_adapter_new(model);
+     cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(dense_cal_model)));
+     // gobject-2.10: g_object_ref_sink(cal);
+     g_object_ref(G_OBJECT(cal));
+     gtk_object_sink(GTK_OBJECT(cal));
+
+     bar = add_daily_sx("bar", start, NULL, NULL);
+     do_test(g_list_length(model->sx_instance_list) == 2, "2 instances");
+
+     remove_sx(foo);
+
+     do_test(g_list_length(model->sx_instance_list) == 1, "1 instance");
+
+     g_object_unref(cal);
+     success("freed calendar");
+     g_object_unref(dense_cal_model);
+     success("freed dense-cal model");
+     g_object_unref(model);
+     success("freed instances");
+}
+
+int
+main(int argc, char **argv)
+{
+     g_type_init();
+     gnc_engine_init(argc, argv);
+     gtk_init(&argc, &argv);
+
+     test();
+
+     print_test_results();
+     exit(get_rv());
+}



More information about the gnucash-changes mailing list