r14521 - gnucash/branches/sx-cleanup - Move SX list from GList to a QofEntity; add SX list mutation events; instance-model reflects SX list mutation; move SX editor to new file.

Joshua Sled jsled at cvs.gnucash.org
Sun Jul 16 17:35:50 EDT 2006


Author: jsled
Date: 2006-07-16 17:35:45 -0400 (Sun, 16 Jul 2006)
New Revision: 14521
Trac: http://svn.gnucash.org/trac/changeset/14521

Added:
   gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c
   gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.h
Removed:
   gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c
   gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h
Modified:
   gnucash/branches/sx-cleanup/ChangeLog
   gnucash/branches/sx-cleanup/src/backend/file/io-gncxml-v2.c
   gnucash/branches/sx-cleanup/src/doc/sx.rst
   gnucash/branches/sx-cleanup/src/engine/SX-book-p.h
   gnucash/branches/sx-cleanup/src/engine/SX-book.c
   gnucash/branches/sx-cleanup/src/engine/SX-book.h
   gnucash/branches/sx-cleanup/src/engine/gnc-engine.h
   gnucash/branches/sx-cleanup/src/gnome/Makefile.am
   gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c
   gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c
   gnucash/branches/sx-cleanup/src/gnome/druid-loan.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c
   gnucash/branches/sx-cleanup/src/gnome/gnc-split-reg.c
   gnucash/branches/sx-cleanup/src/gnome/gw-gnc-spec.scm
   gnucash/branches/sx-cleanup/src/gnome/top-level.c
Log:
Move SX list from GList to a QofEntity; add SX list mutation events; instance-model reflects SX list mutation; move SX editor to new file.

	* 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.


Modified: gnucash/branches/sx-cleanup/ChangeLog
===================================================================
--- gnucash/branches/sx-cleanup/ChangeLog	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/ChangeLog	2006-07-16 21:35:45 UTC (rev 14521)
@@ -1,3 +1,24 @@
+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-15  Joshua Sled  <jsled at asynchronous.org>
 
 	* src/engine/SchedXaction.h (GNC_IS_SX,GNC_SX): added for convenience.

Modified: gnucash/branches/sx-cleanup/src/backend/file/io-gncxml-v2.c
===================================================================
--- gnucash/branches/sx-cleanup/src/backend/file/io-gncxml-v2.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/backend/file/io-gncxml-v2.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -246,16 +246,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
@@ -941,7 +944,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);
@@ -1076,25 +1079,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
@@ -1184,7 +1186,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/branches/sx-cleanup/src/doc/sx.rst
===================================================================
--- gnucash/branches/sx-cleanup/src/doc/sx.rst	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/doc/sx.rst	2006-07-16 21:35:45 UTC (rev 14521)
@@ -9,6 +9,8 @@
   - Show Next "year"s worth of SX instances
     - gnc_sx_get_instances({now + 1yr})
 
+- SX Editor
+
 - SinceLastRun
   - Last .. present (+ create-in-advance, reminder) instances
     - gnc_sx_get_instances(now)
@@ -16,14 +18,17 @@
 TODO
 ----
 
-- 'sx_updated' QOF events
+- [x] sx list -> qof collection
+- [ ] sx engine events
+  - [x] sx list collection add/remove -- sx-list GNC_EVENT_ITEM_ADDED, _REMOVED
+  - [ ] sx modified -- QOF_EVENT_MODIFY
 
 - gnc_dense_cal
   - change number-month properties to display (width, length)
-  - set_data(GncSxUpcomingInstances *future);
-  - set_model(GncSxUpcomingInstances *model);
+  - upcoming_instances_add_to_gnc_dense_cal(GncSxUpcomingInstances *future);
+  - set_model(GncTemporalInstancesModel *mdl)
+    - new interface creation.
     - register callbacks for signals
-    - set_data(...)
 
 - transaction creation
   - verification routine
@@ -43,12 +48,6 @@
 - s/SchedXaction/Scheduled/
 - s/temporal_state/instance_sequence_context/
 
-
-<?c
-
-
-?>
-
 GtkTreeModelIface
 -----------------
 
@@ -60,4 +59,3 @@
   - rows_reordered : ???
 
 - GtkTreeSortableIface
-  - 

