r14852 - gnucash/branches/sx-cleanup - New, simplified implementation of the SinceLastRun dialog. Extensions of GncSxInstanceModel to support (variable parsing, single/flat upcoming-instance list).
Joshua Sled
jsled at cvs.gnucash.org
Sat Sep 16 14:56:47 EDT 2006
Author: jsled
Date: 2006-09-16 14:56:44 -0400 (Sat, 16 Sep 2006)
New Revision: 14852
Trac: http://svn.gnucash.org/trac/changeset/14852
Added:
gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c
gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.h
Modified:
gnucash/branches/sx-cleanup/ChangeLog
gnucash/branches/sx-cleanup/src/doc/sx.rst
gnucash/branches/sx-cleanup/src/engine/SchedXaction.h
gnucash/branches/sx-cleanup/src/gnome/Makefile.am
gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c
gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c
gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.h
gnucash/branches/sx-cleanup/src/gnome/glade/sched-xact.glade
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-plugin-page-sx-list.h
Log:
New, simplified implementation of the SinceLastRun dialog. Extensions of GncSxInstanceModel to support (variable parsing, single/flat upcoming-instance list).
2006-09-16 Joshua Sled <jsled at asynchronous.org>
* src/gnome/gnc-plugin-page-sx-list.c (sxsl_get_sx_vars): Add
variable extraction to instance-model creation. The
GncSxInstances now has a hashtable of variables parsed from the
formula, and the GncSxInstance has a copy of that variables hash.
Not finished, but mostly in place.
* src/gnome/dialog-sx-since-last-run.c: New, simplified version of
the since-last-run dialog. GncSxSlrTreeModelAdapter.
Modified: gnucash/branches/sx-cleanup/ChangeLog
===================================================================
--- gnucash/branches/sx-cleanup/ChangeLog 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/ChangeLog 2006-09-16 18:56:44 UTC (rev 14852)
@@ -1,3 +1,14 @@
+2006-09-16 Joshua Sled <jsled at asynchronous.org>
+
+ * src/gnome/gnc-plugin-page-sx-list.c (sxsl_get_sx_vars): Add
+ variable extraction to instance-model creation. The
+ GncSxInstances now has a hashtable of variables parsed from the
+ formula, and the GncSxInstance has a copy of that variables hash.
+ Not finished, but mostly in place.
+
+ * src/gnome/dialog-sx-since-last-run.c: New, simplified version of
+ the since-last-run dialog. GncSxSlrTreeModelAdapter.
+
2006-07-27 Joshua Sled <jsled at asynchronous.org>
* src/gnome-utils/gnc-dense-cal.c
Modified: gnucash/branches/sx-cleanup/src/doc/sx.rst
===================================================================
--- gnucash/branches/sx-cleanup/src/doc/sx.rst 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/doc/sx.rst 2006-09-16 18:56:44 UTC (rev 14852)
@@ -1,8 +1,8 @@
Scheduled Transactions
-======================
+===============================================================
Overview
---------
+--------------
- SX List
- CRUD operations on SXes
@@ -16,15 +16,22 @@
- gnc_sx_get_instances(now)
TODO
-----
+----------
-- [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
+- meta
+ - [ ] move files around
+ - [ ] GncSxListTreeModelAdapter: s/real/adapted/
+- core
+ - [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
+ - [ ] sx upcoming instance model
+ - [ ] implement sort model
+
- gnc_dense_cal
- - change number-month properties to display (width, length)
+ - [ ] change number-of-month properties to display-named properties (width, length)
- [x] set_model(GncTemporalInstancesModel *mdl)
- [x] new interface creation.
- [x] register callbacks for signals
@@ -32,32 +39,118 @@
- sx-from-trans
- [ ] convert to GObject, hookup destroy/finalize
-- transaction creation
- - verification routine
- - variable binding/requirements.
- - actual creation
- - error handling
+- use Recurrence instead of Freq Spec
+ - [ ] XML migration, handling
-- stateful editing of instances in since-last-run dialog
- - postponed/ignored/to-create constraints
- - processed_valid_reminders_list, contiguous-date logic
- - postponed/ignored/to-create transitions [?]
- - "allowed to finish" decision.
+- since-last-run
+ - [ ] add reminders, postponed to SxInstanceModel
+ - [ ] add obsolete flag to SxInstanceModel
+ - [ ] add mutation support to sx instance model
+ - [ ] state machine
+ - [ ] add variable state to sx instance model
+ - [ ] add sx_upcoming_instance_model()
+ - [ ] add effect_auto_create()
+ - [ ] add some sort of "ready to go" flag and api
+ - [ ] variable setting, primarily
+ - [ ] some sort of commit_changes()
+ - ??? does effect_auto_create() imply or need commit_changes()?
+ - [/] add variable table to instances
Pedantic Todo
-----------------
+----------------------
- s/SchedXaction/Scheduled/
- s/temporal_state/instance_sequence_context/
+- change instance variable from 'i' to '__i' or something
-GtkTreeModelIface
------------------
-- signals
- - row_changed : sx_updated
- - row_inserted : sx_created
- - row_has_child_toggled : are there any children, here?
- - row_deleted : sx_deleted
- - rows_reordered : ???
+============================================================
-- GtkTreeSortableIface
+(eventually real documentation... (?))
+
+Since Last Run
+----------------------
+
++------------------+------------------+------------------+
+| Thing | State | Value |
++------------------+------------------+------------------+
+| - Foo | | |
++------------------+------------------+------------------+
+| - 2006-08-27 | [Postponed|v] | |
++------------------+------------------+------------------+
+| - variable-a | | 42 |
++------------------+------------------+------------------+
+| - variable-b | | 75 |
++------------------+------------------+------------------+
+| - 2006-08-27 | [To-Create|v] | |
++------------------+------------------+------------------+
+| - variable-a | | 31 |
++------------------+------------------+------------------+
+| - variable-b | | (value needed) |
++------------------+------------------+------------------+
+
+
+The since-last-run dialog is a key user interface. More frequently than the
+SX list or editor, the user will be in the process of creating transaction
+instances through this interface.
+
+The old SLR dialog has the following stages:
+
+- Reminders
+ - can be promoted to "to-create"
+- Auto-created, with notification
+- To-Create
+ - postponed, to-create
+ - ignore state.
+- Created review
+- Obsolete SX cleanup
+
+The new SLR dialog will have the following:
+
+- Creation
+ (treemodel consisting of)
+ - auto-created
+ - reminder
+ - postponed
+ - to-create
+ - [obsolete SX]?
+
+There is no seperate to-review page.
+
+Upcoming instance states
+---------------------------------------
+
+ reminder -> to-create
+ postponed -> to-create
+ to-create -> postponed (with constraints)
+ to-create -> ignore
+
+Definitions:
+
+ reminder: a transient upcoming transaction that will not be created.
+ postponed: a historical to-create transaction that the user has
+ explicitly deferred.
+ to-create: an upcoming SX instance that should be created.
+ ignore: a scheduled instance the user has explicitly prevented the
+ instantiation of.
+
+What does the SX need to store?
+- postponed instance list.
+- last state of created instance.
+
+ void gnc_sx_instance_model_change_state(sx_id, instance_id, new_state, **gerror)
+ boolean gnc_sx_instance_model_get_readiness(sx_id, instance_id)
+ boolean gnc_sx_instance_model_set_variables(sx_id, instance_id, variable_name:string, value:string, **gerrror)
+
+Formula Parsing
+------------------------
+
+A SXes formula is parsed in the context of:
+- the template transaction
+ - the accounts of the splits
+- the sequence number
+- the date of the transaction
+- a variable-binding table.
+
+
+
Modified: gnucash/branches/sx-cleanup/src/engine/SchedXaction.h
===================================================================
--- gnucash/branches/sx-cleanup/src/engine/SchedXaction.h 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/engine/SchedXaction.h 2006-09-16 18:56:44 UTC (rev 14852)
@@ -199,7 +199,7 @@
This is a date-sorted state-data instance list.
The list should not be modified by the caller; use the
- gnc_sx_{add,remove}_defer_instance() functions to modifiy the list.
+ gnc_sx_{add,remove}_defer_instance() functions to modify the list.
*/
GList *gnc_sx_get_defer_instances( SchedXaction *sx );
Modified: gnucash/branches/sx-cleanup/src/gnome/Makefile.am
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/Makefile.am 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/Makefile.am 2006-09-16 18:56:44 UTC (rev 14852)
@@ -43,6 +43,7 @@
dialog-sx-editor.c \
dialog-sx-from-trans.c \
dialog-sxsincelast.c \
+ dialog-sx-since-last-run.c \
dialog-tax-info.c \
dialog-userpass.c \
druid-acct-period.c \
@@ -82,6 +83,7 @@
dialog-sx-editor.h \
dialog-sx-from-trans.h \
dialog-sxsincelast.h \
+ dialog-sx-since-last-run.h \
druid-acct-period.h \
druid-hierarchy.h \
druid-merge.h \
Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-editor.c 2006-09-16 18:56:44 UTC (rev 14852)
@@ -58,6 +58,7 @@
/* FIXME: temp until variable-related-stuff settled. */
#include "dialog-sxsincelast.h"
+#include "dialog-sx-since-last-run.h"
#ifdef HAVE_LANGINFO_D_FMT
#include <langinfo.h>
Added: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.c 2006-09-16 18:56:44 UTC (rev 14852)
@@ -0,0 +1,502 @@
+/********************************************************************\
+ * dialog-sx-since-last-run.c : dialog for scheduled transaction *
+ * since-last-run processing. *
+ * Copyright (C) 2006 Joshua Sled <jsled at asynchronous.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of version 2 of the GNU General Public *
+ * License as published by the Free Software Foundation. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+
+#include "config.h"
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glade/glade-xml.h>
+
+#include "dialog-utils.h"
+#include "gnc-plugin-page-sx-list.h"
+#include "dialog-sx-since-last-run.h"
+
+typedef struct _GncSxSlrTreeModelAdapter GncSxSlrTreeModelAdapter;
+
+struct _GncSxSinceLastRunDialog
+{
+ GtkWidget *dialog;
+ GncSxInstanceModel *instances;
+ GncSxSlrTreeModelAdapter *editing_model;
+ GtkTreeView *instance_view;
+};
+
+/* ------------------------------------------------------------ */
+
+struct _GncSxSlrTreeModelAdapter
+{
+ GObject parent;
+
+ /* protected */
+ GncSxInstanceModel *instances;
+ GtkTreeStore *real;
+};
+
+typedef struct _GncSxSlrTreeModelAdapterClass
+{
+ GObjectClass parent;
+} GncSxSlrTreeModelAdapterClass;
+
+GType gnc_sx_slr_tree_model_adapter_get_type(void);
+static void gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass);
+static void gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data);
+static void gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
+GncSxSlrTreeModelAdapter* gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances);
+
+GncSxInstances* gnc_sx_slr_tree_model_adapter_get_sx_instances(GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
+
+#define GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER (gnc_sx_slr_tree_model_adapter_get_type ())
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapter))
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
+#define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
+#define GNC_IS_SX_SLR_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER))
+#define GNC_SX_SLR_TREE_MODEL_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapterClass))
+
+/* ------------------------------------------------------------ */
+
+static void _cell_visibility_func(GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data);
+
+GType
+gnc_sx_slr_tree_model_adapter_get_type(void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof (GncSxSlrTreeModelAdapterClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)gnc_sx_slr_tree_model_adapter_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GncSxSlrTreeModelAdapter),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc)gnc_sx_slr_tree_model_adapter_init /* instance_init */
+ };
+ static const GInterfaceInfo itreeModel_info = {
+ (GInterfaceInitFunc) gnc_sx_slr_tree_model_adapter_interface_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GncSxSlrTreeModelAdapterType",
+ &info, 0);
+ g_type_add_interface_static(type,
+ GTK_TYPE_TREE_MODEL,
+ &itreeModel_info);
+ }
+ return type;
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_class_init(GncSxSlrTreeModelAdapterClass *klass)
+{
+ ; /* nop */
+}
+
+static GtkTreeModelFlags
+gsslrtma_get_flags(GtkTreeModel *tree_model)
+{
+ return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
+}
+
+static gint
+gsslrtma_get_n_columns(GtkTreeModel *tree_model)
+{
+ return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real));
+}
+
+static GType
+gsslrtma_get_column_type(GtkTreeModel *tree_model, gint index)
+{
+ return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), index);
+}
+
+static gboolean
+gsslrtma_get_iter(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
+}
+
+static GtkTreePath*
+gsslrtma_get_path(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gsslrtma_get_value(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value)
+{
+ gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
+}
+
+static gboolean
+gsslrtma_iter_next(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gboolean
+gsslrtma_iter_children(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
+}
+
+static gboolean
+gsslrtma_iter_has_child(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gint
+gsslrtma_iter_n_children(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static gboolean
+gsslrtma_iter_nth_child(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n)
+{
+ return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
+}
+
+static gboolean
+gsslrtma_iter_parent(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
+{
+ return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
+}
+
+static void
+gsslrtma_ref_node(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gsslrtma_unref_node(GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_SLR_TREE_MODEL_ADAPTER(tree_model)->real), iter);
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_interface_init(gpointer g_iface, gpointer iface_data)
+{
+ GtkTreeModelIface *tree_model = (GtkTreeModelIface*)g_iface;
+ tree_model->get_flags = gsslrtma_get_flags;
+ tree_model->get_n_columns = gsslrtma_get_n_columns;
+ tree_model->get_column_type = gsslrtma_get_column_type;
+ tree_model->get_iter = gsslrtma_get_iter;
+ tree_model->get_path = gsslrtma_get_path;
+ tree_model->get_value = gsslrtma_get_value;
+ tree_model->iter_next = gsslrtma_iter_next;
+ tree_model->iter_children = gsslrtma_iter_children;
+ tree_model->iter_has_child = gsslrtma_iter_has_child;
+ tree_model->iter_n_children = gsslrtma_iter_n_children;
+ tree_model->iter_nth_child = gsslrtma_iter_nth_child;
+ tree_model->iter_parent = gsslrtma_iter_parent;
+ tree_model->ref_node = gsslrtma_ref_node;
+ tree_model->unref_node = gsslrtma_unref_node;
+}
+
+static void
+gsslrtma_proxy_row_changed(GtkTreeModel *treemodel,
+ GtkTreePath *arg1,
+ GtkTreeIter *arg2,
+ gpointer user_data)
+{
+ g_signal_emit_by_name(user_data, "row-changed", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_row_deleted(GtkTreeModel *treemodel,
+ GtkTreePath *arg1,
+ gpointer user_data)
+{
+ g_signal_emit_by_name(user_data, "row-deleted", arg1);
+}
+
+static void
+gsslrtma_proxy_row_has_child_toggled(GtkTreeModel *treemodel,
+ GtkTreePath *arg1,
+ GtkTreeIter *arg2,
+ gpointer user_data)
+{
+ g_signal_emit_by_name(user_data, "row-has-child-toggled", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_row_inserted(GtkTreeModel *treemodel,
+ GtkTreePath *arg1,
+ GtkTreeIter *arg2,
+ gpointer user_data)
+{
+ g_signal_emit_by_name(user_data, "row-inserted", arg1, arg2);
+}
+
+static void
+gsslrtma_proxy_rows_reordered(GtkTreeModel *treemodel,
+ GtkTreePath *arg1,
+ GtkTreeIter *arg2,
+ gpointer arg3,
+ gpointer user_data)
+{
+ g_signal_emit_by_name(user_data, "rows-reordered", arg1, arg2, arg3);
+}
+
+static void
+gnc_sx_slr_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
+{
+ GncSxSlrTreeModelAdapter *adapter = GNC_SX_SLR_TREE_MODEL_ADAPTER(instance);
+ // columns: thing-name, instance-state, variable-value
+ // at depth=0: <sx>, N/A, N/A
+ // at depth=1: <instance>, <state>, N/A
+ // at depth=2: <variable>, N/A, <value>
+ adapter->real = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ g_signal_connect(adapter->real, "row-changed", G_CALLBACK(gsslrtma_proxy_row_changed), adapter);
+ g_signal_connect(adapter->real, "row-deleted", G_CALLBACK(gsslrtma_proxy_row_deleted), adapter);
+ g_signal_connect(adapter->real, "row-has-child-toggled", G_CALLBACK(gsslrtma_proxy_row_has_child_toggled), adapter);
+ g_signal_connect(adapter->real, "row-inserted", G_CALLBACK(gsslrtma_proxy_row_inserted), adapter);
+ g_signal_connect(adapter->real, "rows-reordered", G_CALLBACK(gsslrtma_proxy_rows_reordered), adapter);
+}
+
+static void
+_build_variable_name_list(gpointer key, gpointer value, gpointer user_data)
+{
+ GList **name_list = (GList**)user_data;
+ *name_list = g_list_append(*name_list, key);
+}
+
+/* @@fixme: i18n. **/
+/* @@fixme: non-staticize. **/
+static char* gnc_sx_instance_type_names[] = {
+ ("Ignored"),
+ ("Postponed"),
+ ("To-Create"),
+ ("Reminder"),
+ NULL
+};
+
+static void
+gsslrtma_populate_tree_store(GncSxSlrTreeModelAdapter *model)
+{
+ GtkTreeIter sx_iter;
+ GList *list;
+
+ for (list = model->instances->sx_instance_list; list != NULL; list = list->next)
+ {
+ GncSxInstances *instances = (GncSxInstances*)list->data;
+ FreqSpec *fs;
+ GString *frequency_str;
+ char last_occur_date_buf[MAX_DATE_LENGTH+1];
+ char next_occur_date_buf[MAX_DATE_LENGTH+1];
+
+ frequency_str = g_string_sized_new(32);
+ fs = xaccSchedXactionGetFreqSpec(instances->sx);
+ xaccFreqSpecGetFreqStr(fs, frequency_str);
+
+ {
+ GDate *last_occur = xaccSchedXactionGetLastOccurDate(instances->sx);
+ if (last_occur == NULL || !g_date_valid(last_occur))
+ {
+ g_stpcpy(last_occur_date_buf, "never");
+ }
+ else
+ {
+ qof_print_gdate(last_occur_date_buf,
+ MAX_DATE_LENGTH,
+ last_occur);
+ }
+ }
+
+ qof_print_gdate(next_occur_date_buf, MAX_DATE_LENGTH, &instances->next_instance_date);
+
+ gtk_tree_store_append(model->real, &sx_iter, NULL);
+ gtk_tree_store_set(model->real, &sx_iter,
+ 0, xaccSchedXactionGetName(instances->sx),
+ 1, NULL,
+ 2, NULL,
+ -1);
+ g_string_free(frequency_str, TRUE);
+
+ // Insert instance information
+ {
+ GList *inst_iter;
+ GtkTreeIter inst_tree_iter;
+ char instance_date_buf[MAX_DATE_LENGTH+1];
+
+ for (inst_iter = instances->list; inst_iter != NULL; inst_iter = inst_iter->next)
+ {
+ GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
+ qof_print_gdate(instance_date_buf, MAX_DATE_LENGTH, &inst->date);
+ gtk_tree_store_append(model->real, &inst_tree_iter, &sx_iter);
+ gtk_tree_store_set(model->real, &inst_tree_iter,
+ 0, instance_date_buf,
+ 1, gnc_sx_instance_type_names[inst->type],
+ 2, NULL,
+ -1);
+
+ // Insert variable information
+ {
+ GList *names = NULL, *names_iter;
+ GtkTreeIter var_iter;
+
+ g_hash_table_foreach(inst->variable_bindings, _build_variable_name_list, &names);
+ for (names_iter = names; names_iter != NULL; names_iter = names_iter->next)
+ {
+ gtk_tree_store_append(model->real, &var_iter, &inst_tree_iter);
+ gtk_tree_store_set(model->real, &var_iter,
+ 0, (gchar*)names_iter->data,
+ 1, NULL,
+ 2, "(@fixme - value)"
+ -1);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+gsslrtma_updated_cb(GncSxInstanceModel *instances, gpointer user_data)
+{
+ GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data);
+ printf("update\n");
+ gtk_tree_store_clear(model->real);
+ gsslrtma_populate_tree_store(model);
+}
+
+GncSxSlrTreeModelAdapter*
+gnc_sx_slr_tree_model_adapter_new(GncSxInstanceModel *instances)
+{
+ GncSxSlrTreeModelAdapter *rtn;
+ rtn = GNC_SX_SLR_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, NULL));
+ rtn->instances = instances;
+ gsslrtma_populate_tree_store(rtn);
+ g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsslrtma_updated_cb, (gpointer)rtn);
+ return rtn;
+}
+
+
+void
+gnc_sx_sxsincelast_book_opened(void)
+{
+ // Get the instance model
+ // check for mumble and futz
+ // maybe create dialog.
+ printf("not ready\n");
+ //gnc_ui_sxsincelast_dialog_create();
+}
+
+gint
+gnc_ui_sxsincelast_dialog_create(void)
+{
+ GDate now;
+ GncSxInstanceModel *model;
+ g_date_clear(&now, 1);
+ g_date_set_time_t(&now, time(NULL));
+ model = gnc_sx_get_instances(&now);
+ gnc_ui_sx_since_last_run_dialog(model);
+ return 1;
+}
+
+GncSxSinceLastRunDialog*
+gnc_ui_sx_since_last_run_dialog(GncSxInstanceModel *model)
+{
+ GncSxSinceLastRunDialog *dialog;
+ GladeXML *glade;
+
+ dialog = g_new0(GncSxSinceLastRunDialog, 1);
+ dialog->instances = model;
+
+ glade = gnc_glade_xml_new("sched-xact.glade", "since-last-run-dialog");
+ dialog->dialog = glade_xml_get_widget(glade, "since-last-run-dialog");
+
+ dialog->editing_model = gnc_sx_slr_tree_model_adapter_new(model);
+
+ {
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *col;
+ int position = -1;
+
+ dialog->instance_view = GTK_TREE_VIEW(glade_xml_get_widget(glade, "instance_view"));
+ gtk_tree_view_set_model(dialog->instance_view, GTK_TREE_MODEL(dialog->editing_model));
+
+ renderer = gtk_cell_renderer_text_new();
+ col = gtk_tree_view_column_new_with_attributes("SX, Instance, Variable", renderer, "text", ++position, NULL);
+ gtk_tree_view_append_column(dialog->instance_view, col);
+
+ renderer = gtk_cell_renderer_text_new();
+ col = gtk_tree_view_column_new_with_attributes("Instance State", renderer, "text", ++position, NULL);
+ gtk_tree_view_column_set_cell_data_func(col, renderer, _cell_visibility_func, GINT_TO_POINTER(position), NULL);
+ gtk_tree_view_append_column(dialog->instance_view, col);
+
+ renderer = gtk_cell_renderer_text_new();
+ col = gtk_tree_view_column_new_with_attributes("Variable Value", renderer, "text", ++position, NULL);
+ gtk_tree_view_column_set_cell_data_func(col, renderer, _cell_visibility_func, GINT_TO_POINTER(position), NULL);
+ gtk_tree_view_append_column(dialog->instance_view, col);
+ }
+
+ gtk_widget_show_all(dialog->dialog);
+
+ return dialog;
+}
+
+
+static void
+_cell_visibility_func(GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkTreePath *path;
+ int select_depth, path_depth;
+
+ select_depth = GPOINTER_TO_INT(data);
+ path = gtk_tree_model_get_path(tree_model, iter);
+ path_depth = gtk_tree_path_get_depth(path);
+ // printf("item depth: %d\n", path_depth);
+ g_object_set(G_OBJECT(cell), "visible", path_depth == select_depth ? TRUE : FALSE, NULL);
+}
+
Added: gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.h
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.h 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sx-since-last-run.h 2006-09-16 18:56:44 UTC (rev 14852)
@@ -0,0 +1,50 @@
+/********************************************************************\
+ * dialog-sx-since-last-run.h : dialog for scheduled transaction *
+ * since-last-run processing. *
+ * Copyright (C) 2006 Joshua Sled <jsled at asynchronous.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of version 2 of the GNU General Public *
+ * License as published by the Free Software Foundation. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+
+#ifndef DIALOG_SX_SINCE_LAST_RUN_H
+#define DIALOG_SX_SINCE_LAST_RUN_H
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "SchedXaction.h"
+#include "gnc-plugin-page-sx-list.h"
+
+typedef struct _GncSxSinceLastRunDialog GncSxSinceLastRunDialog;
+
+/**
+ * This encapsulates the "run when file opened" application logic. As such,
+ * it should probably move to a non-ui file.
+ **/
+void gnc_sx_sxsincelast_book_opened(void);
+
+/**
+ * Create the since-last-run dialog from the given instance-model.
+ **/
+GncSxSinceLastRunDialog* gnc_ui_sx_since_last_run_dialog(GncSxInstanceModel *model);
+
+// @@fixme: resurect, fix return type.
+gint gnc_ui_sxsincelast_dialog_create( void );
+
+
+#endif
Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.c 2006-09-16 18:56:44 UTC (rev 14852)
@@ -406,6 +406,7 @@
/**
* Used to wrap for the book-open hook, where the book filename is given.
**/
+#if 0
void
gnc_sx_sxsincelast_book_opened (void)
{
@@ -427,8 +428,8 @@
-(ret));
}
}
+#endif // 0
-
static gboolean
show_handler (const char *class, gint component_id,
gpointer user_data, gpointer iter_data)
@@ -455,6 +456,7 @@
* [e.g., for book-open-hook: do nothing; for menu-selection: display an info
* dialog stating there's nothing to do.]
**/
+#if 0
gint
gnc_ui_sxsincelast_dialog_create()
{
@@ -488,6 +490,7 @@
sxsincelast_init( sxsld );
return autoCreateCount;
}
+#endif //0
static void
clist_set_all_cols_autoresize( GtkCList *cl, guint n_cols )
@@ -1698,6 +1701,10 @@
reminderInstanceTuple *rit;
void *seqStateData;
+ void *foo = sxsincelast_init;
+ foo = sxsincelast_populate;
+ foo = show_handler;
+
g_assert( g_date_valid(end) );
g_assert( g_date_valid(reminderEnd) );
Modified: gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.h
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.h 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/dialog-sxsincelast.h 2006-09-16 18:56:44 UTC (rev 14852)
@@ -37,8 +37,8 @@
* [e.g., for book-open-hook: do nothing; for menu-selection: display an info
* dialog stating there's nothing to do.]
**/
-gint gnc_ui_sxsincelast_dialog_create( void );
-void gnc_sx_sxsincelast_book_opened (void);
+//gint gnc_ui_sxsincelast_dialog_create( void );
+//void gnc_sx_sxsincelast_book_opened (void);
/**
* Returns the varaibles from the Splits of the given SchedXaction as the
Modified: gnucash/branches/sx-cleanup/src/gnome/glade/sched-xact.glade
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/glade/sched-xact.glade 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/glade/sched-xact.glade 2006-09-16 18:56:44 UTC (rev 14852)
@@ -8480,4 +8480,114 @@
</child>
</widget>
+<widget class="GtkDialog" id="since-last-run-dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Since Last Run...</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox25">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area25">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVPaned" id="vpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow21">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="instance_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
</glade-interface>
Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-basic-commands.c 2006-09-16 18:56:44 UTC (rev 14852)
@@ -42,6 +42,7 @@
#include "dialog-fincalc.h"
#include "dialog-find-transactions.h"
#include "dialog-sxsincelast.h"
+#include "dialog-sx-since-last-run.h"
#include "dialog-totd.h"
#include "druid-acct-period.h"
#include "druid-loan.h"
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-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.c 2006-09-16 18:56:44 UTC (rev 14852)
@@ -42,7 +42,11 @@
#ifndef HAVE_GLIB26
#include "gkeyfile.h"
#endif
+#include "gnc-exp-parser.h"
#include "gnc-engine.h"
+#include "Transaction.h"
+#include "Split.h"
+#include "gnc-commodity.h"
#include "gnc-event.h"
#include "gnc-dense-cal.h"
#include "gnc-icons.h"
@@ -61,10 +65,6 @@
#define PLUGIN_PAGE_SX_LIST_CM_CLASS "plugin-page-sx-list"
#define GCONF_SECTION "window/pages/sx_list"
-typedef struct _GncSxInstanceDenseCalAdapter GncSxInstanceDenseCalAdapter;
-typedef struct _GncSxInstanceModel GncSxInstanceModel;
-typedef struct _GncSxListTreeModelAdapter GncSxListTreeModelAdapter;
-
typedef struct GncPluginPageSxListPrivate
{
GtkWidget* widget;
@@ -88,62 +88,20 @@
/* ------------------------------------------------------------ */
-struct _GncSxInstanceModel
-{
- GObject parent;
+GType gnc_sx_instance_model_get_type(void);
+static void gnc_sx_instance_model_class_init (GncSxInstanceModelClass *klass);
+static void gnc_sx_instance_model_init(GTypeInstance *instance, gpointer klass);
+static GncSxInstanceModel* gnc_sx_instance_model_new(void);
- /* private */
- gint qof_event_handler_id;
+static GncSxInstance* gnc_sx_instance_new(GncSxInstances *parent, GncSxInstanceType type, GDate *date, gint sequence_num);
- /* signals */
- /* void (*added)(GncSxInstance *sx); // gpointer user_data */
- /* void (*removed)(GncSxInstance *sx); // gpointer user_data */
- /* void (*changed)(GncSxInstance *inst); // gpointer user_data */
+static void sxsl_get_sx_vars(SchedXaction *sx, GHashTable *var_hash);
+static gint _get_vars_helper(Transaction *txn, void *var_hash_data);
+static void clear_variable_numerics(gpointer key, gpointer value, gpointer data);
+static int parse_vars_from_formula(const char *formula, GHashTable *varHash, gnc_numeric *result);
- /* public */
- GDate range_end;
- GList *sx_instance_list; /* <GncSxInstances*> */
-};
+static void gnc_util_copy_hash_table(GHashTable *from, GHashTable *to);
-typedef struct _GncSxInstanceModelClass
-{
- GObjectClass parent;
-
- guint removing_signal_id;
- guint updated_signal_id;
- guint added_signal_id;
-} GncSxInstanceModelClass;
-
-typedef struct _GncSxInstances
-{
- SchedXaction *sx;
-
- GDate next_instance_date;
-
- /** all: <GncSxInstance*> **/
- GList *ignored;
- GList *postponed;
- GList *upcoming;
- GList *remind;
-} GncSxInstances;
-
-typedef enum
-{
- IGNORED, POSTPONED, TO_CREATE, REMINDER, MAX_STATE
-} GncSxInstanceType;
-
-typedef struct _GncSxInstance
-{
- GncSxInstances *parent;
- GncSxInstanceType type;
- GDate date;
-} GncSxInstance;
-
-GType gnc_sx_instance_model_get_type(void);
-static void gnc_sx_instance_model_class_init (GncSxInstanceModelClass *klass);
-static void gnc_sx_instance_model_init(GTypeInstance *instance, gpointer klass);
-GncSxInstanceModel* gnc_sx_instance_model_new(void);
-
static void _gnc_sx_instance_event_handler(QofEntity *ent, QofEventId event_type, gpointer user_data, gpointer evt_data);
#define GNC_TYPE_SX_INSTANCE_MODEL (gnc_sx_instance_model_get_type ())
@@ -246,7 +204,6 @@
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);
@@ -806,6 +763,169 @@
/* ------------------------------------------------------------ */
+static int
+parse_vars_from_formula(const char *formula,
+ GHashTable *varHash,
+ gnc_numeric *result)
+{
+ gnc_numeric num;
+ char *errLoc;
+ int toRet = 0;
+
+ if (!gnc_exp_parser_parse_separate_vars(formula, &num, &errLoc, varHash))
+ {
+ toRet = -1;
+ }
+
+ if (result != NULL)
+ {
+ *result = num;
+ }
+
+ return toRet;
+}
+
+static void
+clear_variable_numerics(gpointer key, gpointer value, gpointer data)
+{
+ g_free((gnc_numeric*)value);
+ g_hash_table_insert((GHashTable*)data, key, NULL);
+}
+
+static gint
+_get_vars_helper(Transaction *txn, void *var_hash_data)
+{
+ GHashTable *var_hash = (GHashTable*)var_hash_data;
+ GList *split_list;
+ kvp_frame *kvpf;
+ kvp_value *kvp_val;
+ Split *s;
+ char *str;
+ gnc_commodity *first_cmdty = NULL;
+
+ split_list = xaccTransGetSplitList(txn);
+ if (split_list == NULL)
+ {
+ return 1;
+ }
+
+ for ( ; split_list; split_list = split_list->next)
+ {
+ gnc_commodity *split_cmdty = NULL;
+ GUID *acct_guid;
+ Account *acct;
+
+ s = (Split*)split_list->data;
+ kvpf = xaccSplitGetSlots(s);
+ kvp_val = kvp_frame_get_slot_path(kvpf,
+ GNC_SX_ID,
+ GNC_SX_ACCOUNT,
+ NULL);
+ acct_guid = kvp_value_get_guid(kvp_val);
+ acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
+ split_cmdty = xaccAccountGetCommodity(acct);
+ if (first_cmdty == NULL)
+ {
+ first_cmdty = split_cmdty;
+ }
+
+ if (! gnc_commodity_equal(split_cmdty, first_cmdty))
+ {
+ gnc_numeric *tmp_num;
+ GString *var_name = g_string_sized_new(16);
+ g_string_printf(var_name, "%s -> %s",
+ gnc_commodity_get_mnemonic(split_cmdty),
+ gnc_commodity_get_mnemonic(first_cmdty));
+ tmp_num = g_new0(gnc_numeric, 1);
+ *tmp_num = gnc_numeric_create(0, 1);
+ g_hash_table_insert(var_hash, g_strdup(var_name->str), tmp_num);
+ g_string_free(var_name, TRUE);
+ }
+
+ // existing... ------------------------------------------
+ kvp_val = kvp_frame_get_slot_path(kvpf,
+ GNC_SX_ID,
+ GNC_SX_CREDIT_FORMULA,
+ NULL);
+ if (kvp_val != NULL)
+ {
+ str = kvp_value_get_string(kvp_val);
+ if (str && strlen(str) != 0)
+ {
+ parse_vars_from_formula(str, var_hash, NULL);
+ }
+ }
+
+ kvp_val = kvp_frame_get_slot_path(kvpf,
+ GNC_SX_ID,
+ GNC_SX_DEBIT_FORMULA,
+ NULL);
+ if (kvp_val != NULL)
+ {
+ str = kvp_value_get_string(kvp_val);
+ if (str && strlen(str) != 0)
+ {
+ parse_vars_from_formula(str, var_hash, NULL);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void
+sxsl_get_sx_vars(SchedXaction *sx, GHashTable *var_hash)
+{
+ AccountGroup *template_group;
+ Account *sx_template_acct;
+ const char *sx_guid_str;
+
+ template_group = gnc_book_get_template_group(gnc_get_current_book());
+ sx_guid_str = guid_to_string(xaccSchedXactionGetGUID(sx));
+ /* Get account named after guid string. */
+ sx_template_acct = xaccGetAccountFromName(template_group, sx_guid_str);
+ xaccAccountForEachTransaction(sx_template_acct, _get_vars_helper, var_hash);
+
+ // @@fixme - This should actually create GncSxVariable structures.
+ g_hash_table_foreach(var_hash, clear_variable_numerics, (gpointer)var_hash);
+}
+
+static void
+_clone_hash_entry(gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *to = (GHashTable*)user_data;
+ g_hash_table_insert(to, key, value);
+}
+
+static void
+gnc_util_copy_hash_table(GHashTable *from, GHashTable *to)
+{
+ g_hash_table_foreach(from, _clone_hash_entry, (gpointer)to);
+}
+
+static GncSxInstance*
+gnc_sx_instance_new(GncSxInstances *parent, GncSxInstanceType type, GDate *date, gint sequence_num)
+{
+ GncSxInstance *rtn = g_new0(GncSxInstance, 1);
+ rtn->parent = parent;
+ rtn->type = type;
+ g_date_clear(&rtn->date, 1);
+ rtn->date = *date;
+
+ if (! parent->variable_names_parsed)
+ {
+ parent->variable_names = g_hash_table_new(g_str_hash, g_str_equal);
+ sxsl_get_sx_vars(parent->sx, parent->variable_names);
+ parent->variable_names_parsed = TRUE;
+
+ // @@fixme: add sequence_num as `i`, non-editable
+ }
+
+ rtn->variable_bindings = g_hash_table_new(g_str_hash, g_str_equal);
+ gnc_util_copy_hash_table(parent->variable_names, rtn->variable_bindings);
+ return rtn;
+}
+
static GncSxInstances*
_gnc_sx_gen_instances(gpointer *data, gpointer user_data)
{
@@ -825,7 +945,18 @@
/* postponed */
{
- /* @@fixme - defer list. */
+ GList *postponed = gnc_sx_get_defer_instances(sx);
+ for ( ; postponed != NULL; postponed = g_list_next(postponed))
+ {
+ GDate inst_date;
+ int seq_num;
+ GncSxInstance *inst;
+
+ inst_date = xaccSchedXactionGetNextInstance(sx, postponed->data);
+ seq_num = gnc_sx_get_instance_count(sx, postponed->data);
+ inst = gnc_sx_instance_new(instances, POSTPONED, &inst_date, seq_num);
+ instances->list = g_list_append(instances->list, inst);
+ }
}
/* to-create */
@@ -833,19 +964,13 @@
sequence_ctx = gnc_sx_create_temporal_state(sx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
instances->next_instance_date = cur_date;
-
- while (g_date_valid(&cur_date)
- && (g_date_compare(&cur_date, &creation_end) <= 0))
+ while (g_date_valid(&cur_date) && g_date_compare(&cur_date, &creation_end) <= 0)
{
GncSxInstance *inst;
- inst = g_new0(GncSxInstance, 1);
- inst->parent = instances;
- inst->type = TO_CREATE;
- g_date_clear(&inst->date, 1);
- inst->date = cur_date;
-
- instances->upcoming = g_list_append(instances->upcoming, inst);
-
+ int seq_num;
+ seq_num = gnc_sx_get_instance_count(sx, sequence_ctx);
+ inst = gnc_sx_instance_new(instances, TO_CREATE, &cur_date, seq_num);
+ instances->list = g_list_append(instances->list, inst);
gnc_sx_incr_temporal_state(sx, sequence_ctx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
}
@@ -854,14 +979,10 @@
while (g_date_valid(&cur_date) && g_date_compare(&cur_date, &remind_end) <= 0)
{
GncSxInstance *inst;
- inst = g_new0(GncSxInstance, 1);
- inst->parent = instances;
- inst->type = REMINDER;
- g_date_clear(&inst->date, 1);
- inst->date = cur_date;
-
- instances->remind = g_list_append(instances->remind, inst);
-
+ int seq_num;
+ seq_num = gnc_sx_get_instance_count(sx, sequence_ctx);
+ inst = gnc_sx_instance_new(instances, REMINDER, &cur_date, seq_num);
+ instances->list = g_list_append(instances->list, inst);
gnc_sx_incr_temporal_state(sx, sequence_ctx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
}
@@ -886,7 +1007,7 @@
return instances;
}
-GncSxInstanceModel*
+static GncSxInstanceModel*
gnc_sx_instance_model_new(void)
{
return GNC_SX_INSTANCE_MODEL(g_object_new(GNC_TYPE_SX_INSTANCE_MODEL, NULL));
@@ -1204,7 +1325,7 @@
= (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
if (insts == NULL)
return 0;
- return g_list_length(insts->upcoming);
+ return g_list_length(insts->list);
}
static void
@@ -1216,7 +1337,7 @@
= (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
if (insts == NULL)
return;
- inst = (GncSxInstance*)g_list_nth_data(insts->upcoming, instance_index);
+ inst = (GncSxInstance*)g_list_nth_data(insts->list, instance_index);
g_date_valid(&inst->date);
*date = inst->date;
g_date_valid(date);
Modified: gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.h
===================================================================
--- gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.h 2006-09-15 21:11:56 UTC (rev 14851)
+++ gnucash/branches/sx-cleanup/src/gnome/gnc-plugin-page-sx-list.h 2006-09-16 18:56:44 UTC (rev 14852)
@@ -32,6 +32,8 @@
#ifndef __GNC_PLUGIN_PAGE_SX_LIST_H
#define __GNC_PLUGIN_PAGE_SX_LIST_H
+#include "config.h"
+#include <glib/gi18n.h>
#include <gtk/gtkwindow.h>
#include "SchedXaction.h"
#include "gnc-plugin-page.h"
@@ -72,6 +74,73 @@
**/
GncPluginPage *gnc_plugin_page_sx_list_new (void);
+
+/** ------------------------------------------------------------ **/
+typedef struct _GncSxInstanceDenseCalAdapter GncSxInstanceDenseCalAdapter;
+typedef struct _GncSxInstanceModel GncSxInstanceModel;
+typedef struct _GncSxListTreeModelAdapter GncSxListTreeModelAdapter;
+
+struct _GncSxInstanceModel
+{
+ GObject parent;
+
+ /* private */
+ gint qof_event_handler_id;
+
+ /* signals */
+ /* void (*added)(GncSxInstance *sx); // gpointer user_data */
+ /* void (*removed)(GncSxInstance *sx); // gpointer user_data */
+ /* void (*changed)(GncSxInstance *inst); // gpointer user_data */
+
+ /* public */
+ GDate range_end;
+ GList *sx_instance_list; /* <GncSxInstances*> */
+};
+
+typedef struct _GncSxInstanceModelClass
+{
+ GObjectClass parent;
+
+ guint removing_signal_id;
+ guint updated_signal_id;
+ guint added_signal_id;
+} GncSxInstanceModelClass;
+
+typedef struct _GncSxInstances
+{
+ SchedXaction *sx;
+ GHashTable /** <char*,NULL> **/ *variable_names;
+ gboolean variable_names_parsed;
+
+ GDate next_instance_date;
+
+ /** GList<GncSxInstance*> **/
+ GList *list;
+} GncSxInstances;
+
+typedef enum
+{
+ IGNORED, POSTPONED, TO_CREATE, REMINDER, MAX_STATE
+} GncSxInstanceType;
+
+typedef struct _GncSxVariable
+{
+ GString *name;
+ GString *value;
+ gboolean editable;
+} GncSxVariable;
+
+typedef struct _GncSxInstance
+{
+ GncSxInstances *parent;
+ GncSxInstanceType type;
+ GDate date;
+ GHashTable *variable_bindings;
+} GncSxInstance;
+
+GncSxInstanceModel* gnc_sx_get_instances(GDate *range_end);
+/** ------------------------------------------------------------ **/
+
G_END_DECLS
#endif /* __GNC_PLUGIN_PAGE_SX_LIST_H */
More information about the gnucash-changes
mailing list