Modified: gnucash/branches/sx-cleanup/src/engine/SX-book-p.h
===================================================================
--- gnucash/branches/sx-cleanup/src/engine/SX-book-p.h	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/engine/SX-book-p.h	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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(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/branches/sx-cleanup/src/engine/SX-book.c
===================================================================
--- gnucash/branches/sx-cleanup/src/engine/SX-book.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/engine/SX-book.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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(QofCollection *col)
 {
@@ -144,78 +144,45 @@
 
 /* ====================================================================== */
 
-SchedXactions *
-gnc_collection_get_schedxaction_list(QofCollection *col)
-{
-  return qof_collection_get_data (col);
-}
-
-GList *
+SchedXactions*
 gnc_collection_get_schedxactions(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/branches/sx-cleanup/src/engine/SX-book.h
===================================================================
--- gnucash/branches/sx-cleanup/src/engine/SX-book.h	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/engine/SX-book.h	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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(QofCollection *col);
-GList * gnc_collection_get_schedxactions(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(QofCollection *col);
+AccountGroup* gnc_book_get_template_group(QofBook* book);
+AccountGroup* gnc_collection_get_template_group(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/branches/sx-cleanup/src/engine/gnc-engine.h
===================================================================
--- gnucash/branches/sx-cleanup/src/engine/gnc-engine.h	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/engine/gnc-engine.h	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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/branches/sx-cleanup/src/gnome/Makefile.am
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/Makefile.am	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/Makefile.am	2006-07-16 21:35:45 UTC (rev 14521)
@@ -40,11 +40,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-tax-info.c \
   dialog-userpass.c \
-  dialog-scheduledxaction.c \
   druid-acct-period.c \
   druid-hierarchy.c \
   druid-merge.c \
@@ -79,9 +79,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 \
   druid-acct-period.h \
   druid-hierarchy.h \
   druid-merge.h \

Deleted: gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h	2006-07-16 21:35:45 UTC (rev 14521)
@@ -1,65 +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);
-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 );
-
-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/branches/sx-cleanup/src/gnome/dialog-sx-editor.c (from rev 14507, gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c)
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.c	2006-07-15 15:04:38 UTC (rev 14507)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -0,0 +1,1795 @@
+/********************************************************************\
+ * dialog-sx-editor.c : dialog for scheduled transaction editing    *
+ * 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 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 <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 "dialog-preferences.h"
+#include "dialog-sx-editor.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_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 _GncSxEditorDialog
+{
+        GladeXML *gxml;
+        GtkWidget *dialog;
+        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 schedXact_editor_create_freq_sel( GncSxEditorDialog *sxed );
+static void schedXact_editor_create_ledger( GncSxEditorDialog *sxed );
+static void schedXact_editor_populate( GncSxEditorDialog * );
+
+static void gnc_sxed_record_size( GncSxEditorDialog *sxed );
+static void gnc_sxed_get_widgets( GncSxEditorDialog *sxed );
+static void endgroup_rb_toggled( GtkButton *b, gpointer d );
+static void set_endgroup_toggle_states( GncSxEditorDialog *sxed, EndType t );
+static void advance_toggle( GtkButton *b, GncSxEditorDialog *sxed );
+static gboolean gnc_sxed_check_consistent( GncSxEditorDialog *sxed );
+static gboolean gnc_sxed_check_changed( GncSxEditorDialog *sxed );
+static void free_keys_and_numerics_ea( gpointer key,
+                                       gpointer value,
+                                       gpointer user_data );
+static void gnc_sxed_save_sx( GncSxEditorDialog *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( GncSxEditorDialog *sxed );
+
+static void gnc_sxed_reg_check_close(GncSxEditorDialog *sxed);
+
+static gint sxed_close_event( GtkDialog *dlg, gpointer ud );
+
+static gboolean sxed_confirmed_cancel( GncSxEditorDialog *sxed );
+
+static gboolean editor_component_sx_equality( gpointer find_data,
+                                              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
+sxed_close_handler ( gpointer user_data )
+{
+        GncSxEditorDialog *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. */
+}
+
+/**
+ * @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( GncSxEditorDialog *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, GncSxEditorDialog *sxed )
+{
+        /* close */
+        gnc_close_gui_component_by_data( DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
+                                         sxed );
+}
+
+static
+void
+editor_help_button_clicked(GtkButton *b, GncSxEditorDialog *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, GncSxEditorDialog *sxed )
+{
+        GNCBook *book;
+        SchedXactions *sxes;
+
+        if ( !gnc_sxed_check_consistent( sxed ) ) 
+                return;
+
+        gnc_sxed_save_sx( sxed );
+
+        /* add to list */
+        // @@fixme -- forget 'new'-flag: check for existance.
+        if ( sxed->newsxP ) {
+                book = gnc_get_current_book ();
+                sxes = gnc_book_get_schedxactions(book);
+                gnc_sxes_add_sx(sxes, sxed->sx);
+                sxed->newsxP = FALSE;
+        }
+
+        /* 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( GncSxEditorDialog *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( GncSxEditorDialog *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())->sx_list;
+                      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( GncSxEditorDialog *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, GncSxEditorDialog *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, GncSxEditorDialog *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_editor_dialog_destroy(GtkObject *object, gpointer data)
+{
+        int i;
+        GncSxEditorDialog *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);
+}
+
+static
+gint
+sxed_close_event( GtkDialog *dlg, gpointer ud )
+{
+        GncSxEditorDialog *sxed = (GncSxEditorDialog*)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( GncSxEditorDialog *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);
+
+}
+
+GncSxEditorDialog *
+gnc_ui_scheduled_xaction_editor_dialog_create(SchedXaction *sx,
+                                              gboolean newSX)
+{
+        GncSxEditorDialog *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 = (GncSxEditorDialog*)dlgExists->data;
+                gtk_window_present( GTK_WINDOW(sxed->dialog) );
+                g_list_free( dlgExists );
+                return sxed;
+        }
+
+        sxed         = g_new0( GncSxEditorDialog, 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->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( GncSxEditorDialog *sxed )
+{
+	gnc_save_window_size( SXED_GCONF_SECTION, GTK_WINDOW(sxed->dialog) );
+}
+
+static
+void
+schedXact_editor_create_freq_sel( GncSxEditorDialog *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( GncSxEditorDialog *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( GncSxEditorDialog *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( GncSxEditorDialog *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
+endgroup_rb_toggled( GtkButton *b, gpointer d )
+{
+        /* figure out which one */
+        GncSxEditorDialog *sxed;
+        gint id;
+
+        sxed = (GncSxEditorDialog*)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 );
+}
+
+/********************************************************************\
+ * gnc_register_check_close                                         *
+ *                                                                  *
+ * Args:   regData - the data struct for this register              *
+ * Return: none                                                     *
+\********************************************************************/
+static void
+gnc_sxed_reg_check_close(GncSxEditorDialog *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
+                 == ((GncSxEditorDialog*)user_data)->sx );
+}
+
+typedef enum { NO_END, DATE_END, COUNT_END } END_TYPE;
+
+static
+void
+gnc_sxed_update_cal( GncSxEditorDialog *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( (GncSxEditorDialog*)ud );
+}
+
+static
+void
+sxed_excal_update_adapt( GtkObject *o, gpointer ud )
+{
+        gnc_sxed_update_cal( (GncSxEditorDialog*)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);
+}
+
+
+/* ------------------------------------------------------------ */
+/* sx app engine;  move to somewhere appropriate. :/ */
+
+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((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"));
+}

Copied: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.h (from rev 14507, gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h)
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-scheduledxaction.h	2006-07-15 15:04:38 UTC (rev 14507)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.h	2006-07-16 21:35:45 UTC (rev 14521)
@@ -0,0 +1,52 @@
+/********************************************************************\
+ * dialog-sx-editor.h : dialog for scheduled transaction editing    *
+ * Copyright (C) 2001,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                   *
+\********************************************************************/
+
+#ifndef DIALOG_SX_EDITOR_H
+#define DIALOG_SX_EDITOR_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 _GncSxEditorDialog;
+
+typedef struct _GncSxEditorDialog GncSxEditorDialog;
+
+GncSxEditorDialog *
+gnc_ui_scheduled_xaction_editor_dialog_create(SchedXaction *sx,
+                                              gboolean newSX);
+
+void gnc_ui_scheduled_xaction_editor_dialog_destroy(GncSxEditorDialog *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

Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-from-trans.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -30,11 +30,10 @@
 
 #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 "gnc-date-edit.h"
@@ -551,7 +550,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 +558,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 +607,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 +623,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. */

Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -63,7 +63,6 @@
 #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"
@@ -85,7 +84,6 @@
 #include "gnc-split-reg.h"
 
 #include "dialog-sxsincelast.h"
-#include "dialog-scheduledxaction.h"
 
 #ifdef HAVE_LANGINFO_D_FMT
 #include <langinfo.h>
@@ -1361,7 +1359,7 @@
                   gpointer arg1, gpointer ud )
 {
         sxSinceLastData *sxsld = (sxSinceLastData*)ud;
-        GList *sxList, *toDelPtr, *elt;
+        GList *toDelPtr;
         GtkCList *cl;
         gint row;
         toDeleteTuple *tdt;
@@ -1384,31 +1382,28 @@
                                               SX_OBSOLETE_CLIST ) );
 
         if ( g_list_length( cl->selection ) > 0 ) {
-                SchedXactionDialog *sxd;
-                sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
+          GList *to_delete = NULL, *del_iter;
+          SchedXactions *sxes;
 
-                gnc_suspend_gui_refresh();
-                for ( toDelPtr = cl->selection;
-                      toDelPtr;
-                      toDelPtr = toDelPtr->next ) {
+          sxes = 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 );
+            to_delete = g_list_append(to_delete, tdt->sx);
+          }
 
-                        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 );
+          for (del_iter = to_delete; del_iter != NULL; del_iter = del_iter->next)
+          {
+            SchedXaction* sx = (SchedXaction*)del_iter->data;
+            gnc_sxes_del_sx(sxes, sx);
+            xaccSchedXactionFree(sx);
+          }
+          g_list_free(to_delete);
 
-                        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 );
-                }
+          gnc_resume_gui_refresh();
         }
 
         sxsincelast_close_handler( sxsld );
@@ -2113,7 +2108,7 @@
         toCreateInstance *tci;
 
         instanceList = NULL;
-        sxList = gnc_book_get_schedxactions( gnc_get_current_book () );
+        sxList = gnc_book_get_schedxactions(gnc_get_current_book ())->sx_list;
 
         if ( sxList == NULL ) {
                 DEBUG( "No scheduled transactions to populate." );

Modified: gnucash/branches/sx-cleanup/src/gnome/druid-loan.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/druid-loan.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/druid-loan.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -34,7 +34,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"
@@ -1968,7 +1967,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 );
@@ -1989,9 +1989,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/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -41,7 +41,6 @@
 #include "dialog-chart-export.h"
 #include "dialog-fincalc.h"
 #include "dialog-find-transactions.h"
-#include "dialog-scheduledxaction.h"
 #include "dialog-sxsincelast.h"
 #include "dialog-totd.h"
 #include "druid-acct-period.h"
@@ -439,7 +438,6 @@
 {
         GncPluginPage *page = gnc_plugin_page_sx_list_new();
         gnc_main_window_open_page(NULL, page);
-        //gnc_ui_scheduled_xaction_dialog_create ();
 }
 
 static void

Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -42,6 +42,7 @@
 #include "gkeyfile.h"
 #endif
 #include "gnc-engine.h"
+#include "gnc-event.h"
 #include "gnc-dense-cal.h"
 #include "gnc-icons.h"
 #include "gnc-plugin-page-sx-list.h"
@@ -50,8 +51,8 @@
 #include "dialog-utils.h"
 #include "gnc-component-manager.h"
 #include "SX-book.h"
-#include "SX-book-p.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;
@@ -207,7 +208,9 @@
 
 static void gppsl_event_handler(QofEntity *ent, QofEventId event_type, gpointer user_data, gpointer evt_data);
 
+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);
@@ -367,7 +370,6 @@
      GtkAction *edit_action, *delete_action;
      gboolean selection_state = TRUE;
 
-     printf("selection changed\n");
      page = GNC_PLUGIN_PAGE(user_data);
      edit_action = gnc_plugin_page_get_action(page, "SxListEditAction");
      delete_action = gnc_plugin_page_get_action(page, "SxListDeleteAction");
@@ -405,6 +407,14 @@
      }
 
      {
+          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;
@@ -433,7 +443,7 @@
           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(tree_view), "row-activated", (GCallback)gppsl_row_activate_cb, (gpointer)page);
+          g_signal_connect(G_OBJECT(priv->tree_view), "row-activated", (GCallback)gppsl_row_activated_cb, (gpointer)page);
      }
 
      {
@@ -564,37 +574,87 @@
 
 /* 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)
 {
-     printf("new\n");
+     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)
 {
-     printf("edit\n");
+     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 = g_list_map(selected_paths, (GMapFunc)_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 SchedXaction*
-_sx_for_iter(gpointer data, gpointer user_data)
+static void
+gppsl_row_activated_cb(GtkTreeView *tree_view,
+                       GtkTreePath *path,
+                       GtkTreeViewColumn *column,
+                       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;
+     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;
-     GList *book_sxes;
      book = gnc_get_current_book();
-     book_sxes = gnc_book_get_schedxactions(book);
-     book_sxes = g_list_remove(book_sxes, sx);
-     gnc_book_set_schedxactions(book, book_sxes);
+     sxes = gnc_book_get_schedxactions(book);
+     gnc_sxes_del_sx(sxes, sx);
      xaccSchedXactionFree(sx);
 }
 
@@ -605,6 +665,8 @@
      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);
@@ -614,7 +676,7 @@
           return;
      }
 
-     to_delete = g_list_map(selected_paths, (GMapFunc)_sx_for_iter, model);
+     to_delete = g_list_map(selected_paths, (GMapFunc)_sx_for_path, model);
      {
           GList *list;
           for (list = to_delete; list != NULL; list = list->next)
@@ -626,8 +688,83 @@
      g_list_free(to_delete);
      g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
      g_list_free(selected_paths);
- }
+}
 
+#if 0 // compare/sort fns
+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 );
+}
+
+#endif // 0 - compare/sort fns
+
 /* ------------------------------------------------------------ */
 
 static GncSxInstances*
@@ -649,7 +786,7 @@
 
      // postponed
      {
-          // defer list.
+          // @@fixme - defer list.
      }
 
      // to-create
@@ -708,7 +845,7 @@
 
      instances = gnc_sx_instance_model_new();
      instances->range_end = *range_end;
-     sxes = gnc_book_get_schedxactions(gnc_get_current_book());
+     sxes = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
      instances->sx_instance_list = g_list_map(sxes, (GMapFunc)_gnc_sx_gen_instances, (gpointer)range_end);
 
      return instances;
@@ -788,41 +925,62 @@
 _gnc_sx_instance_event_handler(QofEntity *ent, QofEventId event_type, gpointer user_data, gpointer evt_data)
 {
      GncSxInstanceModel *instances = GNC_SX_INSTANCE_MODEL(user_data);
-     SchedXaction *sx;
 
-     if (!GNC_IS_SX(ent))
+     // selection rules {
+     //   (gnc_collection_get_schedxaction_list(book), GNC_EVENT_ITEM_ADDED)
+     //   (gnc_collection_get_schedxaction_list(book), GNC_EVENT_ITEM_REMOVED)
+     //   (GNC_IS_SX(ent), QOF_EVENT_MODIFIED)
+     // }
+     if (!(GNC_IS_SX(ent) || GNC_IS_SXES(ent)))
           return;
-     sx = GNC_SX(ent);
 
-     if (event_type & QOF_EVENT_DESTROY)
+     if (GNC_IS_SX(ent))
      {
-          gpointer sx_instance_to_remove = NULL;
-          GList *list;
-          // find, remove, update
-          for (list = instances->sx_instance_list; list != NULL; list = list->next)
+          SchedXaction *sx;
+          sx = GNC_SX(ent);
+          if (event_type & QOF_EVENT_MODIFY)
           {
-               if (sx == ((GncSxInstances*)list->data)->sx)
+               // @re-generate instance, update
+          }
+          /* else { unsupported event type; ignore } */
+     }
+     else if (GNC_IS_SXES(ent))
+     {
+          SchedXactions *sxes = GNC_SXES(ent);
+          SchedXaction *sx = GNC_SX(evt_data);
+
+          sxes = NULL;
+          if (event_type & GNC_EVENT_ITEM_REMOVED)
+          {
+               gpointer sx_instance_to_remove = NULL;
+               GList *list;
+
+               // find, remove, update
+               for (list = instances->sx_instance_list; list != NULL; list = list->next)
                {
-                    sx_instance_to_remove = list->data;
-                    break;
+                    if (sx == ((GncSxInstances*)list->data)->sx)
+                    {
+                         sx_instance_to_remove = list->data;
+                         break;
+                    }
                }
+               if (sx_instance_to_remove != NULL)
+               {
+                    instances->sx_instance_list = g_list_remove(instances->sx_instance_list, sx_instance_to_remove);
+                    g_signal_emit_by_name(instances, "updated");
+               }
+               else { printf("err\n"); }
           }
-          if (sx_instance_to_remove != NULL)
+          else if (event_type & GNC_EVENT_ITEM_ADDED)
           {
-               instances->sx_instance_list = g_list_remove(instances->sx_instance_list, sx_instance_to_remove);
+               // generate instances, add to instance list, emit update.
+               instances->sx_instance_list
+                    = g_list_append(instances->sx_instance_list,
+                                    (*_gnc_sx_gen_instances)((gpointer)sx, (gpointer)&instances->range_end));
                g_signal_emit_by_name(instances, "updated");
           }
-          else { printf("err\n"); }
+          // else { printf("unsupported event type [%d]\n", event_type); }
      }
-     else if (event_type & QOF_EVENT_CREATE)
-     {
-          // add, update
-          g_signal_emit_by_name(instances, "updated");
-     }
-     else { printf("unknown\n"); }
-     /* else { unsupported event type; ignore } */
-
-     instances = 0;
 }
 
 
@@ -1005,7 +1163,6 @@
      g_signal_emit_by_name(user_data, "row-deleted", arg1);
 }
 
-
 static void
 gsltma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
                                    GtkTreePath *arg1,
@@ -1015,7 +1172,6 @@
      g_signal_emit_by_name(user_data, "row-has-child-toggled", arg1, arg2);
 }
 
-
 static void
 gsltma_proxy_row_inserted(GtkTreeModel *treemodel,
                           GtkTreePath *arg1,
@@ -1025,7 +1181,6 @@
      g_signal_emit_by_name(user_data, "row-inserted", arg1, arg2);
 }
 
-
 static void
 gsltma_proxy_rows_reordered(GtkTreeModel *treemodel,
                             GtkTreePath *arg1,
@@ -1050,7 +1205,7 @@
 }
 
 static void
-gsltma_populate(GncSxListTreeModelAdapter *model)
+gsltma_populate_tree_store(GncSxListTreeModelAdapter *model)
 {
      GtkTreeIter iter;
      GList *list;
@@ -1063,7 +1218,6 @@
           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);
@@ -1099,9 +1253,9 @@
 gsltma_updated_cb(GncSxInstanceModel *instances, gpointer user_data)
 {
      GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
-     printf("update!\n");
+     printf("update\n");
      gtk_tree_store_clear(model->real);
-     gsltma_populate(model);
+     gsltma_populate_tree_store(model);
 }
 
 GncSxListTreeModelAdapter*
@@ -1112,8 +1266,7 @@
      rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
      rtn->instances = instances;
 
-     // copy data over...
-     gsltma_populate(rtn);
+     gsltma_populate_tree_store(rtn);
 
      g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsltma_updated_cb, (gpointer)rtn);
 

Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-split-reg.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-split-reg.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-split-reg.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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;
         }
       }

Modified: gnucash/branches/sx-cleanup/src/gnome/gw-gnc-spec.scm
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gw-gnc-spec.scm	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/gw-gnc-spec.scm	2006-07-16 21:35:45 UTC (rev 14521)
@@ -46,7 +46,7 @@
       "#include <gnc-window.h>\n"
       "#include <gnc-plugin-account-tree.h>\n"
       "#include <gnc-splash.h>\n"
-      "#include <dialog-scheduledxaction.h>\n"
+      "#include <dialog-sx-editor.h>\n"
       "#include <dialog-sxsincelast.h>\n" )))
 
   (gw:wrap-function

Modified: gnucash/branches/sx-cleanup/src/gnome/top-level.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/top-level.c	2006-07-16 16:58:07 UTC (rev 14520)
+++ gnucash/branches/sx-cleanup/src/gnome/top-level.c	2006-07-16 21:35:45 UTC (rev 14521)
@@ -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"



More information about the gnucash-changes mailing list